From 741946e98020ea8c6e60ddfde583f6ebbfc2f24a Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 15:40:41 +0100 Subject: [PATCH 001/115] Initial REST implementation --- README.md | 18 +++++++- requirements.txt | 2 + thothrest/__init__.py | 0 thothrest/cli.py | 23 ++++++++++ thothrest/client.py | 76 +++++++++++++++++++++++++++++++ thothrest/errors.py | 14 ++++++ thothrest/thoth-042/__init__.py | 0 thothrest/thoth-042/structures.py | 31 +++++++++++++ 8 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 thothrest/__init__.py create mode 100644 thothrest/cli.py create mode 100644 thothrest/client.py create mode 100644 thothrest/errors.py create mode 100644 thothrest/thoth-042/__init__.py create mode 100644 thothrest/thoth-042/structures.py diff --git a/README.md b/README.md index 1665ca0..d13db5a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -Python client for Thoth's GraphQL API +Python client for Thoth's GraphQL and REST APIs [![Build Status](https://travis-ci.org/openbookpublishers/thoth-client.svg?branch=master)](https://travis-ci.org/openbookpublishers/thoth-client) [![Release](https://img.shields.io/github/release/openbookpublishers/thoth-client.svg?colorB=58839b)](https://github.com/openbookpublishers/thoth-client/releases) [![License](https://img.shields.io/github/license/openbookpublishers/thoth-client.svg?colorB=ff0000)](https://github.com/openbookpublishers/thoth-client/blob/master/LICENSE) ## Usage +### Install ```sh python3 -m pip install thothlibrary==0.5.0 ``` +### GraphQL Usage ```python from thothlibrary import ThothClient @@ -16,3 +18,17 @@ all_works = thoth.works() print(all_works) ``` +### REST Usage +```python +from thothlibrary import ThothRESTClient + +client = ThothRESTClient() +print(client.formats()) +``` + +### CLI REST Usage +```sh +python3 ./thothrest/cli.py +python3 ./thothrest/cli.py formats +python3 ./thothrest/cli.py formats --return-json +``` diff --git a/requirements.txt b/requirements.txt index 9b7a4e2..3322222 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ graphqlclient==0.2.4 requests==2.24.0 +fire +munch \ No newline at end of file diff --git a/thothrest/__init__.py b/thothrest/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothrest/cli.py b/thothrest/cli.py new file mode 100644 index 0000000..6ee3d60 --- /dev/null +++ b/thothrest/cli.py @@ -0,0 +1,23 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +import fire +from client import ThothRESTClient + + +class ThothCLI(object): + """A simple CLI for Thoth REST.""" + + def formats(self, return_json=False): + """ + Full list of metadata formats that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + """ + client = ThothRESTClient() + print(client.formats(return_json)) + + +if __name__ == '__main__': + fire.Fire(ThothCLI) diff --git a/thothrest/client.py b/thothrest/client.py new file mode 100644 index 0000000..14b34b9 --- /dev/null +++ b/thothrest/client.py @@ -0,0 +1,76 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +import json +from collections import namedtuple + +import requests +from errors import ThothRESTError +import importlib + + +class ThothRESTClient: + """A client for Thoth's REST API""" + endpoint = 'https://export.thoth.pub' + version = '042' + + def __init__(self, endpoint='https://export.thoth.pub', version='0.4.2'): + """ + A REST client for Thoth + @param endpoint: the endpoint of the server instance to use + @param version: the version of the API to use + """ + self.endpoint = endpoint + self.version = version.replace('.', '') + + def formats(self, return_json=False): + """ + Full list of metadata formats that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @return: an object or JSON + """ + return self._api_request('formats', '/formats/', return_json) + + def _api_request(self, endpoint_name, url_suffix, return_json=False): + """ + Makes a request to the API + @param endpoint_name: the name of the endpoint + @param url_suffix: the URL suffix + @param return_json: whether to return raw JSON or an object (default) + @return: an object or JSON of the request + """ + response = self._fetch_json(url_suffix) + + if return_json: + return response + else: + return self._build_structure(endpoint_name, response) + + def _build_structure(self, endpoint_name, data): + """ + Builds an object structure for an endpoint + @param endpoint_name: the name of the endpoint + @param data: the data + @return: an object form of the output + """ + structures = importlib.import_module('thoth-{0}.structures'.format(self.version)) + builder = structures.StructureBuilder(endpoint_name, data) + return builder.create_structure() + + def _fetch_json(self, url_suffix): + """ + Fetches JSON from the REST endpoint + @param url_suffix: the URL suffix for the entry + @return: a requests response object + """ + try: + resp = requests.get(self.endpoint + url_suffix) + + if resp.status_code != 200: + raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), resp.status_code) + + return resp.json() + except requests.exceptions.RequestException as e: + raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), e) diff --git a/thothrest/errors.py b/thothrest/errors.py new file mode 100644 index 0000000..f9dddac --- /dev/null +++ b/thothrest/errors.py @@ -0,0 +1,14 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" + + +class ThothRESTError(Exception): + """Exception to report Thoth errors""" + + def __init__(self, request, response): + message = "REST Error.\nRequest:\n{}\n\nResponse:\n{}".format( + request, response) + super().__init__(message) diff --git a/thothrest/thoth-042/__init__.py b/thothrest/thoth-042/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-042/structures.py new file mode 100644 index 0000000..4559fa9 --- /dev/null +++ b/thothrest/thoth-042/structures.py @@ -0,0 +1,31 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +from munch import Munch + +default_fields = {'formats': 'id'} + + +class StructureBuilder: + """A class to build a Thoth object structure""" + def __init__(self, structure, data): + self.structure = structure + self.data = data + + def create_structure(self): + """ + Creates an object structure from dictionary input + @return: an object + """ + structures = [] + for item in self.data: + x = Munch.fromDict(item) + if self.structure in default_fields.keys(): + struct = default_fields[self.structure] + Munch.__repr__ = Munch.__str__ + Munch.__str__ = lambda self: self[struct] + structures.append(x) + + return structures From da6faaaad81e41ccea8746fb9ac2f9f9e4e0d80d Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 15:41:27 +0100 Subject: [PATCH 002/115] Remove unused imports --- thothrest/client.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/thothrest/client.py b/thothrest/client.py index 14b34b9..b00128f 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -3,9 +3,6 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ -import json -from collections import namedtuple - import requests from errors import ThothRESTError import importlib From ada69c37652f16dece58560c287108910a3ed891 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 16:10:05 +0100 Subject: [PATCH 003/115] Rework structure builder --- thothrest/thoth-042/structures.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-042/structures.py index 4559fa9..34a8b13 100644 --- a/thothrest/thoth-042/structures.py +++ b/thothrest/thoth-042/structures.py @@ -5,7 +5,8 @@ """ from munch import Munch -default_fields = {'formats': 'id'} +default_fields = {'formats': 'id', + 'format': 'name'} class StructureBuilder: @@ -20,12 +21,20 @@ def create_structure(self): @return: an object """ structures = [] - for item in self.data: - x = Munch.fromDict(item) - if self.structure in default_fields.keys(): - struct = default_fields[self.structure] - Munch.__repr__ = Munch.__str__ - Munch.__str__ = lambda self: self[struct] - structures.append(x) + if isinstance(self.data, list): + for item in self.data: + x = self._munch(item) + structures.append(x) + else: + x = self._munch(self.data) + return x return structures + + def _munch(self, item): + x = Munch.fromDict(item) + if self.structure in default_fields.keys(): + struct = default_fields[self.structure] + Munch.__repr__ = Munch.__str__ + Munch.__str__ = lambda self: self[struct] + return x From 207257d2fdd1b3ff00e1e640a635a9bf15f96593 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 16:10:14 +0100 Subject: [PATCH 004/115] Add format endpoint --- thothrest/cli.py | 33 +++++++++++++++++++++------------ thothrest/client.py | 9 +++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/thothrest/cli.py b/thothrest/cli.py index 6ee3d60..362012f 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -3,21 +3,30 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ -import fire -from client import ThothRESTClient -class ThothCLI(object): - """A simple CLI for Thoth REST.""" +def _client(): + from client import ThothRESTClient + return ThothRESTClient() - def formats(self, return_json=False): - """ - Full list of metadata formats that can be output by Thoth - @param return_json: whether to return JSON or an object (default) - """ - client = ThothRESTClient() - print(client.formats(return_json)) + +def formats(json=False): + """ + Full list of metadata formats that can be output by Thoth + @param json: whether to return JSON or an object (default) + """ + print(_client().formats(json)) + + +def format(identifier, json=False): + """ + Find the details of a format that can be output by Thoth + @param identifier: the format ID to describe + @param json: whether to return JSON or an object (default) + """ + print(_client().format(identifier, json)) if __name__ == '__main__': - fire.Fire(ThothCLI) + import fire + fire.Fire() diff --git a/thothrest/client.py b/thothrest/client.py index b00128f..e5151f8 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -30,6 +30,15 @@ def formats(self, return_json=False): """ return self._api_request('formats', '/formats/', return_json) + def format(self, identifier, return_json=False): + """ + Find the details of a format that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @param identifier: the format ID to describe + @return: an object or JSON + """ + return self._api_request('format', '/formats/{0}'.format(identifier), return_json) + def _api_request(self, endpoint_name, url_suffix, return_json=False): """ Makes a request to the API From 38720d1f06040e2acd98f4e404f9e56f347bf8cc Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 16:13:45 +0100 Subject: [PATCH 005/115] Add specifications endpoint --- thothrest/cli.py | 8 ++++++++ thothrest/client.py | 8 ++++++++ thothrest/thoth-042/structures.py | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/thothrest/cli.py b/thothrest/cli.py index 362012f..c8d4ee6 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -27,6 +27,14 @@ def format(identifier, json=False): print(_client().format(identifier, json)) +def specifications(json=False): + """ + Full list of metadata specifications that can be output by Thoth + @param json: whether to return JSON or an object (default) + """ + print(_client().specifications(json)) + + if __name__ == '__main__': import fire fire.Fire() diff --git a/thothrest/client.py b/thothrest/client.py index e5151f8..a377523 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -39,6 +39,14 @@ def format(self, identifier, return_json=False): """ return self._api_request('format', '/formats/{0}'.format(identifier), return_json) + def specifications(self, return_json=False): + """ + Full list of metadata specifications that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @return: an object or JSON + """ + return self._api_request('specifications', '/specifications/', return_json) + def _api_request(self, endpoint_name, url_suffix, return_json=False): """ Makes a request to the API diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-042/structures.py index 34a8b13..7d3754a 100644 --- a/thothrest/thoth-042/structures.py +++ b/thothrest/thoth-042/structures.py @@ -6,7 +6,8 @@ from munch import Munch default_fields = {'formats': 'id', - 'format': 'name'} + 'format': 'name', + 'specifications': 'name'} class StructureBuilder: From 63e884ee818a08bc3a203ac889219d2e6b4a9bbd Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 16:16:49 +0100 Subject: [PATCH 006/115] Add specification endpoint --- thothrest/cli.py | 9 +++++++++ thothrest/client.py | 9 +++++++++ thothrest/thoth-042/structures.py | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/thothrest/cli.py b/thothrest/cli.py index c8d4ee6..0ae1639 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -35,6 +35,15 @@ def specifications(json=False): print(_client().specifications(json)) +def specification(identifier, json=False): + """ + Find the details of a metadata specification that can be output by Thoth + @param identifier: the format ID to describe + @param json: whether to return JSON or an object (default) + """ + print(_client().specification(identifier, json)) + + if __name__ == '__main__': import fire fire.Fire() diff --git a/thothrest/client.py b/thothrest/client.py index a377523..dc02eb5 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -47,6 +47,15 @@ def specifications(self, return_json=False): """ return self._api_request('specifications', '/specifications/', return_json) + def specification(self, identifier, return_json=False): + """ + Find the details of a metadata specification that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @param identifier: the specification ID to describe + @return: an object or JSON + """ + return self._api_request('specification', '/specifications/{0}'.format(identifier), return_json) + def _api_request(self, endpoint_name, url_suffix, return_json=False): """ Makes a request to the API diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-042/structures.py index 7d3754a..24774bb 100644 --- a/thothrest/thoth-042/structures.py +++ b/thothrest/thoth-042/structures.py @@ -7,7 +7,8 @@ default_fields = {'formats': 'id', 'format': 'name', - 'specifications': 'name'} + 'specifications': 'name', + 'specification': 'name'} class StructureBuilder: From 77d01f01e2ef6265b9d00ac67cd3898deac0a965 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 16:20:02 +0100 Subject: [PATCH 007/115] Add platforms endpoint --- thothrest/cli.py | 8 ++++++++ thothrest/client.py | 8 ++++++++ thothrest/thoth-042/structures.py | 8 +++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/thothrest/cli.py b/thothrest/cli.py index 0ae1639..1d0f097 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -44,6 +44,14 @@ def specification(identifier, json=False): print(_client().specification(identifier, json)) +def platforms(json=False): + """ + Full list of metadata specifications that can be output by Thoth + @param json: whether to return JSON or an object (default) + """ + print(_client().platforms(json)) + + if __name__ == '__main__': import fire fire.Fire() diff --git a/thothrest/client.py b/thothrest/client.py index dc02eb5..185c630 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -56,6 +56,14 @@ def specification(self, identifier, return_json=False): """ return self._api_request('specification', '/specifications/{0}'.format(identifier), return_json) + def platforms(self, return_json=False): + """ + Full list of platforms supported by Thoth's outputs + @param return_json: whether to return JSON or an object (default) + @return: an object or JSON + """ + return self._api_request('platforms', '/platforms/', return_json) + def _api_request(self, endpoint_name, url_suffix, return_json=False): """ Makes a request to the API diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-042/structures.py index 24774bb..b790b25 100644 --- a/thothrest/thoth-042/structures.py +++ b/thothrest/thoth-042/structures.py @@ -8,7 +8,8 @@ default_fields = {'formats': 'id', 'format': 'name', 'specifications': 'name', - 'specification': 'name'} + 'specification': 'name', + 'platforms': 'name'} class StructureBuilder: @@ -34,6 +35,11 @@ def create_structure(self): return structures def _munch(self, item): + """ + Converts our JSON or dict object into an addressable object + @param item: the item to convert + @return: a converted object with string representation + """ x = Munch.fromDict(item) if self.structure in default_fields.keys(): struct = default_fields[self.structure] From edeab99194eb9b35496eac9edff952adadb95668 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 16:30:44 +0100 Subject: [PATCH 008/115] Add work export --- README.md | 1 + thothrest/cli.py | 19 +++++++++++++++++ thothrest/client.py | 34 +++++++++++++++++++++++++------ thothrest/thoth-042/structures.py | 3 ++- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d13db5a..1a871c7 100644 --- a/README.md +++ b/README.md @@ -31,4 +31,5 @@ print(client.formats()) python3 ./thothrest/cli.py python3 ./thothrest/cli.py formats python3 ./thothrest/cli.py formats --return-json +python3 ./cli.py work onix_3.0::project_muse e0f748b2-984f-45cc-8b9e-13989c31dda4 ``` diff --git a/thothrest/cli.py b/thothrest/cli.py index 1d0f097..0e2fd97 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -52,6 +52,25 @@ def platforms(json=False): print(_client().platforms(json)) +def platform(identifier, json=False): + """ + Find the details of a platform supported by Thoth's outputs + @param identifier: the format ID to describe + @param json: whether to return JSON or an object (default) + """ + print(_client().platform(identifier, json)) + + +def work(identifier, work): + """ + Find the details of a platform supported by Thoth's outputs + @param identifier: the spefication ID + @param work: the work ID + @param json: whether to return JSON or an object (default) + """ + print(_client().work(identifier, work)) + + if __name__ == '__main__': import fire fire.Fire() diff --git a/thothrest/client.py b/thothrest/client.py index 185c630..c6d519a 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -64,20 +64,42 @@ def platforms(self, return_json=False): """ return self._api_request('platforms', '/platforms/', return_json) - def _api_request(self, endpoint_name, url_suffix, return_json=False): + def platform(self, identifier, return_json=False): + """ + Find the details of a metadata specification that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @param identifier: the specification ID to describe + @return: an object or JSON + """ + return self._api_request('platform', '/platforms/{0}'.format(identifier), return_json) + + def work(self, identifier, work, return_json=False): + """ + Obtain a metadata record that adheres to a particular specification for a given work + @param return_json: whether to return JSON or an object (default) + @param identifier: the specification ID + @param identifier: the work ID + @return: an object or JSON + """ + return self._api_request('work', '/specifications/{0}/work/{1}'.format(identifier, work), False, True) + + def _api_request(self, endpoint_name, url_suffix, return_json=False, return_raw=False): """ Makes a request to the API @param endpoint_name: the name of the endpoint @param url_suffix: the URL suffix @param return_json: whether to return raw JSON or an object (default) + @param return_raw: whether to return the raw data returned @return: an object or JSON of the request """ - response = self._fetch_json(url_suffix) + response = self._fetch(url_suffix) if return_json: - return response + return response.json() + elif return_raw: + return response.text else: - return self._build_structure(endpoint_name, response) + return self._build_structure(endpoint_name, response.json()) def _build_structure(self, endpoint_name, data): """ @@ -90,7 +112,7 @@ def _build_structure(self, endpoint_name, data): builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() - def _fetch_json(self, url_suffix): + def _fetch(self, url_suffix): """ Fetches JSON from the REST endpoint @param url_suffix: the URL suffix for the entry @@ -102,6 +124,6 @@ def _fetch_json(self, url_suffix): if resp.status_code != 200: raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), resp.status_code) - return resp.json() + return resp except requests.exceptions.RequestException as e: raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), e) diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-042/structures.py index b790b25..7dda5e1 100644 --- a/thothrest/thoth-042/structures.py +++ b/thothrest/thoth-042/structures.py @@ -9,7 +9,8 @@ 'format': 'name', 'specifications': 'name', 'specification': 'name', - 'platforms': 'name'} + 'platforms': 'name', + 'platform': 'name'} class StructureBuilder: From 212d28bff9e089319df874f2970ea71048d1f898 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Tue, 27 Jul 2021 17:22:38 +0100 Subject: [PATCH 009/115] Refactor to allow version specific endpoints --- thothrest/cli.py | 19 +++++-- thothrest/client.py | 67 +++-------------------- thothrest/thoth-042/endpoints.py | 91 ++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 65 deletions(-) create mode 100644 thothrest/thoth-042/endpoints.py diff --git a/thothrest/cli.py b/thothrest/cli.py index 0e2fd97..ce37956 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -61,16 +61,25 @@ def platform(identifier, json=False): print(_client().platform(identifier, json)) -def work(identifier, work): +def work(identifier, work_identifier): """ Find the details of a platform supported by Thoth's outputs - @param identifier: the spefication ID - @param work: the work ID - @param json: whether to return JSON or an object (default) + @param identifier: the specification ID + @param work_identifier: the work ID + """ + print(_client().work(identifier, work_identifier)) + + +def works(identifier, publisher): + """ + Obtain a metadata record that adheres to a particular specification for all of a given publisher's works + @param identifier: the specification ID + @param publisher: the publisher ID """ - print(_client().work(identifier, work)) + print(_client().works(identifier, publisher)) if __name__ == '__main__': import fire + fire.Fire() diff --git a/thothrest/client.py b/thothrest/client.py index c6d519a..fd7dab1 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -3,6 +3,8 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ +import sys + import requests from errors import ThothRESTError import importlib @@ -22,66 +24,11 @@ def __init__(self, endpoint='https://export.thoth.pub', version='0.4.2'): self.endpoint = endpoint self.version = version.replace('.', '') - def formats(self, return_json=False): - """ - Full list of metadata formats that can be output by Thoth - @param return_json: whether to return JSON or an object (default) - @return: an object or JSON - """ - return self._api_request('formats', '/formats/', return_json) - - def format(self, identifier, return_json=False): - """ - Find the details of a format that can be output by Thoth - @param return_json: whether to return JSON or an object (default) - @param identifier: the format ID to describe - @return: an object or JSON - """ - return self._api_request('format', '/formats/{0}'.format(identifier), return_json) - - def specifications(self, return_json=False): - """ - Full list of metadata specifications that can be output by Thoth - @param return_json: whether to return JSON or an object (default) - @return: an object or JSON - """ - return self._api_request('specifications', '/specifications/', return_json) - - def specification(self, identifier, return_json=False): - """ - Find the details of a metadata specification that can be output by Thoth - @param return_json: whether to return JSON or an object (default) - @param identifier: the specification ID to describe - @return: an object or JSON - """ - return self._api_request('specification', '/specifications/{0}'.format(identifier), return_json) - - def platforms(self, return_json=False): - """ - Full list of platforms supported by Thoth's outputs - @param return_json: whether to return JSON or an object (default) - @return: an object or JSON - """ - return self._api_request('platforms', '/platforms/', return_json) - - def platform(self, identifier, return_json=False): - """ - Find the details of a metadata specification that can be output by Thoth - @param return_json: whether to return JSON or an object (default) - @param identifier: the specification ID to describe - @return: an object or JSON - """ - return self._api_request('platform', '/platforms/{0}'.format(identifier), return_json) - - def work(self, identifier, work, return_json=False): - """ - Obtain a metadata record that adheres to a particular specification for a given work - @param return_json: whether to return JSON or an object (default) - @param identifier: the specification ID - @param identifier: the work ID - @return: an object or JSON - """ - return self._api_request('work', '/specifications/{0}/work/{1}'.format(identifier, work), False, True) + # this is the only magic part + # this basically delegates to the 'endpoints' module inside the current API version + # the constructor function there dynamically adds the methods that are supported in any API version + endpoints = importlib.import_module('thoth-{0}.endpoints'.format(self.version)) + getattr(endpoints, 'ThothRESTClient{0}'.format(self.version))(self) def _api_request(self, endpoint_name, url_suffix, return_json=False, return_raw=False): """ diff --git a/thothrest/thoth-042/endpoints.py b/thothrest/thoth-042/endpoints.py new file mode 100644 index 0000000..a85b899 --- /dev/null +++ b/thothrest/thoth-042/endpoints.py @@ -0,0 +1,91 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +from client import ThothRESTClient + + +class ThothRESTClient042(ThothRESTClient): + + def __init__(self, input_class): + # this is the magic dynamic generation part that wires up the methods + input_class.formats = getattr(self, 'formats') + input_class.format = getattr(self, 'format') + input_class.specifications = getattr(self, 'specifications') + input_class.specification = getattr(self, 'specification') + input_class.platform = getattr(self, 'platform') + input_class.platforms = getattr(self, 'platforms') + input_class.work = getattr(self, 'work') + input_class.works = getattr(self, 'works') + + def formats(self, return_json=False): + """ + Full list of metadata formats that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @return: an object or JSON + """ + return self._api_request('formats', '/formats/', return_json) + + def format(self, identifier, return_json=False): + """ + Find the details of a format that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @param identifier: the format ID to describe + @return: an object or JSON + """ + return self._api_request('format', '/formats/{0}'.format(identifier), return_json) + + def specifications(self, return_json=False): + """ + Full list of metadata specifications that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @return: an object or JSON + """ + return self._api_request('specifications', '/specifications/', return_json) + + def specification(self, identifier, return_json=False): + """ + Find the details of a metadata specification that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @param identifier: the specification ID to describe + @return: an object or JSON + """ + return self._api_request('specification', '/specifications/{0}'.format(identifier), return_json) + + def platforms(self, return_json=False): + """ + Full list of platforms supported by Thoth's outputs + @param return_json: whether to return JSON or an object (default) + @return: an object or JSON + """ + return self._api_request('platforms', '/platforms/', return_json) + + def platform(self, identifier, return_json=False): + """ + Find the details of a metadata specification that can be output by Thoth + @param return_json: whether to return JSON or an object (default) + @param identifier: the platform ID + @return: an object or JSON + """ + return self._api_request('platform', '/platforms/{0}'.format(identifier), return_json) + + def work(self, identifier, work_identifier): + """ + Obtain a metadata record that adheres to a particular specification for a given work + @param identifier: the specification ID + @param work_identifier: the work ID + @return: the metadata record + """ + return self._api_request('work', + '/specifications/{0}/work/{1}'.format(identifier, work_identifier), False, True) + + def works(self, identifier, publisher): + """ + Obtain a metadata record that adheres to a particular specification for all of a given publisher's works + @param identifier: the specification ID + @param publisher: the publisher ID + @return: an object or JSON + """ + return self._api_request('publisher', + '/specifications/{0}/publisher/{1}'.format(identifier, publisher), False, True) From 9fac39b500dea485ad52d3303f77f4888c8f8771 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 13:15:16 +0100 Subject: [PATCH 010/115] First version of client API. Includes: * Versioning of API * Dynamic module imports to allow incremental versioning * Dynamic string formatting of parsed objects * Works query --- README.md | 11 ++- thothlibrary/auth.py | 2 +- thothlibrary/cli.py | 71 ++++++++++++++ thothlibrary/client.py | 60 +++++++++--- thothlibrary/mutation.py | 2 +- thothlibrary/query.py | 72 ++++---------- thothlibrary/thoth-0_4_2/__init__.py | 0 thothlibrary/thoth-0_4_2/endpoints.py | 125 +++++++++++++++++++++++++ thothlibrary/thoth-0_4_2/structures.py | 90 ++++++++++++++++++ 9 files changed, 357 insertions(+), 76 deletions(-) create mode 100644 thothlibrary/cli.py create mode 100644 thothlibrary/thoth-0_4_2/__init__.py create mode 100644 thothlibrary/thoth-0_4_2/endpoints.py create mode 100644 thothlibrary/thoth-0_4_2/structures.py diff --git a/README.md b/README.md index 1a871c7..0c9064d 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,16 @@ python3 -m pip install thothlibrary==0.5.0 ```python from thothlibrary import ThothClient -thoth = ThothClient() -all_works = thoth.works() -print(all_works) +thoth = ThothClient(version="0.4.2") +print(thoth.works()) ``` +### CLI GraphQL Usage +```sh +python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 +``` + + ### REST Usage ```python from thothlibrary import ThothRESTClient diff --git a/thothlibrary/auth.py b/thothlibrary/auth.py index 46f8938..02d6b6d 100644 --- a/thothlibrary/auth.py +++ b/thothlibrary/auth.py @@ -10,7 +10,7 @@ import json import urllib import requests -from .errors import ThothError +from errors import ThothError class ThothAuthenticator(): # pylint: disable=too-few-public-methods diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py new file mode 100644 index 0000000..30bd4ba --- /dev/null +++ b/thothlibrary/cli.py @@ -0,0 +1,71 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" + +from fire import decorators + + +def _client(): + """ + Returns a ThothClient object + @return: + """ + from client import ThothClient + return ThothClient(version="0.4.2") + + +def _raw_parse(value): + """ + This function overrides fire's default argument parsing using decorators. + We need this because, otherwise, fire converts '{field: x}' to a + dictionary object, which messes with GraphQL parameters. + @param value: the input value + @return: the parsed value + """ + return value + + +@decorators.SetParseFn(_raw_parse) +def works(limit=100, order=None, offset=0, publishers=None, filter_str=None, + work_type=None, work_status=None, raw=False): + """ + A list of works + @param limit: the maximum number of results to return + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results + @param publishers: a list of publishers to limit by + @param filter_str: a filter string to search + @param work_type: the work type (e.g. MONOGRAPH) + @param work_status: the work status (e.g. ACTIVE) + @param raw: whether to return a python object or the raw server result + """ + print(*_client().works(limit=limit, order=order, offset=offset, + publishers=publishers, filter_str=filter_str, + work_type=work_type, work_status=work_status, + raw=raw), sep='\n') + + +def works_from_publisher(publishers_id=None, limit=100, offset=0): + """ + Get a list of works from a specific publisher + @param publishers_id: the ID of the publishers + @param limit: the maximum number of results to return (-1 for all) + @param offset: the offset from which to return results + """ + print(_client().works(limit=limit, publishers=publishers_id, offset=offset)) + + +def publishers(json=False): + """ + Full list of metadata formats that can be output by Thoth + @param json: whether to return JSON or an object (default) + """ + print(_client().publishers()) + + +if __name__ == '__main__': + import fire + + fire.Fire() diff --git a/thothlibrary/client.py b/thothlibrary/client.py index ab5230a..37cd9aa 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -5,18 +5,18 @@ This programme is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ - +import importlib from graphqlclient import GraphQLClient -from .auth import ThothAuthenticator -from .mutation import ThothMutation -from .query import ThothQuery +from auth import ThothAuthenticator +from mutation import ThothMutation +from query import ThothQuery class ThothClient(): """Client to Thoth's GraphQL API""" - def __init__(self, thoth_endpoint="https://api.thoth.pub"): + def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """Returns new ThothClient object at the specified GraphQL endpoint thoth_endpoint: Must be the full URL (eg. 'http://localhost'). @@ -24,6 +24,16 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub"): self.auth_endpoint = "{}/account/login".format(thoth_endpoint) self.graphql_endpoint = "{}/graphql".format(thoth_endpoint) self.client = GraphQLClient(self.graphql_endpoint) + self.version = version.replace('.', '_') + + # this is the only magic part for queries + # it delegates to the 'endpoints' module inside the current API version + # the constructor function there dynamically adds the methods that are + # supported in any API version + if issubclass(ThothClient, type(self)): + endpoints = importlib.import_module('thoth-{0}.end' + 'points'.format(self.version)) + getattr(endpoints, 'ThothClient{0}'.format(self.version))(self) def login(self, email, password): """Obtain an authentication token""" @@ -38,18 +48,9 @@ def mutation(self, mutation_name, data): def query(self, query_name, parameters): """Instantiate a thoth query and execute""" - query = ThothQuery(query_name, parameters) + query = ThothQuery(query_name, parameters, self.QUERIES) return query.run(self.client) - def works(self, limit: int = 100, offset: int = 0, filter_str: str = ""): - """Construct and trigger a query to obtain all works""" - parameters = { - "limit": limit, - "offset": offset, - "filter": filter_str, - } - return self.query("works", parameters) - def create_publisher(self, publisher): """Construct and trigger a mutation to add a new publisher object""" return self.mutation("createPublisher", publisher) @@ -93,3 +94,32 @@ def create_contributor(self, contributor): def create_contribution(self, contribution): """Construct and trigger a mutation to add a new contribution object""" return self.mutation("createContribution", contribution) + + def _api_request(self, endpoint_name: str, parameters, + return_raw: bool = False): + """ + Makes a request to the API + @param endpoint_name: the name of the endpoint + @param url_suffix: the URL suffix + @param return_json: whether to return raw JSON or an object (default) + @param return_raw: whether to return the raw data returned + @return: an object or JSON of the request + """ + response = self.query(endpoint_name, parameters) + + if return_raw: + return response + else: + return self._build_structure(endpoint_name, response) + + def _build_structure(self, endpoint_name, data): + """ + Builds an object structure for an endpoint + @param endpoint_name: the name of the endpoint + @param data: the data + @return: an object form of the output + """ + structures = \ + importlib.import_module('thoth-{0}.structures'.format(self.version)) + builder = structures.StructureBuilder(endpoint_name, data) + return builder.create_structure() diff --git a/thothlibrary/mutation.py b/thothlibrary/mutation.py index 4a265a0..30b9571 100644 --- a/thothlibrary/mutation.py +++ b/thothlibrary/mutation.py @@ -10,7 +10,7 @@ import json import urllib -from .errors import ThothError +from errors import ThothError class ThothMutation(): diff --git a/thothlibrary/query.py b/thothlibrary/query.py index a9949f0..b02ea45 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -10,74 +10,28 @@ import json import urllib -from .errors import ThothError +from errors import ThothError -class ThothQuery(): + +class ThothQuery: """GraphQL query in Thoth - Queries are specified in the QUERIES list, which specifies - their fields and desired return value 'fields' must be a list of - tuples (str, bool) where the string represents the attribute and the + Queries are specified in the QUERIES list of the API version, which + specifies their fields and desired return value 'fields' must be a list + of tuples (str, bool) where the string represents the attribute and the boolean represents whether the values should be enclosed with quotes and sanitised. """ - QUERIES = { - "works": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "workType", - "workStatus" - ], - "fields": [ - "workType", - "workStatus", - "fullTitle", - "title", - "subtitle", - "reference", - "edition", - "imprintId", - "doi", - "publicationDate", - "place", - "width", - "height", - "pageCount", - "pageBreakdown", - "imageCount", - "tableCount", - "audioCount", - "videoCount", - "license", - "copyrightHolder", - "landingPage", - "lccn", - "oclc", - "shortAbstract", - "longAbstract", - "generalNote", - "toc", - "coverUrl", - "coverCaption", - "publications { isbn publicationType }", - "contributions { fullName contributionType mainContribution }" - ] - } - } - - def __init__(self, query_name, parameters): - """Returns new ThothMutation object with specified mutation data + def __init__(self, query_name, parameters, queries): + """Returns new ThothQuery object mutation_name: Must match one of the keys found in MUTATIONS. mutation_data: Dictionary of mutation fields and their values. """ + self.QUERIES = queries self.query_name = query_name self.parameters = parameters self.param_str = self.prepare_parameters() @@ -118,7 +72,13 @@ def prepare_parameters(self): """Returns a string with all query parameters.""" parameters = [] for key, value in self.parameters.items(): - parameters.append("{}: {}, ".format(key, json.dumps(value))) + # note that we strip out extraneous quotation marks from parameters + # because ORDER clauses, for instance, do not allow them + + parameters.append("{}: " + "{}, ".format(key, + json.dumps(value). + strip('"').strip("'"))) return ", ".join(parameters) def prepare_fields(self): diff --git a/thothlibrary/thoth-0_4_2/__init__.py b/thothlibrary/thoth-0_4_2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py new file mode 100644 index 0000000..a0b6bf5 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -0,0 +1,125 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +from client import ThothClient + + +class ThothClient0_4_2(ThothClient): + + QUERIES = { + "works": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "workType", + "workStatus" + ], + "fields": [ + "workType", + "workStatus", + "fullTitle", + "title", + "subtitle", + "reference", + "edition", + "imprintId", + "doi", + "publicationDate", + "place", + "width", + "height", + "pageCount", + "pageBreakdown", + "imageCount", + "tableCount", + "audioCount", + "videoCount", + "license", + "copyrightHolder", + "landingPage", + "lccn", + "oclc", + "shortAbstract", + "longAbstract", + "generalNote", + "toc", + "coverUrl", + "coverCaption", + "publications { isbn publicationType }", + "contributions { fullName contributionType mainContribution contributionOrdinal }", + "imprint { publisher { publisherName publisherId } }", + "__typename" + ] + }, + + "publishers": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "workType", + "workStatus" + ], + "fields": [ + "imprints { imprintUrl imprintId imprintName}" + "updatedAt", + "createdAt", + "publisherId", + "publisherName", + "publisherShortname", + "publisherUrl", + ] + } + } + + def __init__(self, input_class): + super().__init__() + + # this is the magic dynamic generation part that wires up the methods + input_class.works = getattr(self, 'works') + input_class.QUERIES = getattr(self, 'QUERIES') + + def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", + order: str = None, publishers: str = None, work_type: str = None, + work_status: str = None, raw: bool = False): + """Construct and trigger a query to obtain all works""" + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + if filter_str: + parameters["filter"] = filter_str + + if order: + parameters["order"] = order + + if publishers: + parameters["publishers"] = publishers + + if work_type: + parameters["workType"] = work_type + + if work_status: + parameters["workStatus"] = work_status + + return self._api_request("works", parameters, return_raw=raw) + + def publishers(self, limit: int = 100, offset: int = 0, + filter_str: str = ""): + """Construct and trigger a query to obtain all publishers""" + parameters = { + "limit": limit, + "offset": offset, + "filter": filter_str, + } + return self.query("publishers", parameters) diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py new file mode 100644 index 0000000..bbcfbf4 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -0,0 +1,90 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +import collections + +from munch import Munch +from datetime import datetime + + +def _muncher_repr(obj): + """ + This is a hacky munch context switcher. It passes the original __repr__ + pointer back + @param obj: the object to represent + @return: the original munch representation + """ + Munch.__repr__ = munch_local + return obj.__repr__() + + +def _parse_authors(obj): + """ + This parses a list of contributors into authors and editors + @param obj: the Work to parse + @return: a string representation of authors + """ + if not 'contributions' in obj: + return None + + author_dict = {} + authors = '' + + for contributor in obj.contributions: + if contributor.contributionType == 'AUTHOR': + author_dict[contributor.contributionOrdinal] = contributor.fullName + if contributor.contributionType == "EDITOR": + author_dict[contributor.contributionOrdinal] = contributor.fullName + " (ed.)" + + od_authors = collections.OrderedDict(sorted(author_dict.items())) + + for k, v in od_authors.items(): + authors += contributor.fullName + ', ' + + return authors + + +default_fields = {'works': lambda + self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}'} + +munch_local = Munch.__repr__ + + +class StructureBuilder: + """A class to build a Thoth object structure""" + + def __init__(self, structure, data): + self.structure = structure + self.data = data + + def create_structure(self): + """ + Creates an object structure from dictionary input + @return: an object + """ + structures = [] + if isinstance(self.data, list): + for item in self.data: + x = self._munch(item) + structures.append(x) + else: + x = self._munch(self.data) + return x + + return structures + + def _munch(self, item): + """ + Converts our JSON or dict object into an addressable object. + Also sets up the Munch __repr__ and __str__ functions. + @param item: the item to convert + @return: a converted object with string representation + """ + x = Munch.fromDict(item) + if self.structure in default_fields.keys(): + struct = default_fields[self.structure] + Munch.__repr__ = Munch.__str__ + Munch.__str__ = struct + return x From 5d7ea4f3ef783c81a018b50c1397a5b3dc8539a5 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 13:33:13 +0100 Subject: [PATCH 011/115] Fix string handling for parameters --- README.md | 2 +- thothlibrary/cli.py | 91 +++++++++++++------------- thothlibrary/query.py | 3 +- thothlibrary/thoth-0_4_2/structures.py | 3 +- 4 files changed, 48 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 0c9064d..b795adc 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh -python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 +python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 30bd4ba..e5ab055 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -4,16 +4,7 @@ it under the terms of the Apache License v2.0. """ -from fire import decorators - - -def _client(): - """ - Returns a ThothClient object - @return: - """ - from client import ThothClient - return ThothClient(version="0.4.2") +import fire def _raw_parse(value): @@ -27,45 +18,53 @@ def _raw_parse(value): return value -@decorators.SetParseFn(_raw_parse) -def works(limit=100, order=None, offset=0, publishers=None, filter_str=None, - work_type=None, work_status=None, raw=False): - """ - A list of works - @param limit: the maximum number of results to return - @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results - @param publishers: a list of publishers to limit by - @param filter_str: a filter string to search - @param work_type: the work type (e.g. MONOGRAPH) - @param work_status: the work status (e.g. ACTIVE) - @param raw: whether to return a python object or the raw server result - """ - print(*_client().works(limit=limit, order=order, offset=offset, - publishers=publishers, filter_str=filter_str, - work_type=work_type, work_status=work_status, - raw=raw), sep='\n') - +class ThothAPI: + def _client(self): + """ + Returns a ThothClient object + @return: + """ + from client import ThothClient + return ThothClient(version="0.4.2") -def works_from_publisher(publishers_id=None, limit=100, offset=0): - """ - Get a list of works from a specific publisher - @param publishers_id: the ID of the publishers - @param limit: the maximum number of results to return (-1 for all) - @param offset: the offset from which to return results - """ - print(_client().works(limit=limit, publishers=publishers_id, offset=offset)) + @fire.decorators.SetParseFn(_raw_parse) + def works(self, limit=100, order=None, offset=0, publishers=None, + filter_str=None, work_type=None, work_status=None, raw=False): + """ + A list of works + @param limit: the maximum number of results to return + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results + @param publishers: a list of publishers to limit by + @param filter_str: a filter string to search + @param work_type: the work type (e.g. MONOGRAPH) + @param work_status: the work status (e.g. ACTIVE) + @param raw: whether to return a python object or the raw server result + """ + print(*self._client().works(limit=limit, order=order, offset=offset, + publishers=publishers, + filter_str=filter_str, + work_type=work_type, + work_status=work_status, + raw=raw), sep='\n') + def works_from_publisher(self, publishers_id=None, limit=100, offset=0): + """ + Get a list of works from a specific publisher + @param publishers_id: the ID of the publishers + @param limit: the maximum number of results to return (-1 for all) + @param offset: the offset from which to return results + """ + print(_client().works(limit=limit, publishers=publishers_id, + offset=offset)) -def publishers(json=False): - """ - Full list of metadata formats that can be output by Thoth - @param json: whether to return JSON or an object (default) - """ - print(_client().publishers()) + def publishers(self, json=False): + """ + Full list of metadata formats that can be output by Thoth + @param json: whether to return JSON or an object (default) + """ + print(_client().publishers()) if __name__ == '__main__': - import fire - - fire.Fire() + fire.Fire(ThothAPI) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index b02ea45..05ccc64 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -77,8 +77,7 @@ def prepare_parameters(self): parameters.append("{}: " "{}, ".format(key, - json.dumps(value). - strip('"').strip("'"))) + value)) return ", ".join(parameters) def prepare_fields(self): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index bbcfbf4..07c7eba 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -46,8 +46,7 @@ def _parse_authors(obj): return authors -default_fields = {'works': lambda - self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}'} +default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}'} munch_local = Munch.__repr__ From e6e2cfa35b200c8e0c8864a930cde3363b6ab862 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 16:45:11 +0100 Subject: [PATCH 012/115] Update docs --- thothlibrary/cli.py | 13 ++----------- thothlibrary/client.py | 5 ++--- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index e5ab055..f771403 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -22,7 +22,7 @@ class ThothAPI: def _client(self): """ Returns a ThothClient object - @return: + @return: a ThothClient """ from client import ThothClient return ThothClient(version="0.4.2") @@ -37,7 +37,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, @param offset: the offset from which to retrieve results @param publishers: a list of publishers to limit by @param filter_str: a filter string to search - @param work_type: the work type (e.g. MONOGRAPH) + @param work_type: the work type (e.g. MONOGR++APH) @param work_status: the work status (e.g. ACTIVE) @param raw: whether to return a python object or the raw server result """ @@ -48,15 +48,6 @@ def works(self, limit=100, order=None, offset=0, publishers=None, work_status=work_status, raw=raw), sep='\n') - def works_from_publisher(self, publishers_id=None, limit=100, offset=0): - """ - Get a list of works from a specific publisher - @param publishers_id: the ID of the publishers - @param limit: the maximum number of results to return (-1 for all) - @param offset: the offset from which to return results - """ - print(_client().works(limit=limit, publishers=publishers_id, - offset=offset)) def publishers(self, json=False): """ diff --git a/thothlibrary/client.py b/thothlibrary/client.py index 37cd9aa..8163bfe 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -100,9 +100,8 @@ def _api_request(self, endpoint_name: str, parameters, """ Makes a request to the API @param endpoint_name: the name of the endpoint - @param url_suffix: the URL suffix - @param return_json: whether to return raw JSON or an object (default) - @param return_raw: whether to return the raw data returned + @param return_raw: whether to return the raw data or an object (default) + @param parameters: the parameters to pass to GraphQL @return: an object or JSON of the request """ response = self.query(endpoint_name, parameters) From 3b73f7a40fe6550fc1f47ba53943e7076da26c1c Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 17:12:27 +0100 Subject: [PATCH 013/115] Add publishers endpoint. Further documentation. --- thothlibrary/cli.py | 75 +++++++++++++++++++------- thothlibrary/client.py | 5 ++ thothlibrary/thoth-0_4_2/endpoints.py | 57 ++++++++++++-------- thothlibrary/thoth-0_4_2/structures.py | 3 +- 4 files changed, 97 insertions(+), 43 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index f771403..9ab445b 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -12,35 +12,52 @@ def _raw_parse(value): This function overrides fire's default argument parsing using decorators. We need this because, otherwise, fire converts '{field: x}' to a dictionary object, which messes with GraphQL parameters. - @param value: the input value - @return: the parsed value + :param value: the input value + :return: the parsed value """ return value class ThothAPI: + + def __init__(self): + """ + A Thoth CLI client + """ + self.endpoint = "https://api.thoth.pub" + self.version = "0.4.2" + def _client(self): """ Returns a ThothClient object - @return: a ThothClient + :return: a ThothClient """ from client import ThothClient - return ThothClient(version="0.4.2") + return ThothClient(version=self.version, thoth_endpoint=self.endpoint) @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, work_type=None, work_status=None, raw=False): - """ - A list of works - @param limit: the maximum number of results to return - @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results - @param publishers: a list of publishers to limit by - @param filter_str: a filter string to search - @param work_type: the work type (e.g. MONOGR++APH) - @param work_status: the work status (e.g. ACTIVE) - @param raw: whether to return a python object or the raw server result + filter_str=None, work_type=None, work_status=None, raw=False, + version=None, endpoint=None): + """ + Retrieves works from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param str work_type: the work type (e.g. MONOGR++APH) + :param str work_status: the work status (e.g. ACTIVE) + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + print(*self._client().works(limit=limit, order=order, offset=offset, publishers=publishers, filter_str=filter_str, @@ -48,13 +65,31 @@ def works(self, limit=100, order=None, offset=0, publishers=None, work_status=work_status, raw=raw), sep='\n') - - def publishers(self, json=False): + @fire.decorators.SetParseFn(_raw_parse) + def publishers(self, limit=100, order=None, offset=0, publishers=None, + filter_str=None, raw=False, version=None, endpoint=None): """ - Full list of metadata formats that can be output by Thoth - @param json: whether to return JSON or an object (default) + Retrieves publishers from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint """ - print(_client().publishers()) + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(*self._client().publishers(limit=limit, order=order, + offset=offset, publishers=publishers, + filter_str=filter_str, + raw=raw), sep='\n') if __name__ == '__main__': diff --git a/thothlibrary/client.py b/thothlibrary/client.py index 8163bfe..d25d6cc 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -122,3 +122,8 @@ def _build_structure(self, endpoint_name, data): importlib.import_module('thoth-{0}.structures'.format(self.version)) builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() + + def _dictionary_append(self, dict, key, value): + if value: + dict[key] = value + return dict \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index a0b6bf5..943cd09 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -7,7 +7,9 @@ class ThothClient0_4_2(ThothClient): - + # the QUERIES field defines the fields that GraphQL will return + # note: every query should contain the field "__typename" if auto-object + # __str__ representation is to work QUERIES = { "works": { "parameters": [ @@ -64,8 +66,6 @@ class ThothClient0_4_2(ThothClient): "filter", "order", "publishers", - "workType", - "workStatus" ], "fields": [ "imprints { imprintUrl imprintId imprintName}" @@ -75,21 +75,38 @@ class ThothClient0_4_2(ThothClient): "publisherName", "publisherShortname", "publisherUrl", + "__typename" ] } } def __init__(self, input_class): + """ + Creates an instance of Thoth 0.4.2 endpoints + @param input_class: the ThothClient instance to be versioned + """ super().__init__() # this is the magic dynamic generation part that wires up the methods input_class.works = getattr(self, 'works') + input_class.publishers = getattr(self, 'publishers') input_class.QUERIES = getattr(self, 'QUERIES') def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): - """Construct and trigger a query to obtain all works""" + """ + Returns a works list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param filter_str: a filter string to search + @param work_type: the work type (e.g. MONOGR++APH) + @param work_status: the work status (e.g. ACTIVE) + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ if order is None: order = {} parameters = { @@ -97,29 +114,25 @@ def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", "limit": limit, } - if filter_str: - parameters["filter"] = filter_str - - if order: - parameters["order"] = order - - if publishers: - parameters["publishers"] = publishers - - if work_type: - parameters["workType"] = work_type - - if work_status: - parameters["workStatus"] = work_status + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'workType', work_type) + self._dictionary_append(parameters, 'workStatus', work_status) return self._api_request("works", parameters, return_raw=raw) - def publishers(self, limit: int = 100, offset: int = 0, - filter_str: str = ""): + def publishers(self, limit: int = 100, offset: int = 0, order: str = None, + filter_str: str = "", publishers: str = None, + raw: bool = False): """Construct and trigger a query to obtain all publishers""" parameters = { "limit": limit, "offset": offset, - "filter": filter_str, } - return self.query("publishers", parameters) + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("publishers", parameters, return_raw=raw) diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 07c7eba..0145acb 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -46,7 +46,8 @@ def _parse_authors(obj): return authors -default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}'} +default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}', + 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{muncher(self)}'} munch_local = Munch.__repr__ From f5126ac6e98edae72e0c69786a187caa5fd75c0a Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 17:18:53 +0100 Subject: [PATCH 014/115] Further docs and cleanup --- thothlibrary/client.py | 6 +++--- thothlibrary/thoth-0_4_2/structures.py | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/thothlibrary/client.py b/thothlibrary/client.py index d25d6cc..ae98991 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -123,7 +123,7 @@ def _build_structure(self, endpoint_name, data): builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() - def _dictionary_append(self, dict, key, value): + def _dictionary_append(self, input_dict, key, value): if value: - dict[key] = value - return dict \ No newline at end of file + input_dict[key] = value + return input_dict diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 0145acb..dc2b4bf 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -45,10 +45,15 @@ def _parse_authors(obj): return authors - +# these are lambda function formatting statements for the endpoints +# they are injected to replace the default dictionary (Munch) __repr__ and +# __str__ methods. They let us create nice-looking string representations +# of objects, such as books default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}', 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{muncher(self)}'} +# this stores the original function pointer of Munch.__repr__ so that we can +# reinect it above in "muncher" munch_local = Munch.__repr__ From d1385ab49aeb9fe42526694d9899b081ba9e88a3 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 17:23:16 +0100 Subject: [PATCH 015/115] Add README for publishers --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b795adc..fd86843 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 ./cli.py publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' ``` From 440fb1e8c80e46e9fa0952aa9a952575e03a40ba Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 17:48:01 +0100 Subject: [PATCH 016/115] Add publisher count endpoint --- README.md | 1 + thothlibrary/cli.py | 22 ++++++++++++++++++++++ thothlibrary/query.py | 20 ++++++++++---------- thothlibrary/thoth-0_4_2/endpoints.py | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index fd86843..da627ae 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ print(thoth.works()) ```sh python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 ./cli.py publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 ./cli.py publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 9ab445b..e0af898 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -91,6 +91,28 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, filter_str=filter_str, raw=raw), sep='\n') + @fire.decorators.SetParseFn(_raw_parse) + def publisher_count(self, publishers=None, filter_str=None, raw=False, + version=None, endpoint=None): + """ + A count of publishers + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().publisher_count(publishers=publishers, + filter_str=filter_str, + raw=raw)) + if __name__ == '__main__': fire.Fire(ThothAPI) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index 05ccc64..9a98efb 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -42,16 +42,14 @@ def prepare_request(self): """Format the query request string""" values = { "query_name": self.query_name, - "parameters": self.param_str, - "fields": self.fields_str + "parameters": "(" + self.param_str + ")" if self.param_str else '', + "fields": "{" + self.fields_str + "}" if self.fields_str else '' } + payload = """ query { - %(query_name)s( - %(parameters)s - ) { - %(fields)s - } + %(query_name)s%(parameters)s + %(fields)s } """ return payload % values @@ -76,10 +74,12 @@ def prepare_parameters(self): # because ORDER clauses, for instance, do not allow them parameters.append("{}: " - "{}, ".format(key, - value)) + "{}, ".format(key, value)) return ", ".join(parameters) def prepare_fields(self): """Returns a string with all query fields.""" - return "\n".join(self.QUERIES[self.query_name]["fields"]) + if self.query_name in self.QUERIES: + return "\n".join(self.QUERIES[self.query_name]["fields"]) + else: + return '' diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 943cd09..615a889 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -77,6 +77,13 @@ class ThothClient0_4_2(ThothClient): "publisherUrl", "__typename" ] + }, + + "publishercount": { + "parameters": [ + "filter", + "publishers", + ], } } @@ -90,6 +97,7 @@ def __init__(self, input_class): # this is the magic dynamic generation part that wires up the methods input_class.works = getattr(self, 'works') input_class.publishers = getattr(self, 'publishers') + input_class.publisher_count = getattr(self, 'publisher_count') input_class.QUERIES = getattr(self, 'QUERIES') def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", @@ -136,3 +144,13 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publishers", parameters, return_raw=raw) + + def publisher_count(self, filter_str: str = "", publishers: str = None, + raw: bool = False): + """Construct and trigger a query to obtain all publishers""" + parameters = {} + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("publisherCount", parameters, return_raw=raw) From 7a002900df6f8b4d276a5b87d891ccd0f5dc603e Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 31 Jul 2021 17:57:11 +0100 Subject: [PATCH 017/115] Add works count --- README.md | 1 + thothlibrary/cli.py | 29 ++++++++++++++++++++++++++- thothlibrary/query.py | 3 ++- thothlibrary/thoth-0_4_2/endpoints.py | 23 ++++++++++++++++++++- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index da627ae..d60f642 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ print(thoth.works()) python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 ./cli.py publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 ./cli.py publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 ./cli.py work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index e0af898..8c03d43 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -46,7 +46,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by :param str filter_str: a filter string to search - :param str work_type: the work type (e.g. MONOGR++APH) + :param str work_type: the work type (e.g. MONOGRAPH) :param str work_status: the work status (e.g. ACTIVE) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version @@ -113,6 +113,33 @@ def publisher_count(self, publishers=None, filter_str=None, raw=False, filter_str=filter_str, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def work_count(self, publishers=None, filter_str=None, raw=False, + work_type=None, work_status=None, version=None, + endpoint=None): + """ + A count of works + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str work_type: the work type (e.g. MONOGRAPH) + :param str work_status: the work status (e.g. ACTIVE) + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().work_count(publishers=publishers, + filter_str=filter_str, + work_type=work_type, + work_status=work_status, + raw=raw)) + if __name__ == '__main__': fire.Fire(ThothAPI) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index 9a98efb..dda693e 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -79,7 +79,8 @@ def prepare_parameters(self): def prepare_fields(self): """Returns a string with all query fields.""" - if self.query_name in self.QUERIES: + if self.query_name in self.QUERIES and \ + 'fields' in self.QUERIES[self.query_name]: return "\n".join(self.QUERIES[self.query_name]["fields"]) else: return '' diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 615a889..9a30726 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -79,7 +79,14 @@ class ThothClient0_4_2(ThothClient): ] }, - "publishercount": { + "publisherCount": { + "parameters": [ + "filter", + "publishers", + ], + }, + + "workCount": { "parameters": [ "filter", "publishers", @@ -98,6 +105,7 @@ def __init__(self, input_class): input_class.works = getattr(self, 'works') input_class.publishers = getattr(self, 'publishers') input_class.publisher_count = getattr(self, 'publisher_count') + input_class.work_count = getattr(self, 'work_count') input_class.QUERIES = getattr(self, 'QUERIES') def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", @@ -154,3 +162,16 @@ def publisher_count(self, filter_str: str = "", publishers: str = None, self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publisherCount", parameters, return_raw=raw) + + def work_count(self, filter_str: str = "", publishers: str = None, + work_type: str = None, work_status: str = None, + raw: bool = False): + """Construct and trigger a query to obtain all publishers""" + parameters = {} + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'workType', work_type) + self._dictionary_append(parameters, 'workStatus', work_status) + + return self._api_request("workCount", parameters, return_raw=raw) \ No newline at end of file From e13e44a25f656baaf98890f67cbbe8e1b281d1be Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 08:49:34 +0100 Subject: [PATCH 018/115] Add workByDoi endpoint --- README.md | 1 + thothlibrary/cli.py | 17 ++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 56 ++++++++++++++++++++++++++ thothlibrary/thoth-0_4_2/structures.py | 1 + 4 files changed, 75 insertions(+) diff --git a/README.md b/README.md index d60f642..e4b74c0 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ print(thoth.works()) ```sh python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 ./cli.py publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 ./cli.py work --doi="https://doi.org/10.11647/OBP.0222" python3 ./cli.py publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 ./cli.py work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 8c03d43..9b962de 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -65,6 +65,23 @@ def works(self, limit=100, order=None, offset=0, publishers=None, work_status=work_status, raw=raw), sep='\n') + @fire.decorators.SetParseFn(_raw_parse) + def work(self, doi, raw=False, version=None, endpoint=None): + """ + Retrieves a work by DOI from a Thoth instance + :param str doi: the doi to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().work_by_doi(doi=doi, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, raw=False, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 9a30726..2b9a46a 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -59,6 +59,48 @@ class ThothClient0_4_2(ThothClient): ] }, + "workByDoi": { + "parameters": [ + "doi" + ], + "fields": [ + "workType", + "workStatus", + "fullTitle", + "title", + "subtitle", + "reference", + "edition", + "imprintId", + "doi", + "publicationDate", + "place", + "width", + "height", + "pageCount", + "pageBreakdown", + "imageCount", + "tableCount", + "audioCount", + "videoCount", + "license", + "copyrightHolder", + "landingPage", + "lccn", + "oclc", + "shortAbstract", + "longAbstract", + "generalNote", + "toc", + "coverUrl", + "coverCaption", + "publications { isbn publicationType }", + "contributions { fullName contributionType mainContribution contributionOrdinal }", + "imprint { publisher { publisherName publisherId } }", + "__typename" + ] + }, + "publishers": { "parameters": [ "limit", @@ -103,6 +145,7 @@ def __init__(self, input_class): # this is the magic dynamic generation part that wires up the methods input_class.works = getattr(self, 'works') + input_class.work_by_doi = getattr(self, 'work_by_doi') input_class.publishers = getattr(self, 'publishers') input_class.publisher_count = getattr(self, 'publisher_count') input_class.work_count = getattr(self, 'work_count') @@ -138,6 +181,19 @@ def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", return self._api_request("works", parameters, return_raw=raw) + def work_by_doi(self, doi: str, raw: bool = False): + """ + Returns a work by DOI + @param doi: the DOI to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'doi': '"' + doi + '"' + } + + return self._api_request("workByDoi", parameters, return_raw=raw) + def publishers(self, limit: int = 100, offset: int = 0, order: str = None, filter_str: str = "", publishers: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index dc2b4bf..788580a 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -50,6 +50,7 @@ def _parse_authors(obj): # __str__ methods. They let us create nice-looking string representations # of objects, such as books default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}', + 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}', 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{muncher(self)}'} # this stores the original function pointer of Munch.__repr__ so that we can From fb402565fa9c933ae2f5b1f8bdb2bc87237e72a3 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 11:08:12 +0100 Subject: [PATCH 019/115] Add publications endpoint --- README.md | 1 + thothlibrary/cli.py | 28 +++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 55 +++++++++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 16 ++++++-- 4 files changed, 96 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e4b74c0..5d21798 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ print(thoth.works()) ```sh python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 ./cli.py publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 ./cli.py publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 ./cli.py work --doi="https://doi.org/10.11647/OBP.0222" python3 ./cli.py publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 ./cli.py work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 9b962de..a78762e 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -157,6 +157,34 @@ def work_count(self, publishers=None, filter_str=None, raw=False, work_status=work_status, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def publications(self, limit=100, order=None, offset=0, publishers=None, + filter_str=None, publication_type=None, raw=False, + version=None, endpoint=None): + """ + Retrieves publications from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param str publication_type: the work type (e.g. PAPERBACK) + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(*self._client().publications(limit=limit, order=order, + offset=offset, publishers=publishers, + filter_str=filter_str, + publication_type=publication_type, + raw=raw), sep='\n') + if __name__ == '__main__': fire.Fire(ThothAPI) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 2b9a46a..2393804 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -59,6 +59,29 @@ class ThothClient0_4_2(ThothClient): ] }, + "publications": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "publicationType", + ], + "fields": [ + "publicationId", + "publicationType", + "workId", + "isbn", + "publicationUrl", + "createdAt", + "updatedAt", + "prices { currencyCode unitPrice __typename}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "__typename" + ] + }, + "workByDoi": { "parameters": [ "doi" @@ -147,10 +170,40 @@ def __init__(self, input_class): input_class.works = getattr(self, 'works') input_class.work_by_doi = getattr(self, 'work_by_doi') input_class.publishers = getattr(self, 'publishers') + input_class.publications = getattr(self, 'publications') input_class.publisher_count = getattr(self, 'publisher_count') input_class.work_count = getattr(self, 'work_count') input_class.QUERIES = getattr(self, 'QUERIES') + def publications(self, limit: int = 100, offset: int = 0, + filter_str: str = "", order: str = None, + publishers: str = None, publication_type: str = None, + raw: bool = False): + """ + Returns a publications list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param filter_str: a filter string to search + @param publication_type: the work type (e.g. PAPERBACK) + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'publicationType', publication_type) + + return self._api_request("publications", parameters, return_raw=raw) + def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): @@ -161,7 +214,7 @@ def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by @param filter_str: a filter string to search - @param work_type: the work type (e.g. MONOGR++APH) + @param work_type: the work type (e.g. MONOGRAPH) @param work_status: the work status (e.g. ACTIVE) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 788580a..a41ca67 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -45,13 +45,23 @@ def _parse_authors(obj): return authors + +def __price_parser(prices): + if len(prices) > 0: + return '({0}{1})'.format(prices[0].unitPrice, prices[0].currencyCode) + else: + return '' + + # these are lambda function formatting statements for the endpoints # they are injected to replace the default dictionary (Munch) __repr__ and # __str__ methods. They let us create nice-looking string representations # of objects, such as books -default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}', - 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{muncher(self)}', - 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{muncher(self)}'} +default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' + f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if self.__typename == 'Publication' else f'{_muncher_repr(self)}', + 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} # this stores the original function pointer of Munch.__repr__ so that we can # reinect it above in "muncher" From 7cab5bf586b5c73887e32604eedcbe0858701e44 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 11:16:32 +0100 Subject: [PATCH 020/115] Add publicationCount endpoint --- README.md | 1 + thothlibrary/cli.py | 25 ++++++++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 28 ++++++++++++++++++++++++--- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5d21798..caa2e72 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ python3 ./cli.py publications --limit=10 --publishers='["85fd969a-a16c-480b-b641 python3 ./cli.py work --doi="https://doi.org/10.11647/OBP.0222" python3 ./cli.py publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 ./cli.py work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 ./cli.py publication_count --publication_type="HARDBACK" ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index a78762e..d673621 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -157,6 +157,31 @@ def work_count(self, publishers=None, filter_str=None, raw=False, work_status=work_status, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def publication_count(self, publishers=None, filter_str=None, raw=False, + publication_type=None, version=None, endpoint=None): + """ + A count of works + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str publication_type: the work type (e.g. MONOGRAPH) + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().publication_count(publishers=publishers, + filter_str=filter_str, + publication_type=publication_type, + raw=raw)) + + @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, publication_type=None, raw=False, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 2393804..770ada5 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -155,6 +155,16 @@ class ThothClient0_4_2(ThothClient): "parameters": [ "filter", "publishers", + "workType", + "workStatus", + ], + }, + + "publicationCount": { + "parameters": [ + "filter", + "publishers", + "publicationType" ], } } @@ -173,6 +183,7 @@ def __init__(self, input_class): input_class.publications = getattr(self, 'publications') input_class.publisher_count = getattr(self, 'publisher_count') input_class.work_count = getattr(self, 'work_count') + input_class.publication_count = getattr(self, 'publication_count') input_class.QUERIES = getattr(self, 'QUERIES') def publications(self, limit: int = 100, offset: int = 0, @@ -264,7 +275,7 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, def publisher_count(self, filter_str: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to obtain all publishers""" + """Construct and trigger a query to count publishers""" parameters = {} self._dictionary_append(parameters, 'filter', filter_str) @@ -275,7 +286,7 @@ def publisher_count(self, filter_str: str = "", publishers: str = None, def work_count(self, filter_str: str = "", publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): - """Construct and trigger a query to obtain all publishers""" + """Construct and trigger a query to count works""" parameters = {} self._dictionary_append(parameters, 'filter', filter_str) @@ -283,4 +294,15 @@ def work_count(self, filter_str: str = "", publishers: str = None, self._dictionary_append(parameters, 'workType', work_type) self._dictionary_append(parameters, 'workStatus', work_status) - return self._api_request("workCount", parameters, return_raw=raw) \ No newline at end of file + return self._api_request("workCount", parameters, return_raw=raw) + + def publication_count(self, filter_str: str = "", publishers: str = None, + publication_type: str = None, raw: bool = False): + """Construct and trigger a query to count publications""" + parameters = {} + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'publicationType', publication_type) + + return self._api_request("publicationCount", parameters, return_raw=raw) From 15eb7eb468ae52f65e97aff104d109fd10803e10 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 11:18:03 +0100 Subject: [PATCH 021/115] Update CLI descriptions --- thothlibrary/cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index d673621..2ebee4e 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -112,7 +112,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, def publisher_count(self, publishers=None, filter_str=None, raw=False, version=None, endpoint=None): """ - A count of publishers + Retrieves a count of publishers from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter_str: a filter string to search :param bool raw: whether to return a python object or the raw server result @@ -135,7 +135,7 @@ def work_count(self, publishers=None, filter_str=None, raw=False, work_type=None, work_status=None, version=None, endpoint=None): """ - A count of works + Retrieves a count of works from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter_str: a filter string to search :param bool raw: whether to return a python object or the raw server result @@ -161,7 +161,7 @@ def work_count(self, publishers=None, filter_str=None, raw=False, def publication_count(self, publishers=None, filter_str=None, raw=False, publication_type=None, version=None, endpoint=None): """ - A count of works + Retrieves a count of publications from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter_str: a filter string to search :param bool raw: whether to return a python object or the raw server result From 9b8c3652ab8ffecfd90c69f3a4be694f229890a3 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 11:23:10 +0100 Subject: [PATCH 022/115] Add CLI description --- thothlibrary/cli.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 2ebee4e..934aaa8 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -19,6 +19,11 @@ def _raw_parse(value): class ThothAPI: + """ + A command line interface for the Thoth python API client. + This tool allows you to query a Thoth API for publications, works, authors + and other endpoints. + """ def __init__(self): """ From 6295b4a0181bdc719d24e96e45fec5e33a4b251c Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 16:14:19 +0100 Subject: [PATCH 023/115] Add publisher endpoint --- thothlibrary/cli.py | 17 +++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 30 ++++++++++++++++++++++++++ thothlibrary/thoth-0_4_2/structures.py | 3 ++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 934aaa8..39f8737 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -87,6 +87,23 @@ def work(self, doi, raw=False, version=None, endpoint=None): print(self._client().work_by_doi(doi=doi, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def publisher(self, publisher_id, raw=False, version=None, endpoint=None): + """ + Retrieves a work by DOI from a Thoth instance + :param str publisher_id: the publisher to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().publisher(publisher_id=publisher_id, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, raw=False, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 770ada5..f40cbd7 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -144,6 +144,22 @@ class ThothClient0_4_2(ThothClient): ] }, + "publisher": { + "parameters": [ + "publisherId", + ], + "fields": [ + "imprints { imprintUrl imprintId imprintName}" + "updatedAt", + "createdAt", + "publisherId", + "publisherName", + "publisherShortname", + "publisherUrl", + "__typename" + ] + }, + "publisherCount": { "parameters": [ "filter", @@ -180,6 +196,7 @@ def __init__(self, input_class): input_class.works = getattr(self, 'works') input_class.work_by_doi = getattr(self, 'work_by_doi') input_class.publishers = getattr(self, 'publishers') + input_class.publisher = getattr(self, 'publisher') input_class.publications = getattr(self, 'publications') input_class.publisher_count = getattr(self, 'publisher_count') input_class.work_count = getattr(self, 'work_count') @@ -258,6 +275,19 @@ def work_by_doi(self, doi: str, raw: bool = False): return self._api_request("workByDoi", parameters, return_raw=raw) + def publisher(self, publisher_id: str, raw: bool = False): + """ + Returns a work by DOI + @param publisher_id: the publisher + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'publisherId': '"' + publisher_id + '"' + } + + return self._api_request("publisher", parameters, return_raw=raw) + def publishers(self, limit: int = 100, offset: int = 0, order: str = None, filter_str: str = "", publishers: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index a41ca67..d300726 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -61,7 +61,8 @@ def __price_parser(prices): 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if self.__typename == 'Publication' else f'{_muncher_repr(self)}', 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} + 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}', + 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} # this stores the original function pointer of Munch.__repr__ so that we can # reinect it above in "muncher" From 6be708b0dd6241f8fa1d5586a482281f8c0a8efa Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 1 Aug 2021 17:11:28 +0100 Subject: [PATCH 024/115] Add contribution and contribution count endpoints --- thothlibrary/cli.py | 52 ++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 76 ++++++++++++++++++++++++++ thothlibrary/thoth-0_4_2/structures.py | 1 + 3 files changed, 129 insertions(+) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 39f8737..67d08f2 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -40,6 +40,35 @@ def _client(self): from client import ThothClient return ThothClient(version=self.version, thoth_endpoint=self.endpoint) + @fire.decorators.SetParseFn(_raw_parse) + def contributions(self, limit=100, order=None, offset=0, publishers=None, + filter_str=None, contribution_type=None, raw=False, + version=None, endpoint=None): + """ + Retrieves works from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param str contribution_type: the contribution type (e.g. AUTHOR) + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(*self._client().contributions(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter_str=filter_str, + contribution_type=contribution_type, + raw=raw), sep='\n') + @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, work_type=None, work_status=None, raw=False, @@ -203,6 +232,29 @@ def publication_count(self, publishers=None, filter_str=None, raw=False, publication_type=publication_type, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def contribution_count(self, publishers=None, filter_str=None, raw=False, + contribution_type=None, version=None, endpoint=None): + """ + Retrieves a count of publications from a Thoth instance + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str contribution_type: the work type (e.g. AUTHOR) + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().contribution_count(publishers=publishers, + filter_str=filter_str, + contribution_type=contribution_type, + raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index f40cbd7..a17dcb7 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -124,6 +124,31 @@ class ThothClient0_4_2(ThothClient): ] }, + "contributions": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "contributionType", + ], + "fields": [ + "contributionId", + "contributionType", + "mainContribution", + "biography", + "institution", + "__typename", + "firstName", + "lastName", + "fullName", + "contributionOrdinal", + "workId", + "contributor {firstName lastName fullName orcid __typename website contributorId}" + ] + }, + "publishers": { "parameters": [ "limit", @@ -182,6 +207,14 @@ class ThothClient0_4_2(ThothClient): "publishers", "publicationType" ], + }, + + "contributionCount": { + "parameters": [ + "filter", + "publishers", + "contributionType" + ], } } @@ -198,7 +231,9 @@ def __init__(self, input_class): input_class.publishers = getattr(self, 'publishers') input_class.publisher = getattr(self, 'publisher') input_class.publications = getattr(self, 'publications') + input_class.contributions = getattr(self, 'contributions') input_class.publisher_count = getattr(self, 'publisher_count') + input_class.contribution_count = getattr(self, 'contribution_count') input_class.work_count = getattr(self, 'work_count') input_class.publication_count = getattr(self, 'publication_count') input_class.QUERIES = getattr(self, 'QUERIES') @@ -232,6 +267,35 @@ def publications(self, limit: int = 100, offset: int = 0, return self._api_request("publications", parameters, return_raw=raw) + def contributions(self, limit: int = 100, offset: int = 0, + filter_str: str = "", order: str = None, + publishers: str = None, contribution_type: str = None, + raw: bool = False): + """ + Returns a contributions list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param filter_str: a filter string to search + @param contribution_type: the contribution type (e.g. AUTHOR) + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'contributionType', contribution_type) + + return self._api_request("contributions", parameters, return_raw=raw) + def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): @@ -326,6 +390,18 @@ def work_count(self, filter_str: str = "", publishers: str = None, return self._api_request("workCount", parameters, return_raw=raw) + def contribution_count(self, filter_str: str = "", publishers: str = None, + contribution_type: str = None, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'contributionType', + contribution_type) + + return self._api_request("contributionCount", parameters, return_raw=raw) + def publication_count(self, filter_str: str = "", publishers: str = None, publication_type: str = None, raw: bool = False): """Construct and trigger a query to count publications""" diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index d300726..1a2bd60 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -62,6 +62,7 @@ def __price_parser(prices): f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if self.__typename == 'Publication' else f'{_muncher_repr(self)}', 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}', + 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if self.__typename == 'Contribution' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} # this stores the original function pointer of Munch.__repr__ so that we can From 15a3ab66fde01c026c3de1f02e90f6760da845d5 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 15:54:53 +0100 Subject: [PATCH 025/115] Substantial refactor to enable unit tests Library now uses its own modified version of the GraphQL client using requests so that we can easily mock these in unit tests Fixed a bug in the CLI where JSON was being single quoted in --raw mode Updated README to reflect correct module calling pattern and reinstated relative imports Added raw unit tests --- LICENSE | 29 ++++++ README.md | 14 +-- requirements.txt | 4 +- thothlibrary/auth.py | 2 +- thothlibrary/cli.py | 58 ++++++++---- thothlibrary/client.py | 19 ++-- thothlibrary/graphql.py | 68 ++++++++++++++ thothlibrary/mutation.py | 2 +- thothlibrary/query.py | 7 +- thothlibrary/thoth-0_4_2/endpoints.py | 2 +- thothlibrary/thoth-0_4_2/tests/__init__.py | 0 .../tests/fixtures/contributions.json | 1 + .../tests/fixtures/publications.json | 1 + .../tests/fixtures/publishers.json | 1 + .../thoth-0_4_2/tests/fixtures/works.json | 1 + thothlibrary/thoth-0_4_2/tests/tests.py | 90 +++++++++++++++++++ 16 files changed, 256 insertions(+), 43 deletions(-) create mode 100644 thothlibrary/graphql.py create mode 100644 thothlibrary/thoth-0_4_2/tests/__init__.py create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publications.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/works.json create mode 100644 thothlibrary/thoth-0_4_2/tests/tests.py diff --git a/LICENSE b/LICENSE index 30291ef..d4794db 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,8 @@ +Most components released under the Apache License. + +Modified GraphQL client released under the MIT License. + + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -199,3 +204,27 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + + +The MIT License (MIT) + +Copyright (c) 2016 graph.cool + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index caa2e72..a4eff42 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh -python3 ./cli.py works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' -python3 ./cli.py publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' -python3 ./cli.py publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' -python3 ./cli.py work --doi="https://doi.org/10.11647/OBP.0222" -python3 ./cli.py publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' -python3 ./cli.py work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' -python3 ./cli.py publication_count --publication_type="HARDBACK" +python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" +python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" ``` diff --git a/requirements.txt b/requirements.txt index 3322222..8c3d0aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -graphqlclient==0.2.4 requests==2.24.0 fire -munch \ No newline at end of file +munch +requests_mock \ No newline at end of file diff --git a/thothlibrary/auth.py b/thothlibrary/auth.py index 02d6b6d..46f8938 100644 --- a/thothlibrary/auth.py +++ b/thothlibrary/auth.py @@ -10,7 +10,7 @@ import json import urllib import requests -from errors import ThothError +from .errors import ThothError class ThothAuthenticator(): # pylint: disable=too-few-public-methods diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 67d08f2..544d5f9 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -37,7 +37,7 @@ def _client(self): Returns a ThothClient object :return: a ThothClient """ - from client import ThothClient + from .client import ThothClient return ThothClient(version=self.version, thoth_endpoint=self.endpoint) @fire.decorators.SetParseFn(_raw_parse) @@ -62,12 +62,18 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - print(*self._client().contributions(limit=limit, order=order, - offset=offset, - publishers=publishers, - filter_str=filter_str, - contribution_type=contribution_type, - raw=raw), sep='\n') + contribs = self._client().contributions(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter_str=filter_str, + contribution_type= + contribution_type, + raw=raw) + + if not raw: + print(*contribs, sep='\n') + else: + print(contribs) @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, @@ -92,12 +98,16 @@ def works(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - print(*self._client().works(limit=limit, order=order, offset=offset, - publishers=publishers, - filter_str=filter_str, - work_type=work_type, - work_status=work_status, - raw=raw), sep='\n') + works = self._client().works(limit=limit, order=order, offset=offset, + publishers=publishers, + filter_str=filter_str, + work_type=work_type, + work_status=work_status, + raw=raw) + if not raw: + print(*works, sep='\n') + else: + print(works) @fire.decorators.SetParseFn(_raw_parse) def work(self, doi, raw=False, version=None, endpoint=None): @@ -154,10 +164,16 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - print(*self._client().publishers(limit=limit, order=order, - offset=offset, publishers=publishers, - filter_str=filter_str, - raw=raw), sep='\n') + publishers = self._client().publishers(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter_str=filter_str, + raw=raw) + + if not raw: + print(*publishers, sep='\n') + else: + print(publishers) @fire.decorators.SetParseFn(_raw_parse) def publisher_count(self, publishers=None, filter_str=None, raw=False, @@ -278,11 +294,15 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - print(*self._client().publications(limit=limit, order=order, + pubs = self._client().publications(limit=limit, order=order, offset=offset, publishers=publishers, filter_str=filter_str, publication_type=publication_type, - raw=raw), sep='\n') + raw=raw) + if not raw: + print(*pubs, sep='\n') + else: + print(pubs) if __name__ == '__main__': diff --git a/thothlibrary/client.py b/thothlibrary/client.py index ae98991..25efefb 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -7,10 +7,10 @@ """ import importlib -from graphqlclient import GraphQLClient -from auth import ThothAuthenticator -from mutation import ThothMutation -from query import ThothQuery +from .graphql import GraphQLClientRequests as GraphQLClient +from .auth import ThothAuthenticator +from .mutation import ThothMutation +from .query import ThothQuery class ThothClient(): @@ -31,8 +31,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): # the constructor function there dynamically adds the methods that are # supported in any API version if issubclass(ThothClient, type(self)): - endpoints = importlib.import_module('thoth-{0}.end' - 'points'.format(self.version)) + endpoints = importlib.import_module('thothlibrary.thoth-{0}.endpoints'.format(self.version)) getattr(endpoints, 'ThothClient{0}'.format(self.version))(self) def login(self, email, password): @@ -46,9 +45,9 @@ def mutation(self, mutation_name, data): mutation = ThothMutation(mutation_name, data) return mutation.run(self.client) - def query(self, query_name, parameters): + def query(self, query_name, parameters, raw=False): """Instantiate a thoth query and execute""" - query = ThothQuery(query_name, parameters, self.QUERIES) + query = ThothQuery(query_name, parameters, self.QUERIES, raw=raw) return query.run(self.client) def create_publisher(self, publisher): @@ -104,7 +103,7 @@ def _api_request(self, endpoint_name: str, parameters, @param parameters: the parameters to pass to GraphQL @return: an object or JSON of the request """ - response = self.query(endpoint_name, parameters) + response = self.query(endpoint_name, parameters, raw=return_raw) if return_raw: return response @@ -119,7 +118,7 @@ def _build_structure(self, endpoint_name, data): @return: an object form of the output """ structures = \ - importlib.import_module('thoth-{0}.structures'.format(self.version)) + importlib.import_module('thothlibrary.thoth-{0}.structures'.format(self.version)) builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() diff --git a/thothlibrary/graphql.py b/thothlibrary/graphql.py new file mode 100644 index 0000000..f2419be --- /dev/null +++ b/thothlibrary/graphql.py @@ -0,0 +1,68 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This file is free software; you may redistribute and/or modify +it under the terms of the MIT License. + +This file is adapted from the Simple GraphQL client for Python 2.7+ +https://github.com/prisma-labs/python-graphql-client + +The modifications here change the library to use the requests framework instead +of urllib. This means that we can then mock requests more easily in unit tests. + +The MIT License (MIT) + +Copyright (c) 2016 graph.cool, ΔQ Programming LLP, July 2021 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" +import requests +import json + + +class GraphQLClientRequests: + def __init__(self, endpoint): + self.endpoint = endpoint + self.token = None + self.headername = None + + def execute(self, query, variables=None): + return self._send(query, variables) + + def inject_token(self, token, headername='Authorization'): + self.token = token + self.headername = headername + + def _send(self, query, variables): + data = {'query': query, + 'variables': variables} + headers = {'Accept': 'application/json', + 'Content-Type': 'application/json'} + + if self.token is not None: + headers[self.headername] = '{}'.format(self.token) + + req = requests.post(self.endpoint, + data=json.dumps(data).encode('utf-8'), + headers=headers) + + try: + response = req.content.decode('utf-8') + return response + except requests.exceptions.RequestException as e: + raise e diff --git a/thothlibrary/mutation.py b/thothlibrary/mutation.py index 30b9571..4a265a0 100644 --- a/thothlibrary/mutation.py +++ b/thothlibrary/mutation.py @@ -10,7 +10,7 @@ import json import urllib -from errors import ThothError +from .errors import ThothError class ThothMutation(): diff --git a/thothlibrary/query.py b/thothlibrary/query.py index dda693e..edece5b 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -11,7 +11,7 @@ import json import urllib -from errors import ThothError +from .errors import ThothError class ThothQuery: @@ -24,7 +24,7 @@ class ThothQuery: and sanitised. """ - def __init__(self, query_name, parameters, queries): + def __init__(self, query_name, parameters, queries, raw=False): """Returns new ThothQuery object mutation_name: Must match one of the keys found in MUTATIONS. @@ -37,6 +37,7 @@ def __init__(self, query_name, parameters, queries): self.param_str = self.prepare_parameters() self.fields_str = self.prepare_fields() self.request = self.prepare_request() + self.raw = raw def prepare_request(self): """Format the query request string""" @@ -61,6 +62,8 @@ def run(self, client): result = client.execute(self.request) if "errors" in result: raise AssertionError + elif self.raw: + return result return json.loads(result)["data"][self.query_name] except (KeyError, TypeError, ValueError, AssertionError, json.decoder.JSONDecodeError, urllib.error.HTTPError): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index a17dcb7..45cc759 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -3,7 +3,7 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ -from client import ThothClient +from thothlibrary.client import ThothClient class ThothClient0_4_2(ThothClient): diff --git a/thothlibrary/thoth-0_4_2/tests/__init__.py b/thothlibrary/thoth-0_4_2/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json new file mode 100644 index 0000000..f9a587e --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json @@ -0,0 +1 @@ +{"data":{"contributions":[{"contributionId":"1a3ef666-c624-4240-a176-b510ff899040","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","contributionOrdinal":1,"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","contributor":{"firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","orcid":"https://orcid.org/0000-0001-7995-5915","__typename":"Contributor","website":"http://www.danielacascella.com","contributorId":"1fab9df5-d9b4-4695-973e-ebb052b184ff"}},{"contributionId":"29e4f46b-851a-4d7b-bb41-e6f305fc2b11","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","contributionOrdinal":1,"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","contributor":{"firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","orcid":"https://orcid.org/0000-0001-9176-8514","__typename":"Contributor","website":null,"contributorId":"c145d392-c37e-41b6-9225-1c3a1a46f460"}},{"contributionId":"1da25444-9af8-4bb6-859f-5591a32c2ee2","contributionType":"AUTHOR","mainContribution":true,"biography":"James Rorty (1890–1973) was an American poet, journalist, and sometime advertising copywriter.","institution":null,"__typename":"Contribution","firstName":"James","lastName":"Rorty","fullName":"James Rorty","contributionOrdinal":1,"workId":"3162a992-05dd-4b74-9fe0-0f16879ce6de","contributor":{"firstName":"James","lastName":"Rorty","fullName":"James Rorty","orcid":null,"__typename":"Contributor","website":null,"contributorId":"abbb2bf1-98b8-4724-844b-3d05e22e428a"}},{"contributionId":"6eedb190-949a-4074-a66a-a839059abfe0","contributionType":"AUTHOR","mainContribution":true,"biography":"Walter Lippmann (1889–1974) was an American journalist and public philosopher. ","institution":null,"__typename":"Contribution","firstName":"Walter","lastName":"Lippmann","fullName":"Walter Lippmann","contributionOrdinal":1,"workId":"6763ec18-b4af-4767-976c-5b808a64e641","contributor":{"firstName":"Walter","lastName":"Lippmann","fullName":"Walter Lippmann","orcid":null,"__typename":"Contributor","website":null,"contributorId":"3e2c867a-fa5b-44b4-a965-cf4b0dd27725"}}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publications.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publications.json new file mode 100644 index 0000000..bec7a74 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publications.json @@ -0,0 +1 @@ +{"data":{"publications":[{"publicationId":"bd118dca-3309-49b5-b814-b5e987e0e760","publicationType":"PAPERBACK","workId":"19c8c38c-9262-4f37-891a-18f767dbf61c","isbn":"978-1-906924-09-6","publicationUrl":"http://www.openbookpublishers.com/product/23","createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","prices":[{"currencyCode":"AUD","unitPrice":29.95,"__typename":"Price"},{"currencyCode":"CAD","unitPrice":29.95,"__typename":"Price"},{"currencyCode":"EUR","unitPrice":19.95,"__typename":"Price"},{"currencyCode":"GBP","unitPrice":15.95,"__typename":"Price"},{"currencyCode":"USD","unitPrice":26.95,"__typename":"Price"}],"work":{"workId":"19c8c38c-9262-4f37-891a-18f767dbf61c","fullTitle":"Telling Tales: The Impact of Germany on English Children’s Books 1780-1918","doi":"https://doi.org/10.11647/OBP.0004","publicationDate":"2009-10-01","place":"Cambridge, UK","contributions":[{"fullName":"David Blamires","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}},"__typename":"Publication"},{"publicationId":"34712b75-dcdd-408b-8d0c-cf29a35be2e5","publicationType":"PAPERBACK","workId":"1399a869-9f56-4980-981d-2cc83f0a6668","isbn":null,"publicationUrl":"http://amzn.to/2hxpKVL","createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","prices":[{"currencyCode":"USD","unitPrice":18.0,"__typename":"Price"}],"work":{"workId":"1399a869-9f56-4980-981d-2cc83f0a6668","fullTitle":"Truth and Fiction: Notes on (Exceptional) Faith in Art","doi":"https://doi.org/10.21983/P3.0007.1.00","publicationDate":"2012-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"Milcho Manchevski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adrian Martin","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"__typename":"Publication"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json new file mode 100644 index 0000000..d255ab5 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json @@ -0,0 +1 @@ +{"data":{"publishers":[{"imprints":[{"imprintUrl":"https://www.matteringpress.org","imprintId":"cb483a78-851f-4936-82d2-8dcd555dcda9","imprintName":"Mattering Press"}],"updatedAt":"2021-03-25T10:48:25.461610+00:00","createdAt":"2021-03-25T10:48:25.461610+00:00","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6","publisherName":"Mattering Press","publisherShortname":null,"publisherUrl":"https://www.matteringpress.org","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://www.mediastudies.press/","imprintId":"5078b33c-5b3f-48bf-bf37-ced6b02beb7c","imprintName":"mediastudies.press"}],"updatedAt":"2021-06-15T14:40:19.458560+00:00","createdAt":"2021-06-15T14:40:19.458560+00:00","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5","publisherName":"mediastudies.press","publisherShortname":null,"publisherUrl":"https://www.mediastudies.press/","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://meson.press","imprintId":"0299480e-869b-486c-8a65-7818598c107b","imprintName":"meson press"}],"updatedAt":"2021-03-25T10:48:55.455503+00:00","createdAt":"2021-03-25T10:48:55.455503+00:00","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b","publisherName":"meson press","publisherShortname":null,"publisherUrl":"https://meson.press","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers"}],"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisherName":"Open Book Publishers","publisherShortname":"OBP","publisherUrl":"https://www.openbookpublishers.com/","__typename":"Publisher"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json new file mode 100644 index 0000000..4c9a7b3 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json @@ -0,0 +1 @@ +{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133,"height":203,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK"},{"isbn":"978-1-953035-71-4","publicationType":"PDF"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK"},{"isbn":null,"publicationType":"PAPERBACK"},{"isbn":"978-1-953035-35-6","publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py new file mode 100644 index 0000000..e656d7b --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -0,0 +1,90 @@ +import unittest + +import requests_mock +from thothlibrary import ThothClient + + +class Thoth042Tests(unittest.TestCase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.endpoint = "https://api.test042.thoth.pub" + self.version = "0.4.2" + + def test_works_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('works', m) + + response = thoth_client.works(raw=True) + + self.assertEqual(mock_response, response) + + return None + + def test_publications_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publications', m) + + response = thoth_client.publications(raw=True) + + self.assertEqual(mock_response, response) + + return None + + def test_publishers_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publishers', m) + + response = thoth_client.publishers(raw=True) + + self.assertEqual(mock_response, response) + + return None + + def test_contributions_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributions', m) + + response = thoth_client.contributions(raw=True) + + self.assertEqual(mock_response, response) + + return None + + def setup_mocker(self, endpoint, m): + """ + Sets up a mocker object by reading a json fixture + @param endpoint: the file to read in the fixtures dir (no extension) + @param m: the requests Mocker object + @return: the mock string + """ + with open("fixtures/{0}.json".format(endpoint), "r") as input_file: + mock_response = input_file.read() + + m.register_uri('POST', 'https://api.thoth.pub/graphql', + text=mock_response) + + thoth_client = ThothClient(version=self.version, + thoth_endpoint=self.endpoint) + + return mock_response, thoth_client + + +if __name__ == '__main__': + unittest.main() From c246706aeda78b06b030ece5796eaf65c07e7643 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 16:09:20 +0100 Subject: [PATCH 026/115] Remove repetition in unit tests --- thothlibrary/thoth-0_4_2/tests/tests.py | 36 +++++++++++-------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index e656d7b..ca30f0d 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -8,6 +8,7 @@ class Thoth042Tests(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + # specify an invalid endpoint so that we don't accidentally self.endpoint = "https://api.test042.thoth.pub" self.version = "0.4.2" @@ -18,11 +19,7 @@ def test_works_raw(self): """ with requests_mock.Mocker() as m: mock_response, thoth_client = self.setup_mocker('works', m) - - response = thoth_client.works(raw=True) - - self.assertEqual(mock_response, response) - + self.raw_tester(mock_response, thoth_client.works) return None def test_publications_raw(self): @@ -32,11 +29,7 @@ def test_publications_raw(self): """ with requests_mock.Mocker() as m: mock_response, thoth_client = self.setup_mocker('publications', m) - - response = thoth_client.publications(raw=True) - - self.assertEqual(mock_response, response) - + self.raw_tester(mock_response, thoth_client.publications) return None def test_publishers_raw(self): @@ -46,11 +39,7 @@ def test_publishers_raw(self): """ with requests_mock.Mocker() as m: mock_response, thoth_client = self.setup_mocker('publishers', m) - - response = thoth_client.publishers(raw=True) - - self.assertEqual(mock_response, response) - + self.raw_tester(mock_response, thoth_client.publishers) return None def test_contributions_raw(self): @@ -60,13 +49,20 @@ def test_contributions_raw(self): """ with requests_mock.Mocker() as m: mock_response, thoth_client = self.setup_mocker('contributions', m) - - response = thoth_client.contributions(raw=True) - - self.assertEqual(mock_response, response) - + self.raw_tester(mock_response, thoth_client.contributions) return None + def raw_tester(self, mock_response, method_to_call): + """ + An echo test that ensures the client returns accurate raw responses + @param mock_response: the mock response + @param method_to_call: the method to call + @return: None or an assertion error + """ + response = method_to_call(raw=True) + self.assertEqual(mock_response, response, + 'Raw response was not echoed back correctly.') + def setup_mocker(self, endpoint, m): """ Sets up a mocker object by reading a json fixture From 8f6184c59a571c0f4a448ea154e26242be770102 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 16:19:31 +0100 Subject: [PATCH 027/115] Fix bug that overwrote custom endpoints --- thothlibrary/client.py | 5 ++++- thothlibrary/thoth-0_4_2/endpoints.py | 6 ++++-- thothlibrary/thoth-0_4_2/tests/tests.py | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/thothlibrary/client.py b/thothlibrary/client.py index 25efefb..5395cde 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -21,6 +21,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): thoth_endpoint: Must be the full URL (eg. 'http://localhost'). """ + self.thoth_endpoint = thoth_endpoint self.auth_endpoint = "{}/account/login".format(thoth_endpoint) self.graphql_endpoint = "{}/graphql".format(thoth_endpoint) self.client = GraphQLClient(self.graphql_endpoint) @@ -32,7 +33,9 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): # supported in any API version if issubclass(ThothClient, type(self)): endpoints = importlib.import_module('thothlibrary.thoth-{0}.endpoints'.format(self.version)) - getattr(endpoints, 'ThothClient{0}'.format(self.version))(self) + getattr(endpoints, 'ThothClient{0}'.format(self.version))(self, + version=version, + thoth_endpoint=thoth_endpoint) def login(self, email, password): """Obtain an authentication token""" diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 45cc759..a5977ab 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -218,12 +218,14 @@ class ThothClient0_4_2(ThothClient): } } - def __init__(self, input_class): + def __init__(self, input_class, thoth_endpoint="https://api.thoth.pub", + version="0.4.2"): """ Creates an instance of Thoth 0.4.2 endpoints @param input_class: the ThothClient instance to be versioned """ - super().__init__() + super().__init__(thoth_endpoint=thoth_endpoint, + version=version) # this is the magic dynamic generation part that wires up the methods input_class.works = getattr(self, 'works') diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index ca30f0d..ea23dca 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -8,7 +8,6 @@ class Thoth042Tests(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - # specify an invalid endpoint so that we don't accidentally self.endpoint = "https://api.test042.thoth.pub" self.version = "0.4.2" @@ -73,7 +72,7 @@ def setup_mocker(self, endpoint, m): with open("fixtures/{0}.json".format(endpoint), "r") as input_file: mock_response = input_file.read() - m.register_uri('POST', 'https://api.thoth.pub/graphql', + m.register_uri('POST', '{}/graphql'.format(self.endpoint), text=mock_response) thoth_client = ThothClient(version=self.version, From 0e036a0b45ed0fb41177d511920494c681c2dd36 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 16:25:37 +0100 Subject: [PATCH 028/115] Add workId field to 0.4.2 defs --- thothlibrary/thoth-0_4_2/endpoints.py | 1 + thothlibrary/thoth-0_4_2/structures.py | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/works.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index a5977ab..116c4a3 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -50,6 +50,7 @@ class ThothClient0_4_2(ThothClient): "longAbstract", "generalNote", "toc", + "workId", "coverUrl", "coverCaption", "publications { isbn publicationType }", diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 1a2bd60..95e40bb 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -57,7 +57,7 @@ def __price_parser(prices): # they are injected to replace the default dictionary (Munch) __repr__ and # __str__ methods. They let us create nice-looking string representations # of objects, such as books -default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', +default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if self.__typename == 'Work' else f'{_muncher_repr(self)}', 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if self.__typename == 'Publication' else f'{_muncher_repr(self)}', 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json index 4c9a7b3..6d3665b 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json @@ -1 +1 @@ -{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133,"height":203,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK"},{"isbn":"978-1-953035-71-4","publicationType":"PDF"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK"},{"isbn":null,"publicationType":"PAPERBACK"},{"isbn":"978-1-953035-35-6","publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"}]}} +{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133,"height":203,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"workId":"b5c810e1-c847-4553-a24e-9893164d9786","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK"},{"isbn":"978-1-953035-71-4","publicationType":"PDF"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK"},{"isbn":null,"publicationType":"PAPERBACK"},{"isbn":"978-1-953035-35-6","publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"}]}} From b96e002a17b48367f47d3ed6a976c5e64a855a91 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 16:39:35 +0100 Subject: [PATCH 029/115] Add serialize option to CLI --- thothlibrary/cli.py | 52 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 544d5f9..4f17e8e 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -5,6 +5,7 @@ """ import fire +import pickle def _raw_parse(value): @@ -43,7 +44,7 @@ def _client(self): @fire.decorators.SetParseFn(_raw_parse) def contributions(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, contribution_type=None, raw=False, - version=None, endpoint=None): + version=None, endpoint=None, serialize=False): """ Retrieves works from a Thoth instance :param int limit: the maximum number of results to return (default: 100) @@ -55,6 +56,7 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: self.endpoint = endpoint @@ -72,13 +74,15 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, if not raw: print(*contribs, sep='\n') + elif serialize: + print(pickle.dumps(contribs)) else: print(contribs) @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, work_type=None, work_status=None, raw=False, - version=None, endpoint=None): + version=None, endpoint=None, serialize=False): """ Retrieves works from a Thoth instance :param int limit: the maximum number of results to return (default: 100) @@ -91,6 +95,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: self.endpoint = endpoint @@ -104,19 +109,23 @@ def works(self, limit=100, order=None, offset=0, publishers=None, work_type=work_type, work_status=work_status, raw=raw) - if not raw: + if not raw and not pickle: print(*works, sep='\n') - else: + elif serialize: + print(pickle.dumps(works)) + elif raw: print(works) @fire.decorators.SetParseFn(_raw_parse) - def work(self, doi, raw=False, version=None, endpoint=None): + def work(self, doi, raw=False, version=None, endpoint=None, + serialize=False): """ Retrieves a work by DOI from a Thoth instance :param str doi: the doi to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: self.endpoint = endpoint @@ -124,16 +133,23 @@ def work(self, doi, raw=False, version=None, endpoint=None): if version: self.version = version - print(self._client().work_by_doi(doi=doi, raw=raw)) + work = self._client().work_by_doi(doi=doi, raw=raw) + + if not serialize: + print(work) + else: + print(pickle.dumps(work)) @fire.decorators.SetParseFn(_raw_parse) - def publisher(self, publisher_id, raw=False, version=None, endpoint=None): + def publisher(self, publisher_id, raw=False, version=None, endpoint=None, + serialize=False): """ Retrieves a work by DOI from a Thoth instance :param str publisher_id: the publisher to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: self.endpoint = endpoint @@ -141,11 +157,17 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None): if version: self.version = version - print(self._client().publisher(publisher_id=publisher_id, raw=raw)) + publisher = self._client().publisher(publisher_id=publisher_id, raw=raw) + + if not serialize: + print(publisher) + else: + print(pickle.dumps(publisher)) @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, raw=False, version=None, endpoint=None): + filter_str=None, raw=False, version=None, endpoint=None, + serialize=False): """ Retrieves publishers from a Thoth instance :param int limit: the maximum number of results to return (default: 100) @@ -156,6 +178,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: @@ -170,8 +193,10 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, filter_str=filter_str, raw=raw) - if not raw: + if not raw and not serialize: print(*publishers, sep='\n') + elif serialize: + print(pickle.dumps(publishers)) else: print(publishers) @@ -275,7 +300,7 @@ def contribution_count(self, publishers=None, filter_str=None, raw=False, @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, publication_type=None, raw=False, - version=None, endpoint=None): + version=None, endpoint=None, serialize=False): """ Retrieves publications from a Thoth instance :param int limit: the maximum number of results to return (default: 100) @@ -287,6 +312,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: self.endpoint = endpoint @@ -299,8 +325,10 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, filter_str=filter_str, publication_type=publication_type, raw=raw) - if not raw: + if not raw and not serialize: print(*pubs, sep='\n') + elif serialize: + print(pickle.dumps(pubs)) else: print(pubs) From 76df9c86ce3c8e4c5c5bdf19c08f563adecff595 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 16:42:42 +0100 Subject: [PATCH 030/115] Fix to serializer --- thothlibrary/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 4f17e8e..091f005 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -72,7 +72,7 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, contribution_type, raw=raw) - if not raw: + if not raw and not serialize: print(*contribs, sep='\n') elif serialize: print(pickle.dumps(contribs)) From 3d3bf7a95d01b1ead8498c51a28c403f7ec21cdb Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:13:41 +0100 Subject: [PATCH 031/115] Fix to serializer --- thothlibrary/cli.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 091f005..59f851a 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -3,6 +3,7 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ +import json import fire import pickle @@ -75,7 +76,7 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, if not raw and not serialize: print(*contribs, sep='\n') elif serialize: - print(pickle.dumps(contribs)) + print(json.dumps(contribs)) else: print(contribs) @@ -109,10 +110,10 @@ def works(self, limit=100, order=None, offset=0, publishers=None, work_type=work_type, work_status=work_status, raw=raw) - if not raw and not pickle: + if not raw and not serialize: print(*works, sep='\n') elif serialize: - print(pickle.dumps(works)) + print(json.dumps(works)) elif raw: print(works) @@ -138,7 +139,7 @@ def work(self, doi, raw=False, version=None, endpoint=None, if not serialize: print(work) else: - print(pickle.dumps(work)) + print(json.dumps(work)) @fire.decorators.SetParseFn(_raw_parse) def publisher(self, publisher_id, raw=False, version=None, endpoint=None, @@ -162,7 +163,7 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None, if not serialize: print(publisher) else: - print(pickle.dumps(publisher)) + print(json.dumps(publisher)) @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, @@ -196,7 +197,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, if not raw and not serialize: print(*publishers, sep='\n') elif serialize: - print(pickle.dumps(publishers)) + print(json.dumps(publishers)) else: print(publishers) @@ -328,7 +329,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, if not raw and not serialize: print(*pubs, sep='\n') elif serialize: - print(pickle.dumps(pubs)) + print(json.dumps(pubs)) else: print(pubs) From cdedb8167871f0e26c10425c431dd6c533179b47 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:14:36 +0100 Subject: [PATCH 032/115] Add initial unit tests for works and stored test output generator --- thothlibrary/thoth-0_4_2/endpoints.py | 16 ++++----- thothlibrary/thoth-0_4_2/structures.py | 18 ++++++---- .../tests/fixtures/contributions.pickle | 1 + .../tests/fixtures/publications.pickle | 1 + .../tests/fixtures/publishers.pickle | 1 + .../thoth-0_4_2/tests/fixtures/works.json | 2 +- .../thoth-0_4_2/tests/fixtures/works.pickle | 1 + .../thoth-0_4_2/tests/fixtures/works_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 12 +++++++ thothlibrary/thoth-0_4_2/tests/tests.py | 33 +++++++++++++++++++ 10 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json create mode 100755 thothlibrary/thoth-0_4_2/tests/genfixtures.sh diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 116c4a3..b46d9d0 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -53,9 +53,9 @@ class ThothClient0_4_2(ThothClient): "workId", "coverUrl", "coverCaption", - "publications { isbn publicationType }", - "contributions { fullName contributionType mainContribution contributionOrdinal }", - "imprint { publisher { publisherName publisherId } }", + "publications { isbn publicationType __typename }", + "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ] }, @@ -118,9 +118,9 @@ class ThothClient0_4_2(ThothClient): "toc", "coverUrl", "coverCaption", - "publications { isbn publicationType }", - "contributions { fullName contributionType mainContribution contributionOrdinal }", - "imprint { publisher { publisherName publisherId } }", + "publications { isbn publicationType __typename }", + "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ] }, @@ -159,7 +159,7 @@ class ThothClient0_4_2(ThothClient): "publishers", ], "fields": [ - "imprints { imprintUrl imprintId imprintName}" + "imprints { imprintUrl imprintId imprintName __typename}" "updatedAt", "createdAt", "publisherId", @@ -175,7 +175,7 @@ class ThothClient0_4_2(ThothClient): "publisherId", ], "fields": [ - "imprints { imprintUrl imprintId imprintName}" + "imprints { imprintUrl imprintId imprintName __typename}" "updatedAt", "createdAt", "publisherId", diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 95e40bb..d1ac473 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -57,13 +57,19 @@ def __price_parser(prices): # they are injected to replace the default dictionary (Munch) __repr__ and # __str__ methods. They let us create nice-looking string representations # of objects, such as books -default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if self.__typename == 'Work' else f'{_muncher_repr(self)}', +default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' - f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if self.__typename == 'Publication' else f'{_muncher_repr(self)}', - 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}', - 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if self.__typename == 'Contribution' else f'{_muncher_repr(self)}', - 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} + f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', + 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', + 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', + 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} + + +#default_fields = {'publications': lambda self: f'HERE {self.__typename}'} + + + # this stores the original function pointer of Munch.__repr__ so that we can # reinect it above in "muncher" diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle new file mode 100644 index 0000000..6cf761d --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle @@ -0,0 +1 @@ +[{"contributionId": "1a3ef666-c624-4240-a176-b510ff899040", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Daniela", "lastName": "Cascella", "fullName": "Daniela Cascella", "contributionOrdinal": 1, "workId": "a01f41d6-1da8-4b0b-87b4-82ecc41c6d55", "contributor": {"firstName": "Daniela", "lastName": "Cascella", "fullName": "Daniela Cascella", "orcid": "https://orcid.org/0000-0001-7995-5915", "__typename": "Contributor", "website": "http://www.danielacascella.com", "contributorId": "1fab9df5-d9b4-4695-973e-ebb052b184ff"}}, {"contributionId": "29e4f46b-851a-4d7b-bb41-e6f305fc2b11", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "contributionOrdinal": 1, "workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "contributor": {"firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "orcid": "https://orcid.org/0000-0001-9176-8514", "__typename": "Contributor", "website": null, "contributorId": "c145d392-c37e-41b6-9225-1c3a1a46f460"}}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle new file mode 100644 index 0000000..2977272 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle @@ -0,0 +1 @@ +[{"publicationId": "bd118dca-3309-49b5-b814-b5e987e0e760", "publicationType": "PAPERBACK", "workId": "19c8c38c-9262-4f37-891a-18f767dbf61c", "isbn": "978-1-906924-09-6", "publicationUrl": "http://www.openbookpublishers.com/product/23", "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "prices": [{"currencyCode": "AUD", "unitPrice": 29.95, "__typename": "Price"}, {"currencyCode": "CAD", "unitPrice": 29.95, "__typename": "Price"}, {"currencyCode": "EUR", "unitPrice": 19.95, "__typename": "Price"}, {"currencyCode": "GBP", "unitPrice": 15.95, "__typename": "Price"}, {"currencyCode": "USD", "unitPrice": 26.95, "__typename": "Price"}], "work": {"workId": "19c8c38c-9262-4f37-891a-18f767dbf61c", "fullTitle": "Telling Tales: The Impact of Germany on English Children\u2019s Books 1780-1918", "doi": "https://doi.org/10.11647/OBP.0004", "publicationDate": "2009-10-01", "place": "Cambridge, UK", "contributions": [{"fullName": "David Blamires", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}, "__typename": "Publication"}, {"publicationId": "34712b75-dcdd-408b-8d0c-cf29a35be2e5", "publicationType": "PAPERBACK", "workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "isbn": null, "publicationUrl": "http://amzn.to/2hxpKVL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "prices": [{"currencyCode": "USD", "unitPrice": 18.0, "__typename": "Price"}], "work": {"workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "fullTitle": "Truth and Fiction: Notes on (Exceptional) Faith in Art", "doi": "https://doi.org/10.21983/P3.0007.1.00", "publicationDate": "2012-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Milcho Manchevski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adrian Martin", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "__typename": "Publication"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle new file mode 100644 index 0000000..df2f631 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle @@ -0,0 +1 @@ +[{"imprints": [{"imprintUrl": "https://www.matteringpress.org", "imprintId": "cb483a78-851f-4936-82d2-8dcd555dcda9", "imprintName": "Mattering Press", "__typename": "Imprint"}], "updatedAt": "2021-03-25T10:48:25.461610+00:00", "createdAt": "2021-03-25T10:48:25.461610+00:00", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6", "publisherName": "Mattering Press", "publisherShortname": null, "publisherUrl": "https://www.matteringpress.org", "__typename": "Publisher"}, {"imprints": [{"imprintUrl": "https://www.mediastudies.press/", "imprintId": "5078b33c-5b3f-48bf-bf37-ced6b02beb7c", "imprintName": "mediastudies.press", "__typename": "Imprint"}], "updatedAt": "2021-06-15T14:40:19.458560+00:00", "createdAt": "2021-06-15T14:40:19.458560+00:00", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5", "publisherName": "mediastudies.press", "publisherShortname": null, "publisherUrl": "https://www.mediastudies.press/", "__typename": "Publisher"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json index 6d3665b..dac1aab 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json @@ -1 +1 @@ -{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133,"height":203,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"workId":"b5c810e1-c847-4553-a24e-9893164d9786","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK"},{"isbn":"978-1-953035-71-4","publicationType":"PDF"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK"},{"isbn":null,"publicationType":"PAPERBACK"},{"isbn":"978-1-953035-35-6","publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"},{"isbn":null,"publicationType":"PDF"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}},"__typename":"Work"}]}} +{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133,"height":203,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"workId":"b5c810e1-c847-4553-a24e-9893164d9786","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-71-4","publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3,"__typename":"Contribution"},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle new file mode 100644 index 0000000..37f1039 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle @@ -0,0 +1 @@ +[{"workType": "MONOGRAPH", "workStatus": "FORTHCOMING", "fullTitle": "(((", "title": "(((", "subtitle": null, "reference": "0370", "edition": 1, "imprintId": "e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1", "doi": "https://doi.org/10.53288/0370.1.00", "publicationDate": null, "place": "Earth, Milky Way", "width": 133, "height": 203, "pageCount": 326, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "De Francesco, Alessandro", "landingPage": "https://punctumbooks.com/titles/three-opening-parentheses/", "lccn": "2021942134", "oclc": null, "shortAbstract": null, "longAbstract": null, "generalNote": null, "toc": null, "workId": "b5c810e1-c847-4553-a24e-9893164d9786", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg", "coverCaption": null, "publications": [{"isbn": "978-1-953035-70-7", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-71-4", "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 3, "__typename": "Contribution"}, {"fullName": "Gen Ueda", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 2, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"}, {"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json new file mode 100644 index 0000000..3c4975d --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json @@ -0,0 +1 @@ +{"data": {"works": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh new file mode 100755 index 0000000..134a8ba --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +cd ../../../ + +bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" + +bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" + +bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle" +bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle" +bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle" +bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index ea23dca..cb66721 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -1,4 +1,6 @@ +import json import unittest +import pickle import requests_mock from thothlibrary import ThothClient @@ -11,6 +13,26 @@ def __init__(self, *args, **kwargs): self.endpoint = "https://api.test042.thoth.pub" self.version = "0.4.2" + def test_works(self): + """ + Tests that good input to works produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('works', m) + self.pickle_tester('works', thoth_client.works) + return None + + def test_works_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('works_bad', m) + self.pickle_tester('works', thoth_client.works, negative=True) + return None + def test_works_raw(self): """ A test to ensure valid passthrough of raw json @@ -62,6 +84,17 @@ def raw_tester(self, mock_response, method_to_call): self.assertEqual(mock_response, response, 'Raw response was not echoed back correctly.') + def pickle_tester(self, pickle_name, endpoint, negative=False): + with open("fixtures/{0}.pickle".format(pickle_name) + , "rb") as pickle_file: + loaded_response = json.load(pickle_file) + response = json.loads(json.dumps(endpoint())) + + if not negative: + self.assertEqual(loaded_response, response) + else: + self.assertNotEqual(loaded_response, response) + def setup_mocker(self, endpoint, m): """ Sets up a mocker object by reading a json fixture From 7923d79cc71d87053febfeeb16e0427cca23b918 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:16:06 +0100 Subject: [PATCH 033/115] Add note to fixture generator --- thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 134a8ba..fde5742 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -1,5 +1,10 @@ #!/bin/bash +# this script will generate the stored fixtures for the test suite +# it should only be run when the program is generating the correct output +# running this when the code produces bad output will yield the test suite +# inoperative/inaccurate. + cd ../../../ bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" From f5a5286c99d48681e3dbb2613187accf181d8a98 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:22:47 +0100 Subject: [PATCH 034/115] Add extra fixture generators Add tests for publications --- .../tests/fixtures/contributions.json | 2 +- .../tests/fixtures/contributions_bad.json | 1 + .../tests/fixtures/publications_bad.json | 1 + .../tests/fixtures/publishers.json | 2 +- .../tests/fixtures/publishers.pickle | 2 +- .../tests/fixtures/publishers_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 8 ++++++- thothlibrary/thoth-0_4_2/tests/tests.py | 21 +++++++++++++++++++ 8 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json index f9a587e..09fec57 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json @@ -1 +1 @@ -{"data":{"contributions":[{"contributionId":"1a3ef666-c624-4240-a176-b510ff899040","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","contributionOrdinal":1,"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","contributor":{"firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","orcid":"https://orcid.org/0000-0001-7995-5915","__typename":"Contributor","website":"http://www.danielacascella.com","contributorId":"1fab9df5-d9b4-4695-973e-ebb052b184ff"}},{"contributionId":"29e4f46b-851a-4d7b-bb41-e6f305fc2b11","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","contributionOrdinal":1,"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","contributor":{"firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","orcid":"https://orcid.org/0000-0001-9176-8514","__typename":"Contributor","website":null,"contributorId":"c145d392-c37e-41b6-9225-1c3a1a46f460"}},{"contributionId":"1da25444-9af8-4bb6-859f-5591a32c2ee2","contributionType":"AUTHOR","mainContribution":true,"biography":"James Rorty (1890–1973) was an American poet, journalist, and sometime advertising copywriter.","institution":null,"__typename":"Contribution","firstName":"James","lastName":"Rorty","fullName":"James Rorty","contributionOrdinal":1,"workId":"3162a992-05dd-4b74-9fe0-0f16879ce6de","contributor":{"firstName":"James","lastName":"Rorty","fullName":"James Rorty","orcid":null,"__typename":"Contributor","website":null,"contributorId":"abbb2bf1-98b8-4724-844b-3d05e22e428a"}},{"contributionId":"6eedb190-949a-4074-a66a-a839059abfe0","contributionType":"AUTHOR","mainContribution":true,"biography":"Walter Lippmann (1889–1974) was an American journalist and public philosopher. ","institution":null,"__typename":"Contribution","firstName":"Walter","lastName":"Lippmann","fullName":"Walter Lippmann","contributionOrdinal":1,"workId":"6763ec18-b4af-4767-976c-5b808a64e641","contributor":{"firstName":"Walter","lastName":"Lippmann","fullName":"Walter Lippmann","orcid":null,"__typename":"Contributor","website":null,"contributorId":"3e2c867a-fa5b-44b4-a965-cf4b0dd27725"}}]}} +{"data":{"contributions":[{"contributionId":"1a3ef666-c624-4240-a176-b510ff899040","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","contributionOrdinal":1,"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","contributor":{"firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","orcid":"https://orcid.org/0000-0001-7995-5915","__typename":"Contributor","website":"http://www.danielacascella.com","contributorId":"1fab9df5-d9b4-4695-973e-ebb052b184ff"}},{"contributionId":"29e4f46b-851a-4d7b-bb41-e6f305fc2b11","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","contributionOrdinal":1,"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","contributor":{"firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","orcid":"https://orcid.org/0000-0001-9176-8514","__typename":"Contributor","website":null,"contributorId":"c145d392-c37e-41b6-9225-1c3a1a46f460"}}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json new file mode 100644 index 0000000..6bdd1da --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json @@ -0,0 +1 @@ +{"data": {"contributions": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json new file mode 100644 index 0000000..2eba765 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json @@ -0,0 +1 @@ +{"data": {"publications": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json index d255ab5..685572b 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json @@ -1 +1 @@ -{"data":{"publishers":[{"imprints":[{"imprintUrl":"https://www.matteringpress.org","imprintId":"cb483a78-851f-4936-82d2-8dcd555dcda9","imprintName":"Mattering Press"}],"updatedAt":"2021-03-25T10:48:25.461610+00:00","createdAt":"2021-03-25T10:48:25.461610+00:00","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6","publisherName":"Mattering Press","publisherShortname":null,"publisherUrl":"https://www.matteringpress.org","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://www.mediastudies.press/","imprintId":"5078b33c-5b3f-48bf-bf37-ced6b02beb7c","imprintName":"mediastudies.press"}],"updatedAt":"2021-06-15T14:40:19.458560+00:00","createdAt":"2021-06-15T14:40:19.458560+00:00","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5","publisherName":"mediastudies.press","publisherShortname":null,"publisherUrl":"https://www.mediastudies.press/","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://meson.press","imprintId":"0299480e-869b-486c-8a65-7818598c107b","imprintName":"meson press"}],"updatedAt":"2021-03-25T10:48:55.455503+00:00","createdAt":"2021-03-25T10:48:55.455503+00:00","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b","publisherName":"meson press","publisherShortname":null,"publisherUrl":"https://meson.press","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers"}],"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisherName":"Open Book Publishers","publisherShortname":"OBP","publisherUrl":"https://www.openbookpublishers.com/","__typename":"Publisher"}]}} +{"data":{"publishers":[{"imprints":[{"imprintUrl":"https://www.matteringpress.org","imprintId":"cb483a78-851f-4936-82d2-8dcd555dcda9","imprintName":"Mattering Press","__typename":"Imprint"}],"updatedAt":"2021-03-25T10:48:25.461610+00:00","createdAt":"2021-03-25T10:48:25.461610+00:00","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6","publisherName":"Mattering Press","publisherShortname":null,"publisherUrl":"https://www.matteringpress.org","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://www.mediastudies.press/","imprintId":"5078b33c-5b3f-48bf-bf37-ced6b02beb7c","imprintName":"mediastudies.press","__typename":"Imprint"}],"updatedAt":"2021-06-15T14:40:19.458560+00:00","createdAt":"2021-06-15T14:40:19.458560+00:00","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5","publisherName":"mediastudies.press","publisherShortname":null,"publisherUrl":"https://www.mediastudies.press/","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://meson.press","imprintId":"0299480e-869b-486c-8a65-7818598c107b","imprintName":"meson press","__typename":"Imprint"}],"updatedAt":"2021-03-25T10:48:55.455503+00:00","createdAt":"2021-03-25T10:48:55.455503+00:00","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b","publisherName":"meson press","publisherShortname":null,"publisherUrl":"https://meson.press","__typename":"Publisher"},{"imprints":[{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers","__typename":"Imprint"}],"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisherName":"Open Book Publishers","publisherShortname":"OBP","publisherUrl":"https://www.openbookpublishers.com/","__typename":"Publisher"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle index df2f631..959a225 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle @@ -1 +1 @@ -[{"imprints": [{"imprintUrl": "https://www.matteringpress.org", "imprintId": "cb483a78-851f-4936-82d2-8dcd555dcda9", "imprintName": "Mattering Press", "__typename": "Imprint"}], "updatedAt": "2021-03-25T10:48:25.461610+00:00", "createdAt": "2021-03-25T10:48:25.461610+00:00", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6", "publisherName": "Mattering Press", "publisherShortname": null, "publisherUrl": "https://www.matteringpress.org", "__typename": "Publisher"}, {"imprints": [{"imprintUrl": "https://www.mediastudies.press/", "imprintId": "5078b33c-5b3f-48bf-bf37-ced6b02beb7c", "imprintName": "mediastudies.press", "__typename": "Imprint"}], "updatedAt": "2021-06-15T14:40:19.458560+00:00", "createdAt": "2021-06-15T14:40:19.458560+00:00", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5", "publisherName": "mediastudies.press", "publisherShortname": null, "publisherUrl": "https://www.mediastudies.press/", "__typename": "Publisher"}] +[{"imprints": [{"imprintUrl": "https://www.matteringpress.org", "imprintId": "cb483a78-851f-4936-82d2-8dcd555dcda9", "imprintName": "Mattering Press", "__typename": "Imprint"}], "updatedAt": "2021-03-25T10:48:25.461610+00:00", "createdAt": "2021-03-25T10:48:25.461610+00:00", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6", "publisherName": "Mattering Press", "publisherShortname": null, "publisherUrl": "https://www.matteringpress.org", "__typename": "Publisher"}, {"imprints": [{"imprintUrl": "https://www.mediastudies.press/", "imprintId": "5078b33c-5b3f-48bf-bf37-ced6b02beb7c", "imprintName": "mediastudies.press", "__typename": "Imprint"}], "updatedAt": "2021-06-15T14:40:19.458560+00:00", "createdAt": "2021-06-15T14:40:19.458560+00:00", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5", "publisherName": "mediastudies.press", "publisherShortname": null, "publisherUrl": "https://www.mediastudies.press/", "__typename": "Publisher"}, {"imprints": [{"imprintUrl": "https://meson.press", "imprintId": "0299480e-869b-486c-8a65-7818598c107b", "imprintName": "meson press", "__typename": "Imprint"}], "updatedAt": "2021-03-25T10:48:55.455503+00:00", "createdAt": "2021-03-25T10:48:55.455503+00:00", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b", "publisherName": "meson press", "publisherShortname": null, "publisherUrl": "https://meson.press", "__typename": "Publisher"}, {"imprints": [{"imprintUrl": "https://www.openbookpublishers.com/", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprintName": "Open Book Publishers", "__typename": "Imprint"}], "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "publisherName": "Open Book Publishers", "publisherShortname": "OBP", "publisherUrl": "https://www.openbookpublishers.com/", "__typename": "Publisher"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json new file mode 100644 index 0000000..a831d5f --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json @@ -0,0 +1 @@ +{"data": {"publishers": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index fde5742..23128ac 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -7,11 +7,17 @@ cd ../../../ +bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json" bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" +bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publications.json" +bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json" +bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" +bash -c "echo '{\"data\": {\"publications\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json" +bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json" bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle" bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle" -bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index cb66721..fffd95c 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -43,6 +43,27 @@ def test_works_raw(self): self.raw_tester(mock_response, thoth_client.works) return None + def test_publications(self): + """ + Tests that good input to publications produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publications', m) + self.pickle_tester('publications', thoth_client.publications) + return None + + def test_publications_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publications_bad', m) + self.pickle_tester('publications', thoth_client.publications, + negative=True) + return None + def test_publications_raw(self): """ A test to ensure valid passthrough of raw json From 28f0b46ddc852330c313496826b83356ea81ec53 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:24:44 +0100 Subject: [PATCH 035/115] Add publishers tests --- thothlibrary/thoth-0_4_2/tests/tests.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index fffd95c..ab5e61d 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -74,6 +74,26 @@ def test_publications_raw(self): self.raw_tester(mock_response, thoth_client.publications) return None + def test_publishers(self): + """ + Tests that good input to publishers produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publishers', m) + self.pickle_tester('publishers', thoth_client.publishers) + return None + + def test_publishers_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publishers_bad', m) + self.pickle_tester('publishers', thoth_client.publishers, + negative=True) + def test_publishers_raw(self): """ A test to ensure valid passthrough of raw json From c07dd7223ce2a06ce8cf6ee1cbc43abdefe83a30 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:28:20 +0100 Subject: [PATCH 036/115] Add contributions test cases --- thothlibrary/thoth-0_4_2/tests/tests.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index ab5e61d..aadde61 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -104,6 +104,27 @@ def test_publishers_raw(self): self.raw_tester(mock_response, thoth_client.publishers) return None + def test_contributions(self): + """ + Tests that good input to contributions produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributions', m) + self.pickle_tester('contributions', thoth_client.contributions) + return None + + def test_contributions_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributions_bad', + m) + self.pickle_tester('contributions', thoth_client.contributions, + negative=True) + def test_contributions_raw(self): """ A test to ensure valid passthrough of raw json From cd49ec951d61ee93331051c790eb9d5fc90fb14f Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:29:57 +0100 Subject: [PATCH 037/115] PEP8 fixes --- thothlibrary/thoth-0_4_2/tests/tests.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index aadde61..9463ce7 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -1,6 +1,5 @@ import json import unittest -import pickle import requests_mock from thothlibrary import ThothClient @@ -59,7 +58,8 @@ def test_publications_bad_input(self): @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publications_bad', m) + mock_response, thoth_client = self.setup_mocker('publications_bad', + m) self.pickle_tester('publications', thoth_client.publications, negative=True) return None @@ -147,8 +147,8 @@ def raw_tester(self, mock_response, method_to_call): 'Raw response was not echoed back correctly.') def pickle_tester(self, pickle_name, endpoint, negative=False): - with open("fixtures/{0}.pickle".format(pickle_name) - , "rb") as pickle_file: + with open("fixtures/{0}.pickle".format(pickle_name), + "rb") as pickle_file: loaded_response = json.load(pickle_file) response = json.loads(json.dumps(endpoint())) From 5bf183aee7534ae0951ffaa3786560521a99fc0a Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:31:58 +0100 Subject: [PATCH 038/115] Add missing docstrings --- thothlibrary/thoth-0_4_2/tests/tests.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 9463ce7..a73cbfd 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -140,13 +140,20 @@ def raw_tester(self, mock_response, method_to_call): An echo test that ensures the client returns accurate raw responses @param mock_response: the mock response @param method_to_call: the method to call - @return: None or an assertion error + @return: None or an assertion """ response = method_to_call(raw=True) self.assertEqual(mock_response, response, 'Raw response was not echoed back correctly.') def pickle_tester(self, pickle_name, endpoint, negative=False): + """ + A test of a function's output against a stored pickle (JSON) + @param pickle_name: the .pickle file in the fixtures directory + @param endpoint: the method to call + @param negative: whether to assert equal (True) or unequal (False) + @return: None or an assertion + """ with open("fixtures/{0}.pickle".format(pickle_name), "rb") as pickle_file: loaded_response = json.load(pickle_file) From 94a1f3bf3041c96359fbf603d2a62f1c339d52ed Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:47:53 +0100 Subject: [PATCH 039/115] Refine docstring comment --- thothlibrary/thoth-0_4_2/tests/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index a73cbfd..45500a9 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -169,7 +169,7 @@ def setup_mocker(self, endpoint, m): Sets up a mocker object by reading a json fixture @param endpoint: the file to read in the fixtures dir (no extension) @param m: the requests Mocker object - @return: the mock string + @return: the mock string, a Thoth client for this version """ with open("fixtures/{0}.json".format(endpoint), "r") as input_file: mock_response = input_file.read() From dfc2ee1d5d382a9c1c882ec74017e79137065329 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:52:20 +0100 Subject: [PATCH 040/115] PEP8 fixes --- thothlibrary/thoth-0_4_2/endpoints.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index b46d9d0..21e5f70 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -295,7 +295,8 @@ def contributions(self, limit: int = 100, offset: int = 0, self._dictionary_append(parameters, 'filter', filter_str) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'contributionType', contribution_type) + self._dictionary_append(parameters, 'contributionType', + contribution_type) return self._api_request("contributions", parameters, return_raw=raw) @@ -403,7 +404,8 @@ def contribution_count(self, filter_str: str = "", publishers: str = None, self._dictionary_append(parameters, 'contributionType', contribution_type) - return self._api_request("contributionCount", parameters, return_raw=raw) + return self._api_request("contributionCount", parameters, + return_raw=raw) def publication_count(self, filter_str: str = "", publishers: str = None, publication_type: str = None, raw: bool = False): @@ -414,4 +416,5 @@ def publication_count(self, filter_str: str = "", publishers: str = None, self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'publicationType', publication_type) - return self._api_request("publicationCount", parameters, return_raw=raw) + return self._api_request("publicationCount", parameters, + return_raw=raw) From 83a05e84398588687e2fea60ba46ed5430d82f03 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 19:55:09 +0100 Subject: [PATCH 041/115] PEP8 and doc fixes --- thothlibrary/thoth-0_4_2/structures.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index d1ac473..d3dfcf3 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -66,13 +66,8 @@ def __price_parser(prices): 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} -#default_fields = {'publications': lambda self: f'HERE {self.__typename}'} - - - - # this stores the original function pointer of Munch.__repr__ so that we can -# reinect it above in "muncher" +# reinect it above in "_muncher_repr" munch_local = Munch.__repr__ From 3034f5f1bed1c1ce1a2905b8da16f890e1d212e9 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 20:28:41 +0100 Subject: [PATCH 042/115] Added work_by_id endpoint, CLI, and tests Some further refactoring of test suite --- thothlibrary/cli.py | 14 ++++- thothlibrary/thoth-0_4_2/endpoints.py | 56 +++++++++++++++++ thothlibrary/thoth-0_4_2/structures.py | 6 +- .../thoth-0_4_2/tests/fixtures/work.json | 1 + .../thoth-0_4_2/tests/fixtures/work.pickle | 1 + .../thoth-0_4_2/tests/fixtures/work_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 9 ++- thothlibrary/thoth-0_4_2/tests/tests.py | 60 ++++++++++++++++++- 8 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/work.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 59f851a..54da74f 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -110,6 +110,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, work_type=work_type, work_status=work_status, raw=raw) + if not raw and not serialize: print(*works, sep='\n') elif serialize: @@ -118,8 +119,8 @@ def works(self, limit=100, order=None, offset=0, publishers=None, print(works) @fire.decorators.SetParseFn(_raw_parse) - def work(self, doi, raw=False, version=None, endpoint=None, - serialize=False): + def work(self, doi=None, workId=None, raw=False, version=None, + endpoint=None, serialize=False): """ Retrieves a work by DOI from a Thoth instance :param str doi: the doi to fetch @@ -127,6 +128,7 @@ def work(self, doi, raw=False, version=None, endpoint=None, :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object + :param workId: a workId to retrieve """ if endpoint: self.endpoint = endpoint @@ -134,7 +136,13 @@ def work(self, doi, raw=False, version=None, endpoint=None, if version: self.version = version - work = self._client().work_by_doi(doi=doi, raw=raw) + if not doi and not workId: + print("You must specify either workId or doi.") + return + elif doi: + work = self._client().work_by_doi(doi=doi, raw=raw) + else: + work = self._client().work_by_id(workId=workId, raw=raw) if not serialize: print(work) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 21e5f70..ec56f36 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -83,6 +83,48 @@ class ThothClient0_4_2(ThothClient): ] }, + "work": { + "parameters": [ + "workId" + ], + "fields": [ + "workType", + "workStatus", + "fullTitle", + "title", + "subtitle", + "reference", + "edition", + "imprintId", + "doi", + "publicationDate", + "place", + "width", + "height", + "pageCount", + "pageBreakdown", + "imageCount", + "tableCount", + "audioCount", + "videoCount", + "license", + "copyrightHolder", + "landingPage", + "lccn", + "oclc", + "shortAbstract", + "longAbstract", + "generalNote", + "toc", + "coverUrl", + "coverCaption", + "publications { isbn publicationType __typename }", + "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "__typename" + ] + }, + "workByDoi": { "parameters": [ "doi" @@ -231,6 +273,7 @@ def __init__(self, input_class, thoth_endpoint="https://api.thoth.pub", # this is the magic dynamic generation part that wires up the methods input_class.works = getattr(self, 'works') input_class.work_by_doi = getattr(self, 'work_by_doi') + input_class.work_by_id = getattr(self, 'work_by_id') input_class.publishers = getattr(self, 'publishers') input_class.publisher = getattr(self, 'publisher') input_class.publications = getattr(self, 'publications') @@ -343,6 +386,19 @@ def work_by_doi(self, doi: str, raw: bool = False): return self._api_request("workByDoi", parameters, return_raw=raw) + def work_by_id(self, workId: str, raw: bool = False): + """ + Returns a work by ID + @param workId: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'workId': '"' + workId + '"' + } + + return self._api_request("work", parameters, return_raw=raw) + def publisher(self, publisher_id: str, raw: bool = False): """ Returns a work by DOI diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index d3dfcf3..8f1ce7b 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -36,7 +36,8 @@ def _parse_authors(obj): if contributor.contributionType == 'AUTHOR': author_dict[contributor.contributionOrdinal] = contributor.fullName if contributor.contributionType == "EDITOR": - author_dict[contributor.contributionOrdinal] = contributor.fullName + " (ed.)" + author_dict[contributor.contributionOrdinal] = \ + contributor.fullName + " (ed.)" od_authors = collections.OrderedDict(sorted(author_dict.items())) @@ -61,13 +62,14 @@ def __price_parser(prices): 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'work': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} # this stores the original function pointer of Munch.__repr__ so that we can -# reinect it above in "_muncher_repr" +# re-inject it above in "_muncher_repr" munch_local = Munch.__repr__ diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work.json b/thothlibrary/thoth-0_4_2/tests/fixtures/work.json new file mode 100644 index 0000000..0fc7f4a --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work.json @@ -0,0 +1 @@ +{"data":{"work":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle new file mode 100644 index 0000000..c1e3bee --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle @@ -0,0 +1 @@ +{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json new file mode 100644 index 0000000..ede5975 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json @@ -0,0 +1 @@ +{"data": {"work": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 23128ac..560b95b 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -5,19 +5,26 @@ # running this when the code produces bad output will yield the test suite # inoperative/inaccurate. +# when updating this script, find and replace: +# 0.4.2 -> new version +# 0_4_2 -> new version with underscores + cd ../../../ bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json" bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publications.json" bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --workId=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" bash -c "echo '{\"data\": {\"publications\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json" bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json" +bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle" bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle" -bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --workId=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 45500a9..a628ac8 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -42,6 +42,57 @@ def test_works_raw(self): self.raw_tester(mock_response, thoth_client.works) return None + def test_work_by_id(self): + """ + Tests that good input to work_by_id produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('work', m) + self.pickle_tester('work', + lambda: + thoth_client.work_by_id(workId='e0f748b2-984f-' + '45cc-8b9e-' + '13989c31dda4')) + return None + + def test_work_by_id_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('work_bad', m) + self.pickle_tester('work', + lambda: thoth_client.work_by_id(workId='e0f748b2' + '-' + '984f-' + '45cc-' + '8b9e-' + '13989c31' + 'dda4') + , negative=True) + return None + + def test_work_by_id_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('work', m) + self.raw_tester(mock_response, + lambda: thoth_client.work_by_id(workId='e0f748b2' + '-' + '984f-' + '45cc-' + '8b9e-' + '13989c31' + 'dda4', + raw=True), + lambda_mode=True) + return None + def test_publications(self): """ Tests that good input to publications produces saved good output @@ -135,14 +186,19 @@ def test_contributions_raw(self): self.raw_tester(mock_response, thoth_client.contributions) return None - def raw_tester(self, mock_response, method_to_call): + def raw_tester(self, mock_response, method_to_call, lambda_mode=False): """ An echo test that ensures the client returns accurate raw responses + @param lambda_mode: whether the passed function is a complete lambda @param mock_response: the mock response @param method_to_call: the method to call @return: None or an assertion """ - response = method_to_call(raw=True) + if not lambda_mode: + response = method_to_call(raw=True) + else: + response = method_to_call() + self.assertEqual(mock_response, response, 'Raw response was not echoed back correctly.') From beb8d9af3ecf68f457eb406381b0b7ba1e0c4703 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 20:29:56 +0100 Subject: [PATCH 043/115] Add note about setting version in tests --- thothlibrary/thoth-0_4_2/tests/tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index a628ac8..f775bc0 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -9,6 +9,8 @@ class Thoth042Tests(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + # we set this fake endpoint to ensure that the tests are definitely + # running against the local objects, rather than the remote server self.endpoint = "https://api.test042.thoth.pub" self.version = "0.4.2" From 3ffe7e0be0553aa0c1ef91d89b84b7ad25e4dc2d Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 20:52:49 +0100 Subject: [PATCH 044/115] Add workByDoi and workById endpoints and tests --- thothlibrary/cli.py | 8 +- thothlibrary/thoth-0_4_2/endpoints.py | 6 +- .../thoth-0_4_2/tests/fixtures/workByDoi.json | 1 + .../tests/fixtures/workByDoi.pickle | 1 + .../tests/fixtures/workByDoi_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 7 +- thothlibrary/thoth-0_4_2/tests/tests.py | 83 +++++++++++++++---- 7 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 54da74f..76e600f 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -119,7 +119,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, print(works) @fire.decorators.SetParseFn(_raw_parse) - def work(self, doi=None, workId=None, raw=False, version=None, + def work(self, doi=None, work_id=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves a work by DOI from a Thoth instance @@ -128,7 +128,7 @@ def work(self, doi=None, workId=None, raw=False, version=None, :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object - :param workId: a workId to retrieve + :param work_id: a workId to retrieve """ if endpoint: self.endpoint = endpoint @@ -136,13 +136,13 @@ def work(self, doi=None, workId=None, raw=False, version=None, if version: self.version = version - if not doi and not workId: + if not doi and not work_id: print("You must specify either workId or doi.") return elif doi: work = self._client().work_by_doi(doi=doi, raw=raw) else: - work = self._client().work_by_id(workId=workId, raw=raw) + work = self._client().work_by_id(work_id=work_id, raw=raw) if not serialize: print(work) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index ec56f36..a63361c 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -386,15 +386,15 @@ def work_by_doi(self, doi: str, raw: bool = False): return self._api_request("workByDoi", parameters, return_raw=raw) - def work_by_id(self, workId: str, raw: bool = False): + def work_by_id(self, work_id: str, raw: bool = False): """ Returns a work by ID - @param workId: the ID to fetch + @param work_id: the ID to fetch @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ parameters = { - 'workId': '"' + workId + '"' + 'workId': '"' + work_id + '"' } return self._api_request("work", parameters, return_raw=raw) diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json new file mode 100644 index 0000000..2be2a7d --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json @@ -0,0 +1 @@ +{"data":{"workByDoi":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle new file mode 100644 index 0000000..c1e3bee --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle @@ -0,0 +1 @@ +{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json new file mode 100644 index 0000000..8f6d657 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json @@ -0,0 +1 @@ +{"data": {"workByDoi": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 560b95b..7710c39 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -15,16 +15,19 @@ bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --r bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publications.json" bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json" -bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --workId=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" bash -c "echo '{\"data\": {\"publications\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json" bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json" bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" +bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle" bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle" bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" -bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --workId=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index f775bc0..1780826 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -44,6 +44,52 @@ def test_works_raw(self): self.raw_tester(mock_response, thoth_client.works) return None + def test_work_by_doi(self): + """ + Tests that good input to work_by_doi produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('workByDoi', m) + self.pickle_tester('workByDoi', + lambda: + thoth_client.work_by_doi(doi='https://doi.org/' + '10.21983/P3.0314.1' + '.00')) + return None + + def test_work_by_doi_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('workByDoi_bad', m) + self.pickle_tester('work', + lambda: thoth_client.work_by_doi(doi='https://' + 'doi.org/10' + '.21983/P3' + '.0314.1.' + '00'), + negative=True) + return None + + def test_work_by_doi_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('workByDoi', m) + self.raw_tester(mock_response, + lambda: thoth_client.work_by_doi(doi='https://doi.' + 'org/10.21983' + '/P3.0314.1.' + '00', + raw=True), + lambda_mode=True) + return None + def test_work_by_id(self): """ Tests that good input to work_by_id produces saved good output @@ -53,9 +99,9 @@ def test_work_by_id(self): mock_response, thoth_client = self.setup_mocker('work', m) self.pickle_tester('work', lambda: - thoth_client.work_by_id(workId='e0f748b2-984f-' - '45cc-8b9e-' - '13989c31dda4')) + thoth_client.work_by_id(work_id='e0f748b2-984f-' + '45cc-8b9e-' + '13989c31dda4')) return None def test_work_by_id_bad_input(self): @@ -66,14 +112,15 @@ def test_work_by_id_bad_input(self): with requests_mock.Mocker() as m: mock_response, thoth_client = self.setup_mocker('work_bad', m) self.pickle_tester('work', - lambda: thoth_client.work_by_id(workId='e0f748b2' - '-' - '984f-' - '45cc-' - '8b9e-' - '13989c31' - 'dda4') - , negative=True) + lambda: thoth_client.work_by_id( + work_id='e0f748b2' + '-' + '984f-' + '45cc-' + '8b9e-' + '13989c31' + 'dda4'), + negative=True) return None def test_work_by_id_raw(self): @@ -84,13 +131,13 @@ def test_work_by_id_raw(self): with requests_mock.Mocker() as m: mock_response, thoth_client = self.setup_mocker('work', m) self.raw_tester(mock_response, - lambda: thoth_client.work_by_id(workId='e0f748b2' - '-' - '984f-' - '45cc-' - '8b9e-' - '13989c31' - 'dda4', + lambda: thoth_client.work_by_id(work_id='e0f748b2' + '-' + '984f-' + '45cc-' + '8b9e-' + '13989c31' + 'dda4', raw=True), lambda_mode=True) return None From 3b077c5f8275853e7dee22e8999cf995e11195f4 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 21:11:30 +0100 Subject: [PATCH 045/115] Add notes on test suite and versioning. Split JSON and object pickle generation. --- README.md | 17 ++++++++++++ thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 18 +++---------- thothlibrary/thoth-0_4_2/tests/genjson.sh | 26 +++++++++++++++++++ 3 files changed, 46 insertions(+), 15 deletions(-) create mode 100755 thothlibrary/thoth-0_4_2/tests/genjson.sh diff --git a/README.md b/README.md index a4eff42..84c4f28 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" +python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" @@ -44,3 +45,19 @@ python3 ./thothrest/cli.py formats python3 ./thothrest/cli.py formats --return-json python3 ./cli.py work onix_3.0::project_muse e0f748b2-984f-45cc-8b9e-13989c31dda4 ``` + +## Test Suite +Tests for GraphQL queries are versioned in the thoth-[ver] folder of thothlibrary. + +Tests confirm that current code produces good, known object outputs from stored GraphQL input. + +## Versioning +The Thoth API is not yet considered stable and functionality changes between versions. The recommended way to add a new version compatibility is: + +1. Read the latest Thoth changelog to understand the changes. +2. Copy the latest thoth-[ver] folder to the correctly named new version. +3. Find and replace the strings specified in genfixtures.sh and genjson.sh. Update the version string in tests and endpoints. +4. Run genjson.sh _only_ from inside the tests directory of the new version. This will fetch the latest server JSON responses and store it inside the fixtures directory for these tests. If there are any errors, then the command line CLI has encountered a breaking change that must first be fixed. +5. Run the test suite for the latest version and examine breakages. Fix these by subclassing the previous versions of the API and overriding broken methods. In the cases of total breakage, a non-subclassed rewrite may be more appropriate. (May also apply at major version breaks.) +6. When the test suite passes, or a new object format has been decided and tests rewritten, run genfixtures.sh to freeze the current test suite. + diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 7710c39..d4936f6 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -9,25 +9,13 @@ # 0.4.2 -> new version # 0_4_2 -> new version with underscores -cd ../../../ - -bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json" -bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" -bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publications.json" -bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json" -bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" -bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" +./genjson.sh -bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" -bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" -bash -c "echo '{\"data\": {\"publications\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json" -bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json" -bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" -bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" +cd ../../../ bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle" bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle" bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" -bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh new file mode 100755 index 0000000..5abc90d --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# this script will generate the stored fixtures for the test suite +# it should only be run when the program is generating the correct output +# running this when the code produces bad output will yield the test suite +# inoperative/inaccurate. + +# when updating this script, find and replace: +# 0.4.2 -> new version +# 0_4_2 -> new version with underscores + +cd ../../../ + +bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json" +bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" +bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publications.json" +bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" +bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" + +bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" +bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" +bash -c "echo '{\"data\": {\"publications\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json" +bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json" +bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" +bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" From a1005f2b20583c443f27fd6199d0f8ab39c2c846 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 21:14:08 +0100 Subject: [PATCH 046/115] Correct docstring on publisher --- thothlibrary/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 76e600f..84613dc 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -153,7 +153,7 @@ def work(self, doi=None, work_id=None, raw=False, version=None, def publisher(self, publisher_id, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves a work by DOI from a Thoth instance + Retrieves a publisher by ID from a Thoth instance :param str publisher_id: the publisher to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version From 0addb9008c18716722b6caf65d2d76d228dd192f Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 21:28:37 +0100 Subject: [PATCH 047/115] Add tests for publisher --- README.md | 3 +- .../thoth-0_4_2/tests/fixtures/publisher.json | 1 + .../tests/fixtures/publisher.pickle | 1 + .../tests/fixtures/publisher_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 2 + thothlibrary/thoth-0_4_2/tests/tests.py | 42 +++++++++++++++++++ 7 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publisher.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publisher.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json diff --git a/README.md b/README.md index 84c4f28..15018f6 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" @@ -58,6 +59,6 @@ The Thoth API is not yet considered stable and functionality changes between ver 2. Copy the latest thoth-[ver] folder to the correctly named new version. 3. Find and replace the strings specified in genfixtures.sh and genjson.sh. Update the version string in tests and endpoints. 4. Run genjson.sh _only_ from inside the tests directory of the new version. This will fetch the latest server JSON responses and store it inside the fixtures directory for these tests. If there are any errors, then the command line CLI has encountered a breaking change that must first be fixed. -5. Run the test suite for the latest version and examine breakages. Fix these by subclassing the previous versions of the API and overriding broken methods. In the cases of total breakage, a non-subclassed rewrite may be more appropriate. (May also apply at major version breaks.) +5. Run the test suite for the latest version and examine breakages. It is possible that breakages are not actually full breakdown, but merely a change in the serialized object. Nonetheless, fix these by subclassing the previous versions of the API and overriding broken methods. In the cases of total breakage, a non-subclassed rewrite may be more appropriate. (May also apply at major version breaks.) 6. When the test suite passes, or a new object format has been decided and tests rewritten, run genfixtures.sh to freeze the current test suite. diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publisher.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publisher.json new file mode 100644 index 0000000..497ce9e --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publisher.json @@ -0,0 +1 @@ +{"data":{"publisher":{"imprints":[{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers","__typename":"Imprint"}],"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisherName":"Open Book Publishers","publisherShortname":"OBP","publisherUrl":"https://www.openbookpublishers.com/","__typename":"Publisher"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publisher.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/publisher.pickle new file mode 100644 index 0000000..ff55de2 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publisher.pickle @@ -0,0 +1 @@ +{"imprints": [{"imprintUrl": "https://www.openbookpublishers.com/", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprintName": "Open Book Publishers", "__typename": "Imprint"}], "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "publisherName": "Open Book Publishers", "publisherShortname": "OBP", "publisherUrl": "https://www.openbookpublishers.com/", "__typename": "Publisher"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json new file mode 100644 index 0000000..719f593 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json @@ -0,0 +1 @@ +{"data": {"publisher": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index d4936f6..1f9b7a8 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -17,5 +17,6 @@ bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --s bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publications.pickle" bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.pickle" +bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publisher.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 5abc90d..eb6ceb9 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -15,6 +15,7 @@ bash -c "python3 -m thothlibrary.cli contributions --version=0.4.2 --limit=2 --r bash -c "python3 -m thothlibrary.cli works --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/works.json" bash -c "python3 -m thothlibrary.cli publications --version=0.4.2 --limit=2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publications.json" bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publishers.json" +bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publisher.json" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" @@ -22,5 +23,6 @@ bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" bash -c "echo '{\"data\": {\"publications\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publications_bad.json" bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publishers_bad.json" +bash -c "echo '{\"data\": {\"publisher\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json" bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 1780826..5e09508 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -174,6 +174,48 @@ def test_publications_raw(self): self.raw_tester(mock_response, thoth_client.publications) return None + def test_publisher(self): + """ + Tests that good input to publisher produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publisher', m) + self.pickle_tester('publisher', + lambda: + thoth_client.publisher( + publisher_id='85fd969a-a16c-480b-b641-cb9adf979c3b')) + return None + + def test_publisher_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publisher_bad', m) + self.pickle_tester('publisher', + lambda: thoth_client.publisher( + publisher_id='85fd969a-a16c-480b-b641-' + 'cb9adf979c3b'), + negative=True) + return None + + def test_publisher_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publisher', m) + self.raw_tester(mock_response, + lambda: thoth_client.publisher( + publisher_id='85fd969a-a16c-480b-b641-' + 'cb9adf979c3b', + raw=True), + lambda_mode=True) + return None + def test_publishers(self): """ Tests that good input to publishers produces saved good output From 19441865761b544c4693f9092665fdf1a33b723e Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 21:31:52 +0100 Subject: [PATCH 048/115] Additional INSTALL instructions --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 15018f6..ece6cb4 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,20 @@ Python client for Thoth's GraphQL and REST APIs ## Usage ### Install +Install is either via pip or cloning the repository. + +From pip: ```sh python3 -m pip install thothlibrary==0.5.0 ``` +Or from the repo: +```sh +git clone git@github.com:dqprogramming/thoth-client.git +cd thoth-client +pip3 install -r ./requirements.txt +``` + ### GraphQL Usage ```python from thothlibrary import ThothClient From 33384ac6264b2b6a9ba66fec0c395c5b511ec213 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sat, 7 Aug 2021 22:32:28 +0100 Subject: [PATCH 049/115] Add ASCII art cover easter egg --- requirements.txt | 3 ++- thothlibrary/cli.py | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8c3d0aa..fd19a02 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ requests==2.24.0 fire munch -requests_mock \ No newline at end of file +requests_mock +ascii_magic \ No newline at end of file diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 84613dc..3c354ca 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -120,7 +120,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, @fire.decorators.SetParseFn(_raw_parse) def work(self, doi=None, work_id=None, raw=False, version=None, - endpoint=None, serialize=False): + endpoint=None, serialize=False, cover_ascii=False): """ Retrieves a work by DOI from a Thoth instance :param str doi: the doi to fetch @@ -128,7 +128,8 @@ def work(self, doi=None, work_id=None, raw=False, version=None, :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object - :param work_id: a workId to retrieve + :param str work_id: a workId to retrieve + :param bool cover_ascii: whether to render an ASCII art cover """ if endpoint: self.endpoint = endpoint @@ -149,6 +150,12 @@ def work(self, doi=None, work_id=None, raw=False, version=None, else: print(json.dumps(work)) + if cover_ascii: + # just for lolz + import ascii_magic + output = ascii_magic.from_url(work.coverUrl, columns=85) + ascii_magic.to_terminal(output) + @fire.decorators.SetParseFn(_raw_parse) def publisher(self, publisher_id, raw=False, version=None, endpoint=None, serialize=False): From 37aff07e9074bb8d1df3ea6a9fc84f0129c1d31a Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 09:34:14 +0100 Subject: [PATCH 050/115] New lazy loader for versioned endpoints --- README.md | 8 ++-- thothlibrary/client.py | 30 ++++++++++----- thothlibrary/thoth-0_4_2/endpoints.py | 26 +++++-------- thothlibrary/thoth-0_4_2/tests/tests.py | 5 +++ thothrest/cli.py | 2 +- thothrest/client.py | 37 ++++++++++++++----- .../{thoth-042 => thoth-0_4_2}/__init__.py | 0 .../{thoth-042 => thoth-0_4_2}/endpoints.py | 21 +++++------ .../{thoth-042 => thoth-0_4_2}/structures.py | 0 9 files changed, 77 insertions(+), 52 deletions(-) rename thothrest/{thoth-042 => thoth-0_4_2}/__init__.py (100%) rename thothrest/{thoth-042 => thoth-0_4_2}/endpoints.py (85%) rename thothrest/{thoth-042 => thoth-0_4_2}/structures.py (100%) diff --git a/README.md b/README.md index ece6cb4..18c057b 100644 --- a/README.md +++ b/README.md @@ -51,10 +51,10 @@ print(client.formats()) ### CLI REST Usage ```sh -python3 ./thothrest/cli.py -python3 ./thothrest/cli.py formats -python3 ./thothrest/cli.py formats --return-json -python3 ./cli.py work onix_3.0::project_muse e0f748b2-984f-45cc-8b9e-13989c31dda4 +python3 -m thothrest.cli +python3 -m thothrest.cli formats +python3 -m thothrest.cli formats --return-json +python3 -m thothrest.cli work onix_3.0::project_muse e0f748b2-984f-45cc-8b9e-13989c31dda4 ``` ## Test Suite diff --git a/thothlibrary/client.py b/thothlibrary/client.py index 5395cde..f545e07 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -1,7 +1,7 @@ """ GraphQL client for Thoth -(c) Open Book Publishers, February 2020 +(c) Open Book Publishers, February 2020 and (c) ΔQ Programming LLP, July 2021 This programme is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ @@ -27,15 +27,24 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): self.client = GraphQLClient(self.graphql_endpoint) self.version = version.replace('.', '_') - # this is the only magic part for queries - # it delegates to the 'endpoints' module inside the current API version - # the constructor function there dynamically adds the methods that are - # supported in any API version + # this is the only 'magic' part for queries + # it wires up the methods named in 'endpoints' list of a versioned + # subclass (e.g. thoth_0_4_2) to this class, thereby providing the + # methods that can be called for any API version if issubclass(ThothClient, type(self)): - endpoints = importlib.import_module('thothlibrary.thoth-{0}.endpoints'.format(self.version)) - getattr(endpoints, 'ThothClient{0}'.format(self.version))(self, - version=version, - thoth_endpoint=thoth_endpoint) + endpoints = \ + importlib.import_module('thothlibrary.thoth-{0}.' + 'endpoints'.format(self.version)) + version_endpoints = \ + getattr(endpoints, + 'ThothClient{0}'.format(self.version))\ + (version=version, + thoth_endpoint=thoth_endpoint) + + [setattr(self, + x, + getattr(version_endpoints, + x)) for x in version_endpoints.endpoints] def login(self, email, password): """Obtain an authentication token""" @@ -121,7 +130,8 @@ def _build_structure(self, endpoint_name, data): @return: an object form of the output """ structures = \ - importlib.import_module('thothlibrary.thoth-{0}.structures'.format(self.version)) + importlib.import_module( + 'thothlibrary.thoth-{0}.structures'.format(self.version)) builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index a63361c..67ccc0a 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -261,29 +261,23 @@ class ThothClient0_4_2(ThothClient): } } - def __init__(self, input_class, thoth_endpoint="https://api.thoth.pub", - version="0.4.2"): + def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """ Creates an instance of Thoth 0.4.2 endpoints @param input_class: the ThothClient instance to be versioned """ + + # this list should specify all API endpoints by method name in this + # class. Note, it should always, also, contain the QUERIES list + self.endpoints = ['works', 'work_by_doi', 'work_by_id', + 'publishers', 'publisher', 'publications', + 'contributions', 'publisher_count', + 'contribution_count', 'work_count', + 'publication_count', 'QUERIES'] + super().__init__(thoth_endpoint=thoth_endpoint, version=version) - # this is the magic dynamic generation part that wires up the methods - input_class.works = getattr(self, 'works') - input_class.work_by_doi = getattr(self, 'work_by_doi') - input_class.work_by_id = getattr(self, 'work_by_id') - input_class.publishers = getattr(self, 'publishers') - input_class.publisher = getattr(self, 'publisher') - input_class.publications = getattr(self, 'publications') - input_class.contributions = getattr(self, 'contributions') - input_class.publisher_count = getattr(self, 'publisher_count') - input_class.contribution_count = getattr(self, 'contribution_count') - input_class.work_count = getattr(self, 'work_count') - input_class.publication_count = getattr(self, 'publication_count') - input_class.QUERIES = getattr(self, 'QUERIES') - def publications(self, limit: int = 100, offset: int = 0, filter_str: str = "", order: str = None, publishers: str = None, publication_type: str = None, diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 5e09508..a680f17 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -1,3 +1,8 @@ +""" +(c) ΔQ Programming LLP, July 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" import json import unittest diff --git a/thothrest/cli.py b/thothrest/cli.py index ce37956..6164e83 100644 --- a/thothrest/cli.py +++ b/thothrest/cli.py @@ -6,7 +6,7 @@ def _client(): - from client import ThothRESTClient + from .client import ThothRESTClient return ThothRESTClient() diff --git a/thothrest/client.py b/thothrest/client.py index fd7dab1..8bea7c9 100644 --- a/thothrest/client.py +++ b/thothrest/client.py @@ -6,7 +6,7 @@ import sys import requests -from errors import ThothRESTError +from .errors import ThothRESTError import importlib @@ -22,15 +22,27 @@ def __init__(self, endpoint='https://export.thoth.pub', version='0.4.2'): @param version: the version of the API to use """ self.endpoint = endpoint - self.version = version.replace('.', '') + self.version = version.replace('.', '_') # this is the only magic part - # this basically delegates to the 'endpoints' module inside the current API version - # the constructor function there dynamically adds the methods that are supported in any API version - endpoints = importlib.import_module('thoth-{0}.endpoints'.format(self.version)) - getattr(endpoints, 'ThothRESTClient{0}'.format(self.version))(self) + # this basically delegates to the 'endpoints' module inside the current + # API version the constructor function there dynamically adds the + # methods that are supported in any API version + if issubclass(ThothRESTClient, type(self)): + endpoints = \ + importlib.import_module('thothrest.thoth-{0}.' + 'endpoints'.format(self.version)) + version_endpoints = \ + getattr(endpoints, + 'ThothRESTClient{0}'.format(self.version))() - def _api_request(self, endpoint_name, url_suffix, return_json=False, return_raw=False): + [setattr(self, + x, + getattr(version_endpoints, + x)) for x in version_endpoints.endpoints] + + def _api_request(self, endpoint_name, url_suffix, return_json=False, + return_raw=False): """ Makes a request to the API @param endpoint_name: the name of the endpoint @@ -55,7 +67,9 @@ def _build_structure(self, endpoint_name, data): @param data: the data @return: an object form of the output """ - structures = importlib.import_module('thoth-{0}.structures'.format(self.version)) + structures = \ + importlib.import_module('thothrest.' + 'thoth-{0}.structures'.format(self.version)) builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() @@ -69,8 +83,11 @@ def _fetch(self, url_suffix): resp = requests.get(self.endpoint + url_suffix) if resp.status_code != 200: - raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), resp.status_code) + raise ThothRESTError('GET {0}{1}'.format(self.endpoint, + url_suffix), + resp.status_code) return resp except requests.exceptions.RequestException as e: - raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), e) + raise ThothRESTError('GET {0}{1}'.format(self.endpoint, url_suffix), + e) diff --git a/thothrest/thoth-042/__init__.py b/thothrest/thoth-0_4_2/__init__.py similarity index 100% rename from thothrest/thoth-042/__init__.py rename to thothrest/thoth-0_4_2/__init__.py diff --git a/thothrest/thoth-042/endpoints.py b/thothrest/thoth-0_4_2/endpoints.py similarity index 85% rename from thothrest/thoth-042/endpoints.py rename to thothrest/thoth-0_4_2/endpoints.py index a85b899..575d4de 100644 --- a/thothrest/thoth-042/endpoints.py +++ b/thothrest/thoth-0_4_2/endpoints.py @@ -3,21 +3,20 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ -from client import ThothRESTClient +from thothrest.client import ThothRESTClient -class ThothRESTClient042(ThothRESTClient): +class ThothRESTClient0_4_2(ThothRESTClient): - def __init__(self, input_class): + def __init__(self): # this is the magic dynamic generation part that wires up the methods - input_class.formats = getattr(self, 'formats') - input_class.format = getattr(self, 'format') - input_class.specifications = getattr(self, 'specifications') - input_class.specification = getattr(self, 'specification') - input_class.platform = getattr(self, 'platform') - input_class.platforms = getattr(self, 'platforms') - input_class.work = getattr(self, 'work') - input_class.works = getattr(self, 'works') + # this list should specify all API endpoints by method name in this + # class. + self.endpoints = ['formats', 'format', 'specifications', + 'specification', 'platform', 'platforms', + 'work', 'works'] + + super().__init__() def formats(self, return_json=False): """ diff --git a/thothrest/thoth-042/structures.py b/thothrest/thoth-0_4_2/structures.py similarity index 100% rename from thothrest/thoth-042/structures.py rename to thothrest/thoth-0_4_2/structures.py From 3db945b3961b781992a28e1452e16b66da1d42bf Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 13:12:09 +0100 Subject: [PATCH 051/115] Add publication endpoint, fixtures, and tests --- README.md | 3 +- thothlibrary/cli.py | 25 +++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 33 +++++++++++- thothlibrary/thoth-0_4_2/structures.py | 27 ++++++---- .../tests/fixtures/publication.json | 1 + .../tests/fixtures/publication.pickle | 1 + .../tests/fixtures/publication_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 3 ++ thothlibrary/thoth-0_4_2/tests/tests.py | 52 +++++++++++++++++++ 10 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publication.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json diff --git a/README.md b/README.md index 18c057b..c4e80f4 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,13 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh -python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" +python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 3c354ca..7e53cdf 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -118,6 +118,31 @@ def works(self, limit=100, order=None, offset=0, publishers=None, elif raw: print(works) + @fire.decorators.SetParseFn(_raw_parse) + def publication(self, publication_id, raw=False, + version=None, endpoint=None, serialize=False): + """ + Retrieves a publication by id from a Thoth instance + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param str publication_id: a publicationId to retrieve + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + publication = self._client().publication(publication_id=publication_id, + raw=raw) + + if not serialize: + print(publication) + else: + print(json.dumps(publication)) + @fire.decorators.SetParseFn(_raw_parse) def work(self, doi=None, work_id=None, raw=False, version=None, endpoint=None, serialize=False, cover_ascii=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 67ccc0a..59b7f33 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -83,6 +83,24 @@ class ThothClient0_4_2(ThothClient): ] }, + "publication": { + "parameters": [ + "publicationId", + ], + "fields": [ + "publicationId", + "publicationType", + "workId", + "isbn", + "publicationUrl", + "createdAt", + "updatedAt", + "prices { currencyCode unitPrice __typename}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "__typename" + ] + }, + "work": { "parameters": [ "workId" @@ -273,11 +291,24 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'publishers', 'publisher', 'publications', 'contributions', 'publisher_count', 'contribution_count', 'work_count', - 'publication_count', 'QUERIES'] + 'publication_count', 'publication', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) + def publication(self, publication_id: str, raw: bool = False): + """ + Returns a publication by ID + @param publication_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'publicationId': '"' + publication_id + '"' + } + + return self._api_request("publication", parameters, return_raw=raw) + def publications(self, limit: int = 100, offset: int = 0, filter_str: str = "", order: str = None, publishers: str = None, publication_type: str = None, diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 8f1ce7b..07b69f8 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -58,15 +58,24 @@ def __price_parser(prices): # they are injected to replace the default dictionary (Munch) __repr__ and # __str__ methods. They let us create nice-looking string representations # of objects, such as books -default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' - f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', - 'workByDoi': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'work': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', - 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', - 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} - +default_fields = {'works': lambda + self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'publications': lambda + self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' + f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', + 'workByDoi': lambda + self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'work': lambda + self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'publishers': lambda + self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', + 'contributions': lambda + self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', + 'publication': lambda + self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' + f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', + 'publisher': lambda + self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} # this stores the original function pointer of Munch.__repr__ so that we can # re-inject it above in "_muncher_repr" diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publication.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publication.json new file mode 100644 index 0000000..f9d569d --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publication.json @@ -0,0 +1 @@ +{"data":{"publication":{"publicationId":"34712b75-dcdd-408b-8d0c-cf29a35be2e5","publicationType":"PAPERBACK","workId":"1399a869-9f56-4980-981d-2cc83f0a6668","isbn":null,"publicationUrl":"http://amzn.to/2hxpKVL","createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","prices":[{"currencyCode":"USD","unitPrice":18.0,"__typename":"Price"}],"work":{"workId":"1399a869-9f56-4980-981d-2cc83f0a6668","fullTitle":"Truth and Fiction: Notes on (Exceptional) Faith in Art","doi":"https://doi.org/10.21983/P3.0007.1.00","publicationDate":"2012-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"Milcho Manchevski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adrian Martin","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"__typename":"Publication"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle new file mode 100644 index 0000000..b9e1c3c --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle @@ -0,0 +1 @@ +{"publicationId": "34712b75-dcdd-408b-8d0c-cf29a35be2e5", "publicationType": "PAPERBACK", "workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "isbn": null, "publicationUrl": "http://amzn.to/2hxpKVL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "prices": [{"currencyCode": "USD", "unitPrice": 18.0, "__typename": "Price"}], "work": {"workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "fullTitle": "Truth and Fiction: Notes on (Exceptional) Faith in Art", "doi": "https://doi.org/10.21983/P3.0007.1.00", "publicationDate": "2012-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Milcho Manchevski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adrian Martin", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "__typename": "Publication"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json new file mode 100644 index 0000000..ce62c12 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json @@ -0,0 +1 @@ +{"data": {"publication": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 1f9b7a8..4b13672 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -20,3 +20,4 @@ bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --seri bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publisher.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" +bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index eb6ceb9..d7cc571 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -18,6 +18,8 @@ bash -c "python3 -m thothlibrary.cli publishers --version=0.4.2 --limit=4 --raw bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publisher.json" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" +bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publication.json" + bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -26,3 +28,4 @@ bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_ bash -c "echo '{\"data\": {\"publisher\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json" bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" +bash -c "echo '{\"data\": {\"publication\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index a680f17..d55f221 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -147,6 +147,58 @@ def test_work_by_id_raw(self): lambda_mode=True) return None + def test_publication(self): + """ + Tests that good input to publication produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publication', m) + self.pickle_tester('publication', + lambda: + thoth_client.publication(publication_id= + '34712b75' + '-dcdd' + '-408b' + '-8d0c' + '-cf29a35' + 'be2e5')) + return None + + def test_publication_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publication_bad', + m) + self.pickle_tester('publication', + lambda: thoth_client.publication( + publication_id='34712b75-dcdd-408b-8d0c-' + 'cf29a35be2e5'), + negative=True) + return None + + def test_publication_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('publication', m) + self.raw_tester(mock_response, + lambda: thoth_client.publication(publication_id= + '34712b75' + '-dcdd' + '-408b' + '-8d0c' + '-cf29a' + '35be2e5', + raw=True), + lambda_mode=True) + return None + def test_publications(self): """ Tests that good input to publications produces saved good output From 0d20bbf71b33324ace90057d752b0815d858c7d4 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 14:59:58 +0100 Subject: [PATCH 052/115] Add supported versions query --- README.md | 1 + thothlibrary/cli.py | 3 +++ thothlibrary/client.py | 23 ++++++++++++++++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c4e80f4..a51b787 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" +python3 -m thothlibrary.cli supported_versions ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 7e53cdf..d54fa0a 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -118,6 +118,9 @@ def works(self, limit=100, order=None, offset=0, publishers=None, elif raw: print(works) + def supported_versions(self): + return self._client().supported_versions() + @fire.decorators.SetParseFn(_raw_parse) def publication(self, publication_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/client.py b/thothlibrary/client.py index f545e07..3f957f0 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -6,14 +6,17 @@ it under the terms of the Apache License v2.0. """ import importlib +import pkgutil -from .graphql import GraphQLClientRequests as GraphQLClient +import thothlibrary from .auth import ThothAuthenticator +from .graphql import GraphQLClientRequests as GraphQLClient from .mutation import ThothMutation from .query import ThothQuery +import re -class ThothClient(): +class ThothClient: """Client to Thoth's GraphQL API""" def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): @@ -106,6 +109,19 @@ def create_contribution(self, contribution): """Construct and trigger a mutation to add a new contribution object""" return self.mutation("createContribution", contribution) + def supported_versions(self): + regex = 'thoth-(\d+_\d+_\d+)' + + versions = [] + + for module in pkgutil.iter_modules(thothlibrary.__path__): + match = re.match(regex, module.name) + + if match: + versions.append(match.group(1).replace('_', '.')) + + return versions + def _api_request(self, endpoint_name: str, parameters, return_raw: bool = False): """ @@ -135,7 +151,8 @@ def _build_structure(self, endpoint_name, data): builder = structures.StructureBuilder(endpoint_name, data) return builder.create_structure() - def _dictionary_append(self, input_dict, key, value): + @staticmethod + def _dictionary_append(input_dict, key, value): if value: input_dict[key] = value return input_dict From 7665efc3ad029043113d52f99a487801f9da2465 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 15:22:21 +0100 Subject: [PATCH 053/115] Add imprints endpoints, cli, and tests --- README.md | 1 + thothlibrary/cli.py | 56 ++++++++++++++++--- thothlibrary/thoth-0_4_2/endpoints.py | 39 ++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/imprints.json | 1 + .../tests/fixtures/imprints.pickle | 1 + .../tests/fixtures/imprints_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 30 ++++++++++ 10 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json diff --git a/README.md b/README.md index a51b787..d8f92e2 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh +python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index d54fa0a..7e1beb1 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -119,6 +119,10 @@ def works(self, limit=100, order=None, offset=0, publishers=None, print(works) def supported_versions(self): + """ + Retrieves a list of supported Thoth versions + @return: a list of supported Thoth versions + """ return self._client().supported_versions() @fire.decorators.SetParseFn(_raw_parse) @@ -231,18 +235,54 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - publishers = self._client().publishers(limit=limit, order=order, - offset=offset, - publishers=publishers, - filter_str=filter_str, - raw=raw) + found_publishers = self._client().publishers(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter_str=filter_str, + raw=raw) + + if not raw and not serialize: + print(*found_publishers, sep='\n') + elif serialize: + print(json.dumps(found_publishers)) + else: + print(found_publishers) + + @fire.decorators.SetParseFn(_raw_parse) + def imprints(self, limit=100, order=None, offset=0, publishers=None, + filter_str=None, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves imprints from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + imprints = self._client().imprints(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter_str=filter_str, + raw=raw) if not raw and not serialize: - print(*publishers, sep='\n') + print(*imprints, sep='\n') elif serialize: - print(json.dumps(publishers)) + print(json.dumps(imprints)) else: - print(publishers) + print(imprints) @fire.decorators.SetParseFn(_raw_parse) def publisher_count(self, publishers=None, filter_str=None, raw=False, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 59b7f33..6fceede 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -230,6 +230,27 @@ class ThothClient0_4_2(ThothClient): ] }, + "imprints": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + ], + "fields": [ + "imprintUrl", + "imprintId", + "imprintName", + "updatedAt", + "createdAt", + "publisherId", + "publisher { publisherName publisherId }", + "works { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "publisher": { "parameters": [ "publisherId", @@ -291,7 +312,8 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'publishers', 'publisher', 'publications', 'contributions', 'publisher_count', 'contribution_count', 'work_count', - 'publication_count', 'publication', 'QUERIES'] + 'publication_count', 'publication', 'imprints', + 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -452,6 +474,21 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("publishers", parameters, return_raw=raw) + def imprints(self, limit: int = 100, offset: int = 0, order: str = None, + filter_str: str = "", publishers: str = None, + raw: bool = False): + """Construct and trigger a query to obtain all publishers""" + parameters = { + "limit": limit, + "offset": offset, + } + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("imprints", parameters, return_raw=raw) + def publisher_count(self, filter_str: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 07b69f8..bb8fb83 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -69,6 +69,8 @@ def __price_parser(prices): self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', 'publishers': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', + 'imprints': lambda + self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', 'publication': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json new file mode 100644 index 0000000..c94561f --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json @@ -0,0 +1 @@ +{"data":{"imprints":[{"imprintUrl":"https://punctumbooks.com/imprints/3ecologies-books/","imprintId":"78b0a283-9be3-4fed-a811-a7d4b9df7b25","imprintName":"3Ecologies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9","fullTitle":"A Manga Perfeita","doi":"https://doi.org/10.21983/P3.0270.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Christine Greiner","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Ernesto Filho","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"c3d008a2-b357-4886-acc4-a2c77f1749ee","fullTitle":"Last Year at Betty and Bob's: An Actual Occasion","doi":"https://doi.org/10.53288/0363.1.00","publicationDate":"2021-07-08","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"781b77bd-edf8-4688-937d-cc7cc47de89f","fullTitle":"Last Year at Betty and Bob's: An Adventure","doi":"https://doi.org/10.21983/P3.0234.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ce38f309-4438-479f-bd1c-b3690dbd7d8d","fullTitle":"Last Year at Betty and Bob's: A Novelty","doi":"https://doi.org/10.21983/P3.0233.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"edf31616-ea2a-4c51-b932-f510b9eb8848","fullTitle":"No Archive Will Restore You","doi":"https://doi.org/10.21983/P3.0231.1.00","publicationDate":"2018-11-13","place":"Earth, Milky Way","contributions":[{"fullName":"Julietta Singh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d4a3f6cb-3023-4088-a5f4-147fb4510874","fullTitle":"Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Matthew Goulish","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Will Dadario","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d9045f8-1d8f-479c-983d-383f3a289bec","fullTitle":"Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art","doi":"https://doi.org/10.21983/P3.0327.1.00","publicationDate":"2021-02-18","place":"Earth, Milky Way","contributions":[{"fullName":"Curt Cloninger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ffa5c5dd-ab4b-4739-8281-275d8c1fb504","fullTitle":"Sweet Spots: Writing the Connective Tissue of Relation","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mattie-Martha Sempert","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"757ff294-0fca-40f5-9f33-39a2d3fd5c8a","fullTitle":"Teaching Myself To See","doi":"https://doi.org/10.21983/P3.0303.1.00","publicationDate":"2021-02-11","place":"Earth, Milky Way","contributions":[{"fullName":"Tito Mukhopadhyay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}]},{"workId":"571255b8-5bf5-4fe1-a201-5bc7aded7f9d","fullTitle":"The Perfect Mango","doi":"https://doi.org/10.21983/P3.0245.1.00","publicationDate":"2019-02-20","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4cfb06e-a5a6-48cc-b7e5-c38228c132a8","fullTitle":"The Unnaming of Aliass","doi":"https://doi.org/10.21983/P3.0299.1.00","publicationDate":"2020-10-01","place":"Earth, Milky Way","contributions":[{"fullName":"Karin Bolender","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/advanced-methods/","imprintId":"ef38d49c-f8cb-4621-9f2f-1637560016e4","imprintName":"Advanced Methods","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"0729b9d1-87d3-4739-8266-4780c3cc93da","fullTitle":"Doing Multispecies Theology","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mathew Arthur","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"af1d6a61-66bd-47fd-a8c5-20e433f7076b","fullTitle":"Inefficient Mapping: A Protocol for Attuning to Phenomena","doi":"https://doi.org/10.53288/0336.1.00","publicationDate":"2021-08-05","place":"Earth, Milky Way","contributions":[{"fullName":"Linda Knight","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aa9059ba-930c-4327-97a1-c8c7877332c1","fullTitle":"Making a Laboratory: Dynamic Configurations with Transversal Video","doi":null,"publicationDate":"2020-08-06","place":"Earth, Milky Way","contributions":[{"fullName":"Ben Spatz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8f256239-8104-4838-9587-ac234aedd822","fullTitle":"Speaking for the Social: A Catalog of Methods","doi":"https://doi.org/10.21983/P3.0378.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Gemma John","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Hannah Knox","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprint/anarchist-developments-in-cultural-studies/","imprintId":"3bdf14c5-7f9f-42d2-8e3b-f78de0475c76","imprintName":"Anarchist Developments in Cultural Studies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1d014946-aa73-4fae-9042-ef8830089f3c","fullTitle":"Blasting the Canon","doi":"https://doi.org/10.21983/P3.0035.1.00","publicationDate":"2013-06-25","place":"Brooklyn, NY","contributions":[{"fullName":"Ruth Kinna","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Süreyyya Evren","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"e1f74d6b-adab-4e56-8bc9-6fbd0eaab89c","fullTitle":"Ontological Anarché: Beyond Materialism and Idealism","doi":"https://doi.org/10.21983/P3.0060.1.00","publicationDate":"2014-01-24","place":"Brooklyn, NY","contributions":[{"fullName":"Jason Adams","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Duane Rousselle","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/brainstorm-books/","imprintId":"1e464718-2055-486b-bcd9-6e21309fcd80","imprintName":"Brainstorm Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"fdd9e45a-08b4-4b98-9c34-bada71a34979","fullTitle":"Animal Emotions: How They Drive Human Behavior","doi":"https://doi.org/10.21983/P3.0305.1.00","publicationDate":"2020-06-18","place":"Earth, Milky Way","contributions":[{"fullName":"Kenneth L. Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Christian Montag","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"811fd271-b1dc-490a-a872-3d6867d59e78","fullTitle":"Aural History","doi":"https://doi.org/10.21983/P3.0282.1.00","publicationDate":"2020-03-12","place":"Earth, Milky Way","contributions":[{"fullName":"Gila Ashtor","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f01cb60b-69bf-4d11-bd3c-fd5b36663029","fullTitle":"Covert Plants: Vegetal Consciousness and Agency in an Anthropocentric World","doi":"https://doi.org/10.21983/P3.0207.1.00","publicationDate":"2018-09-11","place":"Earth, Milky Way","contributions":[{"fullName":"Prudence Gibson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Brits Baylee","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"9bdf38ca-95fd-4cf4-adf6-ed26e97cf213","fullTitle":"Critique of Fantasy, Vol. 1: Between a Crypt and a Datemark","doi":"https://doi.org/10.21983/P3.0277.1.00","publicationDate":"2020-06-25","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"89f9c84b-be5c-4020-8edc-6fbe0b1c25f5","fullTitle":"Critique of Fantasy, Vol. 2: The Contest between B-Genres","doi":"https://doi.org/10.21983/P3.0278.1.00","publicationDate":"2020-11-24","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"79464e83-b688-4b82-84bc-18d105f60f33","fullTitle":"Critique of Fantasy, Vol. 3: The Block of Fame","doi":"https://doi.org/10.21983/P3.0279.1.00","publicationDate":"2021-01-14","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"992c6ff8-e166-4014-85cc-b53af250a4e4","fullTitle":"Hack the Experience: Tools for Artists from Cognitive Science","doi":"https://doi.org/10.21983/P3.0206.1.00","publicationDate":"2018-09-04","place":"Earth, Milky Way","contributions":[{"fullName":"Ryan Dewey","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4a42f23b-5277-49b5-8310-c3c38ded5bf5","fullTitle":"Opioids: Addiction, Narrative, Freedom","doi":"https://doi.org/10.21983/P3.0210.1.00","publicationDate":"2018-10-05","place":"Earth, Milky Way","contributions":[{"fullName":"Maia Dolphin-Krute","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"18d3d876-bcaf-4e1c-a67a-05537f808a99","fullTitle":"The Hegemony of Psychopathy","doi":"https://doi.org/10.21983/P3.0180.1.00","publicationDate":"2017-09-19","place":"Earth, Milky Way","contributions":[{"fullName":"Lajos Brons","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5dca2af4-43f2-4cdb-a7a5-5654a722c4e0","fullTitle":"Visceral: Essays on Illness Not as Metaphor","doi":"https://doi.org/10.21983/P3.0185.1.00","publicationDate":"2017-10-16","place":"Earth, Milky Way","contributions":[{"fullName":"Maia Dolphin-Krute","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/ctm-documents-initiative/","imprintId":"cec45cc6-8cb5-43ed-888f-165f3fa73842","imprintName":"CTM Documents Initiative","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"b950d243-7cfc-4aee-b908-d1776be327df","fullTitle":"Image Photograph","doi":"https://doi.org/10.21983/P3.0106.1.00","publicationDate":"2015-07-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marc Lafia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"14f2b847-faeb-43c9-b116-88a0091b6f1f","fullTitle":"Knowledge, Spirit, Law, Book 2: The Anti-Capitalist Sublime","doi":"https://doi.org/10.21983/P3.0191.1.00","publicationDate":"2017-12-24","place":"Earth, Milky Way","contributions":[{"fullName":"Gavin Keeney","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1e0c7c29-dcd4-470d-b3ee-8c4012ac79dd","fullTitle":"Liquid Life: On Non-Linear Materiality","doi":"https://doi.org/10.21983/P3.0246.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Rachel Armstrong","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"47cd079b-03f3-4a5b-b5e4-36cec4db7fab","fullTitle":"The Digital Dionysus: Nietzsche and the Network-Centric Condition","doi":"https://doi.org/10.21983/P3.0149.1.00","publicationDate":"2016-09-12","place":"Earth, Milky Way","contributions":[{"fullName":"Dan Mellamphy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Nandita Biswas Mellamphy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1950e4ba-651c-4ec9-83f6-df46b777b10f","fullTitle":"The Funambulist Pamphlets 10: Literature","doi":"https://doi.org/10.21983/P3.0075.1.00","publicationDate":"2014-08-14","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"bdfc263a-7ace-43f3-9c80-140c6fb32ec7","fullTitle":"The Funambulist Pamphlets 11: Cinema","doi":"https://doi.org/10.21983/P3.0095.1.00","publicationDate":"2015-02-20","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f5fb8a0e-ea1d-471f-b76a-a000edae5956","fullTitle":"The Funambulist Pamphlets 1: Spinoza","doi":"https://doi.org/10.21983/P3.0033.1.00","publicationDate":"2013-06-13","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"911de470-77e1-4816-b437-545122a7bf26","fullTitle":"The Funambulist Pamphlets 2: Foucault","doi":"https://doi.org/10.21983/P3.0034.1.00","publicationDate":"2013-06-17","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"61da662d-c720-4d22-957c-4d96071ee5f2","fullTitle":"The Funambulist Pamphlets 3: Deleuze","doi":"https://doi.org/10.21983/P3.0038.1.00","publicationDate":"2013-07-04","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"419e17ed-3bcc-430c-a67e-3121537e4702","fullTitle":"The Funambulist Pamphlets 4: Legal Theory","doi":"https://doi.org/10.21983/P3.0042.1.00","publicationDate":"2013-08-15","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fe8ddfb7-0e5b-4604-811c-78cf4db7528b","fullTitle":"The Funambulist Pamphlets 5: Occupy Wall Street","doi":"https://doi.org/10.21983/P3.0046.1.00","publicationDate":"2013-09-08","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13390641-86f6-4351-923d-8c456f175bff","fullTitle":"The Funambulist Pamphlets 6: Palestine","doi":"https://doi.org/10.21983/P3.0054.1.00","publicationDate":"2013-11-13","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"448c3581-9167-491e-86f7-08d5a6c953a9","fullTitle":"The Funambulist Pamphlets 7: Cruel Designs","doi":"https://doi.org/10.21983/P3.0057.1.00","publicationDate":"2013-12-21","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d3cbb60f-537f-4bd7-96cb-d8aba595a947","fullTitle":"The Funambulist Pamphlets 8: Arakawa + Madeline Gins","doi":"https://doi.org/10.21983/P3.0064.1.00","publicationDate":"2014-03-12","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6fab7c76-7567-4b57-8ad7-90a5536d87af","fullTitle":"The Funambulist Pamphlets 9: Science Fiction","doi":"https://doi.org/10.21983/P3.0069.1.00","publicationDate":"2014-05-28","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"84bbf59f-1dbb-445e-8f65-f26574f609b6","fullTitle":"The Funambulist Papers, Volume 1","doi":"https://doi.org/10.21983/P3.0053.1.00","publicationDate":"2013-10-23","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3b41b8de-b9bb-4ebd-a002-52052a9e39a9","fullTitle":"The Funambulist Papers, Volume 2","doi":"https://doi.org/10.21983/P3.0098.1.00","publicationDate":"2015-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/dead-letter-office/","imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","imprintName":"Dead Letter Office","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","fullTitle":"A Bibliography for After Jews and Arabs","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f02786d4-3bcc-473e-8d43-3da66c7e877c","fullTitle":"A Brief Genealogy of Jewish Republicanism: Parting Ways with Judith Butler","doi":"https://doi.org/10.21983/P3.0159.1.00","publicationDate":"2016-12-16","place":"Earth, Milky Way","contributions":[{"fullName":"Irene Tucker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fd67d684-aaff-4260-bb94-9d0373015620","fullTitle":"An Edition of Miles Hogarde's \"A Mirroure of Myserie\"","doi":"https://doi.org/10.21983/P3.0316.1.00","publicationDate":"2021-06-03","place":"Earth, Milky Way","contributions":[{"fullName":"Sebastian Sobecki","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5f441303-4fc6-4a7d-951e-5b966a1cbd91","fullTitle":"An Unspecific Dog: Artifacts of This Late Stage in History","doi":"https://doi.org/10.21983/P3.0163.1.00","publicationDate":"2017-01-18","place":"Earth, Milky Way","contributions":[{"fullName":"Joshua Rothes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7eb6f426-e913-4d69-92c5-15a640f1b4b9","fullTitle":"A Sanctuary of Sounds","doi":"https://doi.org/10.21983/P3.0029.1.00","publicationDate":"2013-05-23","place":"Brooklyn, NY","contributions":[{"fullName":"Andreas Burckhardt","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4fc74913-bde4-426e-b7e5-2f66c60af484","fullTitle":"As If: Essays in As You Like It","doi":"https://doi.org/10.21983/P3.0162.1.00","publicationDate":"2016-12-29","place":"Earth, Milky Way","contributions":[{"fullName":"William N. West","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"06db2bc1-e25a-42c8-8908-fbd774f73204","fullTitle":"Atopological Trilogy: Deleuze and Guattari","doi":"https://doi.org/10.21983/P3.0096.1.00","publicationDate":"2015-03-15","place":"Brooklyn, NY","contributions":[{"fullName":"Zafer Aracagök","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Manola Antonioli","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"a022743e-8b77-4246-a068-e08d57815e27","fullTitle":"CMOK to YOu To: A Correspondence","doi":"https://doi.org/10.21983/P3.0150.1.00","publicationDate":"2016-09-15","place":"Earth, Milky Way","contributions":[{"fullName":"Marc James Léger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Nina Živančević","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f94ded4d-1c87-4503-82f1-a1ca4346e756","fullTitle":"Come As You Are, After Eve Kosofsky Sedgwick","doi":"https://doi.org/10.21983/P3.0342.1.00","publicationDate":"2021-04-06","place":"Earth, Milky Way","contributions":[{"fullName":"Eve Kosofsky Sedgwick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonathan Goldberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"449add5c-b935-47e2-8e46-2545fad86221","fullTitle":"Escargotesque, or, What Is Experience","doi":"https://doi.org/10.21983/P3.0089.1.00","publicationDate":"2015-01-26","place":"Brooklyn, NY","contributions":[{"fullName":"M.H. Bowker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"628bb121-5ba2-4fc1-a741-a8062c45b63b","fullTitle":"Gaffe/Stutter","doi":"https://doi.org/10.21983/P3.0049.1.00","publicationDate":"2013-10-06","place":"Brooklyn, NY","contributions":[{"fullName":"Whitney Anne Trettien","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f131762c-a877-4925-9fa1-50555bc4e2ae","fullTitle":"[Given, If, Then]: A Reading in Three Parts","doi":"https://doi.org/10.21983/P3.0090.1.00","publicationDate":"2015-02-08","place":"Brooklyn, NY","contributions":[{"fullName":"Jennifer Hope Davy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Julia Hölzl","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cb11259b-7b83-498e-bc8a-7c184ee2c279","fullTitle":"Going Postcard: The Letter(s) of Jacques Derrida","doi":"https://doi.org/10.21983/P3.0171.1.00","publicationDate":"2017-05-15","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f8b57164-89e6-48b1-bd70-9d360b53a453","fullTitle":"Helicography","doi":"https://doi.org/10.53288/0352.1.00","publicationDate":"2021-07-22","place":"Earth, Milky Way","contributions":[{"fullName":"Craig Dworkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6689db84-b329-4ca5-b10c-010fd90c7e90","fullTitle":"History of an Abuse","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ceffc30d-1d28-48c3-acee-e6a2dc38ff37","fullTitle":"How We Read","doi":"https://doi.org/10.21983/P3.0259.1.00","publicationDate":"2019-07-18","place":"Earth, Milky Way","contributions":[{"fullName":"Kaitlin Heller","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Suzanne Conklin Akbari","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"63e2f6b6-f324-4bdc-836e-55515ba3cd8f","fullTitle":"How We Write: Thirteen Ways of Looking at a Blank Page","doi":"https://doi.org/10.21983/P3.0110.1.00","publicationDate":"2015-09-11","place":"Brooklyn, NY","contributions":[{"fullName":"Suzanne Conklin Akbari","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f5217945-8c2c-4e65-a5dd-3dbff208dfb7","fullTitle":"In Divisible Cities: A Phanto-Cartographical Missive","doi":"https://doi.org/10.21983/P3.0044.1.00","publicationDate":"2013-08-26","place":"Brooklyn, NY","contributions":[{"fullName":"Dominic Pettman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d5f5978b-32e0-44a1-a72a-c80568c9b93a","fullTitle":"I Open Fire","doi":"https://doi.org/10.21983/P3.0086.1.00","publicationDate":"2014-12-28","place":"Brooklyn, NY","contributions":[{"fullName":"David Pol","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c6125a74-2801-4255-afe9-89cdb8d253f4","fullTitle":"John Gardner: A Tiny Eulogy","doi":"https://doi.org/10.21983/P3.0013.1.00","publicationDate":"2012-11-29","place":"Brooklyn, NY","contributions":[{"fullName":"Phil Jourdan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8377c394-c27a-44cb-98f5-5e5b789ad7b8","fullTitle":"Last Day Every Day: Figural Thinking from Auerbach and Kracauer to Agamben and Brenez","doi":"https://doi.org/10.21983/P3.0012.1.00","publicationDate":"2012-10-23","place":"Brooklyn, NY","contributions":[{"fullName":"Adrian Martin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1809f10a-d0e3-4481-8f96-cca7f240d656","fullTitle":"Letters on the Autonomy Project in Art and Politics","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Janet Sarbanes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5f1db605-88b6-427a-84cb-ce2fcf0f89a3","fullTitle":"Massa por Argamassa: A \"Libraria de Babel\" e o Sonho de Totalidade","doi":"https://doi.org/10.21983/P3.0264.1.00","publicationDate":"2019-09-17","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Basile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Yuri N. Martinez Laskowski","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f20869c5-746f-491b-8c34-f88dc3728e18","fullTitle":"Minóy","doi":"https://doi.org/10.21983/P3.0072.1.00","publicationDate":"2014-06-30","place":"Brooklyn, NY","contributions":[{"fullName":"Joseph Nechvatal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d40aa92-380c-4fae-98d8-c598bb32e7c6","fullTitle":"Misinterest: Essays, Pensées, and Dreams","doi":"https://doi.org/10.21983/P3.0256.1.00","publicationDate":"2019-06-27","place":"Earth, Milky Way","contributions":[{"fullName":"M.H. Bowker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"34682ba4-201f-4122-8e4a-edc3edc57a7b","fullTitle":"Nicholas of Cusa and the Kairos of Modernity: Cassirer, Gadamer, Blumenberg","doi":"https://doi.org/10.21983/P3.0045.1.00","publicationDate":"2013-09-05","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Edward Moore","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1cfca75f-2e57-4f34-85fb-a1585315a2a9","fullTitle":"Noise Thinks the Anthropocene: An Experiment in Noise Poetics","doi":"https://doi.org/10.21983/P3.0244.1.00","publicationDate":"2019-02-13","place":"Earth, Milky Way","contributions":[{"fullName":"Aaron Zwintscher","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"571d5d40-cfd6-4270-9530-88bfcfc5d8b5","fullTitle":"Non-Conceptual Negativity: Damaged Reflections on Turkey","doi":"https://doi.org/10.21983/P3.0247.1.00","publicationDate":"2019-03-27","place":"Earth, Milky Way","contributions":[{"fullName":"Zafer Aracagök","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Fraco \"Bifo\" Berardi","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"3eb0d095-fc27-4add-8202-1dc2333a758c","fullTitle":"Notes on Trumpspace: Politics, Aesthetics, and the Fantasy of Home","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"David Stephenson Markus","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"48e2a673-aec2-4ed6-99d4-46a8de200493","fullTitle":"Nothing in MoMA","doi":"https://doi.org/10.21983/P3.0208.1.00","publicationDate":"2018-09-22","place":"Earth, Milky Way","contributions":[{"fullName":"Abraham Adams","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97019dea-e207-4909-b907-076d0620ff74","fullTitle":"Obiter Dicta","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Erick Verran","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"10a41381-792f-4376-bed1-3781d1b8bae7","fullTitle":"Of Learned Ignorance: Idea of a Treatise in Philosophy","doi":"https://doi.org/10.21983/P3.0031.1.00","publicationDate":"2013-06-04","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b43ec529-2f51-4c59-b3cb-394f3649502c","fullTitle":"Of the Contract","doi":"https://doi.org/10.21983/P3.0174.1.00","publicationDate":"2017-07-11","place":"Earth, Milky Way","contributions":[{"fullName":"Christopher Clifton","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"63b0e966-e81c-4d84-b41d-3445b0d9911f","fullTitle":"Paris Bride: A Modernist Life","doi":"https://doi.org/10.21983/P3.0281.1.00","publicationDate":"2020-02-21","place":"Earth, Milky Way","contributions":[{"fullName":"John Schad","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed1a8fb5-8b71-43ca-9748-ebd43f0d7580","fullTitle":"Philosophy for Militants","doi":"https://doi.org/10.21983/P3.0168.1.00","publicationDate":"2017-03-15","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5b652d05-2b5f-465a-8c66-f4dc01dafd03","fullTitle":"[provisional self-evidence]","doi":"https://doi.org/10.21983/P3.0111.1.00","publicationDate":"2015-09-13","place":"Brooklyn, NY","contributions":[{"fullName":"Rachel Arrighi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cd836291-fb7f-4508-bdff-cd59dca2b447","fullTitle":"Queer Insists (for José Esteban Muñoz)","doi":"https://doi.org/10.21983/P3.0082.1.00","publicationDate":"2014-12-04","place":"Brooklyn, NY","contributions":[{"fullName":"Michael O'Rourke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"46ab709c-3272-4a03-991e-d1b1394b8e2c","fullTitle":"Ravish the Republic: The Archives of the Iron Garters Crime/Art Collective","doi":"https://doi.org/10.21983/P3.0107.1.00","publicationDate":"2015-07-15","place":"Brooklyn, NY","contributions":[{"fullName":"Michael L. Berger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"28a0db09-a149-43fe-ba08-00dde962b4b8","fullTitle":"Reiner Schürmann and Poetics of Politics","doi":"https://doi.org/10.21983/P3.0209.1.00","publicationDate":"2018-09-28","place":"Earth, Milky Way","contributions":[{"fullName":"Christopher Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5dda1ad6-70ac-4a31-baf2-b77f8f5a8190","fullTitle":"Sappho: Fragments","doi":"https://doi.org/10.21983/P3.0238.1.00","publicationDate":"2018-12-31","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Goldberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"L.O. Aranye Fradenburg Joy","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"8cd5ce6c-d604-46ac-b4f7-1f871589d96a","fullTitle":"Still Life: Notes on Barbara Loden's \"Wanda\" (1970)","doi":"https://doi.org/10.53288/0326.1.00","publicationDate":"2021-07-29","place":"Earth, Milky Way","contributions":[{"fullName":"Anna Backman Rogers","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1547aa4b-7629-4a21-8b2b-621223c73ec9","fullTitle":"Still Thriving: On the Importance of Aranye Fradenburg","doi":"https://doi.org/10.21983/P3.0099.1.00","publicationDate":"2015-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"L.O. Aranye Fradenburg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"08543bd7-e603-43ae-bb0f-1d4c1c96030b","fullTitle":"Suite on \"Spiritus Silvestre\": For Symphony","doi":"https://doi.org/10.21983/P3.0020.1.00","publicationDate":"2012-12-25","place":"Brooklyn, NY","contributions":[{"fullName":"Denzil Ford","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9839926e-56ea-4d71-a3de-44cabd1d2893","fullTitle":"Tar for Mortar: \"The Library of Babel\" and the Dream of Totality","doi":"https://doi.org/10.21983/P3.0196.1.00","publicationDate":"2018-03-15","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Basile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"58aadfa5-abc6-4c44-9768-f8ff41502867","fullTitle":"The Afterlife of Genre: Remnants of the Trauerspiel in Buffy the Vampire Slayer","doi":"https://doi.org/10.21983/P3.0061.1.00","publicationDate":"2014-02-21","place":"Brooklyn, NY","contributions":[{"fullName":"Anthony Curtis Adler","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1d30497f-4340-43ab-b328-9fd2fed3106e","fullTitle":"The Anthology of Babel","doi":"https://doi.org/10.21983/P3.0254.1.00","publicationDate":"2020-01-24","place":"Earth, Milky Way","contributions":[{"fullName":"Ed Simon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"26d522d4-fb46-47bf-a344-fe6af86688d3","fullTitle":"The Bodies That Remain","doi":"https://doi.org/10.21983/P3.0212.1.00","publicationDate":"2018-10-16","place":"Earth, Milky Way","contributions":[{"fullName":"Emmy Beber","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a065ad95-716a-4005-b436-a46d9dbd64df","fullTitle":"The Communism of Thought","doi":"https://doi.org/10.21983/P3.0059.1.00","publicationDate":"2014-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c51c8fa-947b-4a12-a2e9-5306ee81d117","fullTitle":"The Death of Conrad Unger: Some Conjectures Regarding Parasitosis and Associated Suicide Behavior","doi":"https://doi.org/10.21983/P3.0008.1.00","publicationDate":"2012-08-13","place":"Brooklyn, NY","contributions":[{"fullName":"Gary L. Shipley","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"33917b8f-775f-4ee2-a43a-6b5285579f84","fullTitle":"The Non-Library","doi":"https://doi.org/10.21983/P3.0065.1.00","publicationDate":"2014-03-13","place":"Brooklyn, NY","contributions":[{"fullName":"Trevor Owen Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"60813d93-663f-4974-8789-1a2ee83cd042","fullTitle":"Theory Is Like a Surging Sea","doi":"https://doi.org/10.21983/P3.0108.1.00","publicationDate":"2015-08-02","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"119e45d6-63ab-4cc4-aabf-06ecba1fb055","fullTitle":"The Witch and the Hysteric: The Monstrous Medieval in Benjamin Christensen's Häxan","doi":"https://doi.org/10.21983/P3.0074.1.00","publicationDate":"2014-08-08","place":"Brooklyn, NY","contributions":[{"fullName":"Patricia Clare Ingham","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alexander Doty","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d6651c3c-c453-42ab-84b3-4e847d3a3324","fullTitle":"Traffic Jams: Analysing Everyday Life through the Immanent Materialism of Deleuze & Guattari","doi":"https://doi.org/10.21983/P3.0023.1.00","publicationDate":"2013-02-13","place":"Brooklyn, NY","contributions":[{"fullName":"David R. Cole","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1399a869-9f56-4980-981d-2cc83f0a6668","fullTitle":"Truth and Fiction: Notes on (Exceptional) Faith in Art","doi":"https://doi.org/10.21983/P3.0007.1.00","publicationDate":"2012-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"Milcho Manchevski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adrian Martin","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"b904a8eb-9c98-4bb1-bf25-3cb9d075b157","fullTitle":"Warez: The Infrastructure and Aesthetics of Piracy","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Martin Eve","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"77e1fa52-1938-47dd-b8a5-2a57bfbc91d1","fullTitle":"What Is Philosophy?","doi":"https://doi.org/10.21983/P3.0011.1.00","publicationDate":"2012-10-09","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"27602ce3-fbd6-4044-8b44-b8421670edae","fullTitle":"Wonder, Horror, and Mystery in Contemporary Cinema: Letters on Malick, Von Trier, and Kieślowski","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Morgan Meis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"J.M. Tyree","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/department-of-eagles/","imprintId":"ef4aece6-6e9c-4f90-b5c3-7e4b78e8942d","imprintName":"Department of Eagles","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"3ccdbbfc-6550-49f4-8ec9-77fc94a7a099","fullTitle":"Broken Narrative: The Politics of Contemporary Art in Albania","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Armando Lulaj","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marco Mazzi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Brenda Porster","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Tomii Keiko","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Osamu Kanemura","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":6},{"fullName":"Jonida Gashi","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":5}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/dotawo/","imprintId":"f891a5f0-2af2-4eda-b686-db9dd74ee73d","imprintName":"Dotawo","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1c39ca0c-0189-44d3-bb2f-9345e2a2b152","fullTitle":"Dotawo: A Journal of Nubian Studies 2","doi":"https://doi.org/10.21983/P3.0104.1.00","publicationDate":"2015-06-01","place":"Brooklyn, NY","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Angelika Jakobi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"861ea7cc-5447-4c60-8657-c50d0a31cd24","fullTitle":"Dotawo: a Journal of Nubian Studies 3: Know-Hows and Techniques in Ancient Sudan","doi":"https://doi.org/10.21983/P3.0148.1.00","publicationDate":"2016-08-11","place":"Earth, Milky Way","contributions":[{"fullName":"Marc Maillot","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"431b58fe-7f59-49d9-bf6f-53eae379ee4d","fullTitle":"Dotawo: A Journal of Nubian Studies 4: Place Names and Place Naming in Nubia","doi":"https://doi.org/10.21983/P3.0184.1.00","publicationDate":"2017-10-12","place":"Earth, Milky Way","contributions":[{"fullName":"Alexandros Tsakos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Robin Seignobos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3c5923bc-e76b-4fbe-8d8c-1a49a49020a8","fullTitle":"Dotawo: A Journal of Nubian Studies 5: Nubian Women","doi":"https://doi.org/10.21983/P3.0242.1.00","publicationDate":"2019-02-05","place":"Earth, Milky Way","contributions":[{"fullName":"Anne Jennings","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"15ab17fe-2486-4ca5-bb47-6b804793f80d","fullTitle":"Dotawo: A Journal of Nubian Studies 6: Miscellanea Nubiana","doi":"https://doi.org/10.21983/P3.0321.1.00","publicationDate":"2019-12-26","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Simmons","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aa431454-40d3-42f5-8069-381a15789257","fullTitle":"Dotawo: A Journal of Nubian Studies 7: Comparative Northern East Sudanic Linguistics","doi":"https://doi.org/10.21983/P3.0350.1.00","publicationDate":"2021-03-23","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7a4506ac-dfdc-4054-b2d1-d8fdf4cea12b","fullTitle":"Nubian Proverbs","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Maher Habbob","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a8e6722a-1858-4f38-995d-bde0b120fe8c","fullTitle":"The Old Nubian Language","doi":"https://doi.org/10.21983/P3.0179.1.00","publicationDate":"2017-09-11","place":"Earth, Milky Way","contributions":[{"fullName":"Eugenia Smagina","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"José Andrés Alonso de la Fuente","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"0cd80cd2-1733-4bde-b48f-a03fc01acfbf","fullTitle":"The Old Nubian Texts from Attiri","doi":"https://doi.org/10.21983/P3.0156.1.00","publicationDate":"2016-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Petra Weschenfelder","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent Pierre-Michel Laisney","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kerstin Weber-Thum","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Alexandros Tsakos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4}]}],"__typename":"Imprint"},{"imprintUrl":null,"imprintId":"47e62ae1-6698-46aa-840c-d4507697459f","imprintName":"eth press","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"5f24bd29-3d48-4a70-8491-6269f7cc6212","fullTitle":"Ballads","doi":"https://doi.org/10.21983/P3.0105.1.00","publicationDate":"2015-06-03","place":"Brooklyn, NY","contributions":[{"fullName":"Richard Owens","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0a8fba81-f1d0-498c-88c4-0b96d3bf2947","fullTitle":"Cotton Nero A.x: The Works of the \"Pearl\" Poet","doi":"https://doi.org/10.21983/P3.0066.1.00","publicationDate":"2014-04-24","place":"Brooklyn, NY","contributions":[{"fullName":"Chris Piuma","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Lisa Ampleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Daniel C. Remein","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"David Hadbawnik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"53cd2c70-eab6-45b7-a147-8ef1c87d9ac0","fullTitle":"dôNrm'-lä-püsl","doi":"https://doi.org/10.21983/P3.0183.1.00","publicationDate":"2017-10-05","place":"Earth, Milky Way","contributions":[{"fullName":"kari edwards","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Tina Žigon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"34584bfe-1cf8-49c5-b8d1-6302ea1cfcfa","fullTitle":"Snowline","doi":"https://doi.org/10.21983/P3.0093.1.00","publicationDate":"2015-02-15","place":"Brooklyn, NY","contributions":[{"fullName":"Donato Mancini","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cc73eed0-a1f9-4ad4-b7d8-2394b92765f0","fullTitle":"Unless As Stone Is","doi":"https://doi.org/10.21983/P3.0058.1.00","publicationDate":"2014-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Sam Lohmann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/gracchi-books/","imprintId":"41193484-91d1-44f3-8d0c-0452a35d17a0","imprintName":"Gracchi Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1603556c-53fc-4d14-b0bf-8c18ad7b24ab","fullTitle":"Social and Intellectual Networking in the Early Middle Ages","doi":null,"publicationDate":null,"place":null,"contributions":[{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"K. Patrick Fazioli","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"6813bf17-373c-49ce-b9e3-1d7ab98f2977","fullTitle":"The Christian Economy of the Early Medieval West: Towards a Temple Society","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Ian Wood","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2f93b300-f147-48f5-95d5-afd0e0161fe6","fullTitle":"Urban Interactions: Communication and Competition in Late Antiquity and the Early Middle Ages","doi":"https://doi.org/10.21983/P3.0300.1.00","publicationDate":"2020-10-15","place":"Earth, Milky Way","contributions":[{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael Burrows","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ian Wood","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"Michael J. Kelly","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"678f4564-d01a-4ffe-8bdb-fead78f87955","fullTitle":"Vera Lex Historiae?: Constructions of Truth in Medieval Historical Narrative","doi":"https://doi.org/10.21983/P3.0369.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Catalin Taranu","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/helvete/","imprintId":"b3dc0be6-6739-4777-ada0-77b1f5074f7d","imprintName":"Helvete","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"417ecc06-51a4-4660-959b-482763864559","fullTitle":"Helvete 1: Incipit","doi":"https://doi.org/10.21983/P3.0027.1.00","publicationDate":"2013-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"Aspasia Stephanou","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Amelia Ishmael","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Zareen Price","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ben Woodard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"3cc0269d-7170-4981-8ac7-5b01e7b9e080","fullTitle":"Helvete 2: With Head Downwards: Inversions in Black Metal","doi":"https://doi.org/10.21983/P3.0102.1.00","publicationDate":"2015-05-19","place":"Brooklyn, NY","contributions":[{"fullName":"Niall Scott","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Steve Shakespeare","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"fa4bc310-b7db-458a-8ba9-13347a91c862","fullTitle":"Helvete 3: Bleeding Black Noise","doi":"https://doi.org/10.21983/P3.0158.1.00","publicationDate":"2016-12-14","place":"Earth, Milky Way","contributions":[{"fullName":"Amelia Ishmael","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/lamma/","imprintId":"f852b678-e8ac-4949-a64d-3891d4855e3d","imprintName":"Lamma","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"ce7ec5ea-88b2-430f-92be-0f2436600a46","fullTitle":"Lamma: A Journal of Libyan Studies 1","doi":"https://doi.org/10.21983/P3.0337.1.00","publicationDate":"2020-07-21","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Benkato","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Leila Tayeb","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Amina Zarrugh","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://www.matteringpress.org","imprintId":"cb483a78-851f-4936-82d2-8dcd555dcda9","imprintName":"Mattering Press","updatedAt":"2021-03-25T16:33:14.299495+00:00","createdAt":"2021-03-25T16:25:02.238699+00:00","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6","publisher":{"publisherName":"Mattering Press","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6"},"works":[{"workId":"95e15115-4009-4cb0-8824-011038e3c116","fullTitle":"Energy Worlds: In Experiment","doi":"https://doi.org/10.28938/9781912729098","publicationDate":"2021-05-01","place":"Manchester","contributions":[{"fullName":"Brit Ross Winthereik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Laura Watts","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"James Maguire","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"091abd14-7bc0-4fe7-8194-552edb02b98b","fullTitle":"Inventing the Social","doi":"https://doi.org/10.28938/9780995527768","publicationDate":"2018-07-11","place":"Manchester","contributions":[{"fullName":"Michael Guggenheim","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alex Wilkie","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Noortje Marres","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c38728e0-9739-4ad3-b0a7-6cda9a9da4b9","fullTitle":"Sensing InSecurity: Sensors as transnational security infrastructures","doi":null,"publicationDate":null,"place":"Manchester","contributions":[]}],"__typename":"Imprint"},{"imprintUrl":"https://www.mediastudies.press/","imprintId":"5078b33c-5b3f-48bf-bf37-ced6b02beb7c","imprintName":"mediastudies.press","updatedAt":"2021-06-15T14:40:51.652638+00:00","createdAt":"2021-06-15T14:40:51.652638+00:00","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5","publisher":{"publisherName":"mediastudies.press","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5"},"works":[{"workId":"6763ec18-b4af-4767-976c-5b808a64e641","fullTitle":"Liberty and the News","doi":"https://doi.org/10.32376/3f8575cb.2e69e142","publicationDate":"2020-11-15","place":"Bethlehem, PA","contributions":[{"fullName":"Walter Lippmann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sue Curry Jansen","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"3162a992-05dd-4b74-9fe0-0f16879ce6de","fullTitle":"Our Master’s Voice: Advertising","doi":"https://doi.org/10.21428/3f8575cb.dbba9917","publicationDate":"2020-10-15","place":"Bethlehem, PA","contributions":[{"fullName":"James Rorty","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jefferson Pooley","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"64891e84-6aac-437a-a380-0481312bd2ef","fullTitle":"Social Media & the Self: An Open Reader","doi":"https://doi.org/10.32376/3f8575cb.1fc3f80a","publicationDate":"2021-07-15","place":"Bethlehem, PA","contributions":[{"fullName":"Jefferson Pooley","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://meson.press","imprintId":"0299480e-869b-486c-8a65-7818598c107b","imprintName":"meson press","updatedAt":"2021-03-25T16:36:00.832381+00:00","createdAt":"2021-03-25T16:36:00.832381+00:00","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b","publisher":{"publisherName":"meson press","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b"},"works":[{"workId":"59ecdda1-efd8-45d2-b6a6-11bc8fe480f5","fullTitle":"Earth and Beyond in Tumultuous Times: A Critical Atlas of the Anthropocene","doi":"https://doi.org/10.14619/1891","publicationDate":"2021-03-15","place":"Lüneburg","contributions":[{"fullName":"Petra Löffler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Réka Patrícia Gál","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"36f7480e-ca45-452c-a5c0-ba1dccf135ec","fullTitle":"Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices","doi":"https://doi.org/10.14619/1860","publicationDate":"2021-05-17","place":"Lueneburg","contributions":[{"fullName":"Wanda Strauven","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"38872158-58b9-4ddf-a90e-f6001ac6c62d","fullTitle":"Trick 17: Mediengeschichten zwischen Zauberkunst und Wissenschaft","doi":"https://doi.org/10.14619/017","publicationDate":"2016-07-14","place":"Lüneburg, Germany","contributions":[{"fullName":"Sebastian Vehlken","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":1},{"fullName":"Jan Müggenburg","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Katja Müller-Helle","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":2},{"fullName":"Florian Sprenger","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":4}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/oe-case-files/","imprintId":"39a17f7f-c3f3-4bfe-8c5e-842d53182aad","imprintName":"Œ Case Files","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"a8bf3374-f153-460d-902a-adea7f41d7c7","fullTitle":"Œ Case Files, Vol. 01","doi":"https://doi.org/10.21983/P3.0354.1.00","publicationDate":"2021-05-13","place":"Earth, Milky Way","contributions":[{"fullName":"Simone Ferracina","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/oliphaunt-books/","imprintId":"353047d8-1ea4-4cc5-bd08-e9cedb4a3e8d","imprintName":"Oliphaunt Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"0090dbfb-bc8f-44aa-9803-08b277861b14","fullTitle":"Animal, Vegetable, Mineral: Ethics and Objects","doi":"https://doi.org/10.21983/P3.0006.1.00","publicationDate":"2012-05-07","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"eb8a2862-e812-4730-ab06-8dff1b6208bf","fullTitle":"Burn after Reading: Vol. 1, Miniature Manifestos for a Post/medieval Studies + Vol. 2, The Future We Want: A Collaboration","doi":"https://doi.org/10.21983/P3.0067.1.00","publicationDate":"2014-04-28","place":"Brooklyn, NY","contributions":[{"fullName":"Myra Seaman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"37cb9bb4-0bb3-4bd3-86ea-d8dfb60c9cd8","fullTitle":"Inhuman Nature","doi":"https://doi.org/10.21983/P3.0078.1.00","publicationDate":"2014-09-23","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"},"works":[{"workId":"fdeb2a1b-af39-4165-889d-cc7a5a31d5fa","fullTitle":"Acoustemologies in Contact: Sounding Subjects and Modes of Listening in Early Modernity","doi":"https://doi.org/10.11647/OBP.0226","publicationDate":"2021-01-19","place":"Cambridge, UK","contributions":[{"fullName":"Emily Wilbourne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Suzanne G. Cusick","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"31aea193-58de-43eb-aadb-23300ba5ee40","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0075","publicationDate":"2016-01-25","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fc088d17-bab2-4bfa-90bc-b320760c6c97","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0181","publicationDate":"2019-10-24","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b59def35-5712-44ed-8490-9073ab1c6cdc","fullTitle":"A European Public Investment Outlook","doi":"https://doi.org/10.11647/OBP.0222","publicationDate":"2020-06-12","place":"Cambridge, UK","contributions":[{"fullName":"Floriana Cerniglia","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Francesco Saraceno","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"528e4526-42e4-4e68-a0d5-f74a285c35a6","fullTitle":"A Fleet Street In Every Town: The Provincial Press in England, 1855-1900","doi":"https://doi.org/10.11647/OBP.0152","publicationDate":"2018-12-13","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Hobbs","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"35941026-43eb-496f-b560-2c21a6dbbbfc","fullTitle":"Agency: Moral Identity and Free Will","doi":"https://doi.org/10.11647/OBP.0197","publicationDate":"2020-04-01","place":"Cambridge, UK","contributions":[{"fullName":"David Weissman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3dbfa65a-ed33-46b5-9105-c5694c9c6bab","fullTitle":"A Handbook and Reader of Ottoman Arabic","doi":"https://doi.org/10.11647/OBP.0208","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Esther-Miriam Wagner","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0229f930-1e01-40b8-b4a8-03ab57624ced","fullTitle":"A Lexicon of Medieval Nordic Law","doi":"https://doi.org/10.11647/OBP.0188","publicationDate":"2020-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Christine Peel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Jeffrey Love","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Erik Simensen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Inger Larsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ulrika Djärv","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"defda2f0-1003-419a-8c3c-ac8d0b1abd17","fullTitle":"A Musicology of Performance: Theory and Method Based on Bach's Solos for Violin","doi":"https://doi.org/10.11647/OBP.0064","publicationDate":"2015-08-17","place":"Cambridge, UK","contributions":[{"fullName":"Dorottya Fabian","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"99af261d-8a31-449e-bf26-20e0178b8ed1","fullTitle":"An Anglo-Norman Reader","doi":"https://doi.org/10.11647/OBP.0110","publicationDate":"2018-02-08","place":"Cambridge, UK","contributions":[{"fullName":"Jane Bliss","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0d45084-d852-470d-b9f7-4719304f8a56","fullTitle":"Animals and Medicine: The Contribution of Animal Experiments to the Control of Disease","doi":"https://doi.org/10.11647/OBP.0055","publicationDate":"2015-05-04","place":"Cambridge, UK","contributions":[{"fullName":"Jack Botting","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Regina Botting","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Adrian R. Morrison","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"5a597468-a3eb-4026-b29e-eb93b8a7b0d6","fullTitle":"Annunciations: Sacred Music for the Twenty-First Century","doi":"https://doi.org/10.11647/OBP.0172","publicationDate":"2019-05-01","place":"Cambridge, UK","contributions":[{"fullName":"George Corbett","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"857a5788-a709-4d56-8607-337c1cabd9a2","fullTitle":"ANZUS and the Early Cold War: Strategy and Diplomacy between Australia, New Zealand and the United States, 1945-1956","doi":"https://doi.org/10.11647/OBP.0141","publicationDate":"2018-09-07","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Kelly","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0263f0c-48cd-4923-aef5-1b204636507c","fullTitle":"A People Passing Rude: British Responses to Russian Culture","doi":"https://doi.org/10.11647/OBP.0022","publicationDate":"2012-11-01","place":"Cambridge, UK","contributions":[{"fullName":"Anthony Cross","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"69c69fef-ab46-45ab-96d5-d7c4e5d4bce4","fullTitle":"Arab Media Systems","doi":"https://doi.org/10.11647/OBP.0238","publicationDate":"2021-03-03","place":"Cambridge, UK","contributions":[{"fullName":"Carola Richter","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Claudia Kozman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1e3ef1d6-a460-4b47-8d14-78c3d18e40c1","fullTitle":"A Time Travel Dialogue","doi":"https://doi.org/10.11647/OBP.0043","publicationDate":"2014-08-01","place":"Cambridge, UK","contributions":[{"fullName":"John W. Carroll","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"664931f6-27ca-4409-bb47-5642ca60117e","fullTitle":"A Victorian Curate: A Study of the Life and Career of the Rev. Dr John Hunt ","doi":"https://doi.org/10.11647/OBP.0248","publicationDate":"2021-05-03","place":"Cambridge, UK","contributions":[{"fullName":"David Yeandle","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"721fc7c9-7531-40cd-9e59-ab1bef5fc261","fullTitle":"Basic Knowledge and Conditions on Knowledge","doi":"https://doi.org/10.11647/OBP.0104","publicationDate":"2017-10-30","place":"Cambridge, UK","contributions":[{"fullName":"Mark McBride","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"39aafd68-dc83-4951-badf-d1f146a38fd4","fullTitle":"B C, Before Computers: On Information Technology from Writing to the Age of Digital Data","doi":"https://doi.org/10.11647/OBP.0225","publicationDate":"2020-10-22","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Robertson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a373ccbd-0665-4faa-bc24-15542e5cb0cf","fullTitle":"Behaviour, Development and Evolution","doi":"https://doi.org/10.11647/OBP.0097","publicationDate":"2017-02-20","place":"Cambridge, UK","contributions":[{"fullName":"Patrick Bateson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"e76e054c-617d-4004-b68d-54739205df8d","fullTitle":"Beyond Holy Russia: The Life and Times of Stephen Graham","doi":"https://doi.org/10.11647/OBP.0040","publicationDate":"2014-02-19","place":"Cambridge, UK","contributions":[{"fullName":"Michael Hughes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fe599a6c-ecd8-4ed3-a39e-5778cb9b77da","fullTitle":"Beyond Price: Essays on Birth and Death","doi":"https://doi.org/10.11647/OBP.0061","publicationDate":"2015-10-08","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c7ded4f3-4850-44eb-bd5b-e196a2254d3f","fullTitle":"Bourdieu and Literature","doi":"https://doi.org/10.11647/OBP.0027","publicationDate":"2011-11-30","place":"Cambridge, UK","contributions":[{"fullName":"John R.W. Speller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"456b46b9-bbec-4832-95ca-b23dcb975df1","fullTitle":"Brownshirt Princess: A Study of the 'Nazi Conscience'","doi":"https://doi.org/10.11647/OBP.0003","publicationDate":"2009-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Lionel Gossman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1","fullTitle":"Chronicles from Kashmir: An Annotated, Multimedia Script","doi":"https://doi.org/10.11647/OBP.0223","publicationDate":"2020-09-14","place":"Cambridge, UK","contributions":[{"fullName":"Nandita Dinesh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c5fe7f09-7dfb-4637-82c8-653a6cb683e7","fullTitle":"Cicero, Against Verres, 2.1.53–86: Latin Text with Introduction, Study Questions, Commentary and English Translation","doi":"https://doi.org/10.11647/OBP.0016","publicationDate":"2011-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a03ba4d1-1576-41d0-9e8b-d74eccb682e2","fullTitle":"Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation","doi":"https://doi.org/10.11647/OBP.0045","publicationDate":"2014-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Louise Hodgson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7e753cbc-c74b-4214-a565-2300f544be77","fullTitle":"Cicero, Philippic 2, 44–50, 78–92, 100–119: Latin Text, Study Aids with Vocabulary, and Commentary","doi":"https://doi.org/10.11647/OBP.0156","publicationDate":"2018-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fd4d3c2a-355f-4bc0-83cb-1cd6764976e7","fullTitle":"Classical Music: Contemporary Perspectives and Challenges","doi":"https://doi.org/10.11647/OBP.0242","publicationDate":"2021-03-30","place":"Cambridge, UK","contributions":[{"fullName":"Beckerman Michael","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Boghossian Paul","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"9ea10b68-b23c-4562-b0ca-03ba548889a3","fullTitle":"Coleridge's Laws: A Study of Coleridge in Malta","doi":"https://doi.org/10.11647/OBP.0005","publicationDate":"2010-01-01","place":"Cambridge, UK","contributions":[{"fullName":"Barry Hough","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Howard Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Lydia Davis","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Micheal John Kooy","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"98776400-e985-488d-a3f1-9d88879db3cf","fullTitle":"Complexity, Security and Civil Society in East Asia: Foreign Policies and the Korean Peninsula","doi":"https://doi.org/10.11647/OBP.0059","publicationDate":"2015-06-22","place":"Cambridge, UK","contributions":[{"fullName":"Kiho Yi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Peter Hayes","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"296c6880-6212-48d2-b327-2c13b6e28d5f","fullTitle":"Conservation Biology in Sub-Saharan Africa","doi":"https://doi.org/10.11647/OBP.0177","publicationDate":"2019-09-08","place":"Cambridge, UK","contributions":[{"fullName":"John W. Wilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Richard B. Primack","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"e5ade02a-2f32-495a-b879-98b54df04c0a","fullTitle":"Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary","doi":"https://doi.org/10.11647/OBP.0068","publicationDate":"2015-10-05","place":"Cambridge, UK","contributions":[{"fullName":"Bret Mulligan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c86acc9-89a0-4b17-bcdd-520d33fc4f54","fullTitle":"Creative Multilingualism: A Manifesto","doi":"https://doi.org/10.11647/OBP.0206","publicationDate":"2020-05-20","place":"Cambridge, UK","contributions":[{"fullName":"Wen-chin Ouyang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Rajinder Dudrah","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Andrew Gosler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Martin Maiden","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Suzanne Graham","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Katrin Kohl","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"10ddfb3d-3434-46f8-a3bb-14dfc0ce9591","fullTitle":"Cultural Heritage Ethics: Between Theory and Practice","doi":"https://doi.org/10.11647/OBP.0047","publicationDate":"2014-10-13","place":"Cambridge, UK","contributions":[{"fullName":"Sandis Constantine","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2b031e1a-678b-4dcb-becb-cbd0f0ce9182","fullTitle":"Deliberation, Representation, Equity: Research Approaches, Tools and Algorithms for Participatory Processes","doi":"https://doi.org/10.11647/OBP.0108","publicationDate":"2017-01-23","place":"Cambridge, UK","contributions":[{"fullName":"Mats Danielson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Love Ekenberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Karin Hansson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Göran Cars","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"bc253bff-cf00-433d-89a2-031500b888ff","fullTitle":"Delivering on the Promise of Democracy: Visual Case Studies in Educational Equity and Transformation","doi":"https://doi.org/10.11647/OBP.0157","publicationDate":"2019-01-16","place":"Cambridge, UK","contributions":[{"fullName":"Sukhwant Jhaj","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"517963d1-a56a-4250-8a07-56743ba60d95","fullTitle":"Democracy and Power: The Delhi Lectures","doi":"https://doi.org/10.11647/OBP.0050","publicationDate":"2014-12-07","place":"Cambridge, UK","contributions":[{"fullName":"Noam Chomsky","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jean Drèze","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"60450f84-3e18-4beb-bafe-87c78b5a0159","fullTitle":"Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition","doi":"https://doi.org/10.11647/OBP.0098","publicationDate":"2016-06-20","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]},{"workId":"b3989be1-9115-4635-b766-92f6ebfabef1","fullTitle":"Denis Diderot's 'Rameau's Nephew': A Multi-media Edition","doi":"https://doi.org/10.11647/OBP.0044","publicationDate":"2014-08-24","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]},{"workId":"594ddcb6-2363-47c8-858e-76af2283e486","fullTitle":"Dickens’s Working Notes for 'Dombey and Son'","doi":"https://doi.org/10.11647/OBP.0092","publicationDate":"2017-09-04","place":"Cambridge, UK","contributions":[{"fullName":"Tony Laing","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d3adf77-c72b-4b69-bf5a-a042a38a837a","fullTitle":"Dictionary of the British English Spelling System","doi":"https://doi.org/10.11647/OBP.0053","publicationDate":"2015-03-30","place":"Cambridge, UK","contributions":[{"fullName":"Greg Brooks","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"364c223d-9c90-4ceb-90e2-51be7d84e923","fullTitle":"Die Europaidee im Zeitalter der Aufklärung","doi":"https://doi.org/10.11647/OBP.0127","publicationDate":"2017-08-21","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d4812e4-c491-4465-8e92-64e4f13662f1","fullTitle":"Digital Humanities Pedagogy: Practices, Principles and Politics","doi":"https://doi.org/10.11647/OBP.0024","publicationDate":"2012-12-20","place":"Cambridge, UK","contributions":[{"fullName":"Brett D. Hirsch","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"43d96298-a683-4098-9492-bba1466cb8e0","fullTitle":"Digital Scholarly Editing: Theories and Practices","doi":"https://doi.org/10.11647/OBP.0095","publicationDate":"2016-08-15","place":"Cambridge, UK","contributions":[{"fullName":"Elena Pierazzo","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Matthew James Driscoll","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"912c2731-3ca1-4ad9-b601-5d968da6b030","fullTitle":"Digital Technology and the Practices of Humanities Research","doi":"https://doi.org/10.11647/OBP.0192","publicationDate":"2020-01-30","place":"Cambridge, UK","contributions":[{"fullName":"Jennifer Edmond","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"78bbcc00-a336-4eb6-b4b5-0c57beec0295","fullTitle":"Discourses We Live By: Narratives of Educational and Social Endeavour","doi":"https://doi.org/10.11647/OBP.0203","publicationDate":"2020-07-03","place":"Cambridge, UK","contributions":[{"fullName":"Hazel R. Wright","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marianne Høyen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1312613f-e01a-499a-b0d0-7289d5b9013d","fullTitle":"Diversity and Rabbinization: Jewish Texts and Societies between 400 and 1000 CE","doi":"https://doi.org/10.11647/OBP.0219","publicationDate":"2021-04-30","place":"Cambridge, UK","contributions":[{"fullName":"Gavin McDowell","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Ron Naiweld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel Stökl Ben Ezra","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"2d74b1a9-c3b0-4278-8cad-856fadc6a19d","fullTitle":"Don Carlos Infante of Spain: A Dramatic Poem","doi":"https://doi.org/10.11647/OBP.0134","publicationDate":"2018-06-04","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"b190b3c5-88c0-4e4a-939a-26995b7ff95c","fullTitle":"Earth 2020: An Insider’s Guide to a Rapidly Changing Planet","doi":"https://doi.org/10.11647/OBP.0193","publicationDate":"2020-04-22","place":"Cambridge, UK","contributions":[{"fullName":"Philippe D. Tortell","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a5e6aa48-02ba-48e4-887f-1c100a532de8","fullTitle":"Economic Fables","doi":"https://doi.org/10.11647/OBP.0020","publicationDate":"2012-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Ariel Rubinstein","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2b63a26d-0db1-4200-983f-8b69d9821d8b","fullTitle":"Engaging Researchers with Data Management: The Cookbook","doi":"https://doi.org/10.11647/OBP.0185","publicationDate":"2019-10-09","place":"Cambridge, UK","contributions":[{"fullName":"Yan Wang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"James Savage","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Connie Clare","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marta Teperek","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Maria Cruz","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Elli Papadopoulou","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"af162e8a-23ab-49e6-896d-e53b9d6c0039","fullTitle":"Essays in Conveyancing and Property Law in Honour of Professor Robert Rennie","doi":"https://doi.org/10.11647/OBP.0056","publicationDate":"2015-05-11","place":"Cambridge, UK","contributions":[{"fullName":"Frankie McCarthy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Stephen Bogle","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"James Chalmers","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"98d053d6-dcc2-409a-8841-9f19920b49ee","fullTitle":"Essays in Honour of Eamonn Cantwell: Yeats Annual No. 20","doi":"https://doi.org/10.11647/OBP.0081","publicationDate":"2016-12-05","place":"Cambridge, UK","contributions":[{"fullName":"Warwick Gould","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"24689aa7-af74-4238-ad75-a9469f094068","fullTitle":"Essays on Paula Rego: Smile When You Think about Hell","doi":"https://doi.org/10.11647/OBP.0178","publicationDate":"2019-09-24","place":"Cambridge, UK","contributions":[{"fullName":"Maria Manuel Lisboa","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f76ab190-35f4-4136-86dd-d7fa02ccaebb","fullTitle":"Ethics for A-Level","doi":"https://doi.org/10.11647/OBP.0125","publicationDate":"2017-07-31","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Fisher","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mark Dimmock","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d90e1915-1d2a-40e6-a94c-79f671031224","fullTitle":"Europa im Geisterkrieg. Studien zu Nietzsche","doi":"https://doi.org/10.11647/OBP.0133","publicationDate":"2018-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Werner Stegmaier","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andrea C. Bertino","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"a0a8d5f1-12d0-4d51-973d-ed1dfa73f01f","fullTitle":"Exploring the Interior: Essays on Literary and Cultural History","doi":"https://doi.org/10.11647/OBP.0126","publicationDate":"2018-05-24","place":"Cambridge, UK","contributions":[{"fullName":"Karl S. Guthke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3795e166-413c-4568-8c19-1117689ef14b","fullTitle":"Feeding the City: Work and Food Culture of the Mumbai Dabbawalas","doi":"https://doi.org/10.11647/OBP.0031","publicationDate":"2013-07-15","place":"Cambridge, UK","contributions":[{"fullName":"Sara Roncaglia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Angela Arnone","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Pier Giorgio Solinas","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"5da7830b-6d55-4eb4-899e-cb2a13b30111","fullTitle":"Fiesco's Conspiracy at Genoa","doi":"https://doi.org/10.11647/OBP.0058","publicationDate":"2015-05-27","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"John Guthrie","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"83b7409e-f076-4598-965e-9e15615be247","fullTitle":"Forests and Food: Addressing Hunger and Nutrition Across Sustainable Landscapes","doi":"https://doi.org/10.11647/OBP.0085","publicationDate":"2015-11-15","place":"Cambridge, UK","contributions":[{"fullName":"Christoph Wildburger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bhaskar Vira","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Stephanie Mansourian","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"1654967f-82f1-4ed0-ae81-7ebbfb9c183d","fullTitle":"Foundations for Moral Relativism","doi":"https://doi.org/10.11647/OBP.0029","publicationDate":"2013-04-17","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"00766beb-0597-48a8-ba70-dd2b8382ec37","fullTitle":"Foundations for Moral Relativism: Second Expanded Edition","doi":"https://doi.org/10.11647/OBP.0086","publicationDate":"2015-11-23","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3083819d-1084-418a-85d4-4f71c2fea139","fullTitle":"From Darkness to Light: Writers in Museums 1798-1898","doi":"https://doi.org/10.11647/OBP.0151","publicationDate":"2019-03-12","place":"Cambridge, UK","contributions":[{"fullName":"Rosella Mamoli Zorzi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Katherine Manthorne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5bf6450f-99a7-4375-ad94-d5bde1b0282c","fullTitle":"From Dust to Digital: Ten Years of the Endangered Archives Programme","doi":"https://doi.org/10.11647/OBP.0052","publicationDate":"2015-02-16","place":"Cambridge, UK","contributions":[{"fullName":"Maja Kominko","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d16896b7-691e-4620-9adb-1d7a42c69bde","fullTitle":"From Goethe to Gundolf: Essays on German Literature and Culture","doi":"https://doi.org/10.11647/OBP.0258","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Roger Paulin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3a167e24-36b5-4d0e-b55f-af6be9a7c827","fullTitle":"Frontier Encounters: Knowledge and Practice at the Russian, Chinese and Mongolian Border","doi":"https://doi.org/10.11647/OBP.0026","publicationDate":"2012-08-01","place":"Cambridge, UK","contributions":[{"fullName":"Grégory Delaplace","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Caroline Humphrey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Franck Billé","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1471f4c3-a88c-4301-b98a-7193be6dde4b","fullTitle":"Gallucci's Commentary on Dürer’s 'Four Books on Human Proportion': Renaissance Proportion Theory","doi":"https://doi.org/10.11647/OBP.0198","publicationDate":"2020-03-25","place":"Cambridge, UK","contributions":[{"fullName":"James Hutson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"101eb7c2-f15f-41f9-b53a-dfccd4b28301","fullTitle":"Global Warming in Local Discourses: How Communities around the World Make Sense of Climate Change","doi":"https://doi.org/10.11647/OBP.0212","publicationDate":"2020-10-14","place":"Cambridge, UK","contributions":[{"fullName":"Michael Brüggemann","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Simone Rödder","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"32e99c61-2352-4a88-bb9a-bd81f113ba1e","fullTitle":"God's Babies: Natalism and Bible Interpretation in Modern America","doi":"https://doi.org/10.11647/OBP.0048","publicationDate":"2014-12-17","place":"Cambridge, UK","contributions":[{"fullName":"John McKeown","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ab3a9d7f-c9b9-42bf-9942-45f68b40bcd6","fullTitle":"Hanging on to the Edges: Essays on Science, Society and the Academic Life","doi":"https://doi.org/10.11647/OBP.0155","publicationDate":"2018-10-15","place":"Cambridge, UK","contributions":[{"fullName":"Daniel Nettle","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9d5ac1c6-a763-49b4-98b2-355d888169be","fullTitle":"Henry James's Europe: Heritage and Transfer","doi":"https://doi.org/10.11647/OBP.0013","publicationDate":"2011-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Adrian Harding","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Annick Duperray","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dennis Tredy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b7790cae-1901-446e-b529-b5fe393d8061","fullTitle":"History of International Relations: A Non-European Perspective","doi":"https://doi.org/10.11647/OBP.0074","publicationDate":"2019-07-31","place":"Cambridge, UK","contributions":[{"fullName":"Erik Ringmar","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7b9b68c6-8bb6-42c5-8b19-bf5e56b7293e","fullTitle":"How to Read a Folktale: The 'Ibonia' Epic from Madagascar","doi":"https://doi.org/10.11647/OBP.0034","publicationDate":"2013-10-08","place":"Cambridge, UK","contributions":[{"fullName":"Lee Haring","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"23651a20-a26e-4253-b0a9-c8b5bf1409c7","fullTitle":"Human and Machine Consciousness","doi":"https://doi.org/10.11647/OBP.0107","publicationDate":"2018-03-07","place":"Cambridge, UK","contributions":[{"fullName":"David Gamez","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"27def25d-48ad-470d-9fbe-1ddc8376e1cb","fullTitle":"Human Cultures through the Scientific Lens: Essays in Evolutionary Cognitive Anthropology","doi":"https://doi.org/10.11647/OBP.0257","publicationDate":"2021-07-09","place":"Cambridge, UK","contributions":[{"fullName":"Pascal Boyer","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"859a1313-7b02-4c66-8010-dbe533c4412a","fullTitle":"Hyperion or the Hermit in Greece","doi":"https://doi.org/10.11647/OBP.0160","publicationDate":"2019-02-25","place":"Cambridge, UK","contributions":[{"fullName":"Howard Gaskill","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1f591391-7497-4447-8c06-d25006a1b922","fullTitle":"Image, Knife, and Gluepot: Early Assemblage in Manuscript and Print","doi":"https://doi.org/10.11647/OBP.0145","publicationDate":"2019-07-16","place":"Cambridge, UK","contributions":[{"fullName":"Kathryn M. Rudy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"50516c2a-154e-4758-9b94-586987af2b7f","fullTitle":"Information and Empire: Mechanisms of Communication in Russia, 1600-1854","doi":"https://doi.org/10.11647/OBP.0122","publicationDate":"2017-11-27","place":"Cambridge, UK","contributions":[{"fullName":"Katherine Bowers","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Simon Franklin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1549f31d-4783-4a63-a050-90ffafd77328","fullTitle":"Infrastructure Investment in Indonesia: A Focus on Ports","doi":"https://doi.org/10.11647/OBP.0189","publicationDate":"2019-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Colin Duffield","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Felix Kin Peng Hui","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Sally Wilson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"1692a92d-f86a-4155-9e6c-16f38586b7fc","fullTitle":"Intellectual Property and Public Health in the Developing World","doi":"https://doi.org/10.11647/OBP.0093","publicationDate":"2016-05-30","place":"Cambridge, UK","contributions":[{"fullName":"Monirul Azam","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d6850e99-33ce-4cae-ac7c-bd82cf23432b","fullTitle":"In the Lands of the Romanovs: An Annotated Bibliography of First-hand English-language Accounts of the Russian Empire (1613-1917)","doi":"https://doi.org/10.11647/OBP.0042","publicationDate":"2014-04-27","place":"Cambridge, UK","contributions":[{"fullName":"Anthony Cross","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4455a769-d374-4eed-8e6a-84c220757c0d","fullTitle":"Introducing Vigilant Audiences","doi":"https://doi.org/10.11647/OBP.0200","publicationDate":"2020-10-14","place":"Cambridge, UK","contributions":[{"fullName":"Rashid Gabdulhakov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel Trottier","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Qian Huang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"e414ca1b-a7f2-48c7-9adb-549a04711241","fullTitle":"Inventory Analytics","doi":"https://doi.org/10.11647/OBP.0252","publicationDate":"2021-05-24","place":"Cambridge, UK","contributions":[{"fullName":"Roberto Rossi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ad55c2c5-9769-4648-9c42-dc4cef1f1c99","fullTitle":"Is Behavioral Economics Doomed? The Ordinary versus the Extraordinary","doi":"https://doi.org/10.11647/OBP.0021","publicationDate":"2012-09-17","place":"Cambridge, UK","contributions":[{"fullName":"David K. Levine","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2ceb72f2-ddde-45a7-84a9-27523849f8f5","fullTitle":"Jane Austen: Reflections of a Reader","doi":"https://doi.org/10.11647/OBP.0216","publicationDate":"2021-02-03","place":"Cambridge, UK","contributions":[{"fullName":"Nora Bartlett","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jane Stabler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5b542db8-c128-48ff-a48c-003c95eaca25","fullTitle":"Jewish-Muslim Intellectual History Entangled: Textual Materials from the Firkovitch Collection, Saint Petersburg","doi":"https://doi.org/10.11647/OBP.0214","publicationDate":"2020-08-03","place":"Cambridge, UK","contributions":[{"fullName":"Jan Thiele","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Wilferd Madelung","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Omar Hamdan","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Adang Camilla","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sabine Schmidtke","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Bruno Chiesa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"df7eb598-914a-49eb-9cbd-9766bd06be84","fullTitle":"Just Managing? What it Means for the Families of Austerity Britain","doi":"https://doi.org/10.11647/OBP.0112","publicationDate":"2017-05-29","place":"Cambridge, UK","contributions":[{"fullName":"Paul Kyprianou","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mark O'Brien","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c5e415c4-1ed1-4c58-abae-b1476689a867","fullTitle":"Knowledge and the Norm of Assertion: An Essay in Philosophical Science","doi":"https://doi.org/10.11647/OBP.0083","publicationDate":"2016-02-26","place":"Cambridge, UK","contributions":[{"fullName":"John Turri","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9fc774fa-3a18-42d8-89e3-b5a23d822dd6","fullTitle":"Labor and Value: Rethinking Marx’s Theory of Exploitation","doi":"https://doi.org/10.11647/OBP.0182","publicationDate":"2019-10-02","place":"Cambridge, UK","contributions":[{"fullName":"Ernesto Screpanti","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"29e28ee7-c52d-43f3-95da-f99f33f0e737","fullTitle":"Les Bienveillantes de Jonathan Littell: Études réunies par Murielle Lucie Clément","doi":"https://doi.org/10.11647/OBP.0006","publicationDate":"2010-04-01","place":"Cambridge, UK","contributions":[{"fullName":"Murielle Lucie Clément","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d9e671dd-ab2a-4fd0-ada3-4925449a63a8","fullTitle":"Letters of Blood and Other Works in English","doi":"https://doi.org/10.11647/OBP.0017","publicationDate":"2011-11-30","place":"Cambridge, UK","contributions":[{"fullName":"Göran Printz-Påhlson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Robert Archambeau","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Elinor Shaffer","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":4},{"fullName":"Lars-Håkan Svensson","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"c699f257-f3e4-4c98-9a3f-741c6a40b62a","fullTitle":"L’idée de l’Europe: au Siècle des Lumières","doi":"https://doi.org/10.11647/OBP.0116","publicationDate":"2017-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"a795aafb-d189-4d15-8e64-b9a3fbfa8e09","fullTitle":"Life Histories of Etnos Theory in Russia and Beyond","doi":"https://doi.org/10.11647/OBP.0150","publicationDate":"2019-02-06","place":"Cambridge, UK","contributions":[{"fullName":"Dmitry V Arzyutov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"David G. Anderson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sergei S. Alymov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"5c55effb-2a3e-4e0d-a46d-edad7830fd8e","fullTitle":"Lifestyle in Siberia and the Russian North","doi":"https://doi.org/10.11647/OBP.0171","publicationDate":"2019-11-22","place":"Cambridge, UK","contributions":[{"fullName":"Joachim Otto Habeck","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6090bfc8-3143-4599-b0dd-17705f754e8c","fullTitle":"Like Nobody's Business: An Insider's Guide to How US University Finances Really Work","doi":"https://doi.org/10.11647/OBP.0240","publicationDate":"2021-02-23","place":"Cambridge, UK","contributions":[{"fullName":"Andrew C. Comrie","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"25a2f70a-832d-4c8d-b28f-75f838b6e171","fullTitle":"Liminal Spaces: Migration and Women of the Guyanese Diaspora","doi":"https://doi.org/10.11647/OBP.0218","publicationDate":"2020-09-29","place":"Cambridge, UK","contributions":[{"fullName":"Grace Aneiza Ali","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9845c8a9-b283-4cb8-8961-d41e5fe795f1","fullTitle":"Literature Against Criticism: University English and Contemporary Fiction in Conflict","doi":"https://doi.org/10.11647/OBP.0102","publicationDate":"2016-10-17","place":"Cambridge, UK","contributions":[{"fullName":"Martin Paul Eve","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f957ab3d-c925-4bf2-82fa-9809007753e7","fullTitle":"Living Earth Community: Multiple Ways of Being and Knowing","doi":"https://doi.org/10.11647/OBP.0186","publicationDate":"2020-05-07","place":"Cambridge, UK","contributions":[{"fullName":"John Grim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Mary Evelyn Tucker","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Sam Mickey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"545f9f42-87c0-415e-9086-eee27925c85b","fullTitle":"Long Narrative Songs from the Mongghul of Northeast Tibet: Texts in Mongghul, Chinese, and English","doi":"https://doi.org/10.11647/OBP.0124","publicationDate":"2017-10-30","place":"Cambridge, UK","contributions":[{"fullName":"Gerald Roche","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Li Dechun","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/peanut-books/","imprintId":"5cc7d3db-f300-4813-9c68-3ccc18a6277b","imprintName":"Peanut Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"14a2356a-4767-4136-b44a-684a28dc87a6","fullTitle":"In a Trance: On Paleo Art","doi":"https://doi.org/10.21983/P3.0081.1.00","publicationDate":"2014-11-13","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Skoblow","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"200b11a8-57d6-4f81-b089-ddd4ee7fe2f2","fullTitle":"The Apartment of Tragic Appliances: Poems","doi":"https://doi.org/10.21983/P3.0030.1.00","publicationDate":"2013-05-26","place":"Brooklyn, NY","contributions":[{"fullName":"Michael D. Snediker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"49ebcb4a-928f-4d83-9596-b296dfce0b20","fullTitle":"The Petroleum Manga: A Project by Marina Zurkow","doi":"https://doi.org/10.21983/P3.0062.1.00","publicationDate":"2014-02-25","place":"Brooklyn, NY","contributions":[{"fullName":"Marina Zurkow","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2a360648-3157-4a1b-9ba7-a61895a8a10c","fullTitle":"Where the Tiny Things Are: Feathered Essays","doi":"https://doi.org/10.21983/P3.0181.1.00","publicationDate":"2017-09-26","place":"Earth, Milky Way","contributions":[{"fullName":"Nicole Walker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/","imprintId":"7522e351-8a91-40fa-bf45-02cb38368b0b","imprintName":"punctum books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"5402ea62-7a1b-48b4-b5fb-7b114c04bc27","fullTitle":"A Boy Asleep under the Sun: Versions of Sandro Penna","doi":"https://doi.org/10.21983/P3.0080.1.00","publicationDate":"2014-11-11","place":"Brooklyn, NY","contributions":[{"fullName":"Sandro Penna","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Peter Valente","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Peter Valente","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"8a27431b-b1f9-4fed-a8e0-0a0aadc9d98c","fullTitle":"A Buddha Land in This World: Philosophy, Utopia, and Radical Buddhism","doi":"https://doi.org/10.53288/0373.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Lajos Brons","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"eeb920c0-6f2e-462c-a315-3687b5ca8da3","fullTitle":"Action [poems]","doi":"https://doi.org/10.21983/P3.0083.1.00","publicationDate":"2014-12-10","place":"Brooklyn, NY","contributions":[{"fullName":"Anthony Opal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"20dab41d-2267-4a68-befa-d787b7c98599","fullTitle":"After the \"Speculative Turn\": Realism, Philosophy, and Feminism","doi":"https://doi.org/10.21983/P3.0152.1.00","publicationDate":"2016-10-26","place":"Earth, Milky Way","contributions":[{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katerina Kolozova","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13a03c11-0f22-4d40-881d-b935452d4bf3","fullTitle":"Air Supplied","doi":"https://doi.org/10.21983/P3.0201.1.00","publicationDate":"2018-05-23","place":"Earth, Milky Way","contributions":[{"fullName":"David Cross","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5147a952-3d44-4beb-8d49-b41c91bce733","fullTitle":"Alternative Historiographies of the Digital Humanities","doi":"https://doi.org/10.53288/0274.1.00","publicationDate":"2021-06-24","place":"Earth, Milky Way","contributions":[{"fullName":"Adeline Koh","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dorothy Kim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f712541c-07b4-477c-8b8c-8c1a307810d0","fullTitle":"And Another Thing: Nonanthropocentrism and Art","doi":"https://doi.org/10.21983/P3.0144.1.00","publicationDate":"2016-06-18","place":"Earth, Milky Way","contributions":[{"fullName":"Katherine Behar","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Emmy Mikelson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"27e17948-02c4-4ba3-8244-5c229cc8e9b8","fullTitle":"Anglo-Saxon(ist) Pasts, postSaxon Futures","doi":"https://doi.org/10.21983/P3.0262.1.00","publicationDate":"2019-12-30","place":"Earth, Milky Way","contributions":[{"fullName":"Donna-Beth Ellard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f3c9e9d8-9a38-4558-be2e-cab9a70d62f0","fullTitle":"Annotations to Geoffrey Hill's Speech! Speech!","doi":"https://doi.org/10.21983/P3.0004.1.00","publicationDate":"2012-01-26","place":"Brooklyn, NY","contributions":[{"fullName":"Ann Hassan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"baf524c6-0a2c-40f2-90a7-e19c6e1b6b97","fullTitle":"Anthropocene Unseen: A Lexicon","doi":"https://doi.org/10.21983/P3.0265.1.00","publicationDate":"2020-02-07","place":"Earth, Milky Way","contributions":[{"fullName":"Cymene Howe","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anand Pandian","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f6afff19-25ae-41f8-8a7a-6c1acffafc39","fullTitle":"Antiracism Inc.: Why the Way We Talk about Racial Justice Matters","doi":"https://doi.org/10.21983/P3.0250.1.00","publicationDate":"2019-04-25","place":"Earth, Milky Way","contributions":[{"fullName":"Paula Ioanide","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alison Reed","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Felice Blake","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"88c47bd3-f8c9-4157-9d1a-770d9be8c173","fullTitle":"A Nuclear Refrain: Emotion, Empire, and the Democratic Potential of Protest","doi":"https://doi.org/10.21983/P3.0271.1.00","publicationDate":"2019-12-19","place":"Earth, Milky Way","contributions":[{"fullName":"Kye Askins","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Phil Johnstone","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kelvin Mason","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"41508a3c-614b-473e-aa74-edcb6b09dc9d","fullTitle":"Ardea: A Philosophical Novella","doi":"https://doi.org/10.21983/P3.0147.1.00","publicationDate":"2016-07-09","place":"Earth, Milky Way","contributions":[{"fullName":"Freya Mathews","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ae9f8357-4b39-4809-a8e9-766e200fb937","fullTitle":"A Rushed Quality","doi":"https://doi.org/10.21983/P3.0103.1.00","publicationDate":"2015-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Odell","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3f78b298-8826-4162-886e-af21a77f2957","fullTitle":"Athens and the War on Public Space: Tracing a City in Crisis","doi":"https://doi.org/10.21983/P3.0199.1.00","publicationDate":"2018-04-20","place":"Earth, Milky Way","contributions":[{"fullName":"Christos Filippidis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Klara Jaya Brekke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Antonis Vradis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"3da27fb9-7a15-446e-ae0f-258c7dd4fd94","fullTitle":"Barton Myers: Works of Architecture and Urbanism","doi":"https://doi.org/10.21983/P3.0249.1.00","publicationDate":"2019-07-05","place":"Earth, Milky Way","contributions":[{"fullName":"Kris Miller-Fisher","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jocelyn Gibbs","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f4d42680-8b02-4e3a-9ec8-44aee852b29f","fullTitle":"Bathroom Songs: Eve Kosofsky Sedgwick as a Poet","doi":"https://doi.org/10.21983/P3.0189.1.00","publicationDate":"2017-11-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jason Edwards","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"637566b3-dca3-4a8b-b5bd-01fcbb77ca09","fullTitle":"Beowulf: A Translation","doi":"https://doi.org/10.21983/P3.0009.1.00","publicationDate":"2012-08-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Hadbawnik","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Thomas Meyer","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel C. Remein","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"David Hadbawnik","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"9bae1a52-f764-417d-9d45-4df12f71cf07","fullTitle":"Beowulf by All","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Elaine Treharne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jean Abbott","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mateusz Fafinski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"a2ce9f9c-f594-4165-83be-e3751d4d17fe","fullTitle":"Beta Exercise: The Theory and Practice of Osamu Kanemura","doi":"https://doi.org/10.21983/P3.0241.1.00","publicationDate":"2019-01-23","place":"Earth, Milky Way","contributions":[{"fullName":"Osamu Kanemura","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Marco Mazzi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Nicholas Marshall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Michiyo Miyake","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"735d8962-5ec7-41ce-a73a-a43c35cc354f","fullTitle":"Between Species/Between Spaces: Art and Science on the Outer Cape","doi":"https://doi.org/10.21983/P3.0325.1.00","publicationDate":"2020-08-13","place":"Earth, Milky Way","contributions":[{"fullName":"Dylan Gauthier","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kendra Sullivan","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a871cb31-e158-401d-a639-3767131c0f34","fullTitle":"Bigger Than You: Big Data and Obesity","doi":"https://doi.org/10.21983/P3.0135.1.00","publicationDate":"2016-03-03","place":"Earth, Milky Way","contributions":[{"fullName":"Katherine Behar","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"940d0880-83b5-499d-9f39-1bf30ccfc4d0","fullTitle":"Book of Anonymity","doi":"https://doi.org/10.21983/P3.0315.1.00","publicationDate":"2021-03-04","place":"Earth, Milky Way","contributions":[{"fullName":"Anon Collective","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"006571ae-ac0e-4cb0-8a3f-71280aa7f23b","fullTitle":"Broken Records","doi":"https://doi.org/10.21983/P3.0137.1.00","publicationDate":"2016-03-21","place":"Earth, Milky Way","contributions":[{"fullName":"Snežana Žabić","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"47c71c05-a4f1-48da-b8d5-9e5ba139a8ea","fullTitle":"Building Black: Towards Antiracist Architecture","doi":"https://doi.org/10.21983/P3.0372.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Elliot C. Mason","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"dd9008ae-0172-4e07-b3cf-50c35c51b606","fullTitle":"Bullied: The Story of an Abuse","doi":"https://doi.org/10.21983/P3.0356.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"46344fe3-1d72-4ddd-a57e-1d3f4377d2a2","fullTitle":"Centaurs, Rioting in Thessaly: Memory and the Classical World","doi":"https://doi.org/10.21983/P3.0192.1.00","publicationDate":"2018-01-09","place":"Earth, Milky Way","contributions":[{"fullName":"Martyn Hudson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7f1d3e2e-c708-4f59-81cf-104c1ca528d0","fullTitle":"Chaste Cinematics","doi":"https://doi.org/10.21983/P3.0117.1.00","publicationDate":"2015-10-31","place":"Brooklyn, NY","contributions":[{"fullName":"Victor J. Vitanza","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b2d1b2e3-226e-43c2-a898-fbad7b410e3f","fullTitle":"Christina McPhee: A Commonplace Book","doi":"https://doi.org/10.21983/P3.0186.1.00","publicationDate":"2017-10-17","place":"Earth, Milky Way","contributions":[{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"45aa16fa-5fd5-4449-a3bd-52d734fcb0a9","fullTitle":"Cinema's Doppelgängers\n","doi":"https://doi.org/10.53288/0320.1.00","publicationDate":"2021-06-17","place":"Earth, Milky Way","contributions":[{"fullName":"Doug Dibbern","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"84447325-88e2-4658-8597-3f2329451156","fullTitle":"Clinical Encounters in Sexuality: Psychoanalytic Practice and Queer Theory","doi":"https://doi.org/10.21983/P3.0167.1.00","publicationDate":"2017-03-07","place":"Earth, Milky Way","contributions":[{"fullName":"Eve Watson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Noreen Giffney","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d0430e3-3640-4d87-8f02-cbb45f6ae83b","fullTitle":"Comic Providence","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Janet Thormann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0ff62120-4478-46dc-8d01-1d7e1dc5b7a6","fullTitle":"Commonist Tendencies: Mutual Aid beyond Communism","doi":"https://doi.org/10.21983/P3.0040.1.00","publicationDate":"2013-07-23","place":"Brooklyn, NY","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea","doi":"https://doi.org/10.21983/P3.0269.1.00","publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"93330f65-a84f-4c5c-aa44-f710c714eca2","fullTitle":"Continent. Year 1: A Selection of Issues 1.1–1.4","doi":"https://doi.org/10.21983/P3.0016.1.00","publicationDate":"2012-12-12","place":"Brooklyn, NY","contributions":[{"fullName":"Nico Jenkins","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Adam Staley Groves","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Paul Boshears","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Jamie Allen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3d78e15e-19cb-464a-a238-b5291dbfd49f","fullTitle":"Creep: A Life, A Theory, An Apology","doi":"https://doi.org/10.21983/P3.0178.1.00","publicationDate":"2017-08-29","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f2a2626b-4029-4e43-bb84-7b3cacf61b23","fullTitle":"Crisis States: Governance, Resistance & Precarious Capitalism","doi":"https://doi.org/10.21983/P3.0146.1.00","publicationDate":"2016-07-05","place":"Earth, Milky Way","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"639a3c5b-82ad-4557-897b-2bfebe3dc53c","fullTitle":"Critique of Sovereignty, Book 1: Contemporary Theories of Sovereignty","doi":"https://doi.org/10.21983/P3.0114.1.00","publicationDate":"2015-09-28","place":"Brooklyn, NY","contributions":[{"fullName":"Marc Lombardo","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f37627c1-d89f-434c-9915-f1f2f33dc037","fullTitle":"Crush","doi":"https://doi.org/10.21983/P3.0063.1.00","publicationDate":"2014-02-27","place":"Brooklyn, NY","contributions":[{"fullName":"Will Stockton","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"D. Gilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"43355368-b29b-4fa1-9ed6-780f4983364a","fullTitle":"Damayanti and Nala's Tale","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Dan Rudmann","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"11749800-364e-4a27-bf79-9f0ceeacb4d6","fullTitle":"Dark Chaucer: An Assortment","doi":"https://doi.org/10.21983/P3.0018.1.00","publicationDate":"2012-12-23","place":"Brooklyn, NY","contributions":[{"fullName":"Nicola Masciandaro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Myra Seaman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"7fe2c6dc-6673-4537-a397-1f0377c2296f","fullTitle":"Dear Professor: A Chronicle of Absences","doi":"https://doi.org/10.21983/P3.0160.1.00","publicationDate":"2016-12-19","place":"Earth, Milky Way","contributions":[{"fullName":"Filip Noterdaeme","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Shuki Cohen","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"0985e294-aa85-40d0-90ce-af53ae37898d","fullTitle":"Deleuze and the Passions","doi":"https://doi.org/10.21983/P3.0161.1.00","publicationDate":"2016-12-21","place":"Earth, Milky Way","contributions":[{"fullName":"Sjoerd van Tuinen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ceciel Meiborg","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9e6bb4d8-4e05-4cd7-abe9-4a795ade0340","fullTitle":"Derrida and Queer Theory","doi":"https://doi.org/10.21983/P3.0172.1.00","publicationDate":"2017-05-26","place":"Earth, Milky Way","contributions":[{"fullName":"Christian Hite","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9e11adff-abed-4b5d-adef-b0c4466231e8","fullTitle":"Desire/Love","doi":"https://doi.org/10.21983/P3.0015.1.00","publicationDate":"2012-12-05","place":"Brooklyn, NY","contributions":[{"fullName":"Lauren Berlant","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6141d35a-a5a6-43ee-b6b6-5caa41bce869","fullTitle":"Desire/Love","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Lauren Berlant","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13c12944-701a-41f4-9d85-c753267d564b","fullTitle":"Destroyer of Naivetés","doi":"https://doi.org/10.21983/P3.0118.1.00","publicationDate":"2015-11-07","place":"Brooklyn, NY","contributions":[{"fullName":"Joseph Nechvatal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"69c890c5-d8c5-4295-b5a7-688560929d8b","fullTitle":"Dialectics Unbound: On the Possibility of Total Writing","doi":"https://doi.org/10.21983/P3.0041.1.00","publicationDate":"2013-07-28","place":"Brooklyn, NY","contributions":[{"fullName":"Maxwell Kennel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"25be3523-34b5-43c9-a3e2-b12ffb859025","fullTitle":"Dire Pessimism: An Essay","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Thomas Carl Wall","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"245c521a-5014-4da0-bf2b-35eff9673367","fullTitle":"dis/cord: Thinking Sound through Agential Realism","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Kevin Toksöz Fairbarn","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"488c640d-e742-465a-98b4-1234bb09d038","fullTitle":"Diseases of the Head: Essays on the Horrors of Speculative Philosophy","doi":"https://doi.org/10.21983/P3.0280.1.00","publicationDate":"2020-09-24","place":"Earth, Milky Way","contributions":[{"fullName":"Matt Rosen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"754c1299-9b8d-41ac-a1d6-534f174fa87b","fullTitle":"Disturbing Times: Medieval Pasts, Reimagined Futures","doi":"https://doi.org/10.21983/P3.0313.1.00","publicationDate":"2020-06-04","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Anna Kłosowska","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Catherine E. Karkov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"438e0846-b4b9-4c84-9545-d7a6fb13e996","fullTitle":"Divine Name Verification: An Essay on Anti-Darwinism, Intelligent Design, and the Computational Nature of Reality","doi":"https://doi.org/10.21983/P3.0043.1.00","publicationDate":"2013-08-23","place":"Brooklyn, NY","contributions":[{"fullName":"Noah Horwitz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9d1f849d-cf0f-4d0c-8dab-8819fad00337","fullTitle":"Dollar Theater Theory","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Trevor Owen Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cd037a39-f6b9-462a-a207-5079a000065b","fullTitle":"Dotawo: A Journal of Nubian Studies 1","doi":"https://doi.org/10.21983/P3.0071.1.00","publicationDate":"2014-06-23","place":"Brooklyn, NY","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Angelika Jakobi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"6092f859-05fe-475d-b914-3c1a6534e6b9","fullTitle":"Down to Earth: A Memoir","doi":"https://doi.org/10.21983/P3.0306.1.00","publicationDate":"2020-10-22","place":"Earth, Milky Way","contributions":[{"fullName":"Gísli Pálsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna Yates","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrina Downs-Rose","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"ac6acc15-6927-4cef-95d3-1c71183ef2a6","fullTitle":"Echoes of No Thing: Thinking between Heidegger and Dōgen","doi":"https://doi.org/10.21983/P3.0239.1.00","publicationDate":"2019-01-04","place":"Earth, Milky Way","contributions":[{"fullName":"Nico Jenkins","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2658fe95-2df3-4e7d-8df6-e86c18359a23","fullTitle":"Ephemeral Coast, S. Wales","doi":"https://doi.org/10.21983/P3.0079.1.00","publicationDate":"2014-11-01","place":"Brooklyn, NY","contributions":[{"fullName":"Celina Jeffery","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"98ce9caa-487e-4391-86c9-e5d8129be5b6","fullTitle":"Essays on the Peripheries","doi":"https://doi.org/10.21983/P3.0291.1.00","publicationDate":"2021-04-22","place":"Earth, Milky Way","contributions":[{"fullName":"Peter Valente","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"19b32470-bf29-48e1-99db-c08ef90516a9","fullTitle":"Everyday Cinema: The Films of Marc Lafia","doi":"https://doi.org/10.21983/P3.0164.1.00","publicationDate":"2017-01-31","place":"Earth, Milky Way","contributions":[{"fullName":"Marc Lafia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"859e72c3-8159-48e4-b2f0-842f3400cb8d","fullTitle":"Extraterritorialities in Occupied Worlds","doi":"https://doi.org/10.21983/P3.0131.1.00","publicationDate":"2016-02-16","place":"Earth, Milky Way","contributions":[{"fullName":"Ruti Sela Maayan Amir","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1b870455-0b99-4d0e-af22-49f4ebbb6493","fullTitle":"Finding Room in Beirut: Places of the Everyday","doi":"https://doi.org/10.21983/P3.0243.1.00","publicationDate":"2019-02-08","place":"Earth, Milky Way","contributions":[{"fullName":"Carole Lévesque","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6ca16a49-7c95-4c81-b8f0-8f3c7e42de7d","fullTitle":"Flash + Cube (1965–1975)","doi":"https://doi.org/10.21983/P3.0036.1.00","publicationDate":"2013-07-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marget Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7fbc96cf-4c88-4e70-b1fe-d4e69324184a","fullTitle":"Flash + Cube (1965–1975)","doi":null,"publicationDate":"2012-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marget Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f4a04558-958a-43da-b009-d5b7580c532f","fullTitle":"Follow for Now, Volume 2: More Interviews with Friends and Heroes","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Roy Christopher","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97a2ac65-5b1b-4ab8-8588-db8340f04d27","fullTitle":"Fuckhead","doi":"https://doi.org/10.21983/P3.0048.1.00","publicationDate":"2013-09-24","place":"Brooklyn, NY","contributions":[{"fullName":"David Rawson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f3294e78-9a12-49ff-983e-ed6154ff621e","fullTitle":"Gender Trouble Couplets, Volume 1","doi":"https://doi.org/10.21983/P3.0266.1.00","publicationDate":"2019-11-15","place":"Earth, Milky Way","contributions":[{"fullName":"A.W. Strouse","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna M. Kłosowska","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"c80467d8-d472-4643-9a50-4ac489da14dd","fullTitle":"Geographies of Identity","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jill Darling","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"bbe77bbb-0242-46d7-92d2-cfd35c17fe8f","fullTitle":"Heathen Earth: Trumpism and Political Ecology","doi":"https://doi.org/10.21983/P3.0170.1.00","publicationDate":"2017-05-09","place":"Earth, Milky Way","contributions":[{"fullName":"Kyle McGee","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"875a78d7-fad2-4c22-bb04-35e0456b6efa","fullTitle":"Heavy Processing (More than a Feeling)","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"T.L. Cowan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jasmine Rault","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7f72c34d-4515-42eb-a32e-38fe74217b70","fullTitle":"Hephaestus Reloaded: Composed for Ten Hands / Efesto Reloaded: Composizioni per 10 mani","doi":"https://doi.org/10.21983/P3.0258.1.00","publicationDate":"2019-12-13","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Berg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Brunella Antomarini","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Miltos Maneta","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Vladimir D’Amora","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pietro Traversa","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":8},{"fullName":"Patrick Camiller","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":7},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":6}]},{"workId":"b63ffeb5-7906-4c74-8ec2-68cbe87f593c","fullTitle":"History According to Cattle","doi":"https://doi.org/10.21983/P3.0116.1.00","publicationDate":"2015-10-01","place":"Brooklyn, NY","contributions":[{"fullName":"Terike Haapoja","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Laura Gustafsson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4f46d026-49c6-4319-b79a-a6f70d412b5c","fullTitle":"Homotopia? Gay Identity, Sameness & the Politics of Desire","doi":"https://doi.org/10.21983/P3.0124.1.00","publicationDate":"2015-12-25","place":"Brooklyn, NY","contributions":[{"fullName":"Jonathan Kemp","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0257269-5ca3-40b3-b4e1-90f66baddb88","fullTitle":"Humid, All Too Humid: Overheated Observations","doi":"https://doi.org/10.21983/P3.0132.1.00","publicationDate":"2016-02-25","place":"Earth, Milky Way","contributions":[{"fullName":"Dominic Pettman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"241f9c62-26be-4d0f-864b-ad4b243a03c3","fullTitle":"Imperial Physique","doi":"https://doi.org/10.21983/P3.0268.1.00","publicationDate":"2019-11-19","place":"Earth, Milky Way","contributions":[{"fullName":"JH Phrydas","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aeed0683-e022-42d0-a954-f9f36afc4bbf","fullTitle":"Incomparable Poetry: An Essay on the Financial Crisis of 2007–2008 and Irish Literature","doi":"https://doi.org/10.21983/P3.0286.1.00","publicationDate":"2020-05-14","place":"Earth, Milky Way","contributions":[{"fullName":"Robert Kiely","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5ec826f5-18ab-498c-8b66-bd288618df15","fullTitle":"Insurrectionary Infrastructures","doi":"https://doi.org/10.21983/P3.0200.1.00","publicationDate":"2018-05-02","place":"Earth, Milky Way","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"89990379-94c2-4590-9037-cbd5052694a4","fullTitle":"Intimate Bureaucracies","doi":"https://doi.org/10.21983/P3.0005.1.00","publicationDate":"2012-03-09","place":"Brooklyn, NY","contributions":[{"fullName":"dj readies","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"85a2a2fe-d515-4784-b451-d26ec4c62a4f","fullTitle":"Iteration:Again: 13 Public Art Projects across Tasmania","doi":"https://doi.org/10.21983/P3.0037.1.00","publicationDate":"2013-07-02","place":"Brooklyn, NY","contributions":[{"fullName":"David Cross","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael Edwards","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"f3db2a03-75db-4837-af31-4bb0cb189fa2","fullTitle":"Itinerant Philosophy: On Alphonso Lingis","doi":"https://doi.org/10.21983/P3.0073.1.00","publicationDate":"2014-08-04","place":"Brooklyn, NY","contributions":[{"fullName":"Tom Sparrow","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bobby George","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1376b0f4-e967-4a6f-8d7d-8ba876bbbdde","fullTitle":"Itinerant Spectator/Itinerant Spectacle","doi":"https://doi.org/10.21983/P3.0056.1.00","publicationDate":"2013-12-20","place":"Brooklyn, NY","contributions":[{"fullName":"P.A. Skantze","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"da814d9f-14ff-4660-acfe-52ac2a2058fa","fullTitle":"Journal of Badiou Studies 3: On Ethics","doi":"https://doi.org/10.21983/P3.0070.1.00","publicationDate":"2014-06-04","place":"Brooklyn, NY","contributions":[{"fullName":"Arthur Rose","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Nicolò Fazioni","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7e2e26fd-4b0b-4c0b-a1fa-278524c43757","fullTitle":"Journal of Badiou Studies 5: Architheater","doi":"https://doi.org/10.21983/P3.0173.1.00","publicationDate":"2017-07-07","place":"Earth, Milky Way","contributions":[{"fullName":"Arthur Rose","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adi Efal-Lautenschläger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"d2e40ec1-5c2a-404d-8e9f-6727c7c178dc","fullTitle":"Kill Boxes: Facing the Legacy of US-Sponsored Torture, Indefinite Detention, and Drone Warfare","doi":"https://doi.org/10.21983/P3.0166.1.00","publicationDate":"2017-03-02","place":"Earth, Milky Way","contributions":[{"fullName":"Elisabeth Weber","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Richard Falk","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"75693fd0-e93a-4fc3-b82e-4c83a11f28b1","fullTitle":"Knocking the Hustle: Against the Neoliberal Turn in Black Politics","doi":"https://doi.org/10.21983/P3.0121.1.00","publicationDate":"2015-12-10","place":"Brooklyn, NY","contributions":[{"fullName":"Lester K. Spence","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed3ea389-5d5c-430c-9453-814ed94e027b","fullTitle":"Knowledge, Spirit, Law, Book 1: Radical Scholarship","doi":"https://doi.org/10.21983/P3.0123.1.00","publicationDate":"2015-12-24","place":"Brooklyn, NY","contributions":[{"fullName":"Gavin Keeney","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d0d59741-4866-42c3-8528-f65c3da3ffdd","fullTitle":"Language Parasites: Of Phorontology","doi":"https://doi.org/10.21983/P3.0169.1.00","publicationDate":"2017-05-04","place":"Earth, Milky Way","contributions":[{"fullName":"Sean Braune","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1a71ecd5-c868-44af-9b53-b45888fb241c","fullTitle":"Lapidari 1: Texts","doi":"https://doi.org/10.21983/P3.0094.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonida Gashi","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"df518095-84ff-4138-b2f9-5d8fe6ddf53a","fullTitle":"Lapidari 2: Images, Part I","doi":"https://doi.org/10.21983/P3.0091.1.00","publicationDate":"2015-02-15","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"a9d68f12-1de4-4c08-84b1-fe9a786ab47f","fullTitle":"Lapidari 3: Images, Part II","doi":"https://doi.org/10.21983/P3.0092.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"08788fe1-c17d-4f6b-aeab-c81aa3036940","fullTitle":"Left Bank Dream","doi":"https://doi.org/10.21983/P3.0084.1.00","publicationDate":"2014-12-26","place":"Brooklyn, NY","contributions":[{"fullName":"Beryl Scholssman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b4d68a6d-01fb-48f1-9f64-1fcdaaf1cdfd","fullTitle":"Leper Creativity: Cyclonopedia Symposium","doi":"https://doi.org/10.21983/P3.0017.1.00","publicationDate":"2012-12-22","place":"Brooklyn, NY","contributions":[{"fullName":"Eugene Thacker","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Nicola Masciandaro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Edward Keller","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"00e012c5-9232-472c-bd8b-8ca4ea6d1275","fullTitle":"Li Bo Unkempt","doi":"https://doi.org/10.21983/P3.0322.1.00","publicationDate":"2021-03-30","place":"Earth, Milky Way","contributions":[{"fullName":"Kidder Smith","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Kidder Smith","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mike Zhai","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Traktung Yeshe Dorje","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":4},{"fullName":"Maria Dolgenas","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":5}]},{"workId":"534c3d13-b18b-4be5-91e6-768c0cf09361","fullTitle":"Living with Monsters","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Ilana Gershon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Yasmine Musharbash","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"636a5aa6-1d37-4cd2-8742-4dcad8c67e0c","fullTitle":"Love Don't Need a Reason: The Life & Music of Michael Callen","doi":"https://doi.org/10.21983/P3.0297.1.00","publicationDate":"2020-11-05","place":"Earth, Milky Way","contributions":[{"fullName":"Matthew J.\n Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6dcf29ea-76c1-4121-ad7f-2341574c45fe","fullTitle":"Luminol Theory","doi":"https://doi.org/10.21983/P3.0177.1.00","publicationDate":"2017-08-24","place":"Earth, Milky Way","contributions":[{"fullName":"Laura E. Joyce","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed96eea8-82c6-46c5-a19b-dad5e45962c6","fullTitle":"Make and Let Die: Untimely Sovereignties","doi":"https://doi.org/10.21983/P3.0136.1.00","publicationDate":"2016-03-10","place":"Earth, Milky Way","contributions":[{"fullName":"Kathleen Biddick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Eileen A. Joy","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"003137ea-4fe6-470d-8bd3-f936ad065f3c","fullTitle":"Making the Geologic Now: Responses to Material Conditions of Contemporary Life","doi":"https://doi.org/10.21983/P3.0014.1.00","publicationDate":"2012-12-04","place":"Brooklyn, NY","contributions":[{"fullName":"Elisabeth Ellsworth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jamie Kruse","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"35ed7096-8218-43d7-a572-6453c9892ed1","fullTitle":"Manifesto for a Post-Critical Pedagogy","doi":"https://doi.org/10.21983/P3.0193.1.00","publicationDate":"2018-01-11","place":"Earth, Milky Way","contributions":[{"fullName":"Piotr Zamojski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Joris Vlieghe","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Naomi Hodgson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":null,"imprintId":"3437ff40-3bff-4cda-9f0b-1003d2980335","imprintName":"Risking Education","updatedAt":"2021-07-06T17:43:41.987789+00:00","createdAt":"2021-07-06T17:43:41.987789+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","fullTitle":"Nothing As We Need It: A Chimera","doi":"https://doi.org/10.53288/0382.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Daniela Cascella","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/speculations/","imprintId":"dcf8d636-38ae-4a63-bae1-40a61b5a3417","imprintName":"Speculations","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"03da5b84-80ba-48bc-89b9-b63fc56b364b","fullTitle":"Speculations","doi":"https://doi.org/10.21983/P3.0343.1.00","publicationDate":"2020-07-30","place":"Earth, Milky Way","contributions":[{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c00d9a0c-320d-4dfb-ba0c-d1adbdb491ef","fullTitle":"Speculations 3","doi":"https://doi.org/10.21983/P3.0010.1.00","publicationDate":"2012-09-03","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"2c71d808-d1a7-4918-afbb-2dfc121e7768","fullTitle":"Speculations II","doi":"https://doi.org/10.21983/P3.0344.1.00","publicationDate":"2020-07-30","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"ee2cb855-4c94-4176-b62c-3114985dd84e","fullTitle":"Speculations IV: Speculative Realism","doi":"https://doi.org/10.21983/P3.0032.1.00","publicationDate":"2013-06-05","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"435a1db3-1bbb-44b2-9368-7b2fd8a4e63e","fullTitle":"Speculations VI","doi":"https://doi.org/10.21983/P3.0122.1.00","publicationDate":"2015-12-12","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/thought-crimes/","imprintId":"f2dc7495-17af-4d8a-9306-168fc6fa1f41","imprintName":"Thought | Crimes","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1bba80bd-2efd-41a2-9b09-4ff8da0efeb9","fullTitle":"New Developments in Anarchist Studies","doi":"https://doi.org/10.21983/P3.0349.1.00","publicationDate":"2015-06-13","place":"Brooklyn, NY","contributions":[{"fullName":"pj lilley","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jeff Shantz","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5a1cd53e-640b-46e7-82a6-d95bc4907e36","fullTitle":"The Spectacle of the False Flag: Parapolitics from JFK to Watergate","doi":"https://doi.org/10.21983/P3.0347.1.00","publicationDate":"2014-03-01","place":"Brooklyn, NY","contributions":[{"fullName":"Eric Wilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Guido Giacomo Preparata","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2},{"fullName":"Jeff Shantz","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"c8245465-2937-40fd-9c3e-7bd33deef477","fullTitle":"Who Killed the Berkeley School? Struggles Over Radical Criminology ","doi":"https://doi.org/10.21983/P3.0348.1.00","publicationDate":"2014-04-21","place":"Brooklyn, NY","contributions":[{"fullName":"Julia Schwendinger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Herman Schwendinger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jeff Shantz","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/tiny-collections/","imprintId":"be4c8448-93c8-4146-8d9c-84d121bc4bec","imprintName":"Tiny Collections","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","fullTitle":"Closer to Dust","doi":"https://doi.org/10.53288/0324.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Sara A. Rich","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"771e1cde-d224-4cb6-bac7-7f5ef4d1a405","fullTitle":"Coconuts: A Tiny History","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Kathleen E. Kennedy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"20d15631-f886-43a0-b00b-b62426710bdf","fullTitle":"Elemental Disappearances","doi":"https://doi.org/10.21983/P3.0157.1.00","publicationDate":"2016-11-28","place":"Earth, Milky Way","contributions":[{"fullName":"Jason Bahbak Mohaghegh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Dejan Lukić","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"177e3717-4c07-4f31-9318-616ad3b71e89","fullTitle":"Sea Monsters: Things from the Sea, Volume 2","doi":"https://doi.org/10.21983/P3.0182.1.00","publicationDate":"2017-09-29","place":"Earth, Milky Way","contributions":[{"fullName":"Asa Simon Mittman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Thea Tomaini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6dd15dd7-ae8c-4438-a597-7c99d5be4138","fullTitle":"Walk on the Beach: Things from the Sea, Volume 1","doi":"https://doi.org/10.21983/P3.0143.1.00","publicationDate":"2016-06-17","place":"Earth, Milky Way","contributions":[{"fullName":"Maggie M. Williams","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Karen Eileen Overbey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/uitgeverij/","imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","imprintName":"Uitgeverij","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"b5c810e1-c847-4553-a24e-9893164d9786","fullTitle":"(((","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}]},{"workId":"df9bf011-efaf-49a7-9497-2a4d4cfde9e8","fullTitle":"An Anthology of Asemic Handwriting","doi":"https://doi.org/10.21983/P3.0220.1.00","publicationDate":"2013-08-26","place":"The Hague/Tirana","contributions":[{"fullName":"Michael Jacobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Tim Gaze","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8b77c06a-3c1c-48ac-a32e-466ef37f293e","fullTitle":"A Neo Tropical Companion","doi":"https://doi.org/10.21983/P3.0217.1.00","publicationDate":"2012-01-26","place":"The Hague/Tirana","contributions":[{"fullName":"Jamie Stewart","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c3c09f99-71f9-431c-b0f4-ff30c3f7fe11","fullTitle":"Continuum: Writings on Poetry as Artistic Practice","doi":"https://doi.org/10.21983/P3.0229.1.00","publicationDate":"2015-11-26","place":"The Hague/Tirana","contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c30545e-539b-419a-8b96-5f6c475bab9e","fullTitle":"Disrupting the Digital Humanities","doi":"https://doi.org/10.21983/P3.0230.1.00","publicationDate":"2018-11-06","place":"Earth, Milky Way","contributions":[{"fullName":"Jesse Stommel","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dorothy Kim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"dfe575e1-2836-43f3-a11b-316af9509612","fullTitle":"Exegesis of a Renunciation – Esegesi di una rinuncia","doi":"https://doi.org/10.21983/P3.0226.1.00","publicationDate":"2014-10-14","place":"The Hague/Tirana","contributions":[{"fullName":"Francesco Aprile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bartolomé Ferrando","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2},{"fullName":"Caggiula Cristiano","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"a9b27739-0d29-4238-8a41-47b3ac2d5bd5","fullTitle":"Filial Arcade & Other Poems","doi":"https://doi.org/10.21983/P3.0223.1.00","publicationDate":"2013-12-21","place":"The Hague/Tirana","contributions":[{"fullName":"Adam Staley Groves","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"c2c22cdf-b9d5-406d-9127-45cea8e741b1","fullTitle":"Hippolytus","doi":"https://doi.org/10.21983/P3.0218.1.00","publicationDate":"2012-08-21","place":"The Hague/Tirana","contributions":[{"fullName":"Euripides","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sean Gurd","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"ebeae9d6-7543-4cd4-9fa9-c39c43ba0d4b","fullTitle":"Men in Aïda","doi":"https://doi.org/10.21983/P3.0224.0.00","publicationDate":"2014-12-31","place":"The Hague/Tirana","contributions":[{"fullName":"David J. Melnick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sean Gurd","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"d24a0567-d430-4768-8c4d-1b9d59394af2","fullTitle":"On Blinking","doi":"https://doi.org/10.21983/P3.0219.1.00","publicationDate":"2012-08-23","place":"The Hague/Tirana","contributions":[{"fullName":"Sarah Brigid Hannis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeremy Fernando","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97d205c8-32f0-4e64-a7df-bf56334be638","fullTitle":"paq'batlh: A Klingon Epic","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Floris Schönfeld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. Van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Kees Ligtelijn","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marc Okrand","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"e81ef154-5bc3-481b-9083-64fd7aeb7575","fullTitle":"paq'batlh: The Klingon Epic","doi":"https://doi.org/10.21983/P3.0215.1.00","publicationDate":"2011-10-10","place":"The Hague/Tirana","contributions":[{"fullName":"Floris Schönfeld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. Van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Kees Ligtelijn","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marc Okrand","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"119f1640-dfb4-488f-a564-ef507d74b72d","fullTitle":"Pen in the Park: A Resistance Fairytale – Pen Parkta: Bir Direniş Masalı","doi":"https://doi.org/10.21983/P3.0225.1.00","publicationDate":"2014-02-12","place":"The Hague/Tirana","contributions":[{"fullName":"Raşel Meseri","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sanne Karssenberg","contributionType":"ILUSTRATOR","mainContribution":false,"contributionOrdinal":2}]},{"workId":"0cb39600-2fd2-4a7a-9d3a-6d92b8e32e9e","fullTitle":"Poetry from Beyond the Grave","doi":"https://doi.org/10.21983/P3.0222.1.00","publicationDate":"2013-05-10","place":"The Hague/Tirana","contributions":[{"fullName":"Francisco Cândido \"Chico\" Xavier","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vitor Peqeuno","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeremy Fernando","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"69365c88-4571-45f3-8770-5a94f7c9badc","fullTitle":"Poetry Vocare","doi":"https://doi.org/10.21983/P3.0213.1.00","publicationDate":"2011-01-23","place":"The Hague/Tirana","contributions":[{"fullName":"Adam Staley Groves","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Judith Balso","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"bc283f71-9f37-47c4-b30b-8ed9f3be9f9c","fullTitle":"The Guerrilla I Like a Poet – Ang Gerilya Ay Tulad ng Makata","doi":"https://doi.org/10.21983/P3.0221.1.00","publicationDate":"2013-09-27","place":"The Hague/Tirana","contributions":[{"fullName":"Jose Maria Sison","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonas Staal","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"7be9aa8c-b8af-4b2f-96ff-16e4532f2b83","fullTitle":"The Miracle of Saint Mina – Gis Miinan Nokkor","doi":"https://doi.org/10.21983/P3.0216.1.00","publicationDate":"2012-01-05","place":"The Hague/Tirana","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"El-Shafie El-Guzuuli","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b55c95a7-ce6e-4cfb-8945-cab4e04001e5","fullTitle":"To Be, or Not to Be: Paraphrased","doi":"https://doi.org/10.21983/P3.0227.1.00","publicationDate":"2016-06-17","place":"The Hague/Tirana","contributions":[{"fullName":"Bardsley Rosenbridge","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"367397db-bcb4-4f0e-9185-4be74c119c19","fullTitle":"Writing Art","doi":"https://doi.org/10.21983/P3.0228.1.00","publicationDate":"2015-11-26","place":"The Hague/Tirana","contributions":[{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Alessandro De Francesco","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"6a109b6a-55e9-4dd5-b670-61926c10e611","fullTitle":"Writing Death","doi":"https://doi.org/10.21983/P3.0214.1.00","publicationDate":"2011-06-06","place":"The Hague/Tirana","contributions":[{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Avital Ronell","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]}],"__typename":"Imprint"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle new file mode 100644 index 0000000..1e592a8 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle @@ -0,0 +1 @@ +[{"imprintUrl": "https://punctumbooks.com/imprints/3ecologies-books/", "imprintId": "78b0a283-9be3-4fed-a811-a7d4b9df7b25", "imprintName": "3Ecologies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9", "fullTitle": "A Manga Perfeita", "doi": "https://doi.org/10.21983/P3.0270.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Christine Greiner", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Ernesto Filho", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "c3d008a2-b357-4886-acc4-a2c77f1749ee", "fullTitle": "Last Year at Betty and Bob's: An Actual Occasion", "doi": "https://doi.org/10.53288/0363.1.00", "publicationDate": "2021-07-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "781b77bd-edf8-4688-937d-cc7cc47de89f", "fullTitle": "Last Year at Betty and Bob's: An Adventure", "doi": "https://doi.org/10.21983/P3.0234.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ce38f309-4438-479f-bd1c-b3690dbd7d8d", "fullTitle": "Last Year at Betty and Bob's: A Novelty", "doi": "https://doi.org/10.21983/P3.0233.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "edf31616-ea2a-4c51-b932-f510b9eb8848", "fullTitle": "No Archive Will Restore You", "doi": "https://doi.org/10.21983/P3.0231.1.00", "publicationDate": "2018-11-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Julietta Singh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d4a3f6cb-3023-4088-a5f4-147fb4510874", "fullTitle": "Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew Goulish", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Will Dadario", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d9045f8-1d8f-479c-983d-383f3a289bec", "fullTitle": "Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art", "doi": "https://doi.org/10.21983/P3.0327.1.00", "publicationDate": "2021-02-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Curt Cloninger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ffa5c5dd-ab4b-4739-8281-275d8c1fb504", "fullTitle": "Sweet Spots: Writing the Connective Tissue of Relation", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mattie-Martha Sempert", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "757ff294-0fca-40f5-9f33-39a2d3fd5c8a", "fullTitle": "Teaching Myself To See", "doi": "https://doi.org/10.21983/P3.0303.1.00", "publicationDate": "2021-02-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Tito Mukhopadhyay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "571255b8-5bf5-4fe1-a201-5bc7aded7f9d", "fullTitle": "The Perfect Mango", "doi": "https://doi.org/10.21983/P3.0245.1.00", "publicationDate": "2019-02-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4cfb06e-a5a6-48cc-b7e5-c38228c132a8", "fullTitle": "The Unnaming of Aliass", "doi": "https://doi.org/10.21983/P3.0299.1.00", "publicationDate": "2020-10-01", "place": "Earth, Milky Way", "contributions": [{"fullName": "Karin Bolender", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/advanced-methods/", "imprintId": "ef38d49c-f8cb-4621-9f2f-1637560016e4", "imprintName": "Advanced Methods", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "0729b9d1-87d3-4739-8266-4780c3cc93da", "fullTitle": "Doing Multispecies Theology", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mathew Arthur", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "af1d6a61-66bd-47fd-a8c5-20e433f7076b", "fullTitle": "Inefficient Mapping: A Protocol for Attuning to Phenomena", "doi": "https://doi.org/10.53288/0336.1.00", "publicationDate": "2021-08-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Linda Knight", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aa9059ba-930c-4327-97a1-c8c7877332c1", "fullTitle": "Making a Laboratory: Dynamic Configurations with Transversal Video", "doi": null, "publicationDate": "2020-08-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ben Spatz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8f256239-8104-4838-9587-ac234aedd822", "fullTitle": "Speaking for the Social: A Catalog of Methods", "doi": "https://doi.org/10.21983/P3.0378.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Gemma John", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Hannah Knox", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprint/anarchist-developments-in-cultural-studies/", "imprintId": "3bdf14c5-7f9f-42d2-8e3b-f78de0475c76", "imprintName": "Anarchist Developments in Cultural Studies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1d014946-aa73-4fae-9042-ef8830089f3c", "fullTitle": "Blasting the Canon", "doi": "https://doi.org/10.21983/P3.0035.1.00", "publicationDate": "2013-06-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Ruth Kinna", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "S\u00fcreyyya Evren", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "e1f74d6b-adab-4e56-8bc9-6fbd0eaab89c", "fullTitle": "Ontological Anarch\u00e9: Beyond Materialism and Idealism", "doi": "https://doi.org/10.21983/P3.0060.1.00", "publicationDate": "2014-01-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jason Adams", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Duane Rousselle", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/brainstorm-books/", "imprintId": "1e464718-2055-486b-bcd9-6e21309fcd80", "imprintName": "Brainstorm Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "fdd9e45a-08b4-4b98-9c34-bada71a34979", "fullTitle": "Animal Emotions: How They Drive Human Behavior", "doi": "https://doi.org/10.21983/P3.0305.1.00", "publicationDate": "2020-06-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kenneth L. Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Christian Montag", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "811fd271-b1dc-490a-a872-3d6867d59e78", "fullTitle": "Aural History", "doi": "https://doi.org/10.21983/P3.0282.1.00", "publicationDate": "2020-03-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Gila Ashtor", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f01cb60b-69bf-4d11-bd3c-fd5b36663029", "fullTitle": "Covert Plants: Vegetal Consciousness and Agency in an Anthropocentric World", "doi": "https://doi.org/10.21983/P3.0207.1.00", "publicationDate": "2018-09-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Prudence Gibson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Brits Baylee", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "9bdf38ca-95fd-4cf4-adf6-ed26e97cf213", "fullTitle": "Critique of Fantasy, Vol. 1: Between a Crypt and a Datemark", "doi": "https://doi.org/10.21983/P3.0277.1.00", "publicationDate": "2020-06-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "89f9c84b-be5c-4020-8edc-6fbe0b1c25f5", "fullTitle": "Critique of Fantasy, Vol. 2: The Contest between B-Genres", "doi": "https://doi.org/10.21983/P3.0278.1.00", "publicationDate": "2020-11-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "79464e83-b688-4b82-84bc-18d105f60f33", "fullTitle": "Critique of Fantasy, Vol. 3: The Block of Fame", "doi": "https://doi.org/10.21983/P3.0279.1.00", "publicationDate": "2021-01-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "992c6ff8-e166-4014-85cc-b53af250a4e4", "fullTitle": "Hack the Experience: Tools for Artists from Cognitive Science", "doi": "https://doi.org/10.21983/P3.0206.1.00", "publicationDate": "2018-09-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ryan Dewey", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4a42f23b-5277-49b5-8310-c3c38ded5bf5", "fullTitle": "Opioids: Addiction, Narrative, Freedom", "doi": "https://doi.org/10.21983/P3.0210.1.00", "publicationDate": "2018-10-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maia Dolphin-Krute", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "18d3d876-bcaf-4e1c-a67a-05537f808a99", "fullTitle": "The Hegemony of Psychopathy", "doi": "https://doi.org/10.21983/P3.0180.1.00", "publicationDate": "2017-09-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Lajos Brons", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5dca2af4-43f2-4cdb-a7a5-5654a722c4e0", "fullTitle": "Visceral: Essays on Illness Not as Metaphor", "doi": "https://doi.org/10.21983/P3.0185.1.00", "publicationDate": "2017-10-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maia Dolphin-Krute", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/ctm-documents-initiative/", "imprintId": "cec45cc6-8cb5-43ed-888f-165f3fa73842", "imprintName": "CTM Documents Initiative", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "b950d243-7cfc-4aee-b908-d1776be327df", "fullTitle": "Image Photograph", "doi": "https://doi.org/10.21983/P3.0106.1.00", "publicationDate": "2015-07-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marc Lafia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "14f2b847-faeb-43c9-b116-88a0091b6f1f", "fullTitle": "Knowledge, Spirit, Law, Book 2: The Anti-Capitalist Sublime", "doi": "https://doi.org/10.21983/P3.0191.1.00", "publicationDate": "2017-12-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Gavin Keeney", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1e0c7c29-dcd4-470d-b3ee-8c4012ac79dd", "fullTitle": "Liquid Life: On Non-Linear Materiality", "doi": "https://doi.org/10.21983/P3.0246.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Rachel Armstrong", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "47cd079b-03f3-4a5b-b5e4-36cec4db7fab", "fullTitle": "The Digital Dionysus: Nietzsche and the Network-Centric Condition", "doi": "https://doi.org/10.21983/P3.0149.1.00", "publicationDate": "2016-09-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dan Mellamphy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Nandita Biswas Mellamphy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1950e4ba-651c-4ec9-83f6-df46b777b10f", "fullTitle": "The Funambulist Pamphlets 10: Literature", "doi": "https://doi.org/10.21983/P3.0075.1.00", "publicationDate": "2014-08-14", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "bdfc263a-7ace-43f3-9c80-140c6fb32ec7", "fullTitle": "The Funambulist Pamphlets 11: Cinema", "doi": "https://doi.org/10.21983/P3.0095.1.00", "publicationDate": "2015-02-20", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f5fb8a0e-ea1d-471f-b76a-a000edae5956", "fullTitle": "The Funambulist Pamphlets 1: Spinoza", "doi": "https://doi.org/10.21983/P3.0033.1.00", "publicationDate": "2013-06-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "911de470-77e1-4816-b437-545122a7bf26", "fullTitle": "The Funambulist Pamphlets 2: Foucault", "doi": "https://doi.org/10.21983/P3.0034.1.00", "publicationDate": "2013-06-17", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "61da662d-c720-4d22-957c-4d96071ee5f2", "fullTitle": "The Funambulist Pamphlets 3: Deleuze", "doi": "https://doi.org/10.21983/P3.0038.1.00", "publicationDate": "2013-07-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "419e17ed-3bcc-430c-a67e-3121537e4702", "fullTitle": "The Funambulist Pamphlets 4: Legal Theory", "doi": "https://doi.org/10.21983/P3.0042.1.00", "publicationDate": "2013-08-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fe8ddfb7-0e5b-4604-811c-78cf4db7528b", "fullTitle": "The Funambulist Pamphlets 5: Occupy Wall Street", "doi": "https://doi.org/10.21983/P3.0046.1.00", "publicationDate": "2013-09-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13390641-86f6-4351-923d-8c456f175bff", "fullTitle": "The Funambulist Pamphlets 6: Palestine", "doi": "https://doi.org/10.21983/P3.0054.1.00", "publicationDate": "2013-11-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "448c3581-9167-491e-86f7-08d5a6c953a9", "fullTitle": "The Funambulist Pamphlets 7: Cruel Designs", "doi": "https://doi.org/10.21983/P3.0057.1.00", "publicationDate": "2013-12-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d3cbb60f-537f-4bd7-96cb-d8aba595a947", "fullTitle": "The Funambulist Pamphlets 8: Arakawa + Madeline Gins", "doi": "https://doi.org/10.21983/P3.0064.1.00", "publicationDate": "2014-03-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6fab7c76-7567-4b57-8ad7-90a5536d87af", "fullTitle": "The Funambulist Pamphlets 9: Science Fiction", "doi": "https://doi.org/10.21983/P3.0069.1.00", "publicationDate": "2014-05-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "84bbf59f-1dbb-445e-8f65-f26574f609b6", "fullTitle": "The Funambulist Papers, Volume 1", "doi": "https://doi.org/10.21983/P3.0053.1.00", "publicationDate": "2013-10-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3b41b8de-b9bb-4ebd-a002-52052a9e39a9", "fullTitle": "The Funambulist Papers, Volume 2", "doi": "https://doi.org/10.21983/P3.0098.1.00", "publicationDate": "2015-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/dead-letter-office/", "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "imprintName": "Dead Letter Office", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "fullTitle": "A Bibliography for After Jews and Arabs", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f02786d4-3bcc-473e-8d43-3da66c7e877c", "fullTitle": "A Brief Genealogy of Jewish Republicanism: Parting Ways with Judith Butler", "doi": "https://doi.org/10.21983/P3.0159.1.00", "publicationDate": "2016-12-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Irene Tucker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fd67d684-aaff-4260-bb94-9d0373015620", "fullTitle": "An Edition of Miles Hogarde's \"A Mirroure of Myserie\"", "doi": "https://doi.org/10.21983/P3.0316.1.00", "publicationDate": "2021-06-03", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sebastian Sobecki", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5f441303-4fc6-4a7d-951e-5b966a1cbd91", "fullTitle": "An Unspecific Dog: Artifacts of This Late Stage in History", "doi": "https://doi.org/10.21983/P3.0163.1.00", "publicationDate": "2017-01-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Joshua Rothes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7eb6f426-e913-4d69-92c5-15a640f1b4b9", "fullTitle": "A Sanctuary of Sounds", "doi": "https://doi.org/10.21983/P3.0029.1.00", "publicationDate": "2013-05-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Andreas Burckhardt", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4fc74913-bde4-426e-b7e5-2f66c60af484", "fullTitle": "As If: Essays in As You Like It", "doi": "https://doi.org/10.21983/P3.0162.1.00", "publicationDate": "2016-12-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "William N. West", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "06db2bc1-e25a-42c8-8908-fbd774f73204", "fullTitle": "Atopological Trilogy: Deleuze and Guattari", "doi": "https://doi.org/10.21983/P3.0096.1.00", "publicationDate": "2015-03-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Zafer Aracag\u00f6k", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Manola Antonioli", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "a022743e-8b77-4246-a068-e08d57815e27", "fullTitle": "CMOK to YOu To: A Correspondence", "doi": "https://doi.org/10.21983/P3.0150.1.00", "publicationDate": "2016-09-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc James L\u00e9ger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Nina \u017divan\u010devi\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f94ded4d-1c87-4503-82f1-a1ca4346e756", "fullTitle": "Come As You Are, After Eve Kosofsky Sedgwick", "doi": "https://doi.org/10.21983/P3.0342.1.00", "publicationDate": "2021-04-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eve Kosofsky Sedgwick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonathan Goldberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "449add5c-b935-47e2-8e46-2545fad86221", "fullTitle": "Escargotesque, or, What Is Experience", "doi": "https://doi.org/10.21983/P3.0089.1.00", "publicationDate": "2015-01-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "M.H. Bowker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "628bb121-5ba2-4fc1-a741-a8062c45b63b", "fullTitle": "Gaffe/Stutter", "doi": "https://doi.org/10.21983/P3.0049.1.00", "publicationDate": "2013-10-06", "place": "Brooklyn, NY", "contributions": [{"fullName": "Whitney Anne Trettien", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f131762c-a877-4925-9fa1-50555bc4e2ae", "fullTitle": "[Given, If, Then]: A Reading in Three Parts", "doi": "https://doi.org/10.21983/P3.0090.1.00", "publicationDate": "2015-02-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jennifer Hope Davy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Julia H\u00f6lzl", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cb11259b-7b83-498e-bc8a-7c184ee2c279", "fullTitle": "Going Postcard: The Letter(s) of Jacques Derrida", "doi": "https://doi.org/10.21983/P3.0171.1.00", "publicationDate": "2017-05-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f8b57164-89e6-48b1-bd70-9d360b53a453", "fullTitle": "Helicography", "doi": "https://doi.org/10.53288/0352.1.00", "publicationDate": "2021-07-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Craig Dworkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6689db84-b329-4ca5-b10c-010fd90c7e90", "fullTitle": "History of an Abuse", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ceffc30d-1d28-48c3-acee-e6a2dc38ff37", "fullTitle": "How We Read", "doi": "https://doi.org/10.21983/P3.0259.1.00", "publicationDate": "2019-07-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kaitlin Heller", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Suzanne Conklin Akbari", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "63e2f6b6-f324-4bdc-836e-55515ba3cd8f", "fullTitle": "How We Write: Thirteen Ways of Looking at a Blank Page", "doi": "https://doi.org/10.21983/P3.0110.1.00", "publicationDate": "2015-09-11", "place": "Brooklyn, NY", "contributions": [{"fullName": "Suzanne Conklin Akbari", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f5217945-8c2c-4e65-a5dd-3dbff208dfb7", "fullTitle": "In Divisible Cities: A Phanto-Cartographical Missive", "doi": "https://doi.org/10.21983/P3.0044.1.00", "publicationDate": "2013-08-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Dominic Pettman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d5f5978b-32e0-44a1-a72a-c80568c9b93a", "fullTitle": "I Open Fire", "doi": "https://doi.org/10.21983/P3.0086.1.00", "publicationDate": "2014-12-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Pol", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c6125a74-2801-4255-afe9-89cdb8d253f4", "fullTitle": "John Gardner: A Tiny Eulogy", "doi": "https://doi.org/10.21983/P3.0013.1.00", "publicationDate": "2012-11-29", "place": "Brooklyn, NY", "contributions": [{"fullName": "Phil Jourdan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8377c394-c27a-44cb-98f5-5e5b789ad7b8", "fullTitle": "Last Day Every Day: Figural Thinking from Auerbach and Kracauer to Agamben and Brenez", "doi": "https://doi.org/10.21983/P3.0012.1.00", "publicationDate": "2012-10-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Adrian Martin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1809f10a-d0e3-4481-8f96-cca7f240d656", "fullTitle": "Letters on the Autonomy Project in Art and Politics", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Janet Sarbanes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5f1db605-88b6-427a-84cb-ce2fcf0f89a3", "fullTitle": "Massa por Argamassa: A \"Libraria de Babel\" e o Sonho de Totalidade", "doi": "https://doi.org/10.21983/P3.0264.1.00", "publicationDate": "2019-09-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Basile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Yuri N. Martinez Laskowski", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f20869c5-746f-491b-8c34-f88dc3728e18", "fullTitle": "Min\u00f3y", "doi": "https://doi.org/10.21983/P3.0072.1.00", "publicationDate": "2014-06-30", "place": "Brooklyn, NY", "contributions": [{"fullName": "Joseph Nechvatal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d40aa92-380c-4fae-98d8-c598bb32e7c6", "fullTitle": "Misinterest: Essays, Pens\u00e9es, and Dreams", "doi": "https://doi.org/10.21983/P3.0256.1.00", "publicationDate": "2019-06-27", "place": "Earth, Milky Way", "contributions": [{"fullName": "M.H. Bowker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "34682ba4-201f-4122-8e4a-edc3edc57a7b", "fullTitle": "Nicholas of Cusa and the Kairos of Modernity: Cassirer, Gadamer, Blumenberg", "doi": "https://doi.org/10.21983/P3.0045.1.00", "publicationDate": "2013-09-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Edward Moore", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1cfca75f-2e57-4f34-85fb-a1585315a2a9", "fullTitle": "Noise Thinks the Anthropocene: An Experiment in Noise Poetics", "doi": "https://doi.org/10.21983/P3.0244.1.00", "publicationDate": "2019-02-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Aaron Zwintscher", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "571d5d40-cfd6-4270-9530-88bfcfc5d8b5", "fullTitle": "Non-Conceptual Negativity: Damaged Reflections on Turkey", "doi": "https://doi.org/10.21983/P3.0247.1.00", "publicationDate": "2019-03-27", "place": "Earth, Milky Way", "contributions": [{"fullName": "Zafer Aracag\u00f6k", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Fraco \"Bifo\" Berardi", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "3eb0d095-fc27-4add-8202-1dc2333a758c", "fullTitle": "Notes on Trumpspace: Politics, Aesthetics, and the Fantasy of Home", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "David Stephenson Markus", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "48e2a673-aec2-4ed6-99d4-46a8de200493", "fullTitle": "Nothing in MoMA", "doi": "https://doi.org/10.21983/P3.0208.1.00", "publicationDate": "2018-09-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Abraham Adams", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97019dea-e207-4909-b907-076d0620ff74", "fullTitle": "Obiter Dicta", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Erick Verran", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "10a41381-792f-4376-bed1-3781d1b8bae7", "fullTitle": "Of Learned Ignorance: Idea of a Treatise in Philosophy", "doi": "https://doi.org/10.21983/P3.0031.1.00", "publicationDate": "2013-06-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b43ec529-2f51-4c59-b3cb-394f3649502c", "fullTitle": "Of the Contract", "doi": "https://doi.org/10.21983/P3.0174.1.00", "publicationDate": "2017-07-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christopher Clifton", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "63b0e966-e81c-4d84-b41d-3445b0d9911f", "fullTitle": "Paris Bride: A Modernist Life", "doi": "https://doi.org/10.21983/P3.0281.1.00", "publicationDate": "2020-02-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "John Schad", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed1a8fb5-8b71-43ca-9748-ebd43f0d7580", "fullTitle": "Philosophy for Militants", "doi": "https://doi.org/10.21983/P3.0168.1.00", "publicationDate": "2017-03-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5b652d05-2b5f-465a-8c66-f4dc01dafd03", "fullTitle": "[provisional self-evidence]", "doi": "https://doi.org/10.21983/P3.0111.1.00", "publicationDate": "2015-09-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Rachel Arrighi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cd836291-fb7f-4508-bdff-cd59dca2b447", "fullTitle": "Queer Insists (for Jos\u00e9 Esteban Mu\u00f1oz)", "doi": "https://doi.org/10.21983/P3.0082.1.00", "publicationDate": "2014-12-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael O'Rourke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "46ab709c-3272-4a03-991e-d1b1394b8e2c", "fullTitle": "Ravish the Republic: The Archives of the Iron Garters Crime/Art Collective", "doi": "https://doi.org/10.21983/P3.0107.1.00", "publicationDate": "2015-07-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael L. Berger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "28a0db09-a149-43fe-ba08-00dde962b4b8", "fullTitle": "Reiner Sch\u00fcrmann and Poetics of Politics", "doi": "https://doi.org/10.21983/P3.0209.1.00", "publicationDate": "2018-09-28", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christopher Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5dda1ad6-70ac-4a31-baf2-b77f8f5a8190", "fullTitle": "Sappho: Fragments", "doi": "https://doi.org/10.21983/P3.0238.1.00", "publicationDate": "2018-12-31", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Goldberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "L.O. Aranye Fradenburg Joy", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "8cd5ce6c-d604-46ac-b4f7-1f871589d96a", "fullTitle": "Still Life: Notes on Barbara Loden's \"Wanda\" (1970)", "doi": "https://doi.org/10.53288/0326.1.00", "publicationDate": "2021-07-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anna Backman Rogers", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1547aa4b-7629-4a21-8b2b-621223c73ec9", "fullTitle": "Still Thriving: On the Importance of Aranye Fradenburg", "doi": "https://doi.org/10.21983/P3.0099.1.00", "publicationDate": "2015-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "L.O. Aranye Fradenburg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "08543bd7-e603-43ae-bb0f-1d4c1c96030b", "fullTitle": "Suite on \"Spiritus Silvestre\": For Symphony", "doi": "https://doi.org/10.21983/P3.0020.1.00", "publicationDate": "2012-12-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Denzil Ford", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9839926e-56ea-4d71-a3de-44cabd1d2893", "fullTitle": "Tar for Mortar: \"The Library of Babel\" and the Dream of Totality", "doi": "https://doi.org/10.21983/P3.0196.1.00", "publicationDate": "2018-03-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Basile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "58aadfa5-abc6-4c44-9768-f8ff41502867", "fullTitle": "The Afterlife of Genre: Remnants of the Trauerspiel in Buffy the Vampire Slayer", "doi": "https://doi.org/10.21983/P3.0061.1.00", "publicationDate": "2014-02-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "Anthony Curtis Adler", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1d30497f-4340-43ab-b328-9fd2fed3106e", "fullTitle": "The Anthology of Babel", "doi": "https://doi.org/10.21983/P3.0254.1.00", "publicationDate": "2020-01-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ed Simon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "26d522d4-fb46-47bf-a344-fe6af86688d3", "fullTitle": "The Bodies That Remain", "doi": "https://doi.org/10.21983/P3.0212.1.00", "publicationDate": "2018-10-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Emmy Beber", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a065ad95-716a-4005-b436-a46d9dbd64df", "fullTitle": "The Communism of Thought", "doi": "https://doi.org/10.21983/P3.0059.1.00", "publicationDate": "2014-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c51c8fa-947b-4a12-a2e9-5306ee81d117", "fullTitle": "The Death of Conrad Unger: Some Conjectures Regarding Parasitosis and Associated Suicide Behavior", "doi": "https://doi.org/10.21983/P3.0008.1.00", "publicationDate": "2012-08-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Gary L. Shipley", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "33917b8f-775f-4ee2-a43a-6b5285579f84", "fullTitle": "The Non-Library", "doi": "https://doi.org/10.21983/P3.0065.1.00", "publicationDate": "2014-03-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Trevor Owen Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "60813d93-663f-4974-8789-1a2ee83cd042", "fullTitle": "Theory Is Like a Surging Sea", "doi": "https://doi.org/10.21983/P3.0108.1.00", "publicationDate": "2015-08-02", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "119e45d6-63ab-4cc4-aabf-06ecba1fb055", "fullTitle": "The Witch and the Hysteric: The Monstrous Medieval in Benjamin Christensen's H\u00e4xan", "doi": "https://doi.org/10.21983/P3.0074.1.00", "publicationDate": "2014-08-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "Patricia Clare Ingham", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alexander Doty", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d6651c3c-c453-42ab-84b3-4e847d3a3324", "fullTitle": "Traffic Jams: Analysing Everyday Life through the Immanent Materialism of Deleuze & Guattari", "doi": "https://doi.org/10.21983/P3.0023.1.00", "publicationDate": "2013-02-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "David R. Cole", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "fullTitle": "Truth and Fiction: Notes on (Exceptional) Faith in Art", "doi": "https://doi.org/10.21983/P3.0007.1.00", "publicationDate": "2012-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Milcho Manchevski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adrian Martin", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "b904a8eb-9c98-4bb1-bf25-3cb9d075b157", "fullTitle": "Warez: The Infrastructure and Aesthetics of Piracy", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Martin Eve", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "77e1fa52-1938-47dd-b8a5-2a57bfbc91d1", "fullTitle": "What Is Philosophy?", "doi": "https://doi.org/10.21983/P3.0011.1.00", "publicationDate": "2012-10-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "27602ce3-fbd6-4044-8b44-b8421670edae", "fullTitle": "Wonder, Horror, and Mystery in Contemporary Cinema: Letters on Malick, Von Trier, and Kie\u015blowski", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Morgan Meis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "J.M. Tyree", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/department-of-eagles/", "imprintId": "ef4aece6-6e9c-4f90-b5c3-7e4b78e8942d", "imprintName": "Department of Eagles", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "3ccdbbfc-6550-49f4-8ec9-77fc94a7a099", "fullTitle": "Broken Narrative: The Politics of Contemporary Art in Albania", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Armando Lulaj", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marco Mazzi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Brenda Porster", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Tomii Keiko", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Osamu Kanemura", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 6}, {"fullName": "Jonida Gashi", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 5}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/dotawo/", "imprintId": "f891a5f0-2af2-4eda-b686-db9dd74ee73d", "imprintName": "Dotawo", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1c39ca0c-0189-44d3-bb2f-9345e2a2b152", "fullTitle": "Dotawo: A Journal of Nubian Studies 2", "doi": "https://doi.org/10.21983/P3.0104.1.00", "publicationDate": "2015-06-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Angelika Jakobi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "861ea7cc-5447-4c60-8657-c50d0a31cd24", "fullTitle": "Dotawo: a Journal of Nubian Studies 3: Know-Hows and Techniques in Ancient Sudan", "doi": "https://doi.org/10.21983/P3.0148.1.00", "publicationDate": "2016-08-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc Maillot", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "431b58fe-7f59-49d9-bf6f-53eae379ee4d", "fullTitle": "Dotawo: A Journal of Nubian Studies 4: Place Names and Place Naming in Nubia", "doi": "https://doi.org/10.21983/P3.0184.1.00", "publicationDate": "2017-10-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alexandros Tsakos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Robin Seignobos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3c5923bc-e76b-4fbe-8d8c-1a49a49020a8", "fullTitle": "Dotawo: A Journal of Nubian Studies 5: Nubian Women", "doi": "https://doi.org/10.21983/P3.0242.1.00", "publicationDate": "2019-02-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anne Jennings", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "15ab17fe-2486-4ca5-bb47-6b804793f80d", "fullTitle": "Dotawo: A Journal of Nubian Studies 6: Miscellanea Nubiana", "doi": "https://doi.org/10.21983/P3.0321.1.00", "publicationDate": "2019-12-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Simmons", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aa431454-40d3-42f5-8069-381a15789257", "fullTitle": "Dotawo: A Journal of Nubian Studies 7: Comparative Northern East Sudanic Linguistics", "doi": "https://doi.org/10.21983/P3.0350.1.00", "publicationDate": "2021-03-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7a4506ac-dfdc-4054-b2d1-d8fdf4cea12b", "fullTitle": "Nubian Proverbs", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Maher Habbob", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a8e6722a-1858-4f38-995d-bde0b120fe8c", "fullTitle": "The Old Nubian Language", "doi": "https://doi.org/10.21983/P3.0179.1.00", "publicationDate": "2017-09-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eugenia Smagina", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jos\u00e9 Andr\u00e9s Alonso de la Fuente", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "0cd80cd2-1733-4bde-b48f-a03fc01acfbf", "fullTitle": "The Old Nubian Texts from Attiri", "doi": "https://doi.org/10.21983/P3.0156.1.00", "publicationDate": "2016-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Petra Weschenfelder", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent Pierre-Michel Laisney", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kerstin Weber-Thum", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Alexandros Tsakos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}]}], "__typename": "Imprint"}, {"imprintUrl": null, "imprintId": "47e62ae1-6698-46aa-840c-d4507697459f", "imprintName": "eth press", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "5f24bd29-3d48-4a70-8491-6269f7cc6212", "fullTitle": "Ballads", "doi": "https://doi.org/10.21983/P3.0105.1.00", "publicationDate": "2015-06-03", "place": "Brooklyn, NY", "contributions": [{"fullName": "Richard Owens", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0a8fba81-f1d0-498c-88c4-0b96d3bf2947", "fullTitle": "Cotton Nero A.x: The Works of the \"Pearl\" Poet", "doi": "https://doi.org/10.21983/P3.0066.1.00", "publicationDate": "2014-04-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Chris Piuma", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Lisa Ampleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Daniel C. Remein", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "David Hadbawnik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "53cd2c70-eab6-45b7-a147-8ef1c87d9ac0", "fullTitle": "d\u00f4Nrm'-l\u00e4-p\u00fcsl", "doi": "https://doi.org/10.21983/P3.0183.1.00", "publicationDate": "2017-10-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "kari edwards", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Tina \u017digon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "34584bfe-1cf8-49c5-b8d1-6302ea1cfcfa", "fullTitle": "Snowline", "doi": "https://doi.org/10.21983/P3.0093.1.00", "publicationDate": "2015-02-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Donato Mancini", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cc73eed0-a1f9-4ad4-b7d8-2394b92765f0", "fullTitle": "Unless As Stone Is", "doi": "https://doi.org/10.21983/P3.0058.1.00", "publicationDate": "2014-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Sam Lohmann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/gracchi-books/", "imprintId": "41193484-91d1-44f3-8d0c-0452a35d17a0", "imprintName": "Gracchi Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1603556c-53fc-4d14-b0bf-8c18ad7b24ab", "fullTitle": "Social and Intellectual Networking in the Early Middle Ages", "doi": null, "publicationDate": null, "place": null, "contributions": [{"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "K. Patrick Fazioli", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "6813bf17-373c-49ce-b9e3-1d7ab98f2977", "fullTitle": "The Christian Economy of the Early Medieval West: Towards a Temple Society", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Ian Wood", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2f93b300-f147-48f5-95d5-afd0e0161fe6", "fullTitle": "Urban Interactions: Communication and Competition in Late Antiquity and the Early Middle Ages", "doi": "https://doi.org/10.21983/P3.0300.1.00", "publicationDate": "2020-10-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael Burrows", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ian Wood", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Michael J. Kelly", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "678f4564-d01a-4ffe-8bdb-fead78f87955", "fullTitle": "Vera Lex Historiae?: Constructions of Truth in Medieval Historical Narrative", "doi": "https://doi.org/10.21983/P3.0369.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Catalin Taranu", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/helvete/", "imprintId": "b3dc0be6-6739-4777-ada0-77b1f5074f7d", "imprintName": "Helvete", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "417ecc06-51a4-4660-959b-482763864559", "fullTitle": "Helvete 1: Incipit", "doi": "https://doi.org/10.21983/P3.0027.1.00", "publicationDate": "2013-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Aspasia Stephanou", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Amelia Ishmael", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Zareen Price", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ben Woodard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "3cc0269d-7170-4981-8ac7-5b01e7b9e080", "fullTitle": "Helvete 2: With Head Downwards: Inversions in Black Metal", "doi": "https://doi.org/10.21983/P3.0102.1.00", "publicationDate": "2015-05-19", "place": "Brooklyn, NY", "contributions": [{"fullName": "Niall Scott", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Steve Shakespeare", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "fa4bc310-b7db-458a-8ba9-13347a91c862", "fullTitle": "Helvete 3: Bleeding Black Noise", "doi": "https://doi.org/10.21983/P3.0158.1.00", "publicationDate": "2016-12-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Amelia Ishmael", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/lamma/", "imprintId": "f852b678-e8ac-4949-a64d-3891d4855e3d", "imprintName": "Lamma", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "ce7ec5ea-88b2-430f-92be-0f2436600a46", "fullTitle": "Lamma: A Journal of Libyan Studies 1", "doi": "https://doi.org/10.21983/P3.0337.1.00", "publicationDate": "2020-07-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Benkato", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Leila Tayeb", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Amina Zarrugh", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://www.matteringpress.org", "imprintId": "cb483a78-851f-4936-82d2-8dcd555dcda9", "imprintName": "Mattering Press", "updatedAt": "2021-03-25T16:33:14.299495+00:00", "createdAt": "2021-03-25T16:25:02.238699+00:00", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6", "publisher": {"publisherName": "Mattering Press", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6"}, "works": [{"workId": "95e15115-4009-4cb0-8824-011038e3c116", "fullTitle": "Energy Worlds: In Experiment", "doi": "https://doi.org/10.28938/9781912729098", "publicationDate": "2021-05-01", "place": "Manchester", "contributions": [{"fullName": "Brit Ross Winthereik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Laura Watts", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "James Maguire", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "091abd14-7bc0-4fe7-8194-552edb02b98b", "fullTitle": "Inventing the Social", "doi": "https://doi.org/10.28938/9780995527768", "publicationDate": "2018-07-11", "place": "Manchester", "contributions": [{"fullName": "Michael Guggenheim", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alex Wilkie", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Noortje Marres", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c38728e0-9739-4ad3-b0a7-6cda9a9da4b9", "fullTitle": "Sensing InSecurity: Sensors as transnational security infrastructures", "doi": null, "publicationDate": null, "place": "Manchester", "contributions": []}], "__typename": "Imprint"}, {"imprintUrl": "https://www.mediastudies.press/", "imprintId": "5078b33c-5b3f-48bf-bf37-ced6b02beb7c", "imprintName": "mediastudies.press", "updatedAt": "2021-06-15T14:40:51.652638+00:00", "createdAt": "2021-06-15T14:40:51.652638+00:00", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5", "publisher": {"publisherName": "mediastudies.press", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5"}, "works": [{"workId": "6763ec18-b4af-4767-976c-5b808a64e641", "fullTitle": "Liberty and the News", "doi": "https://doi.org/10.32376/3f8575cb.2e69e142", "publicationDate": "2020-11-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "Walter Lippmann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sue Curry Jansen", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "3162a992-05dd-4b74-9fe0-0f16879ce6de", "fullTitle": "Our Master\u2019s Voice: Advertising", "doi": "https://doi.org/10.21428/3f8575cb.dbba9917", "publicationDate": "2020-10-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "James Rorty", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jefferson Pooley", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "64891e84-6aac-437a-a380-0481312bd2ef", "fullTitle": "Social Media & the Self: An Open Reader", "doi": "https://doi.org/10.32376/3f8575cb.1fc3f80a", "publicationDate": "2021-07-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "Jefferson Pooley", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://meson.press", "imprintId": "0299480e-869b-486c-8a65-7818598c107b", "imprintName": "meson press", "updatedAt": "2021-03-25T16:36:00.832381+00:00", "createdAt": "2021-03-25T16:36:00.832381+00:00", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b", "publisher": {"publisherName": "meson press", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b"}, "works": [{"workId": "59ecdda1-efd8-45d2-b6a6-11bc8fe480f5", "fullTitle": "Earth and Beyond in Tumultuous Times: A Critical Atlas of the Anthropocene", "doi": "https://doi.org/10.14619/1891", "publicationDate": "2021-03-15", "place": "L\u00fcneburg", "contributions": [{"fullName": "Petra L\u00f6ffler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "R\u00e9ka Patr\u00edcia G\u00e1l", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "36f7480e-ca45-452c-a5c0-ba1dccf135ec", "fullTitle": "Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices", "doi": "https://doi.org/10.14619/1860", "publicationDate": "2021-05-17", "place": "Lueneburg", "contributions": [{"fullName": "Wanda Strauven", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "38872158-58b9-4ddf-a90e-f6001ac6c62d", "fullTitle": "Trick 17: Mediengeschichten zwischen Zauberkunst und Wissenschaft", "doi": "https://doi.org/10.14619/017", "publicationDate": "2016-07-14", "place": "L\u00fcneburg, Germany", "contributions": [{"fullName": "Sebastian Vehlken", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 1}, {"fullName": "Jan M\u00fcggenburg", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Katja M\u00fcller-Helle", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Florian Sprenger", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 4}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/oe-case-files/", "imprintId": "39a17f7f-c3f3-4bfe-8c5e-842d53182aad", "imprintName": "\u0152 Case Files", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "a8bf3374-f153-460d-902a-adea7f41d7c7", "fullTitle": "\u0152 Case Files, Vol. 01", "doi": "https://doi.org/10.21983/P3.0354.1.00", "publicationDate": "2021-05-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Simone Ferracina", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/oliphaunt-books/", "imprintId": "353047d8-1ea4-4cc5-bd08-e9cedb4a3e8d", "imprintName": "Oliphaunt Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "0090dbfb-bc8f-44aa-9803-08b277861b14", "fullTitle": "Animal, Vegetable, Mineral: Ethics and Objects", "doi": "https://doi.org/10.21983/P3.0006.1.00", "publicationDate": "2012-05-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "eb8a2862-e812-4730-ab06-8dff1b6208bf", "fullTitle": "Burn after Reading: Vol. 1, Miniature Manifestos for a Post/medieval Studies + Vol. 2, The Future We Want: A Collaboration", "doi": "https://doi.org/10.21983/P3.0067.1.00", "publicationDate": "2014-04-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Myra Seaman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "37cb9bb4-0bb3-4bd3-86ea-d8dfb60c9cd8", "fullTitle": "Inhuman Nature", "doi": "https://doi.org/10.21983/P3.0078.1.00", "publicationDate": "2014-09-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://www.openbookpublishers.com/", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprintName": "Open Book Publishers", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}, "works": [{"workId": "fdeb2a1b-af39-4165-889d-cc7a5a31d5fa", "fullTitle": "Acoustemologies in Contact: Sounding Subjects and Modes of Listening in Early Modernity", "doi": "https://doi.org/10.11647/OBP.0226", "publicationDate": "2021-01-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Emily Wilbourne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Suzanne G. Cusick", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "31aea193-58de-43eb-aadb-23300ba5ee40", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0075", "publicationDate": "2016-01-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fc088d17-bab2-4bfa-90bc-b320760c6c97", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0181", "publicationDate": "2019-10-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b59def35-5712-44ed-8490-9073ab1c6cdc", "fullTitle": "A European Public Investment Outlook", "doi": "https://doi.org/10.11647/OBP.0222", "publicationDate": "2020-06-12", "place": "Cambridge, UK", "contributions": [{"fullName": "Floriana Cerniglia", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Francesco Saraceno", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "528e4526-42e4-4e68-a0d5-f74a285c35a6", "fullTitle": "A Fleet Street In Every Town: The Provincial Press in England, 1855-1900", "doi": "https://doi.org/10.11647/OBP.0152", "publicationDate": "2018-12-13", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Hobbs", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "35941026-43eb-496f-b560-2c21a6dbbbfc", "fullTitle": "Agency: Moral Identity and Free Will", "doi": "https://doi.org/10.11647/OBP.0197", "publicationDate": "2020-04-01", "place": "Cambridge, UK", "contributions": [{"fullName": "David Weissman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3dbfa65a-ed33-46b5-9105-c5694c9c6bab", "fullTitle": "A Handbook and Reader of Ottoman Arabic", "doi": "https://doi.org/10.11647/OBP.0208", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Esther-Miriam Wagner", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0229f930-1e01-40b8-b4a8-03ab57624ced", "fullTitle": "A Lexicon of Medieval Nordic Law", "doi": "https://doi.org/10.11647/OBP.0188", "publicationDate": "2020-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Christine Peel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Jeffrey Love", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Erik Simensen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Inger Larsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ulrika Dj\u00e4rv", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "defda2f0-1003-419a-8c3c-ac8d0b1abd17", "fullTitle": "A Musicology of Performance: Theory and Method Based on Bach's Solos for Violin", "doi": "https://doi.org/10.11647/OBP.0064", "publicationDate": "2015-08-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Dorottya Fabian", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "99af261d-8a31-449e-bf26-20e0178b8ed1", "fullTitle": "An Anglo-Norman Reader", "doi": "https://doi.org/10.11647/OBP.0110", "publicationDate": "2018-02-08", "place": "Cambridge, UK", "contributions": [{"fullName": "Jane Bliss", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0d45084-d852-470d-b9f7-4719304f8a56", "fullTitle": "Animals and Medicine: The Contribution of Animal Experiments to the Control of Disease", "doi": "https://doi.org/10.11647/OBP.0055", "publicationDate": "2015-05-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Jack Botting", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Regina Botting", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Adrian R. Morrison", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "5a597468-a3eb-4026-b29e-eb93b8a7b0d6", "fullTitle": "Annunciations: Sacred Music for the Twenty-First Century", "doi": "https://doi.org/10.11647/OBP.0172", "publicationDate": "2019-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "George Corbett", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "857a5788-a709-4d56-8607-337c1cabd9a2", "fullTitle": "ANZUS and the Early Cold War: Strategy and Diplomacy between Australia, New Zealand and the United States, 1945-1956", "doi": "https://doi.org/10.11647/OBP.0141", "publicationDate": "2018-09-07", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Kelly", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0263f0c-48cd-4923-aef5-1b204636507c", "fullTitle": "A People Passing Rude: British Responses to Russian Culture", "doi": "https://doi.org/10.11647/OBP.0022", "publicationDate": "2012-11-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Anthony Cross", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "69c69fef-ab46-45ab-96d5-d7c4e5d4bce4", "fullTitle": "Arab Media Systems", "doi": "https://doi.org/10.11647/OBP.0238", "publicationDate": "2021-03-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Carola Richter", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Claudia Kozman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1e3ef1d6-a460-4b47-8d14-78c3d18e40c1", "fullTitle": "A Time Travel Dialogue", "doi": "https://doi.org/10.11647/OBP.0043", "publicationDate": "2014-08-01", "place": "Cambridge, UK", "contributions": [{"fullName": "John W. Carroll", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "664931f6-27ca-4409-bb47-5642ca60117e", "fullTitle": "A Victorian Curate: A Study of the Life and Career of the Rev. Dr John Hunt ", "doi": "https://doi.org/10.11647/OBP.0248", "publicationDate": "2021-05-03", "place": "Cambridge, UK", "contributions": [{"fullName": "David Yeandle", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "721fc7c9-7531-40cd-9e59-ab1bef5fc261", "fullTitle": "Basic Knowledge and Conditions on Knowledge", "doi": "https://doi.org/10.11647/OBP.0104", "publicationDate": "2017-10-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Mark McBride", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "39aafd68-dc83-4951-badf-d1f146a38fd4", "fullTitle": "B C, Before Computers: On Information Technology from Writing to the Age of Digital Data", "doi": "https://doi.org/10.11647/OBP.0225", "publicationDate": "2020-10-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Robertson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a373ccbd-0665-4faa-bc24-15542e5cb0cf", "fullTitle": "Behaviour, Development and Evolution", "doi": "https://doi.org/10.11647/OBP.0097", "publicationDate": "2017-02-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Patrick Bateson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "e76e054c-617d-4004-b68d-54739205df8d", "fullTitle": "Beyond Holy Russia: The Life and Times of Stephen Graham", "doi": "https://doi.org/10.11647/OBP.0040", "publicationDate": "2014-02-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Michael Hughes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fe599a6c-ecd8-4ed3-a39e-5778cb9b77da", "fullTitle": "Beyond Price: Essays on Birth and Death", "doi": "https://doi.org/10.11647/OBP.0061", "publicationDate": "2015-10-08", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c7ded4f3-4850-44eb-bd5b-e196a2254d3f", "fullTitle": "Bourdieu and Literature", "doi": "https://doi.org/10.11647/OBP.0027", "publicationDate": "2011-11-30", "place": "Cambridge, UK", "contributions": [{"fullName": "John R.W. Speller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "456b46b9-bbec-4832-95ca-b23dcb975df1", "fullTitle": "Brownshirt Princess: A Study of the 'Nazi Conscience'", "doi": "https://doi.org/10.11647/OBP.0003", "publicationDate": "2009-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Lionel Gossman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1", "fullTitle": "Chronicles from Kashmir: An Annotated, Multimedia Script", "doi": "https://doi.org/10.11647/OBP.0223", "publicationDate": "2020-09-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Nandita Dinesh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c5fe7f09-7dfb-4637-82c8-653a6cb683e7", "fullTitle": "Cicero, Against Verres, 2.1.53\u201386: Latin Text with Introduction, Study Questions, Commentary and English Translation", "doi": "https://doi.org/10.11647/OBP.0016", "publicationDate": "2011-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a03ba4d1-1576-41d0-9e8b-d74eccb682e2", "fullTitle": "Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation", "doi": "https://doi.org/10.11647/OBP.0045", "publicationDate": "2014-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Louise Hodgson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7e753cbc-c74b-4214-a565-2300f544be77", "fullTitle": "Cicero, Philippic 2, 44\u201350, 78\u201392, 100\u2013119: Latin Text, Study Aids with Vocabulary, and Commentary", "doi": "https://doi.org/10.11647/OBP.0156", "publicationDate": "2018-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fd4d3c2a-355f-4bc0-83cb-1cd6764976e7", "fullTitle": "Classical Music: Contemporary Perspectives and Challenges", "doi": "https://doi.org/10.11647/OBP.0242", "publicationDate": "2021-03-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Beckerman Michael", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Boghossian Paul", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "9ea10b68-b23c-4562-b0ca-03ba548889a3", "fullTitle": "Coleridge's Laws: A Study of Coleridge in Malta", "doi": "https://doi.org/10.11647/OBP.0005", "publicationDate": "2010-01-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Barry Hough", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Howard Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Lydia Davis", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Micheal John Kooy", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "98776400-e985-488d-a3f1-9d88879db3cf", "fullTitle": "Complexity, Security and Civil Society in East Asia: Foreign Policies and the Korean Peninsula", "doi": "https://doi.org/10.11647/OBP.0059", "publicationDate": "2015-06-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Kiho Yi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Peter Hayes", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "296c6880-6212-48d2-b327-2c13b6e28d5f", "fullTitle": "Conservation Biology in Sub-Saharan Africa", "doi": "https://doi.org/10.11647/OBP.0177", "publicationDate": "2019-09-08", "place": "Cambridge, UK", "contributions": [{"fullName": "John W. Wilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Richard B. Primack", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "e5ade02a-2f32-495a-b879-98b54df04c0a", "fullTitle": "Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary", "doi": "https://doi.org/10.11647/OBP.0068", "publicationDate": "2015-10-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Bret Mulligan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c86acc9-89a0-4b17-bcdd-520d33fc4f54", "fullTitle": "Creative Multilingualism: A Manifesto", "doi": "https://doi.org/10.11647/OBP.0206", "publicationDate": "2020-05-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Wen-chin Ouyang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Rajinder Dudrah", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Andrew Gosler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Martin Maiden", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Suzanne Graham", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Katrin Kohl", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "10ddfb3d-3434-46f8-a3bb-14dfc0ce9591", "fullTitle": "Cultural Heritage Ethics: Between Theory and Practice", "doi": "https://doi.org/10.11647/OBP.0047", "publicationDate": "2014-10-13", "place": "Cambridge, UK", "contributions": [{"fullName": "Sandis Constantine", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2b031e1a-678b-4dcb-becb-cbd0f0ce9182", "fullTitle": "Deliberation, Representation, Equity: Research Approaches, Tools and Algorithms for Participatory Processes", "doi": "https://doi.org/10.11647/OBP.0108", "publicationDate": "2017-01-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Mats Danielson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Love Ekenberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Karin Hansson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "G\u00f6ran Cars", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "bc253bff-cf00-433d-89a2-031500b888ff", "fullTitle": "Delivering on the Promise of Democracy: Visual Case Studies in Educational Equity and Transformation", "doi": "https://doi.org/10.11647/OBP.0157", "publicationDate": "2019-01-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Sukhwant Jhaj", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "517963d1-a56a-4250-8a07-56743ba60d95", "fullTitle": "Democracy and Power: The Delhi Lectures", "doi": "https://doi.org/10.11647/OBP.0050", "publicationDate": "2014-12-07", "place": "Cambridge, UK", "contributions": [{"fullName": "Noam Chomsky", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jean Dr\u00e8ze", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "60450f84-3e18-4beb-bafe-87c78b5a0159", "fullTitle": "Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition", "doi": "https://doi.org/10.11647/OBP.0098", "publicationDate": "2016-06-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "b3989be1-9115-4635-b766-92f6ebfabef1", "fullTitle": "Denis Diderot's 'Rameau's Nephew': A Multi-media Edition", "doi": "https://doi.org/10.11647/OBP.0044", "publicationDate": "2014-08-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "594ddcb6-2363-47c8-858e-76af2283e486", "fullTitle": "Dickens\u2019s Working Notes for 'Dombey and Son'", "doi": "https://doi.org/10.11647/OBP.0092", "publicationDate": "2017-09-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Tony Laing", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d3adf77-c72b-4b69-bf5a-a042a38a837a", "fullTitle": "Dictionary of the British English Spelling System", "doi": "https://doi.org/10.11647/OBP.0053", "publicationDate": "2015-03-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Greg Brooks", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "364c223d-9c90-4ceb-90e2-51be7d84e923", "fullTitle": "Die Europaidee im Zeitalter der Aufkl\u00e4rung", "doi": "https://doi.org/10.11647/OBP.0127", "publicationDate": "2017-08-21", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d4812e4-c491-4465-8e92-64e4f13662f1", "fullTitle": "Digital Humanities Pedagogy: Practices, Principles and Politics", "doi": "https://doi.org/10.11647/OBP.0024", "publicationDate": "2012-12-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Brett D. Hirsch", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "43d96298-a683-4098-9492-bba1466cb8e0", "fullTitle": "Digital Scholarly Editing: Theories and Practices", "doi": "https://doi.org/10.11647/OBP.0095", "publicationDate": "2016-08-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Elena Pierazzo", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Matthew James Driscoll", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "912c2731-3ca1-4ad9-b601-5d968da6b030", "fullTitle": "Digital Technology and the Practices of Humanities Research", "doi": "https://doi.org/10.11647/OBP.0192", "publicationDate": "2020-01-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Jennifer Edmond", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "78bbcc00-a336-4eb6-b4b5-0c57beec0295", "fullTitle": "Discourses We Live By: Narratives of Educational and Social Endeavour", "doi": "https://doi.org/10.11647/OBP.0203", "publicationDate": "2020-07-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Hazel R. Wright", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marianne H\u00f8yen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1312613f-e01a-499a-b0d0-7289d5b9013d", "fullTitle": "Diversity and Rabbinization: Jewish Texts and Societies between 400 and 1000 CE", "doi": "https://doi.org/10.11647/OBP.0219", "publicationDate": "2021-04-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Gavin McDowell", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Ron Naiweld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel St\u00f6kl Ben Ezra", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "2d74b1a9-c3b0-4278-8cad-856fadc6a19d", "fullTitle": "Don Carlos Infante of Spain: A Dramatic Poem", "doi": "https://doi.org/10.11647/OBP.0134", "publicationDate": "2018-06-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "b190b3c5-88c0-4e4a-939a-26995b7ff95c", "fullTitle": "Earth 2020: An Insider\u2019s Guide to a Rapidly Changing Planet", "doi": "https://doi.org/10.11647/OBP.0193", "publicationDate": "2020-04-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Philippe D. Tortell", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a5e6aa48-02ba-48e4-887f-1c100a532de8", "fullTitle": "Economic Fables", "doi": "https://doi.org/10.11647/OBP.0020", "publicationDate": "2012-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Ariel Rubinstein", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2b63a26d-0db1-4200-983f-8b69d9821d8b", "fullTitle": "Engaging Researchers with Data Management: The Cookbook", "doi": "https://doi.org/10.11647/OBP.0185", "publicationDate": "2019-10-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Yan Wang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "James Savage", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Connie Clare", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marta Teperek", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Maria Cruz", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Elli Papadopoulou", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "af162e8a-23ab-49e6-896d-e53b9d6c0039", "fullTitle": "Essays in Conveyancing and Property Law in Honour of Professor Robert Rennie", "doi": "https://doi.org/10.11647/OBP.0056", "publicationDate": "2015-05-11", "place": "Cambridge, UK", "contributions": [{"fullName": "Frankie McCarthy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Stephen Bogle", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "James Chalmers", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "98d053d6-dcc2-409a-8841-9f19920b49ee", "fullTitle": "Essays in Honour of Eamonn Cantwell: Yeats Annual No. 20", "doi": "https://doi.org/10.11647/OBP.0081", "publicationDate": "2016-12-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Warwick Gould", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "24689aa7-af74-4238-ad75-a9469f094068", "fullTitle": "Essays on Paula Rego: Smile When You Think about Hell", "doi": "https://doi.org/10.11647/OBP.0178", "publicationDate": "2019-09-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Maria Manuel Lisboa", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f76ab190-35f4-4136-86dd-d7fa02ccaebb", "fullTitle": "Ethics for A-Level", "doi": "https://doi.org/10.11647/OBP.0125", "publicationDate": "2017-07-31", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Fisher", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mark Dimmock", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d90e1915-1d2a-40e6-a94c-79f671031224", "fullTitle": "Europa im Geisterkrieg. Studien zu Nietzsche", "doi": "https://doi.org/10.11647/OBP.0133", "publicationDate": "2018-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Werner Stegmaier", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andrea C. Bertino", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "a0a8d5f1-12d0-4d51-973d-ed1dfa73f01f", "fullTitle": "Exploring the Interior: Essays on Literary and Cultural History", "doi": "https://doi.org/10.11647/OBP.0126", "publicationDate": "2018-05-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Karl S. Guthke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3795e166-413c-4568-8c19-1117689ef14b", "fullTitle": "Feeding the City: Work and Food Culture of the Mumbai Dabbawalas", "doi": "https://doi.org/10.11647/OBP.0031", "publicationDate": "2013-07-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Sara Roncaglia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Angela Arnone", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Pier Giorgio Solinas", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "5da7830b-6d55-4eb4-899e-cb2a13b30111", "fullTitle": "Fiesco's Conspiracy at Genoa", "doi": "https://doi.org/10.11647/OBP.0058", "publicationDate": "2015-05-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "John Guthrie", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "83b7409e-f076-4598-965e-9e15615be247", "fullTitle": "Forests and Food: Addressing Hunger and Nutrition Across Sustainable Landscapes", "doi": "https://doi.org/10.11647/OBP.0085", "publicationDate": "2015-11-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Christoph Wildburger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bhaskar Vira", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Stephanie Mansourian", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "1654967f-82f1-4ed0-ae81-7ebbfb9c183d", "fullTitle": "Foundations for Moral Relativism", "doi": "https://doi.org/10.11647/OBP.0029", "publicationDate": "2013-04-17", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "00766beb-0597-48a8-ba70-dd2b8382ec37", "fullTitle": "Foundations for Moral Relativism: Second Expanded Edition", "doi": "https://doi.org/10.11647/OBP.0086", "publicationDate": "2015-11-23", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3083819d-1084-418a-85d4-4f71c2fea139", "fullTitle": "From Darkness to Light: Writers in Museums 1798-1898", "doi": "https://doi.org/10.11647/OBP.0151", "publicationDate": "2019-03-12", "place": "Cambridge, UK", "contributions": [{"fullName": "Rosella Mamoli Zorzi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Katherine Manthorne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5bf6450f-99a7-4375-ad94-d5bde1b0282c", "fullTitle": "From Dust to Digital: Ten Years of the Endangered Archives Programme", "doi": "https://doi.org/10.11647/OBP.0052", "publicationDate": "2015-02-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Maja Kominko", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d16896b7-691e-4620-9adb-1d7a42c69bde", "fullTitle": "From Goethe to Gundolf: Essays on German Literature and Culture", "doi": "https://doi.org/10.11647/OBP.0258", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Roger Paulin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3a167e24-36b5-4d0e-b55f-af6be9a7c827", "fullTitle": "Frontier Encounters: Knowledge and Practice at the Russian, Chinese and Mongolian Border", "doi": "https://doi.org/10.11647/OBP.0026", "publicationDate": "2012-08-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Gr\u00e9gory Delaplace", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Caroline Humphrey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Franck Bill\u00e9", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1471f4c3-a88c-4301-b98a-7193be6dde4b", "fullTitle": "Gallucci's Commentary on D\u00fcrer\u2019s 'Four Books on Human Proportion': Renaissance Proportion Theory", "doi": "https://doi.org/10.11647/OBP.0198", "publicationDate": "2020-03-25", "place": "Cambridge, UK", "contributions": [{"fullName": "James Hutson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "101eb7c2-f15f-41f9-b53a-dfccd4b28301", "fullTitle": "Global Warming in Local Discourses: How Communities around the World Make Sense of Climate Change", "doi": "https://doi.org/10.11647/OBP.0212", "publicationDate": "2020-10-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Michael Br\u00fcggemann", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Simone R\u00f6dder", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "32e99c61-2352-4a88-bb9a-bd81f113ba1e", "fullTitle": "God's Babies: Natalism and Bible Interpretation in Modern America", "doi": "https://doi.org/10.11647/OBP.0048", "publicationDate": "2014-12-17", "place": "Cambridge, UK", "contributions": [{"fullName": "John McKeown", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ab3a9d7f-c9b9-42bf-9942-45f68b40bcd6", "fullTitle": "Hanging on to the Edges: Essays on Science, Society and the Academic Life", "doi": "https://doi.org/10.11647/OBP.0155", "publicationDate": "2018-10-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Daniel Nettle", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9d5ac1c6-a763-49b4-98b2-355d888169be", "fullTitle": "Henry James's Europe: Heritage and Transfer", "doi": "https://doi.org/10.11647/OBP.0013", "publicationDate": "2011-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Adrian Harding", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Annick Duperray", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dennis Tredy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b7790cae-1901-446e-b529-b5fe393d8061", "fullTitle": "History of International Relations: A Non-European Perspective", "doi": "https://doi.org/10.11647/OBP.0074", "publicationDate": "2019-07-31", "place": "Cambridge, UK", "contributions": [{"fullName": "Erik Ringmar", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7b9b68c6-8bb6-42c5-8b19-bf5e56b7293e", "fullTitle": "How to Read a Folktale: The 'Ibonia' Epic from Madagascar", "doi": "https://doi.org/10.11647/OBP.0034", "publicationDate": "2013-10-08", "place": "Cambridge, UK", "contributions": [{"fullName": "Lee Haring", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "23651a20-a26e-4253-b0a9-c8b5bf1409c7", "fullTitle": "Human and Machine Consciousness", "doi": "https://doi.org/10.11647/OBP.0107", "publicationDate": "2018-03-07", "place": "Cambridge, UK", "contributions": [{"fullName": "David Gamez", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "27def25d-48ad-470d-9fbe-1ddc8376e1cb", "fullTitle": "Human Cultures through the Scientific Lens: Essays in Evolutionary Cognitive Anthropology", "doi": "https://doi.org/10.11647/OBP.0257", "publicationDate": "2021-07-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Pascal Boyer", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "859a1313-7b02-4c66-8010-dbe533c4412a", "fullTitle": "Hyperion or the Hermit in Greece", "doi": "https://doi.org/10.11647/OBP.0160", "publicationDate": "2019-02-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Howard Gaskill", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1f591391-7497-4447-8c06-d25006a1b922", "fullTitle": "Image, Knife, and Gluepot: Early Assemblage in Manuscript and Print", "doi": "https://doi.org/10.11647/OBP.0145", "publicationDate": "2019-07-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Kathryn M. Rudy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "50516c2a-154e-4758-9b94-586987af2b7f", "fullTitle": "Information and Empire: Mechanisms of Communication in Russia, 1600-1854", "doi": "https://doi.org/10.11647/OBP.0122", "publicationDate": "2017-11-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Katherine Bowers", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Simon Franklin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1549f31d-4783-4a63-a050-90ffafd77328", "fullTitle": "Infrastructure Investment in Indonesia: A Focus on Ports", "doi": "https://doi.org/10.11647/OBP.0189", "publicationDate": "2019-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Colin Duffield", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Felix Kin Peng Hui", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Sally Wilson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "1692a92d-f86a-4155-9e6c-16f38586b7fc", "fullTitle": "Intellectual Property and Public Health in the Developing World", "doi": "https://doi.org/10.11647/OBP.0093", "publicationDate": "2016-05-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Monirul Azam", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d6850e99-33ce-4cae-ac7c-bd82cf23432b", "fullTitle": "In the Lands of the Romanovs: An Annotated Bibliography of First-hand English-language Accounts of the Russian Empire (1613-1917)", "doi": "https://doi.org/10.11647/OBP.0042", "publicationDate": "2014-04-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Anthony Cross", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4455a769-d374-4eed-8e6a-84c220757c0d", "fullTitle": "Introducing Vigilant Audiences", "doi": "https://doi.org/10.11647/OBP.0200", "publicationDate": "2020-10-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Rashid Gabdulhakov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel Trottier", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Qian Huang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "e414ca1b-a7f2-48c7-9adb-549a04711241", "fullTitle": "Inventory Analytics", "doi": "https://doi.org/10.11647/OBP.0252", "publicationDate": "2021-05-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Roberto Rossi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ad55c2c5-9769-4648-9c42-dc4cef1f1c99", "fullTitle": "Is Behavioral Economics Doomed? The Ordinary versus the Extraordinary", "doi": "https://doi.org/10.11647/OBP.0021", "publicationDate": "2012-09-17", "place": "Cambridge, UK", "contributions": [{"fullName": "David K. Levine", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2ceb72f2-ddde-45a7-84a9-27523849f8f5", "fullTitle": "Jane Austen: Reflections of a Reader", "doi": "https://doi.org/10.11647/OBP.0216", "publicationDate": "2021-02-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Nora Bartlett", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jane Stabler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5b542db8-c128-48ff-a48c-003c95eaca25", "fullTitle": "Jewish-Muslim Intellectual History Entangled: Textual Materials from the Firkovitch Collection, Saint Petersburg", "doi": "https://doi.org/10.11647/OBP.0214", "publicationDate": "2020-08-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Jan Thiele", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Wilferd Madelung", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Omar Hamdan", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Adang Camilla", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sabine Schmidtke", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Bruno Chiesa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "df7eb598-914a-49eb-9cbd-9766bd06be84", "fullTitle": "Just Managing? What it Means for the Families of Austerity Britain", "doi": "https://doi.org/10.11647/OBP.0112", "publicationDate": "2017-05-29", "place": "Cambridge, UK", "contributions": [{"fullName": "Paul Kyprianou", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mark O'Brien", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c5e415c4-1ed1-4c58-abae-b1476689a867", "fullTitle": "Knowledge and the Norm of Assertion: An Essay in Philosophical Science", "doi": "https://doi.org/10.11647/OBP.0083", "publicationDate": "2016-02-26", "place": "Cambridge, UK", "contributions": [{"fullName": "John Turri", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9fc774fa-3a18-42d8-89e3-b5a23d822dd6", "fullTitle": "Labor and Value: Rethinking Marx\u2019s Theory of Exploitation", "doi": "https://doi.org/10.11647/OBP.0182", "publicationDate": "2019-10-02", "place": "Cambridge, UK", "contributions": [{"fullName": "Ernesto Screpanti", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "29e28ee7-c52d-43f3-95da-f99f33f0e737", "fullTitle": "Les Bienveillantes de Jonathan Littell: \u00c9tudes r\u00e9unies par Murielle Lucie Cl\u00e9ment", "doi": "https://doi.org/10.11647/OBP.0006", "publicationDate": "2010-04-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Murielle Lucie Cl\u00e9ment", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d9e671dd-ab2a-4fd0-ada3-4925449a63a8", "fullTitle": "Letters of Blood and Other Works in English", "doi": "https://doi.org/10.11647/OBP.0017", "publicationDate": "2011-11-30", "place": "Cambridge, UK", "contributions": [{"fullName": "G\u00f6ran Printz-P\u00e5hlson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Robert Archambeau", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Elinor Shaffer", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Lars-H\u00e5kan Svensson", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "c699f257-f3e4-4c98-9a3f-741c6a40b62a", "fullTitle": "L\u2019id\u00e9e de l\u2019Europe: au Si\u00e8cle des Lumi\u00e8res", "doi": "https://doi.org/10.11647/OBP.0116", "publicationDate": "2017-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "a795aafb-d189-4d15-8e64-b9a3fbfa8e09", "fullTitle": "Life Histories of Etnos Theory in Russia and Beyond", "doi": "https://doi.org/10.11647/OBP.0150", "publicationDate": "2019-02-06", "place": "Cambridge, UK", "contributions": [{"fullName": "Dmitry V Arzyutov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "David G. Anderson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sergei S. Alymov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "5c55effb-2a3e-4e0d-a46d-edad7830fd8e", "fullTitle": "Lifestyle in Siberia and the Russian North", "doi": "https://doi.org/10.11647/OBP.0171", "publicationDate": "2019-11-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Joachim Otto Habeck", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6090bfc8-3143-4599-b0dd-17705f754e8c", "fullTitle": "Like Nobody's Business: An Insider's Guide to How US University Finances Really Work", "doi": "https://doi.org/10.11647/OBP.0240", "publicationDate": "2021-02-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew C. Comrie", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "25a2f70a-832d-4c8d-b28f-75f838b6e171", "fullTitle": "Liminal Spaces: Migration and Women of the Guyanese Diaspora", "doi": "https://doi.org/10.11647/OBP.0218", "publicationDate": "2020-09-29", "place": "Cambridge, UK", "contributions": [{"fullName": "Grace Aneiza Ali", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9845c8a9-b283-4cb8-8961-d41e5fe795f1", "fullTitle": "Literature Against Criticism: University English and Contemporary Fiction in Conflict", "doi": "https://doi.org/10.11647/OBP.0102", "publicationDate": "2016-10-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Martin Paul Eve", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f957ab3d-c925-4bf2-82fa-9809007753e7", "fullTitle": "Living Earth Community: Multiple Ways of Being and Knowing", "doi": "https://doi.org/10.11647/OBP.0186", "publicationDate": "2020-05-07", "place": "Cambridge, UK", "contributions": [{"fullName": "John Grim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Mary Evelyn Tucker", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Sam Mickey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "545f9f42-87c0-415e-9086-eee27925c85b", "fullTitle": "Long Narrative Songs from the Mongghul of Northeast Tibet: Texts in Mongghul, Chinese, and English", "doi": "https://doi.org/10.11647/OBP.0124", "publicationDate": "2017-10-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Gerald Roche", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Li Dechun", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/peanut-books/", "imprintId": "5cc7d3db-f300-4813-9c68-3ccc18a6277b", "imprintName": "Peanut Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "14a2356a-4767-4136-b44a-684a28dc87a6", "fullTitle": "In a Trance: On Paleo Art", "doi": "https://doi.org/10.21983/P3.0081.1.00", "publicationDate": "2014-11-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Skoblow", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "200b11a8-57d6-4f81-b089-ddd4ee7fe2f2", "fullTitle": "The Apartment of Tragic Appliances: Poems", "doi": "https://doi.org/10.21983/P3.0030.1.00", "publicationDate": "2013-05-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael D. Snediker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "49ebcb4a-928f-4d83-9596-b296dfce0b20", "fullTitle": "The Petroleum Manga: A Project by Marina Zurkow", "doi": "https://doi.org/10.21983/P3.0062.1.00", "publicationDate": "2014-02-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marina Zurkow", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2a360648-3157-4a1b-9ba7-a61895a8a10c", "fullTitle": "Where the Tiny Things Are: Feathered Essays", "doi": "https://doi.org/10.21983/P3.0181.1.00", "publicationDate": "2017-09-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nicole Walker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/", "imprintId": "7522e351-8a91-40fa-bf45-02cb38368b0b", "imprintName": "punctum books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "5402ea62-7a1b-48b4-b5fb-7b114c04bc27", "fullTitle": "A Boy Asleep under the Sun: Versions of Sandro Penna", "doi": "https://doi.org/10.21983/P3.0080.1.00", "publicationDate": "2014-11-11", "place": "Brooklyn, NY", "contributions": [{"fullName": "Sandro Penna", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Peter Valente", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Peter Valente", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "8a27431b-b1f9-4fed-a8e0-0a0aadc9d98c", "fullTitle": "A Buddha Land in This World: Philosophy, Utopia, and Radical Buddhism", "doi": "https://doi.org/10.53288/0373.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Lajos Brons", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "eeb920c0-6f2e-462c-a315-3687b5ca8da3", "fullTitle": "Action [poems]", "doi": "https://doi.org/10.21983/P3.0083.1.00", "publicationDate": "2014-12-10", "place": "Brooklyn, NY", "contributions": [{"fullName": "Anthony Opal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "20dab41d-2267-4a68-befa-d787b7c98599", "fullTitle": "After the \"Speculative Turn\": Realism, Philosophy, and Feminism", "doi": "https://doi.org/10.21983/P3.0152.1.00", "publicationDate": "2016-10-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katerina Kolozova", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13a03c11-0f22-4d40-881d-b935452d4bf3", "fullTitle": "Air Supplied", "doi": "https://doi.org/10.21983/P3.0201.1.00", "publicationDate": "2018-05-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "David Cross", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5147a952-3d44-4beb-8d49-b41c91bce733", "fullTitle": "Alternative Historiographies of the Digital Humanities", "doi": "https://doi.org/10.53288/0274.1.00", "publicationDate": "2021-06-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adeline Koh", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dorothy Kim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f712541c-07b4-477c-8b8c-8c1a307810d0", "fullTitle": "And Another Thing: Nonanthropocentrism and Art", "doi": "https://doi.org/10.21983/P3.0144.1.00", "publicationDate": "2016-06-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Katherine Behar", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Emmy Mikelson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "27e17948-02c4-4ba3-8244-5c229cc8e9b8", "fullTitle": "Anglo-Saxon(ist) Pasts, postSaxon Futures", "doi": "https://doi.org/10.21983/P3.0262.1.00", "publicationDate": "2019-12-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Donna-Beth Ellard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f3c9e9d8-9a38-4558-be2e-cab9a70d62f0", "fullTitle": "Annotations to Geoffrey Hill's Speech! Speech!", "doi": "https://doi.org/10.21983/P3.0004.1.00", "publicationDate": "2012-01-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Ann Hassan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "baf524c6-0a2c-40f2-90a7-e19c6e1b6b97", "fullTitle": "Anthropocene Unseen: A Lexicon", "doi": "https://doi.org/10.21983/P3.0265.1.00", "publicationDate": "2020-02-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Cymene Howe", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anand Pandian", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f6afff19-25ae-41f8-8a7a-6c1acffafc39", "fullTitle": "Antiracism Inc.: Why the Way We Talk about Racial Justice Matters", "doi": "https://doi.org/10.21983/P3.0250.1.00", "publicationDate": "2019-04-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Paula Ioanide", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alison Reed", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Felice Blake", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "88c47bd3-f8c9-4157-9d1a-770d9be8c173", "fullTitle": "A Nuclear Refrain: Emotion, Empire, and the Democratic Potential of Protest", "doi": "https://doi.org/10.21983/P3.0271.1.00", "publicationDate": "2019-12-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kye Askins", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Phil Johnstone", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kelvin Mason", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "41508a3c-614b-473e-aa74-edcb6b09dc9d", "fullTitle": "Ardea: A Philosophical Novella", "doi": "https://doi.org/10.21983/P3.0147.1.00", "publicationDate": "2016-07-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Freya Mathews", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ae9f8357-4b39-4809-a8e9-766e200fb937", "fullTitle": "A Rushed Quality", "doi": "https://doi.org/10.21983/P3.0103.1.00", "publicationDate": "2015-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Odell", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3f78b298-8826-4162-886e-af21a77f2957", "fullTitle": "Athens and the War on Public Space: Tracing a City in Crisis", "doi": "https://doi.org/10.21983/P3.0199.1.00", "publicationDate": "2018-04-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christos Filippidis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Klara Jaya Brekke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Antonis Vradis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "3da27fb9-7a15-446e-ae0f-258c7dd4fd94", "fullTitle": "Barton Myers: Works of Architecture and Urbanism", "doi": "https://doi.org/10.21983/P3.0249.1.00", "publicationDate": "2019-07-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kris Miller-Fisher", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jocelyn Gibbs", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f4d42680-8b02-4e3a-9ec8-44aee852b29f", "fullTitle": "Bathroom Songs: Eve Kosofsky Sedgwick as a Poet", "doi": "https://doi.org/10.21983/P3.0189.1.00", "publicationDate": "2017-11-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jason Edwards", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "637566b3-dca3-4a8b-b5bd-01fcbb77ca09", "fullTitle": "Beowulf: A Translation", "doi": "https://doi.org/10.21983/P3.0009.1.00", "publicationDate": "2012-08-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Hadbawnik", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Thomas Meyer", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel C. Remein", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "David Hadbawnik", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "9bae1a52-f764-417d-9d45-4df12f71cf07", "fullTitle": "Beowulf by All", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Elaine Treharne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jean Abbott", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mateusz Fafinski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "a2ce9f9c-f594-4165-83be-e3751d4d17fe", "fullTitle": "Beta Exercise: The Theory and Practice of Osamu Kanemura", "doi": "https://doi.org/10.21983/P3.0241.1.00", "publicationDate": "2019-01-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "Osamu Kanemura", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Marco Mazzi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Nicholas Marshall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Michiyo Miyake", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "735d8962-5ec7-41ce-a73a-a43c35cc354f", "fullTitle": "Between Species/Between Spaces: Art and Science on the Outer Cape", "doi": "https://doi.org/10.21983/P3.0325.1.00", "publicationDate": "2020-08-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dylan Gauthier", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kendra Sullivan", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a871cb31-e158-401d-a639-3767131c0f34", "fullTitle": "Bigger Than You: Big Data and Obesity", "doi": "https://doi.org/10.21983/P3.0135.1.00", "publicationDate": "2016-03-03", "place": "Earth, Milky Way", "contributions": [{"fullName": "Katherine Behar", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "940d0880-83b5-499d-9f39-1bf30ccfc4d0", "fullTitle": "Book of Anonymity", "doi": "https://doi.org/10.21983/P3.0315.1.00", "publicationDate": "2021-03-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anon Collective", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "006571ae-ac0e-4cb0-8a3f-71280aa7f23b", "fullTitle": "Broken Records", "doi": "https://doi.org/10.21983/P3.0137.1.00", "publicationDate": "2016-03-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sne\u017eana \u017dabi\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "47c71c05-a4f1-48da-b8d5-9e5ba139a8ea", "fullTitle": "Building Black: Towards Antiracist Architecture", "doi": "https://doi.org/10.21983/P3.0372.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Elliot C. Mason", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "dd9008ae-0172-4e07-b3cf-50c35c51b606", "fullTitle": "Bullied: The Story of an Abuse", "doi": "https://doi.org/10.21983/P3.0356.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "46344fe3-1d72-4ddd-a57e-1d3f4377d2a2", "fullTitle": "Centaurs, Rioting in Thessaly: Memory and the Classical World", "doi": "https://doi.org/10.21983/P3.0192.1.00", "publicationDate": "2018-01-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Martyn Hudson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7f1d3e2e-c708-4f59-81cf-104c1ca528d0", "fullTitle": "Chaste Cinematics", "doi": "https://doi.org/10.21983/P3.0117.1.00", "publicationDate": "2015-10-31", "place": "Brooklyn, NY", "contributions": [{"fullName": "Victor J. Vitanza", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b2d1b2e3-226e-43c2-a898-fbad7b410e3f", "fullTitle": "Christina McPhee: A Commonplace Book", "doi": "https://doi.org/10.21983/P3.0186.1.00", "publicationDate": "2017-10-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "45aa16fa-5fd5-4449-a3bd-52d734fcb0a9", "fullTitle": "Cinema's Doppelg\u00e4ngers\n", "doi": "https://doi.org/10.53288/0320.1.00", "publicationDate": "2021-06-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Doug Dibbern", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "84447325-88e2-4658-8597-3f2329451156", "fullTitle": "Clinical Encounters in Sexuality: Psychoanalytic Practice and Queer Theory", "doi": "https://doi.org/10.21983/P3.0167.1.00", "publicationDate": "2017-03-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eve Watson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Noreen Giffney", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d0430e3-3640-4d87-8f02-cbb45f6ae83b", "fullTitle": "Comic Providence", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Janet Thormann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0ff62120-4478-46dc-8d01-1d7e1dc5b7a6", "fullTitle": "Commonist Tendencies: Mutual Aid beyond Communism", "doi": "https://doi.org/10.21983/P3.0040.1.00", "publicationDate": "2013-07-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea", "doi": "https://doi.org/10.21983/P3.0269.1.00", "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "93330f65-a84f-4c5c-aa44-f710c714eca2", "fullTitle": "Continent. Year 1: A Selection of Issues 1.1\u20131.4", "doi": "https://doi.org/10.21983/P3.0016.1.00", "publicationDate": "2012-12-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Adam Staley Groves", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Paul Boshears", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Jamie Allen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3d78e15e-19cb-464a-a238-b5291dbfd49f", "fullTitle": "Creep: A Life, A Theory, An Apology", "doi": "https://doi.org/10.21983/P3.0178.1.00", "publicationDate": "2017-08-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f2a2626b-4029-4e43-bb84-7b3cacf61b23", "fullTitle": "Crisis States: Governance, Resistance & Precarious Capitalism", "doi": "https://doi.org/10.21983/P3.0146.1.00", "publicationDate": "2016-07-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "639a3c5b-82ad-4557-897b-2bfebe3dc53c", "fullTitle": "Critique of Sovereignty, Book 1: Contemporary Theories of Sovereignty", "doi": "https://doi.org/10.21983/P3.0114.1.00", "publicationDate": "2015-09-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marc Lombardo", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f37627c1-d89f-434c-9915-f1f2f33dc037", "fullTitle": "Crush", "doi": "https://doi.org/10.21983/P3.0063.1.00", "publicationDate": "2014-02-27", "place": "Brooklyn, NY", "contributions": [{"fullName": "Will Stockton", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "D. Gilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "43355368-b29b-4fa1-9ed6-780f4983364a", "fullTitle": "Damayanti and Nala's Tale", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Dan Rudmann", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "11749800-364e-4a27-bf79-9f0ceeacb4d6", "fullTitle": "Dark Chaucer: An Assortment", "doi": "https://doi.org/10.21983/P3.0018.1.00", "publicationDate": "2012-12-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nicola Masciandaro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Myra Seaman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "7fe2c6dc-6673-4537-a397-1f0377c2296f", "fullTitle": "Dear Professor: A Chronicle of Absences", "doi": "https://doi.org/10.21983/P3.0160.1.00", "publicationDate": "2016-12-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Filip Noterdaeme", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Shuki Cohen", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "0985e294-aa85-40d0-90ce-af53ae37898d", "fullTitle": "Deleuze and the Passions", "doi": "https://doi.org/10.21983/P3.0161.1.00", "publicationDate": "2016-12-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sjoerd van Tuinen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ceciel Meiborg", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9e6bb4d8-4e05-4cd7-abe9-4a795ade0340", "fullTitle": "Derrida and Queer Theory", "doi": "https://doi.org/10.21983/P3.0172.1.00", "publicationDate": "2017-05-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christian Hite", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9e11adff-abed-4b5d-adef-b0c4466231e8", "fullTitle": "Desire/Love", "doi": "https://doi.org/10.21983/P3.0015.1.00", "publicationDate": "2012-12-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Lauren Berlant", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6141d35a-a5a6-43ee-b6b6-5caa41bce869", "fullTitle": "Desire/Love", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Lauren Berlant", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13c12944-701a-41f4-9d85-c753267d564b", "fullTitle": "Destroyer of Naivet\u00e9s", "doi": "https://doi.org/10.21983/P3.0118.1.00", "publicationDate": "2015-11-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Joseph Nechvatal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "69c890c5-d8c5-4295-b5a7-688560929d8b", "fullTitle": "Dialectics Unbound: On the Possibility of Total Writing", "doi": "https://doi.org/10.21983/P3.0041.1.00", "publicationDate": "2013-07-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Maxwell Kennel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "25be3523-34b5-43c9-a3e2-b12ffb859025", "fullTitle": "Dire Pessimism: An Essay", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Thomas Carl Wall", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "245c521a-5014-4da0-bf2b-35eff9673367", "fullTitle": "dis/cord: Thinking Sound through Agential Realism", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Kevin Toks\u00f6z Fairbarn", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "488c640d-e742-465a-98b4-1234bb09d038", "fullTitle": "Diseases of the Head: Essays on the Horrors of Speculative Philosophy", "doi": "https://doi.org/10.21983/P3.0280.1.00", "publicationDate": "2020-09-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Matt Rosen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "754c1299-9b8d-41ac-a1d6-534f174fa87b", "fullTitle": "Disturbing Times: Medieval Pasts, Reimagined Futures", "doi": "https://doi.org/10.21983/P3.0313.1.00", "publicationDate": "2020-06-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Anna K\u0142osowska", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Catherine E. Karkov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "438e0846-b4b9-4c84-9545-d7a6fb13e996", "fullTitle": "Divine Name Verification: An Essay on Anti-Darwinism, Intelligent Design, and the Computational Nature of Reality", "doi": "https://doi.org/10.21983/P3.0043.1.00", "publicationDate": "2013-08-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Noah Horwitz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9d1f849d-cf0f-4d0c-8dab-8819fad00337", "fullTitle": "Dollar Theater Theory", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Trevor Owen Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cd037a39-f6b9-462a-a207-5079a000065b", "fullTitle": "Dotawo: A Journal of Nubian Studies 1", "doi": "https://doi.org/10.21983/P3.0071.1.00", "publicationDate": "2014-06-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Angelika Jakobi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "6092f859-05fe-475d-b914-3c1a6534e6b9", "fullTitle": "Down to Earth: A Memoir", "doi": "https://doi.org/10.21983/P3.0306.1.00", "publicationDate": "2020-10-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "G\u00edsli P\u00e1lsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna Yates", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrina Downs-Rose", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "ac6acc15-6927-4cef-95d3-1c71183ef2a6", "fullTitle": "Echoes of No Thing: Thinking between Heidegger and D\u014dgen", "doi": "https://doi.org/10.21983/P3.0239.1.00", "publicationDate": "2019-01-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2658fe95-2df3-4e7d-8df6-e86c18359a23", "fullTitle": "Ephemeral Coast, S. Wales", "doi": "https://doi.org/10.21983/P3.0079.1.00", "publicationDate": "2014-11-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Celina Jeffery", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "98ce9caa-487e-4391-86c9-e5d8129be5b6", "fullTitle": "Essays on the Peripheries", "doi": "https://doi.org/10.21983/P3.0291.1.00", "publicationDate": "2021-04-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Peter Valente", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "19b32470-bf29-48e1-99db-c08ef90516a9", "fullTitle": "Everyday Cinema: The Films of Marc Lafia", "doi": "https://doi.org/10.21983/P3.0164.1.00", "publicationDate": "2017-01-31", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc Lafia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "859e72c3-8159-48e4-b2f0-842f3400cb8d", "fullTitle": "Extraterritorialities in Occupied Worlds", "doi": "https://doi.org/10.21983/P3.0131.1.00", "publicationDate": "2016-02-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ruti Sela Maayan Amir", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1b870455-0b99-4d0e-af22-49f4ebbb6493", "fullTitle": "Finding Room in Beirut: Places of the Everyday", "doi": "https://doi.org/10.21983/P3.0243.1.00", "publicationDate": "2019-02-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Carole L\u00e9vesque", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6ca16a49-7c95-4c81-b8f0-8f3c7e42de7d", "fullTitle": "Flash + Cube (1965\u20131975)", "doi": "https://doi.org/10.21983/P3.0036.1.00", "publicationDate": "2013-07-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marget Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7fbc96cf-4c88-4e70-b1fe-d4e69324184a", "fullTitle": "Flash + Cube (1965\u20131975)", "doi": null, "publicationDate": "2012-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marget Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f4a04558-958a-43da-b009-d5b7580c532f", "fullTitle": "Follow for Now, Volume 2: More Interviews with Friends and Heroes", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Roy Christopher", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97a2ac65-5b1b-4ab8-8588-db8340f04d27", "fullTitle": "Fuckhead", "doi": "https://doi.org/10.21983/P3.0048.1.00", "publicationDate": "2013-09-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Rawson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f3294e78-9a12-49ff-983e-ed6154ff621e", "fullTitle": "Gender Trouble Couplets, Volume 1", "doi": "https://doi.org/10.21983/P3.0266.1.00", "publicationDate": "2019-11-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "A.W. Strouse", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna M. K\u0142osowska", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "c80467d8-d472-4643-9a50-4ac489da14dd", "fullTitle": "Geographies of Identity", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jill Darling", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "bbe77bbb-0242-46d7-92d2-cfd35c17fe8f", "fullTitle": "Heathen Earth: Trumpism and Political Ecology", "doi": "https://doi.org/10.21983/P3.0170.1.00", "publicationDate": "2017-05-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kyle McGee", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "875a78d7-fad2-4c22-bb04-35e0456b6efa", "fullTitle": "Heavy Processing (More than a Feeling)", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "T.L. Cowan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jasmine Rault", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7f72c34d-4515-42eb-a32e-38fe74217b70", "fullTitle": "Hephaestus Reloaded: Composed for Ten Hands / Efesto Reloaded: Composizioni per 10 mani", "doi": "https://doi.org/10.21983/P3.0258.1.00", "publicationDate": "2019-12-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Berg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Brunella Antomarini", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Miltos Maneta", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Vladimir D\u2019Amora", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pietro Traversa", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 8}, {"fullName": "Patrick Camiller", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 7}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 6}]}, {"workId": "b63ffeb5-7906-4c74-8ec2-68cbe87f593c", "fullTitle": "History According to Cattle", "doi": "https://doi.org/10.21983/P3.0116.1.00", "publicationDate": "2015-10-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Terike Haapoja", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Laura Gustafsson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4f46d026-49c6-4319-b79a-a6f70d412b5c", "fullTitle": "Homotopia? Gay Identity, Sameness & the Politics of Desire", "doi": "https://doi.org/10.21983/P3.0124.1.00", "publicationDate": "2015-12-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jonathan Kemp", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0257269-5ca3-40b3-b4e1-90f66baddb88", "fullTitle": "Humid, All Too Humid: Overheated Observations", "doi": "https://doi.org/10.21983/P3.0132.1.00", "publicationDate": "2016-02-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dominic Pettman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "241f9c62-26be-4d0f-864b-ad4b243a03c3", "fullTitle": "Imperial Physique", "doi": "https://doi.org/10.21983/P3.0268.1.00", "publicationDate": "2019-11-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "JH Phrydas", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aeed0683-e022-42d0-a954-f9f36afc4bbf", "fullTitle": "Incomparable Poetry: An Essay on the Financial Crisis of 2007\u20132008 and Irish Literature", "doi": "https://doi.org/10.21983/P3.0286.1.00", "publicationDate": "2020-05-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Robert Kiely", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5ec826f5-18ab-498c-8b66-bd288618df15", "fullTitle": "Insurrectionary Infrastructures", "doi": "https://doi.org/10.21983/P3.0200.1.00", "publicationDate": "2018-05-02", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "89990379-94c2-4590-9037-cbd5052694a4", "fullTitle": "Intimate Bureaucracies", "doi": "https://doi.org/10.21983/P3.0005.1.00", "publicationDate": "2012-03-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "dj readies", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "85a2a2fe-d515-4784-b451-d26ec4c62a4f", "fullTitle": "Iteration:Again: 13 Public Art Projects across Tasmania", "doi": "https://doi.org/10.21983/P3.0037.1.00", "publicationDate": "2013-07-02", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Cross", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael Edwards", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "f3db2a03-75db-4837-af31-4bb0cb189fa2", "fullTitle": "Itinerant Philosophy: On Alphonso Lingis", "doi": "https://doi.org/10.21983/P3.0073.1.00", "publicationDate": "2014-08-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Tom Sparrow", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bobby George", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1376b0f4-e967-4a6f-8d7d-8ba876bbbdde", "fullTitle": "Itinerant Spectator/Itinerant Spectacle", "doi": "https://doi.org/10.21983/P3.0056.1.00", "publicationDate": "2013-12-20", "place": "Brooklyn, NY", "contributions": [{"fullName": "P.A. Skantze", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "da814d9f-14ff-4660-acfe-52ac2a2058fa", "fullTitle": "Journal of Badiou Studies 3: On Ethics", "doi": "https://doi.org/10.21983/P3.0070.1.00", "publicationDate": "2014-06-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Arthur Rose", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Nicol\u00f2 Fazioni", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7e2e26fd-4b0b-4c0b-a1fa-278524c43757", "fullTitle": "Journal of Badiou Studies 5: Architheater", "doi": "https://doi.org/10.21983/P3.0173.1.00", "publicationDate": "2017-07-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Arthur Rose", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adi Efal-Lautenschl\u00e4ger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "d2e40ec1-5c2a-404d-8e9f-6727c7c178dc", "fullTitle": "Kill Boxes: Facing the Legacy of US-Sponsored Torture, Indefinite Detention, and Drone Warfare", "doi": "https://doi.org/10.21983/P3.0166.1.00", "publicationDate": "2017-03-02", "place": "Earth, Milky Way", "contributions": [{"fullName": "Elisabeth Weber", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Richard Falk", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "75693fd0-e93a-4fc3-b82e-4c83a11f28b1", "fullTitle": "Knocking the Hustle: Against the Neoliberal Turn in Black Politics", "doi": "https://doi.org/10.21983/P3.0121.1.00", "publicationDate": "2015-12-10", "place": "Brooklyn, NY", "contributions": [{"fullName": "Lester K. Spence", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed3ea389-5d5c-430c-9453-814ed94e027b", "fullTitle": "Knowledge, Spirit, Law, Book 1: Radical Scholarship", "doi": "https://doi.org/10.21983/P3.0123.1.00", "publicationDate": "2015-12-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Gavin Keeney", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d0d59741-4866-42c3-8528-f65c3da3ffdd", "fullTitle": "Language Parasites: Of Phorontology", "doi": "https://doi.org/10.21983/P3.0169.1.00", "publicationDate": "2017-05-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sean Braune", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1a71ecd5-c868-44af-9b53-b45888fb241c", "fullTitle": "Lapidari 1: Texts", "doi": "https://doi.org/10.21983/P3.0094.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonida Gashi", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "df518095-84ff-4138-b2f9-5d8fe6ddf53a", "fullTitle": "Lapidari 2: Images, Part I", "doi": "https://doi.org/10.21983/P3.0091.1.00", "publicationDate": "2015-02-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "a9d68f12-1de4-4c08-84b1-fe9a786ab47f", "fullTitle": "Lapidari 3: Images, Part II", "doi": "https://doi.org/10.21983/P3.0092.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "08788fe1-c17d-4f6b-aeab-c81aa3036940", "fullTitle": "Left Bank Dream", "doi": "https://doi.org/10.21983/P3.0084.1.00", "publicationDate": "2014-12-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Beryl Scholssman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b4d68a6d-01fb-48f1-9f64-1fcdaaf1cdfd", "fullTitle": "Leper Creativity: Cyclonopedia Symposium", "doi": "https://doi.org/10.21983/P3.0017.1.00", "publicationDate": "2012-12-22", "place": "Brooklyn, NY", "contributions": [{"fullName": "Eugene Thacker", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Nicola Masciandaro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Edward Keller", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "00e012c5-9232-472c-bd8b-8ca4ea6d1275", "fullTitle": "Li Bo Unkempt", "doi": "https://doi.org/10.21983/P3.0322.1.00", "publicationDate": "2021-03-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kidder Smith", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Kidder Smith", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mike Zhai", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Traktung Yeshe Dorje", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Maria Dolgenas", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "534c3d13-b18b-4be5-91e6-768c0cf09361", "fullTitle": "Living with Monsters", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Ilana Gershon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Yasmine Musharbash", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "636a5aa6-1d37-4cd2-8742-4dcad8c67e0c", "fullTitle": "Love Don't Need a Reason: The Life & Music of Michael Callen", "doi": "https://doi.org/10.21983/P3.0297.1.00", "publicationDate": "2020-11-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew J.\n Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6dcf29ea-76c1-4121-ad7f-2341574c45fe", "fullTitle": "Luminol Theory", "doi": "https://doi.org/10.21983/P3.0177.1.00", "publicationDate": "2017-08-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laura E. Joyce", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed96eea8-82c6-46c5-a19b-dad5e45962c6", "fullTitle": "Make and Let Die: Untimely Sovereignties", "doi": "https://doi.org/10.21983/P3.0136.1.00", "publicationDate": "2016-03-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kathleen Biddick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Eileen A. Joy", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "003137ea-4fe6-470d-8bd3-f936ad065f3c", "fullTitle": "Making the Geologic Now: Responses to Material Conditions of Contemporary Life", "doi": "https://doi.org/10.21983/P3.0014.1.00", "publicationDate": "2012-12-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Elisabeth Ellsworth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jamie Kruse", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "35ed7096-8218-43d7-a572-6453c9892ed1", "fullTitle": "Manifesto for a Post-Critical Pedagogy", "doi": "https://doi.org/10.21983/P3.0193.1.00", "publicationDate": "2018-01-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Piotr Zamojski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Joris Vlieghe", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Naomi Hodgson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": null, "imprintId": "3437ff40-3bff-4cda-9f0b-1003d2980335", "imprintName": "Risking Education", "updatedAt": "2021-07-06T17:43:41.987789+00:00", "createdAt": "2021-07-06T17:43:41.987789+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "a01f41d6-1da8-4b0b-87b4-82ecc41c6d55", "fullTitle": "Nothing As We Need It: A Chimera", "doi": "https://doi.org/10.53288/0382.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Daniela Cascella", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/speculations/", "imprintId": "dcf8d636-38ae-4a63-bae1-40a61b5a3417", "imprintName": "Speculations", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "03da5b84-80ba-48bc-89b9-b63fc56b364b", "fullTitle": "Speculations", "doi": "https://doi.org/10.21983/P3.0343.1.00", "publicationDate": "2020-07-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c00d9a0c-320d-4dfb-ba0c-d1adbdb491ef", "fullTitle": "Speculations 3", "doi": "https://doi.org/10.21983/P3.0010.1.00", "publicationDate": "2012-09-03", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "2c71d808-d1a7-4918-afbb-2dfc121e7768", "fullTitle": "Speculations II", "doi": "https://doi.org/10.21983/P3.0344.1.00", "publicationDate": "2020-07-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "ee2cb855-4c94-4176-b62c-3114985dd84e", "fullTitle": "Speculations IV: Speculative Realism", "doi": "https://doi.org/10.21983/P3.0032.1.00", "publicationDate": "2013-06-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "435a1db3-1bbb-44b2-9368-7b2fd8a4e63e", "fullTitle": "Speculations VI", "doi": "https://doi.org/10.21983/P3.0122.1.00", "publicationDate": "2015-12-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/thought-crimes/", "imprintId": "f2dc7495-17af-4d8a-9306-168fc6fa1f41", "imprintName": "Thought | Crimes", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1bba80bd-2efd-41a2-9b09-4ff8da0efeb9", "fullTitle": "New Developments in Anarchist Studies", "doi": "https://doi.org/10.21983/P3.0349.1.00", "publicationDate": "2015-06-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "pj lilley", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jeff Shantz", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5a1cd53e-640b-46e7-82a6-d95bc4907e36", "fullTitle": "The Spectacle of the False Flag: Parapolitics from JFK to Watergate", "doi": "https://doi.org/10.21983/P3.0347.1.00", "publicationDate": "2014-03-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Eric Wilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Guido Giacomo Preparata", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Jeff Shantz", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "c8245465-2937-40fd-9c3e-7bd33deef477", "fullTitle": "Who Killed the Berkeley School? Struggles Over Radical Criminology ", "doi": "https://doi.org/10.21983/P3.0348.1.00", "publicationDate": "2014-04-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "Julia Schwendinger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Herman Schwendinger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jeff Shantz", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/tiny-collections/", "imprintId": "be4c8448-93c8-4146-8d9c-84d121bc4bec", "imprintName": "Tiny Collections", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "fullTitle": "Closer to Dust", "doi": "https://doi.org/10.53288/0324.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Sara A. Rich", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "771e1cde-d224-4cb6-bac7-7f5ef4d1a405", "fullTitle": "Coconuts: A Tiny History", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Kathleen E. Kennedy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "20d15631-f886-43a0-b00b-b62426710bdf", "fullTitle": "Elemental Disappearances", "doi": "https://doi.org/10.21983/P3.0157.1.00", "publicationDate": "2016-11-28", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jason Bahbak Mohaghegh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Dejan Luki\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "177e3717-4c07-4f31-9318-616ad3b71e89", "fullTitle": "Sea Monsters: Things from the Sea, Volume 2", "doi": "https://doi.org/10.21983/P3.0182.1.00", "publicationDate": "2017-09-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Asa Simon Mittman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Thea Tomaini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6dd15dd7-ae8c-4438-a597-7c99d5be4138", "fullTitle": "Walk on the Beach: Things from the Sea, Volume 1", "doi": "https://doi.org/10.21983/P3.0143.1.00", "publicationDate": "2016-06-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maggie M. Williams", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Karen Eileen Overbey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/uitgeverij/", "imprintId": "e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1", "imprintName": "Uitgeverij", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "b5c810e1-c847-4553-a24e-9893164d9786", "fullTitle": "(((", "doi": "https://doi.org/10.53288/0370.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Gen Ueda", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "df9bf011-efaf-49a7-9497-2a4d4cfde9e8", "fullTitle": "An Anthology of Asemic Handwriting", "doi": "https://doi.org/10.21983/P3.0220.1.00", "publicationDate": "2013-08-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Michael Jacobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Tim Gaze", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8b77c06a-3c1c-48ac-a32e-466ef37f293e", "fullTitle": "A Neo Tropical Companion", "doi": "https://doi.org/10.21983/P3.0217.1.00", "publicationDate": "2012-01-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jamie Stewart", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c3c09f99-71f9-431c-b0f4-ff30c3f7fe11", "fullTitle": "Continuum: Writings on Poetry as Artistic Practice", "doi": "https://doi.org/10.21983/P3.0229.1.00", "publicationDate": "2015-11-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c30545e-539b-419a-8b96-5f6c475bab9e", "fullTitle": "Disrupting the Digital Humanities", "doi": "https://doi.org/10.21983/P3.0230.1.00", "publicationDate": "2018-11-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jesse Stommel", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dorothy Kim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "dfe575e1-2836-43f3-a11b-316af9509612", "fullTitle": "Exegesis of a Renunciation \u2013 Esegesi di una rinuncia", "doi": "https://doi.org/10.21983/P3.0226.1.00", "publicationDate": "2014-10-14", "place": "The Hague/Tirana", "contributions": [{"fullName": "Francesco Aprile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bartolom\u00e9 Ferrando", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Caggiula Cristiano", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "a9b27739-0d29-4238-8a41-47b3ac2d5bd5", "fullTitle": "Filial Arcade & Other Poems", "doi": "https://doi.org/10.21983/P3.0223.1.00", "publicationDate": "2013-12-21", "place": "The Hague/Tirana", "contributions": [{"fullName": "Adam Staley Groves", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "c2c22cdf-b9d5-406d-9127-45cea8e741b1", "fullTitle": "Hippolytus", "doi": "https://doi.org/10.21983/P3.0218.1.00", "publicationDate": "2012-08-21", "place": "The Hague/Tirana", "contributions": [{"fullName": "Euripides", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sean Gurd", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "ebeae9d6-7543-4cd4-9fa9-c39c43ba0d4b", "fullTitle": "Men in A\u00efda", "doi": "https://doi.org/10.21983/P3.0224.0.00", "publicationDate": "2014-12-31", "place": "The Hague/Tirana", "contributions": [{"fullName": "David J. Melnick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sean Gurd", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "d24a0567-d430-4768-8c4d-1b9d59394af2", "fullTitle": "On Blinking", "doi": "https://doi.org/10.21983/P3.0219.1.00", "publicationDate": "2012-08-23", "place": "The Hague/Tirana", "contributions": [{"fullName": "Sarah Brigid Hannis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeremy Fernando", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97d205c8-32f0-4e64-a7df-bf56334be638", "fullTitle": "paq'batlh: A Klingon Epic", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Floris Sch\u00f6nfeld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. Van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Kees Ligtelijn", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marc Okrand", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "e81ef154-5bc3-481b-9083-64fd7aeb7575", "fullTitle": "paq'batlh: The Klingon Epic", "doi": "https://doi.org/10.21983/P3.0215.1.00", "publicationDate": "2011-10-10", "place": "The Hague/Tirana", "contributions": [{"fullName": "Floris Sch\u00f6nfeld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. Van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Kees Ligtelijn", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marc Okrand", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "119f1640-dfb4-488f-a564-ef507d74b72d", "fullTitle": "Pen in the Park: A Resistance Fairytale \u2013 Pen Parkta: Bir Direni\u015f Masal\u0131", "doi": "https://doi.org/10.21983/P3.0225.1.00", "publicationDate": "2014-02-12", "place": "The Hague/Tirana", "contributions": [{"fullName": "Ra\u015fel Meseri", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sanne Karssenberg", "contributionType": "ILUSTRATOR", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "0cb39600-2fd2-4a7a-9d3a-6d92b8e32e9e", "fullTitle": "Poetry from Beyond the Grave", "doi": "https://doi.org/10.21983/P3.0222.1.00", "publicationDate": "2013-05-10", "place": "The Hague/Tirana", "contributions": [{"fullName": "Francisco C\u00e2ndido \"Chico\" Xavier", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vitor Peqeuno", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeremy Fernando", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "69365c88-4571-45f3-8770-5a94f7c9badc", "fullTitle": "Poetry Vocare", "doi": "https://doi.org/10.21983/P3.0213.1.00", "publicationDate": "2011-01-23", "place": "The Hague/Tirana", "contributions": [{"fullName": "Adam Staley Groves", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Judith Balso", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "bc283f71-9f37-47c4-b30b-8ed9f3be9f9c", "fullTitle": "The Guerrilla I Like a Poet \u2013 Ang Gerilya Ay Tulad ng Makata", "doi": "https://doi.org/10.21983/P3.0221.1.00", "publicationDate": "2013-09-27", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jose Maria Sison", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonas Staal", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "7be9aa8c-b8af-4b2f-96ff-16e4532f2b83", "fullTitle": "The Miracle of Saint Mina \u2013 Gis Miinan Nokkor", "doi": "https://doi.org/10.21983/P3.0216.1.00", "publicationDate": "2012-01-05", "place": "The Hague/Tirana", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "El-Shafie El-Guzuuli", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b55c95a7-ce6e-4cfb-8945-cab4e04001e5", "fullTitle": "To Be, or Not to Be: Paraphrased", "doi": "https://doi.org/10.21983/P3.0227.1.00", "publicationDate": "2016-06-17", "place": "The Hague/Tirana", "contributions": [{"fullName": "Bardsley Rosenbridge", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "367397db-bcb4-4f0e-9185-4be74c119c19", "fullTitle": "Writing Art", "doi": "https://doi.org/10.21983/P3.0228.1.00", "publicationDate": "2015-11-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Alessandro De Francesco", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "6a109b6a-55e9-4dd5-b670-61926c10e611", "fullTitle": "Writing Death", "doi": "https://doi.org/10.21983/P3.0214.1.00", "publicationDate": "2011-06-06", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Avital Ronell", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}], "__typename": "Imprint"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json new file mode 100644 index 0000000..45684d3 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json @@ -0,0 +1 @@ +{"data": {"imprints": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 4b13672..8bfa953 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -21,3 +21,4 @@ bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85 bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle" +bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index d7cc571..0dc49f0 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -19,6 +19,7 @@ bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85 bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/work.json" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publication.json" +bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" @@ -28,4 +29,5 @@ bash -c "echo '{\"data\": {\"publishers\": [\"1\"] } }' > thothlibrary/thoth-0_ bash -c "echo '{\"data\": {\"publisher\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publisher_bad.json" bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" -bash -c "echo '{\"data\": {\"publication\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"publication\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json" +bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index d55f221..93599e7 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -303,6 +303,36 @@ def test_publishers_raw(self): self.raw_tester(mock_response, thoth_client.publishers) return None + def test_imprints(self): + """ + Tests that good input to publishers produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('imprints', m) + self.pickle_tester('imprints', thoth_client.imprints) + return None + + def test_imprints_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('imprints_bad', m) + self.pickle_tester('imprints', thoth_client.imprints, + negative=True) + + def test_imprints_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('imprints', m) + self.raw_tester(mock_response, thoth_client.imprints) + return None + def test_contributions(self): """ Tests that good input to contributions produces saved good output From a7d3fd1dc6ce9ba747c6ef1c8403ea544b8870d5 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 15:32:02 +0100 Subject: [PATCH 054/115] Add imprint endpoints, cli, and tests --- README.md | 1 + thothlibrary/cli.py | 24 ++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 32 +++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/imprint.json | 1 + .../thoth-0_4_2/tests/fixtures/imprint.pickle | 1 + .../tests/fixtures/imprint_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 44 +++++++++++++++++++ 10 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json diff --git a/README.md b/README.md index d8f92e2..3b4cfaa 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh +python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 7e1beb1..9421d03 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -212,6 +212,30 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None, else: print(json.dumps(publisher)) + @fire.decorators.SetParseFn(_raw_parse) + def imprint(self, imprint_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a publisher by ID from a Thoth instance + :param str imprint_id: the imprint to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + imprint = self._client().imprint(imprint_id=imprint_id, raw=raw) + + if not serialize: + print(imprint) + else: + print(json.dumps(imprint)) + @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, raw=False, version=None, endpoint=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 6fceede..850ca55 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -251,6 +251,23 @@ class ThothClient0_4_2(ThothClient): ] }, + "imprint": { + "parameters": [ + "imprintId", + ], + "fields": [ + "imprintUrl", + "imprintId", + "imprintName", + "updatedAt", + "createdAt", + "publisherId", + "publisher { publisherName publisherId }", + "works { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "publisher": { "parameters": [ "publisherId", @@ -313,7 +330,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributions', 'publisher_count', 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', - 'QUERIES'] + 'imprint', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -459,6 +476,19 @@ def publisher(self, publisher_id: str, raw: bool = False): return self._api_request("publisher", parameters, return_raw=raw) + def imprint(self, imprint_id: str, raw: bool = False): + """ + Returns a work by DOI + @param imprint_id: the imprint + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'imprintId': '"' + imprint_id + '"' + } + + return self._api_request("imprint", parameters, return_raw=raw) + def publishers(self, limit: int = 100, offset: int = 0, order: str = None, filter_str: str = "", publishers: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index bb8fb83..1f91867 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -71,6 +71,8 @@ def __price_parser(prices): self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', 'imprints': lambda self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', + 'imprint': lambda + self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', 'publication': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json new file mode 100644 index 0000000..e531da5 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json @@ -0,0 +1 @@ +{"data":{"imprint":{"imprintUrl":"https://punctumbooks.com/imprints/3ecologies-books/","imprintId":"78b0a283-9be3-4fed-a811-a7d4b9df7b25","imprintName":"3Ecologies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9","fullTitle":"A Manga Perfeita","doi":"https://doi.org/10.21983/P3.0270.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Christine Greiner","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Ernesto Filho","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"c3d008a2-b357-4886-acc4-a2c77f1749ee","fullTitle":"Last Year at Betty and Bob's: An Actual Occasion","doi":"https://doi.org/10.53288/0363.1.00","publicationDate":"2021-07-08","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"781b77bd-edf8-4688-937d-cc7cc47de89f","fullTitle":"Last Year at Betty and Bob's: An Adventure","doi":"https://doi.org/10.21983/P3.0234.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ce38f309-4438-479f-bd1c-b3690dbd7d8d","fullTitle":"Last Year at Betty and Bob's: A Novelty","doi":"https://doi.org/10.21983/P3.0233.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"edf31616-ea2a-4c51-b932-f510b9eb8848","fullTitle":"No Archive Will Restore You","doi":"https://doi.org/10.21983/P3.0231.1.00","publicationDate":"2018-11-13","place":"Earth, Milky Way","contributions":[{"fullName":"Julietta Singh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d4a3f6cb-3023-4088-a5f4-147fb4510874","fullTitle":"Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Matthew Goulish","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Will Dadario","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d9045f8-1d8f-479c-983d-383f3a289bec","fullTitle":"Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art","doi":"https://doi.org/10.21983/P3.0327.1.00","publicationDate":"2021-02-18","place":"Earth, Milky Way","contributions":[{"fullName":"Curt Cloninger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ffa5c5dd-ab4b-4739-8281-275d8c1fb504","fullTitle":"Sweet Spots: Writing the Connective Tissue of Relation","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mattie-Martha Sempert","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"757ff294-0fca-40f5-9f33-39a2d3fd5c8a","fullTitle":"Teaching Myself To See","doi":"https://doi.org/10.21983/P3.0303.1.00","publicationDate":"2021-02-11","place":"Earth, Milky Way","contributions":[{"fullName":"Tito Mukhopadhyay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}]},{"workId":"571255b8-5bf5-4fe1-a201-5bc7aded7f9d","fullTitle":"The Perfect Mango","doi":"https://doi.org/10.21983/P3.0245.1.00","publicationDate":"2019-02-20","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4cfb06e-a5a6-48cc-b7e5-c38228c132a8","fullTitle":"The Unnaming of Aliass","doi":"https://doi.org/10.21983/P3.0299.1.00","publicationDate":"2020-10-01","place":"Earth, Milky Way","contributions":[{"fullName":"Karin Bolender","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle new file mode 100644 index 0000000..bcbb6e4 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle @@ -0,0 +1 @@ +{"imprintUrl": "https://punctumbooks.com/imprints/3ecologies-books/", "imprintId": "78b0a283-9be3-4fed-a811-a7d4b9df7b25", "imprintName": "3Ecologies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9", "fullTitle": "A Manga Perfeita", "doi": "https://doi.org/10.21983/P3.0270.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Christine Greiner", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Ernesto Filho", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "c3d008a2-b357-4886-acc4-a2c77f1749ee", "fullTitle": "Last Year at Betty and Bob's: An Actual Occasion", "doi": "https://doi.org/10.53288/0363.1.00", "publicationDate": "2021-07-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "781b77bd-edf8-4688-937d-cc7cc47de89f", "fullTitle": "Last Year at Betty and Bob's: An Adventure", "doi": "https://doi.org/10.21983/P3.0234.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ce38f309-4438-479f-bd1c-b3690dbd7d8d", "fullTitle": "Last Year at Betty and Bob's: A Novelty", "doi": "https://doi.org/10.21983/P3.0233.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "edf31616-ea2a-4c51-b932-f510b9eb8848", "fullTitle": "No Archive Will Restore You", "doi": "https://doi.org/10.21983/P3.0231.1.00", "publicationDate": "2018-11-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Julietta Singh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d4a3f6cb-3023-4088-a5f4-147fb4510874", "fullTitle": "Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew Goulish", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Will Dadario", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d9045f8-1d8f-479c-983d-383f3a289bec", "fullTitle": "Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art", "doi": "https://doi.org/10.21983/P3.0327.1.00", "publicationDate": "2021-02-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Curt Cloninger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ffa5c5dd-ab4b-4739-8281-275d8c1fb504", "fullTitle": "Sweet Spots: Writing the Connective Tissue of Relation", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mattie-Martha Sempert", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "757ff294-0fca-40f5-9f33-39a2d3fd5c8a", "fullTitle": "Teaching Myself To See", "doi": "https://doi.org/10.21983/P3.0303.1.00", "publicationDate": "2021-02-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Tito Mukhopadhyay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "571255b8-5bf5-4fe1-a201-5bc7aded7f9d", "fullTitle": "The Perfect Mango", "doi": "https://doi.org/10.21983/P3.0245.1.00", "publicationDate": "2019-02-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4cfb06e-a5a6-48cc-b7e5-c38228c132a8", "fullTitle": "The Unnaming of Aliass", "doi": "https://doi.org/10.21983/P3.0299.1.00", "publicationDate": "2020-10-01", "place": "Earth, Milky Way", "contributions": [{"fullName": "Karin Bolender", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json new file mode 100644 index 0000000..cf2e897 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json @@ -0,0 +1 @@ +{"data": {"imprint": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 8bfa953..5ec2951 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -21,4 +21,5 @@ bash -c "python3 -m thothlibrary.cli publisher --version=0.4.2 --publisher_id=85 bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984f-45cc-8b9e-13989c31dda4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle" bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle" -bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle" +bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 0dc49f0..eae42aa 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -20,6 +20,7 @@ bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984 bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json" bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publication.json" bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json" +bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" @@ -30,4 +31,5 @@ bash -c "echo '{\"data\": {\"publisher\": [\"1\"] } }' > thothlibrary/thoth-0_4 bash -c "echo '{\"data\": {\"work\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/work_bad.json" bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi_bad.json" bash -c "echo '{\"data\": {\"publication\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json" -bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json" +bash -c "echo '{\"data\": {\"imprint\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 93599e7..82194da 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -303,6 +303,50 @@ def test_publishers_raw(self): self.raw_tester(mock_response, thoth_client.publishers) return None + def test_imprint(self): + """ + Tests that good input to imprint produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('imprint', m) + self.pickle_tester('imprint', + lambda: + thoth_client.imprint( + imprint_id='78b0a283-9be3-4fed-a811-' + 'a7d4b9df7b25')) + return None + + def test_imprint_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('imprint_bad', m) + self.pickle_tester('imprint', + lambda: thoth_client.imprint( + imprint_id='78b0a283-9be3-4fed-a811-' + 'a7d4b9df7b25'), + negative=True) + return None + + def test_imprint_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('imprint', m) + self.raw_tester(mock_response, + lambda: thoth_client.imprint( + imprint_id='78b0a283-9be3-4fed-a811-' + 'a7d4b9df7b25', + raw=True), + lambda_mode=True) + return None + + def test_imprints(self): """ Tests that good input to publishers produces saved good output From 0e488b41a15c4fc2fb02f20184d1367eaee9beb4 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 15:50:28 +0100 Subject: [PATCH 055/115] Add imprint count endpoint --- README.md | 1 + thothlibrary/cli.py | 22 ++++++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 19 ++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b4cfaa..027bf1f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ print(thoth.works()) ```sh python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 9421d03..dfa55ea 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -330,6 +330,28 @@ def publisher_count(self, publishers=None, filter_str=None, raw=False, filter_str=filter_str, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def imprint_count(self, publishers=None, filter_str=None, raw=False, + version=None, endpoint=None): + """ + Retrieves a count of imprints from a Thoth instance + :param str publishers: a list of publishers to limit by + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().imprint_count(publishers=publishers, + filter_str=filter_str, + raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def work_count(self, publishers=None, filter_str=None, raw=False, work_type=None, work_status=None, version=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 850ca55..3306bf3 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -291,6 +291,13 @@ class ThothClient0_4_2(ThothClient): ], }, + "imprintCount": { + "parameters": [ + "filter", + "publishers", + ], + }, + "workCount": { "parameters": [ "filter", @@ -330,7 +337,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributions', 'publisher_count', 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', - 'imprint', 'QUERIES'] + 'imprint', 'imprint_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -529,6 +536,16 @@ def publisher_count(self, filter_str: str = "", publishers: str = None, return self._api_request("publisherCount", parameters, return_raw=raw) + def imprint_count(self, filter_str: str = "", publishers: str = None, + raw: bool = False): + """Construct and trigger a query to count publishers""" + parameters = {} + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("imprintCount", parameters, return_raw=raw) + def work_count(self, filter_str: str = "", publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): From c1c6827531d5c88d0827ffedfdefbdefc5adbfb9 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 16:14:12 +0100 Subject: [PATCH 056/115] Add contributors endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 32 ++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 44 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../tests/fixtures/contributors.json | 1 + .../tests/fixtures/contributors.pickle | 1 + .../tests/fixtures/contributors_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 2 + thothlibrary/thoth-0_4_2/tests/tests.py | 31 +++++++++++++ 10 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json diff --git a/README.md b/README.md index 027bf1f..d6a4d29 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh +python3 -m thothlibrary.cli contributors --limit=10 python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index dfa55ea..a5db26b 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -80,6 +80,38 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, else: print(contribs) + @fire.decorators.SetParseFn(_raw_parse) + def contributors(self, limit=100, order=None, offset=0, filter_str=None, + raw=False, version=None, endpoint=None, serialize=False): + """ + Retrieves contributors from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str filter_str: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + contribs = self._client().contributors(limit=limit, order=order, + offset=offset, + filter_str=filter_str, + raw=raw) + + if not raw and not serialize: + print(*contribs, sep='\n') + elif serialize: + print(json.dumps(contribs)) + else: + print(contribs) + @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, filter_str=None, work_type=None, work_status=None, raw=False, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 3306bf3..29f59cb 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -210,6 +210,24 @@ class ThothClient0_4_2(ThothClient): ] }, + "contributors": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + ], + "fields": [ + "contributorId", + "firstName", + "lastName", + "fullName", + "orcid", + "__typename", + "contributions { contributionId contributionType work { workId fullTitle} }" + ] + }, + "publishers": { "parameters": [ "limit", @@ -337,7 +355,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributions', 'publisher_count', 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', - 'imprint', 'imprint_count', 'QUERIES'] + 'imprint', 'imprint_count', 'contributors', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -414,6 +432,30 @@ def contributions(self, limit: int = 100, offset: int = 0, return self._api_request("contributions", parameters, return_raw=raw) + def contributors(self, limit: int = 100, offset: int = 0, + filter_str: str = "", order: str = None, + raw: bool = False): + """ + Returns a contributions list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param filter_str: a filter string to search + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'order', order) + + return self._api_request("contributors", parameters, return_raw=raw) + def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 1f91867..8ed49f9 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -75,6 +75,8 @@ def __price_parser(prices): self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', 'contributions': lambda self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', + 'contributors': lambda + self: f'{self.fullName} ({self.contributions[0].contributionType} of {self.contributions[0].work.fullTitle}) [{self.contributorId}]' if '__typename' in self and self.__typename == 'Contributor' else f'{_muncher_repr(self)}', 'publication': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json new file mode 100644 index 0000000..64da99a --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json @@ -0,0 +1 @@ +{"data":{"contributors":[{"contributorId":"1c3aade6-6d48-41b4-8def-b435f4b43573","firstName":"Aaron D.","lastName":"Hornkohl","fullName":"Aaron D. Hornkohl","orcid":null,"__typename":"Contributor","contributions":[{"contributionId":"39fcc56a-2ac1-4665-ac51-46fb34257c6a","contributionType":"EDITOR","work":{"workId":"703bbdfe-d984-4807-8a80-26a196cfd0f0","fullTitle":"New Perspectives in Biblical and Rabbinic Hebrew"}},{"contributionId":"e2174988-2c75-4b80-8c3c-0338045241c8","contributionType":"EDITOR","work":{"workId":"ff10a672-857b-4adb-b6bb-c54104eb277d","fullTitle":"Studies in Semitic Vocalisation and Reading Traditions"}}]},{"contributorId":"10147774-6630-4e5f-b04c-2219060a96af","firstName":"Aaron","lastName":"Zwintscher","fullName":"Aaron Zwintscher","orcid":null,"__typename":"Contributor","contributions":[{"contributionId":"44556e41-d503-43e1-a1fd-9e0409e95de9","contributionType":"AUTHOR","work":{"workId":"1cfca75f-2e57-4f34-85fb-a1585315a2a9","fullTitle":"Noise Thinks the Anthropocene: An Experiment in Noise Poetics"}}]},{"contributorId":"f17755ac-badf-41e1-aaa8-4c905afe369d","firstName":"Abraham","lastName":"Adams","fullName":"Abraham Adams","orcid":null,"__typename":"Contributor","contributions":[{"contributionId":"a274143f-7652-42f9-a64e-94e03d70861f","contributionType":"AUTHOR","work":{"workId":"48e2a673-aec2-4ed6-99d4-46a8de200493","fullTitle":"Nothing in MoMA"}}]},{"contributorId":"09b8028c-87a5-4d27-a82a-1e505ec45e8a","firstName":"Adam","lastName":"Benkato","fullName":"Adam Benkato","orcid":"https://orcid.org/0000-0003-4299-5205","__typename":"Contributor","contributions":[{"contributionId":"6aa9ff0f-d2bb-4410-a395-3d58277b5945","contributionType":"EDITOR","work":{"workId":"ce7ec5ea-88b2-430f-92be-0f2436600a46","fullTitle":"Lamma: A Journal of Libyan Studies 1"}}]}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle new file mode 100644 index 0000000..6a5d288 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle @@ -0,0 +1 @@ +[{"contributorId": "1c3aade6-6d48-41b4-8def-b435f4b43573", "firstName": "Aaron D.", "lastName": "Hornkohl", "fullName": "Aaron D. Hornkohl", "orcid": null, "__typename": "Contributor", "contributions": [{"contributionId": "39fcc56a-2ac1-4665-ac51-46fb34257c6a", "contributionType": "EDITOR", "work": {"workId": "703bbdfe-d984-4807-8a80-26a196cfd0f0", "fullTitle": "New Perspectives in Biblical and Rabbinic Hebrew"}}, {"contributionId": "e2174988-2c75-4b80-8c3c-0338045241c8", "contributionType": "EDITOR", "work": {"workId": "ff10a672-857b-4adb-b6bb-c54104eb277d", "fullTitle": "Studies in Semitic Vocalisation and Reading Traditions"}}]}, {"contributorId": "10147774-6630-4e5f-b04c-2219060a96af", "firstName": "Aaron", "lastName": "Zwintscher", "fullName": "Aaron Zwintscher", "orcid": null, "__typename": "Contributor", "contributions": [{"contributionId": "44556e41-d503-43e1-a1fd-9e0409e95de9", "contributionType": "AUTHOR", "work": {"workId": "1cfca75f-2e57-4f34-85fb-a1585315a2a9", "fullTitle": "Noise Thinks the Anthropocene: An Experiment in Noise Poetics"}}]}, {"contributorId": "f17755ac-badf-41e1-aaa8-4c905afe369d", "firstName": "Abraham", "lastName": "Adams", "fullName": "Abraham Adams", "orcid": null, "__typename": "Contributor", "contributions": [{"contributionId": "a274143f-7652-42f9-a64e-94e03d70861f", "contributionType": "AUTHOR", "work": {"workId": "48e2a673-aec2-4ed6-99d4-46a8de200493", "fullTitle": "Nothing in MoMA"}}]}, {"contributorId": "09b8028c-87a5-4d27-a82a-1e505ec45e8a", "firstName": "Adam", "lastName": "Benkato", "fullName": "Adam Benkato", "orcid": "https://orcid.org/0000-0003-4299-5205", "__typename": "Contributor", "contributions": [{"contributionId": "6aa9ff0f-d2bb-4410-a395-3d58277b5945", "contributionType": "EDITOR", "work": {"workId": "ce7ec5ea-88b2-430f-92be-0f2436600a46", "fullTitle": "Lamma: A Journal of Libyan Studies 1"}}]}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json new file mode 100644 index 0000000..ddfa266 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json @@ -0,0 +1 @@ +{"data": {"contributors": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 5ec2951..e98f84f 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -22,4 +22,5 @@ bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --work_id=e0f748b2-984 bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/10.21983/P3.0314.1.00 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle" bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/publication.pickle" bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle" -bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle" +bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index eae42aa..26df13a 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -21,6 +21,7 @@ bash -c "python3 -m thothlibrary.cli work --version=0.4.2 --doi=https://doi.org/ bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/publication.json" bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json" bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json" +bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" @@ -33,3 +34,4 @@ bash -c "echo '{\"data\": {\"workByDoi\": [\"1\"] } }' > thothlibrary/thoth-0_4 bash -c "echo '{\"data\": {\"publication\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/publication_bad.json" bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json" bash -c "echo '{\"data\": {\"imprint\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json" +bash -c "echo '{\"data\": {\"contributors\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 82194da..c812744 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -408,6 +408,37 @@ def test_contributions_raw(self): self.raw_tester(mock_response, thoth_client.contributions) return None + def test_contributors(self): + """ + Tests that good input to contributors produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributors', m) + self.pickle_tester('contributors', thoth_client.contributors) + return None + + def test_contributors_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributors_bad', + m) + self.pickle_tester('contributors', thoth_client.contributors, + negative=True) + + def test_contributors_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributors', m) + self.raw_tester(mock_response, thoth_client.contributors) + return None + def raw_tester(self, mock_response, method_to_call, lambda_mode=False): """ An echo test that ensures the client returns accurate raw responses From 6e3ac86f13bf45c05cea76c0de937f03ba9f9f50 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 16:32:19 +0100 Subject: [PATCH 057/115] Add contributor endpoint, tests, and CLI --- README.md | 11 ++--- thothlibrary/cli.py | 25 +++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 31 ++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../tests/fixtures/contributor.json | 1 + .../tests/fixtures/contributor.pickle | 1 + .../tests/fixtures/contributor_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 2 + thothlibrary/thoth-0_4_2/tests/tests.py | 45 ++++++++++++++++++- 10 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json diff --git a/README.md b/README.md index d6a4d29..4eda85f 100644 --- a/README.md +++ b/README.md @@ -29,21 +29,22 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh +python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 python3 -m thothlibrary.cli contributors --limit=10 python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' -python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b -python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' +python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" +python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b +python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" python3 -m thothlibrary.cli works --limit=10 --order='{field: PUBLICATION_DATE, direction: DESC}' --work_status=ACTIVE --work_type=MONOGRAPH --offset=1 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' -python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli work_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' -python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" -python3 -m thothlibrary.cli supported_versions ``` diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index a5db26b..7a6c663 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -244,6 +244,31 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None, else: print(json.dumps(publisher)) + @fire.decorators.SetParseFn(_raw_parse) + def contributor(self, contributor_id, raw=False, version=None, + endpoint=None, serialize=False): + """ + Retrieves a contriibutor by ID from a Thoth instance + :param str contributor_id: the contributor to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + contributor = self._client().contributor(contributor_id=contributor_id, + raw=raw) + + if not serialize: + print(contributor) + else: + print(json.dumps(contributor)) + @fire.decorators.SetParseFn(_raw_parse) def imprint(self, imprint_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 29f59cb..ce6a342 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -228,6 +228,21 @@ class ThothClient0_4_2(ThothClient): ] }, + "contributor": { + "parameters": [ + "contributorId" + ], + "fields": [ + "contributorId", + "firstName", + "lastName", + "fullName", + "orcid", + "__typename", + "contributions { contributionId contributionType work { workId fullTitle} }" + ] + }, + "publishers": { "parameters": [ "limit", @@ -355,11 +370,25 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributions', 'publisher_count', 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', - 'imprint', 'imprint_count', 'contributors', 'QUERIES'] + 'imprint', 'imprint_count', 'contributors', + 'contributor', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) + def contributor(self, contributor_id: str, raw: bool = False): + """ + Returns a contributor by ID + @param contributor_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'contributorId': '"' + contributor_id + '"' + } + + return self._api_request("contributor", parameters, return_raw=raw) + def publication(self, publication_id: str, raw: bool = False): """ Returns a publication by ID diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 8ed49f9..5df2fa7 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -77,6 +77,8 @@ def __price_parser(prices): self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', 'contributors': lambda self: f'{self.fullName} ({self.contributions[0].contributionType} of {self.contributions[0].work.fullTitle}) [{self.contributorId}]' if '__typename' in self and self.__typename == 'Contributor' else f'{_muncher_repr(self)}', + 'contributor': lambda + self: f'{self.fullName} ({self.contributions[0].contributionType} of {self.contributions[0].work.fullTitle}) [{self.contributorId}]' if '__typename' in self and self.__typename == 'Contributor' else f'{_muncher_repr(self)}', 'publication': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json new file mode 100644 index 0000000..3b86458 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json @@ -0,0 +1 @@ +{"data":{"contributor":{"contributorId":"e8def8cf-0dfe-4da9-b7fa-f77e7aec7524","firstName":"Martin Paul","lastName":"Eve","fullName":"Martin Paul Eve","orcid":"https://orcid.org/0000-0002-5589-8511","__typename":"Contributor","contributions":[{"contributionId":"4f1718e2-6ff3-4f65-a1bc-870da9f4ae9d","contributionType":"AUTHOR","work":{"workId":"9845c8a9-b283-4cb8-8961-d41e5fe795f1","fullTitle":"Literature Against Criticism: University English and Contemporary Fiction in Conflict"}}]}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle new file mode 100644 index 0000000..5703b40 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle @@ -0,0 +1 @@ +{"contributorId": "e8def8cf-0dfe-4da9-b7fa-f77e7aec7524", "firstName": "Martin Paul", "lastName": "Eve", "fullName": "Martin Paul Eve", "orcid": "https://orcid.org/0000-0002-5589-8511", "__typename": "Contributor", "contributions": [{"contributionId": "4f1718e2-6ff3-4f65-a1bc-870da9f4ae9d", "contributionType": "AUTHOR", "work": {"workId": "9845c8a9-b283-4cb8-8961-d41e5fe795f1", "fullTitle": "Literature Against Criticism: University English and Contemporary Fiction in Conflict"}}]} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json new file mode 100644 index 0000000..d9d73e9 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json @@ -0,0 +1 @@ +{"data": {"contributor": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index e98f84f..b810832 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -24,3 +24,4 @@ bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_i bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle" bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle" bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle" +bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 26df13a..7897aac 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -22,6 +22,7 @@ bash -c "python3 -m thothlibrary.cli publication --version=0.4.2 --publication_i bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json" bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json" bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json" +bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" @@ -35,3 +36,4 @@ bash -c "echo '{\"data\": {\"publication\": [\"1\"] } }' > thothlibrary/thoth-0 bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprints_bad.json" bash -c "echo '{\"data\": {\"imprint\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json" bash -c "echo '{\"data\": {\"contributors\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json" +bash -c "echo '{\"data\": {\"contributor\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index c812744..4e6c73c 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -346,7 +346,6 @@ def test_imprint_raw(self): lambda_mode=True) return None - def test_imprints(self): """ Tests that good input to publishers produces saved good output @@ -408,6 +407,50 @@ def test_contributions_raw(self): self.raw_tester(mock_response, thoth_client.contributions) return None + def test_contributor(self): + """ + Tests that good input to contributor produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributor', m) + self.pickle_tester('contributor', + lambda: + thoth_client.contributor( + contributor_id='e8def8cf-0dfe-4da9-b7fa-' + 'f77e7aec7524')) + return None + + def test_contributor_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributor_bad', + m) + self.pickle_tester('contributor', + lambda: thoth_client.contributor( + contributor_id='e8def8cf-0dfe-4da9-b7fa-' + 'f77e7aec7524'), + negative=True) + return None + + def test_contributor_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributor', m) + self.raw_tester(mock_response, + lambda: thoth_client.contributor( + contributor_id='e8def8cf-0dfe-4da9-b7fa-' + 'f77e7aec7524', + raw=True), + lambda_mode=True) + return None + def test_contributors(self): """ Tests that good input to contributors produces saved good output From 8e0d5f3f3df8a7181d9bf1466992875c3824c81b Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 16:46:08 +0100 Subject: [PATCH 058/115] Add contributor_count endpoint and CLI Rename "filter_str" to "filter" in CLI and API --- README.md | 1 + thothlibrary/cli.py | 86 +++++++++++++--------- thothlibrary/thoth-0_4_2/endpoints.py | 102 +++++++++++++++++++------- 3 files changed, 128 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 4eda85f..fd95aa9 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ print(thoth.works()) ```sh python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 python3 -m thothlibrary.cli contributors --limit=10 +python3 -m thothlibrary.cli contributor_count --filter="Vincent" python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 7a6c663..28a2d9c 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -6,7 +6,6 @@ import json import fire -import pickle def _raw_parse(value): @@ -44,7 +43,7 @@ def _client(self): @fire.decorators.SetParseFn(_raw_parse) def contributions(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, contribution_type=None, raw=False, + filter=None, contribution_type=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves works from a Thoth instance @@ -52,7 +51,7 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param str contribution_type: the contribution type (e.g. AUTHOR) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version @@ -68,7 +67,7 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, contribs = self._client().contributions(limit=limit, order=order, offset=offset, publishers=publishers, - filter_str=filter_str, + filter=filter, contribution_type= contribution_type, raw=raw) @@ -81,14 +80,14 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, print(contribs) @fire.decorators.SetParseFn(_raw_parse) - def contributors(self, limit=100, order=None, offset=0, filter_str=None, + def contributors(self, limit=100, order=None, offset=0, filter=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves contributors from a Thoth instance :param int limit: the maximum number of results to return (default: 100) :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -102,7 +101,7 @@ def contributors(self, limit=100, order=None, offset=0, filter_str=None, contribs = self._client().contributors(limit=limit, order=order, offset=offset, - filter_str=filter_str, + filter=filter, raw=raw) if not raw and not serialize: @@ -114,7 +113,7 @@ def contributors(self, limit=100, order=None, offset=0, filter_str=None, @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, work_type=None, work_status=None, raw=False, + filter=None, work_type=None, work_status=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves works from a Thoth instance @@ -122,7 +121,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param str work_type: the work type (e.g. MONOGRAPH) :param str work_status: the work status (e.g. ACTIVE) :param bool raw: whether to return a python object or the raw server result @@ -138,7 +137,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, works = self._client().works(limit=limit, order=order, offset=offset, publishers=publishers, - filter_str=filter_str, + filter=filter, work_type=work_type, work_status=work_status, raw=raw) @@ -295,7 +294,7 @@ def imprint(self, imprint_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, raw=False, version=None, endpoint=None, + filter=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves publishers from a Thoth instance @@ -303,7 +302,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -319,7 +318,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, found_publishers = self._client().publishers(limit=limit, order=order, offset=offset, publishers=publishers, - filter_str=filter_str, + filter=filter, raw=raw) if not raw and not serialize: @@ -331,7 +330,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, @fire.decorators.SetParseFn(_raw_parse) def imprints(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, raw=False, version=None, endpoint=None, + filter=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves imprints from a Thoth instance @@ -339,7 +338,7 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -355,7 +354,7 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, imprints = self._client().imprints(limit=limit, order=order, offset=offset, publishers=publishers, - filter_str=filter_str, + filter=filter, raw=raw) if not raw and not serialize: @@ -366,12 +365,31 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, print(imprints) @fire.decorators.SetParseFn(_raw_parse) - def publisher_count(self, publishers=None, filter_str=None, raw=False, + def contributor_count(self, filter=None, raw=False, version=None, + endpoint=None): + """ + Retrieves a count of contributors from a Thoth instance + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().contributor_count(filter=filter, raw=raw)) + + @fire.decorators.SetParseFn(_raw_parse) + def publisher_count(self, publishers=None, filter=None, raw=False, version=None, endpoint=None): """ Retrieves a count of publishers from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -384,16 +402,16 @@ def publisher_count(self, publishers=None, filter_str=None, raw=False, self.version = version print(self._client().publisher_count(publishers=publishers, - filter_str=filter_str, + filter=filter, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def imprint_count(self, publishers=None, filter_str=None, raw=False, + def imprint_count(self, publishers=None, filter=None, raw=False, version=None, endpoint=None): """ Retrieves a count of imprints from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -406,17 +424,17 @@ def imprint_count(self, publishers=None, filter_str=None, raw=False, self.version = version print(self._client().imprint_count(publishers=publishers, - filter_str=filter_str, + filter=filter, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def work_count(self, publishers=None, filter_str=None, raw=False, + def work_count(self, publishers=None, filter=None, raw=False, work_type=None, work_status=None, version=None, endpoint=None): """ Retrieves a count of works from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str work_type: the work type (e.g. MONOGRAPH) @@ -431,18 +449,18 @@ def work_count(self, publishers=None, filter_str=None, raw=False, self.version = version print(self._client().work_count(publishers=publishers, - filter_str=filter_str, + filter=filter, work_type=work_type, work_status=work_status, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def publication_count(self, publishers=None, filter_str=None, raw=False, + def publication_count(self, publishers=None, filter=None, raw=False, publication_type=None, version=None, endpoint=None): """ Retrieves a count of publications from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str publication_type: the work type (e.g. MONOGRAPH) @@ -456,17 +474,17 @@ def publication_count(self, publishers=None, filter_str=None, raw=False, self.version = version print(self._client().publication_count(publishers=publishers, - filter_str=filter_str, + filter=filter, publication_type=publication_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def contribution_count(self, publishers=None, filter_str=None, raw=False, + def contribution_count(self, publishers=None, filter=None, raw=False, contribution_type=None, version=None, endpoint=None): """ Retrieves a count of publications from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str contribution_type: the work type (e.g. AUTHOR) @@ -480,13 +498,13 @@ def contribution_count(self, publishers=None, filter_str=None, raw=False, self.version = version print(self._client().contribution_count(publishers=publishers, - filter_str=filter_str, + filter=filter, contribution_type=contribution_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, - filter_str=None, publication_type=None, raw=False, + filter=None, publication_type=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves publications from a Thoth instance @@ -494,7 +512,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by - :param str filter_str: a filter string to search + :param str filter: a filter string to search :param str publication_type: the work type (e.g. PAPERBACK) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version @@ -509,7 +527,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, pubs = self._client().publications(limit=limit, order=order, offset=offset, publishers=publishers, - filter_str=filter_str, + filter=filter, publication_type=publication_type, raw=raw) if not raw and not serialize: diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index ce6a342..d2c7a7a 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -331,6 +331,12 @@ class ThothClient0_4_2(ThothClient): ], }, + "contributorCount": { + "parameters": [ + "filter", + ], + }, + "workCount": { "parameters": [ "filter", @@ -371,7 +377,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', - 'contributor', 'QUERIES'] + 'contributor', 'contributor_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -403,7 +409,7 @@ def publication(self, publication_id: str, raw: bool = False): return self._api_request("publication", parameters, return_raw=raw) def publications(self, limit: int = 100, offset: int = 0, - filter_str: str = "", order: str = None, + filter: str = "", order: str = None, publishers: str = None, publication_type: str = None, raw: bool = False): """ @@ -412,7 +418,7 @@ def publications(self, limit: int = 100, offset: int = 0, @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param filter_str: a filter string to search + @param filter: a filter string to search @param publication_type: the work type (e.g. PAPERBACK) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response @@ -424,7 +430,10 @@ def publications(self, limit: int = 100, offset: int = 0, "limit": limit, } - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'publicationType', publication_type) @@ -432,7 +441,7 @@ def publications(self, limit: int = 100, offset: int = 0, return self._api_request("publications", parameters, return_raw=raw) def contributions(self, limit: int = 100, offset: int = 0, - filter_str: str = "", order: str = None, + filter: str = "", order: str = None, publishers: str = None, contribution_type: str = None, raw: bool = False): """ @@ -441,7 +450,7 @@ def contributions(self, limit: int = 100, offset: int = 0, @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param filter_str: a filter string to search + @param filter: a filter string to search @param contribution_type: the contribution type (e.g. AUTHOR) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response @@ -453,7 +462,10 @@ def contributions(self, limit: int = 100, offset: int = 0, "limit": limit, } - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'contributionType', @@ -462,14 +474,14 @@ def contributions(self, limit: int = 100, offset: int = 0, return self._api_request("contributions", parameters, return_raw=raw) def contributors(self, limit: int = 100, offset: int = 0, - filter_str: str = "", order: str = None, + filter: str = "", order: str = None, raw: bool = False): """ Returns a contributions list @param limit: the maximum number of results to return (default: 100) @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) - @param filter_str: a filter string to search + @param filter: a filter string to search @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ @@ -480,12 +492,15 @@ def contributors(self, limit: int = 100, offset: int = 0, "limit": limit, } - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) return self._api_request("contributors", parameters, return_raw=raw) - def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", + def works(self, limit: int = 100, offset: int = 0, filter: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): """ @@ -494,7 +509,7 @@ def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param filter_str: a filter string to search + @param filter: a filter string to search @param work_type: the work type (e.g. MONOGRAPH) @param work_status: the work status (e.g. ACTIVE) @param raw: whether to return a python object or the raw server result @@ -507,7 +522,10 @@ def works(self, limit: int = 100, offset: int = 0, filter_str: str = "", "limit": limit, } - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'workType', work_type) @@ -568,7 +586,7 @@ def imprint(self, imprint_id: str, raw: bool = False): return self._api_request("imprint", parameters, return_raw=raw) def publishers(self, limit: int = 100, offset: int = 0, order: str = None, - filter_str: str = "", publishers: str = None, + filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" parameters = { @@ -576,14 +594,17 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publishers", parameters, return_raw=raw) def imprints(self, limit: int = 100, offset: int = 0, order: str = None, - filter_str: str = "", publishers: str = None, + filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" parameters = { @@ -591,51 +612,63 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("imprints", parameters, return_raw=raw) - def publisher_count(self, filter_str: str = "", publishers: str = None, + def publisher_count(self, filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" parameters = {} - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publisherCount", parameters, return_raw=raw) - def imprint_count(self, filter_str: str = "", publishers: str = None, + def imprint_count(self, filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" parameters = {} - self._dictionary_append(parameters, 'filter', filter_str) + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("imprintCount", parameters, return_raw=raw) - def work_count(self, filter_str: str = "", publishers: str = None, + def work_count(self, filter: str = "", publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): """Construct and trigger a query to count works""" parameters = {} - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'workType', work_type) self._dictionary_append(parameters, 'workStatus', work_status) return self._api_request("workCount", parameters, return_raw=raw) - def contribution_count(self, filter_str: str = "", publishers: str = None, + def contribution_count(self, filter: str = "", publishers: str = None, contribution_type: str = None, raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'contributionType', contribution_type) @@ -643,14 +676,29 @@ def contribution_count(self, filter_str: str = "", publishers: str = None, return self._api_request("contributionCount", parameters, return_raw=raw) - def publication_count(self, filter_str: str = "", publishers: str = None, + def publication_count(self, filter: str = "", publishers: str = None, publication_type: str = None, raw: bool = False): """Construct and trigger a query to count publications""" parameters = {} - self._dictionary_append(parameters, 'filter', filter_str) + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'publicationType', publication_type) return self._api_request("publicationCount", parameters, return_raw=raw) + + def contributor_count(self, filter: str = "", raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + + return self._api_request("contributorCount", parameters, + return_raw=raw) From 866ae5b4c7907cd9183bb364fd9e73508fea0681 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 17:24:43 +0100 Subject: [PATCH 059/115] Add contributions and contribution_count to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fd95aa9..afdf4e0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh +python3 -m thothlibrary.cli contributions --limit=10 +python3 -m thothlibrary.cli contribution_count python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 python3 -m thothlibrary.cli contributors --limit=10 python3 -m thothlibrary.cli contributor_count --filter="Vincent" From 451ce0f94fd69d205a7550e5f0445319703eaa31 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 17:41:53 +0100 Subject: [PATCH 060/115] Add contribution endpoint, CLI, and tests --- README.md | 1 + thothlibrary/cli.py | 32 +++++++++++-- thothlibrary/thoth-0_4_2/endpoints.py | 47 +++++++++++++++---- thothlibrary/thoth-0_4_2/structures.py | 4 +- .../tests/fixtures/contribution.json | 1 + .../tests/fixtures/contribution.pickle | 1 + .../tests/fixtures/contribution_bad.json | 1 + .../tests/fixtures/contributions.json | 2 +- .../tests/fixtures/contributions.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 3 +- thothlibrary/thoth-0_4_2/tests/tests.py | 44 +++++++++++++++++ 12 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json diff --git a/README.md b/README.md index afdf4e0..068f729 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ print(thoth.works()) ### CLI GraphQL Usage ```sh +python3 -m thothlibrary.cli contribution --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 python3 -m thothlibrary.cli contributions --limit=10 python3 -m thothlibrary.cli contribution_count python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 28a2d9c..f42d2e8 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -43,15 +43,14 @@ def _client(self): @fire.decorators.SetParseFn(_raw_parse) def contributions(self, limit=100, order=None, offset=0, publishers=None, - filter=None, contribution_type=None, raw=False, - version=None, endpoint=None, serialize=False): + contribution_type=None, raw=False, version=None, + endpoint=None, serialize=False): """ Retrieves works from a Thoth instance :param int limit: the maximum number of results to return (default: 100) :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search :param str contribution_type: the contribution type (e.g. AUTHOR) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version @@ -67,7 +66,6 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, contribs = self._client().contributions(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, contribution_type= contribution_type, raw=raw) @@ -268,6 +266,32 @@ def contributor(self, contributor_id, raw=False, version=None, else: print(json.dumps(contributor)) + @fire.decorators.SetParseFn(_raw_parse) + def contribution(self, contribution_id, raw=False, version=None, + endpoint=None, serialize=False): + """ + Retrieves a contribution by ID from a Thoth instance + :param str contribution_id: the contributor to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + contribution = self._client().contribution(contribution_id= + contribution_id, + raw=raw) + + if not serialize: + print(contribution) + else: + print(json.dumps(contribution)) + @fire.decorators.SetParseFn(_raw_parse) def imprint(self, imprint_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index d2c7a7a..deb8130 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -206,6 +206,28 @@ class ThothClient0_4_2(ThothClient): "fullName", "contributionOrdinal", "workId", + "work { fullTitle }", + "contributor {firstName lastName fullName orcid __typename website contributorId}" + ] + }, + + "contribution": { + "parameters": [ + "contributionId", + ], + "fields": [ + "contributionId", + "contributionType", + "mainContribution", + "biography", + "institution", + "__typename", + "firstName", + "lastName", + "fullName", + "contributionOrdinal", + "workId", + "work { fullTitle }", "contributor {firstName lastName fullName orcid __typename website contributorId}" ] }, @@ -373,7 +395,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): # class. Note, it should always, also, contain the QUERIES list self.endpoints = ['works', 'work_by_doi', 'work_by_id', 'publishers', 'publisher', 'publications', - 'contributions', 'publisher_count', + 'contributions', 'contribution', 'publisher_count', 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', @@ -441,16 +463,14 @@ def publications(self, limit: int = 100, offset: int = 0, return self._api_request("publications", parameters, return_raw=raw) def contributions(self, limit: int = 100, offset: int = 0, - filter: str = "", order: str = None, - publishers: str = None, contribution_type: str = None, - raw: bool = False): + order: str = None, publishers: str = None, + contribution_type: str = None, raw: bool = False): """ Returns a contributions list @param limit: the maximum number of results to return (default: 100) @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param filter: a filter string to search @param contribution_type: the contribution type (e.g. AUTHOR) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response @@ -462,10 +482,6 @@ def contributions(self, limit: int = 100, offset: int = 0, "limit": limit, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) - - self._dictionary_append(parameters, 'filter', filter) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'contributionType', @@ -572,6 +588,19 @@ def publisher(self, publisher_id: str, raw: bool = False): return self._api_request("publisher", parameters, return_raw=raw) + def contribution(self, contribution_id: str, raw: bool = False): + """ + Returns a contribution by ID + @param contribution_id: the contribution ID + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'contributionId': '"' + contribution_id + '"' + } + + return self._api_request("contribution", parameters, return_raw=raw) + def imprint(self, imprint_id: str, raw: bool = False): """ Returns a work by DOI diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 5df2fa7..a739837 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -74,7 +74,9 @@ def __price_parser(prices): 'imprint': lambda self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', 'contributions': lambda - self: f'{self.fullName} ({self.contributionType}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', + self: f'{self.fullName} ({self.contributionType} of {self.work.fullTitle}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', + 'contribution': lambda + self: f'{self.fullName} ({self.contributionType} of {self.work.fullTitle}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', 'contributors': lambda self: f'{self.fullName} ({self.contributions[0].contributionType} of {self.contributions[0].work.fullTitle}) [{self.contributorId}]' if '__typename' in self and self.__typename == 'Contributor' else f'{_muncher_repr(self)}', 'contributor': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json new file mode 100644 index 0000000..9116c45 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json @@ -0,0 +1 @@ +{"data":{"contribution":{"contributionId":"29e4f46b-851a-4d7b-bb41-e6f305fc2b11","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","contributionOrdinal":1,"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","work":{"fullTitle":"Closer to Dust"},"contributor":{"firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","orcid":"https://orcid.org/0000-0001-9176-8514","__typename":"Contributor","website":null,"contributorId":"c145d392-c37e-41b6-9225-1c3a1a46f460"}}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle new file mode 100644 index 0000000..309815b --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle @@ -0,0 +1 @@ +{"contributionId": "29e4f46b-851a-4d7b-bb41-e6f305fc2b11", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "contributionOrdinal": 1, "workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "work": {"fullTitle": "Closer to Dust"}, "contributor": {"firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "orcid": "https://orcid.org/0000-0001-9176-8514", "__typename": "Contributor", "website": null, "contributorId": "c145d392-c37e-41b6-9225-1c3a1a46f460"}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json new file mode 100644 index 0000000..5ba553b --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json @@ -0,0 +1 @@ +{"data": {"contribution": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json index 09fec57..d020677 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.json @@ -1 +1 @@ -{"data":{"contributions":[{"contributionId":"1a3ef666-c624-4240-a176-b510ff899040","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","contributionOrdinal":1,"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","contributor":{"firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","orcid":"https://orcid.org/0000-0001-7995-5915","__typename":"Contributor","website":"http://www.danielacascella.com","contributorId":"1fab9df5-d9b4-4695-973e-ebb052b184ff"}},{"contributionId":"29e4f46b-851a-4d7b-bb41-e6f305fc2b11","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","contributionOrdinal":1,"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","contributor":{"firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","orcid":"https://orcid.org/0000-0001-9176-8514","__typename":"Contributor","website":null,"contributorId":"c145d392-c37e-41b6-9225-1c3a1a46f460"}}]}} +{"data":{"contributions":[{"contributionId":"1a3ef666-c624-4240-a176-b510ff899040","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","contributionOrdinal":1,"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","work":{"fullTitle":"Nothing As We Need It: A Chimera"},"contributor":{"firstName":"Daniela","lastName":"Cascella","fullName":"Daniela Cascella","orcid":"https://orcid.org/0000-0001-7995-5915","__typename":"Contributor","website":"http://www.danielacascella.com","contributorId":"1fab9df5-d9b4-4695-973e-ebb052b184ff"}},{"contributionId":"29e4f46b-851a-4d7b-bb41-e6f305fc2b11","contributionType":"AUTHOR","mainContribution":true,"biography":null,"institution":null,"__typename":"Contribution","firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","contributionOrdinal":1,"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","work":{"fullTitle":"Closer to Dust"},"contributor":{"firstName":"Sara A.","lastName":"Rich","fullName":"Sara A. Rich","orcid":"https://orcid.org/0000-0001-9176-8514","__typename":"Contributor","website":null,"contributorId":"c145d392-c37e-41b6-9225-1c3a1a46f460"}}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle index 6cf761d..44b98f8 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributions.pickle @@ -1 +1 @@ -[{"contributionId": "1a3ef666-c624-4240-a176-b510ff899040", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Daniela", "lastName": "Cascella", "fullName": "Daniela Cascella", "contributionOrdinal": 1, "workId": "a01f41d6-1da8-4b0b-87b4-82ecc41c6d55", "contributor": {"firstName": "Daniela", "lastName": "Cascella", "fullName": "Daniela Cascella", "orcid": "https://orcid.org/0000-0001-7995-5915", "__typename": "Contributor", "website": "http://www.danielacascella.com", "contributorId": "1fab9df5-d9b4-4695-973e-ebb052b184ff"}}, {"contributionId": "29e4f46b-851a-4d7b-bb41-e6f305fc2b11", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "contributionOrdinal": 1, "workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "contributor": {"firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "orcid": "https://orcid.org/0000-0001-9176-8514", "__typename": "Contributor", "website": null, "contributorId": "c145d392-c37e-41b6-9225-1c3a1a46f460"}}] +[{"contributionId": "1a3ef666-c624-4240-a176-b510ff899040", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Daniela", "lastName": "Cascella", "fullName": "Daniela Cascella", "contributionOrdinal": 1, "workId": "a01f41d6-1da8-4b0b-87b4-82ecc41c6d55", "work": {"fullTitle": "Nothing As We Need It: A Chimera"}, "contributor": {"firstName": "Daniela", "lastName": "Cascella", "fullName": "Daniela Cascella", "orcid": "https://orcid.org/0000-0001-7995-5915", "__typename": "Contributor", "website": "http://www.danielacascella.com", "contributorId": "1fab9df5-d9b4-4695-973e-ebb052b184ff"}}, {"contributionId": "29e4f46b-851a-4d7b-bb41-e6f305fc2b11", "contributionType": "AUTHOR", "mainContribution": true, "biography": null, "institution": null, "__typename": "Contribution", "firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "contributionOrdinal": 1, "workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "work": {"fullTitle": "Closer to Dust"}, "contributor": {"firstName": "Sara A.", "lastName": "Rich", "fullName": "Sara A. Rich", "orcid": "https://orcid.org/0000-0001-9176-8514", "__typename": "Contributor", "website": null, "contributorId": "c145d392-c37e-41b6-9225-1c3a1a46f460"}}] diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index b810832..682d02f 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -25,3 +25,4 @@ bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thot bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle" bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle" bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle" +bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 7897aac..feaedbe 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -23,7 +23,7 @@ bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --raw > thothlibra bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json" bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json" bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json" - +bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -37,3 +37,4 @@ bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_ bash -c "echo '{\"data\": {\"imprint\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json" bash -c "echo '{\"data\": {\"contributors\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json" bash -c "echo '{\"data\": {\"contributor\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json" +bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 4e6c73c..0b70d6f 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -451,6 +451,50 @@ def test_contributor_raw(self): lambda_mode=True) return None + def test_contribution(self): + """ + Tests that good input to contribution produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contribution', m) + self.pickle_tester('contribution', + lambda: + thoth_client.contribution( + contribution_id='29e4f46b-851a-4d7b-bb41-' + 'e6f305fc2b11')) + return None + + def test_contribution_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contribution_bad', + m) + self.pickle_tester('contribution', + lambda: thoth_client.contribution( + contribution_id='29e4f46b-851a-4d7b-bb41-' + 'e6f305fc2b11'), + negative=True) + return None + + def test_contribution_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contribution', m) + self.raw_tester(mock_response, + lambda: thoth_client.contribution( + contribution_id='29e4f46b-851a-4d7b-bb41-' + 'e6f305fc2b11', + raw=True), + lambda_mode=True) + return None + def test_contributors(self): """ Tests that good input to contributors produces saved good output From 3eb8ad82859bc7158d909fd28257732c70361806 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 18:24:01 +0100 Subject: [PATCH 061/115] Add serieses endpoint, CLI, and tests --- README.md | 1 + thothlibrary/cli.py | 38 ++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 44 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/serieses.json | 1 + .../tests/fixtures/serieses.pickle | 1 + .../tests/fixtures/serieses_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 30 +++++++++++++ 10 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json diff --git a/README.md b/README.md index 068f729..e5d01f0 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index f42d2e8..fbbdbd3 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -388,6 +388,44 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, else: print(imprints) + @fire.decorators.SetParseFn(_raw_parse) + def serieses(self, limit=100, order=None, offset=0, publishers=None, + filter=None, series_type=None, raw=False, version=None, + endpoint=None, serialize=False): + """ + Retrieves serieses from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param series_type: the type of serieses to return (e.g. BOOK_SERIES) + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + serieses = self._client().serieses(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + series_type=series_type, + raw=raw) + + if not raw and not serialize: + print(*serieses, sep='\n') + elif serialize: + print(json.dumps(serieses)) + else: + print(serieses) + @fire.decorators.SetParseFn(_raw_parse) def contributor_count(self, filter=None, raw=False, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index deb8130..94a9856 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -285,6 +285,28 @@ class ThothClient0_4_2(ThothClient): ] }, + "serieses": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "seriesType" + ], + "fields": [ + "seriesId", + "seriesType", + "seriesName", + "updatedAt", + "createdAt", + "imprintId", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "issues { issueId work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } } }", + "__typename" + ] + }, + "imprints": { "parameters": [ "limit", @@ -399,7 +421,8 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contribution_count', 'work_count', 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', - 'contributor', 'contributor_count', 'QUERIES'] + 'contributor', 'contributor_count', 'serieses', + 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -632,6 +655,25 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("publishers", parameters, return_raw=raw) + def serieses(self, limit: int = 100, offset: int = 0, order: str = None, + filter: str = "", publishers: str = None, + series_type: str = "", raw: bool = False): + """Construct and trigger a query to obtain all serieses""" + parameters = { + "limit": limit, + "offset": offset, + } + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'seriesType', series_type) + + return self._api_request("serieses", parameters, return_raw=raw) + def imprints(self, limit: int = 100, offset: int = 0, order: str = None, filter: str = "", publishers: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index a739837..653a6de 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -84,6 +84,8 @@ def __price_parser(prices): 'publication': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', + 'serieses': lambda + self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json b/thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json new file mode 100644 index 0000000..b3008b9 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json @@ -0,0 +1 @@ +{"data":{"serieses":[{"seriesId":"7c662a4d-14ac-44cc-8325-5dc0e207cb96","seriesType":"BOOK_SERIES","seriesName":"Applied Theatre Praxis","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}},"issues":[{"issueId":"0d4687f9-3d86-4518-9437-e3e1832bd779","work":{"workId":"41aed95c-de6c-4b37-b533-fe79af56cf82","fullTitle":"Theatre and War: Notes from the Field","doi":"https://doi.org/10.11647/OBP.0099","publicationDate":"2016-07-27","place":"Cambridge, UK","contributions":[{"fullName":"Nandita Dinesh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"94dada1b-337b-4f0c-8cab-723cdf8e297a","work":{"workId":"7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1","fullTitle":"Chronicles from Kashmir: An Annotated, Multimedia Script","doi":"https://doi.org/10.11647/OBP.0223","publicationDate":"2020-09-14","place":"Cambridge, UK","contributions":[{"fullName":"Nandita Dinesh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}}],"__typename":"Series"},{"seriesId":"ca4b4ff7-f461-464b-8768-dfad8ce20968","seriesType":"BOOK_SERIES","seriesName":"Classics Textbooks","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}},"issues":[{"issueId":"658e0d3d-8bf1-4086-b054-d001fe6ad7b0","work":{"workId":"c5fe7f09-7dfb-4637-82c8-653a6cb683e7","fullTitle":"Cicero, Against Verres, 2.1.53–86: Latin Text with Introduction, Study Questions, Commentary and English Translation","doi":"https://doi.org/10.11647/OBP.0016","publicationDate":"2011-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"1287f135-4603-4b20-bb85-526a25d07466","work":{"workId":"d578b548-3938-4047-9426-ea82796ad7b3","fullTitle":"Virgil, Aeneid, 4.1–299: Latin Text, Study Questions, Commentary and Interpretative Essays","doi":"https://doi.org/10.11647/OBP.0023","publicationDate":"2012-11-22","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"9ac898bf-ecf3-43e0-a095-cd242f296dca","work":{"workId":"26928aa4-c6b9-42ca-9ffb-12fbbea7f06d","fullTitle":"Tacitus, Annals, 15.20-23, 33-45: Latin Text, Study Aids with Vocabulary, and Commentary","doi":"https://doi.org/10.11647/OBP.0035","publicationDate":"2013-09-20","place":"Cambridge, UK","contributions":[{"fullName":"Mathew Owen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"4d4168d9-dfd8-4f28-af3d-586f0ad6b0e5","work":{"workId":"a03ba4d1-1576-41d0-9e8b-d74eccb682e2","fullTitle":"Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation","doi":"https://doi.org/10.11647/OBP.0045","publicationDate":"2014-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Louise Hodgson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"91860e97-ef4e-4924-a204-ccd59df63370","work":{"workId":"a292bc0f-f026-4759-acd0-da081c2b9f1d","fullTitle":"Ovid, Metamorphoses, 3.511-733: Latin Text with Introduction, Commentary, Glossary of Terms, Vocabulary Aid and Study Questions","doi":"https://doi.org/10.11647/OBP.0073","publicationDate":"2016-09-05","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andrew Zissos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"0bf32777-2185-4596-85da-e0c8fda987d0","work":{"workId":"7e753cbc-c74b-4214-a565-2300f544be77","fullTitle":"Cicero, Philippic 2, 44–50, 78–92, 100–119: Latin Text, Study Aids with Vocabulary, and Commentary","doi":"https://doi.org/10.11647/OBP.0156","publicationDate":"2018-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"42f28391-75d2-4b3c-b746-bf40255f5d9d","work":{"workId":"85cc4bb1-a397-4904-9213-36f1e71e334c","fullTitle":"Virgil, Aeneid 11, Pallas and Camilla, 1–224, 498–521, 532–596, 648–689, 725–835: Latin Text, Study Aids with Vocabulary, and Commentary","doi":"https://doi.org/10.11647/OBP.0158","publicationDate":"2018-12-05","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"John Henderson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]}}],"__typename":"Series"},{"seriesId":"4051770d-6aa3-4ac5-a49c-029e4aa90f3d","seriesType":"BOOK_SERIES","seriesName":"Dickinson College Commentaries","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}},"issues":[{"issueId":"3c776175-61d4-433b-a6b9-2491913d16fa","work":{"workId":"e5ade02a-2f32-495a-b879-98b54df04c0a","fullTitle":"Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary","doi":"https://doi.org/10.11647/OBP.0068","publicationDate":"2015-10-05","place":"Cambridge, UK","contributions":[{"fullName":"Bret Mulligan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"1fa54ac9-becc-47b3-8878-2234a14421dc","work":{"workId":"f47b7d98-56cb-4d8c-a313-0d0e09d06352","fullTitle":"Ovid, Amores (Book 1)","doi":"https://doi.org/10.11647/OBP.0067","publicationDate":"2016-05-15","place":"Cambridge, UK","contributions":[{"fullName":"William Turpin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}}],"__typename":"Series"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle new file mode 100644 index 0000000..1415997 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle @@ -0,0 +1 @@ +[{"seriesId": "7c662a4d-14ac-44cc-8325-5dc0e207cb96", "seriesType": "BOOK_SERIES", "seriesName": "Applied Theatre Praxis", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}, "issues": [{"issueId": "0d4687f9-3d86-4518-9437-e3e1832bd779", "work": {"workId": "41aed95c-de6c-4b37-b533-fe79af56cf82", "fullTitle": "Theatre and War: Notes from the Field", "doi": "https://doi.org/10.11647/OBP.0099", "publicationDate": "2016-07-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Nandita Dinesh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "94dada1b-337b-4f0c-8cab-723cdf8e297a", "work": {"workId": "7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1", "fullTitle": "Chronicles from Kashmir: An Annotated, Multimedia Script", "doi": "https://doi.org/10.11647/OBP.0223", "publicationDate": "2020-09-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Nandita Dinesh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}], "__typename": "Series"}, {"seriesId": "ca4b4ff7-f461-464b-8768-dfad8ce20968", "seriesType": "BOOK_SERIES", "seriesName": "Classics Textbooks", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}, "issues": [{"issueId": "658e0d3d-8bf1-4086-b054-d001fe6ad7b0", "work": {"workId": "c5fe7f09-7dfb-4637-82c8-653a6cb683e7", "fullTitle": "Cicero, Against Verres, 2.1.53\u201386: Latin Text with Introduction, Study Questions, Commentary and English Translation", "doi": "https://doi.org/10.11647/OBP.0016", "publicationDate": "2011-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "1287f135-4603-4b20-bb85-526a25d07466", "work": {"workId": "d578b548-3938-4047-9426-ea82796ad7b3", "fullTitle": "Virgil, Aeneid, 4.1\u2013299: Latin Text, Study Questions, Commentary and Interpretative Essays", "doi": "https://doi.org/10.11647/OBP.0023", "publicationDate": "2012-11-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "9ac898bf-ecf3-43e0-a095-cd242f296dca", "work": {"workId": "26928aa4-c6b9-42ca-9ffb-12fbbea7f06d", "fullTitle": "Tacitus, Annals, 15.20-23, 33-45: Latin Text, Study Aids with Vocabulary, and Commentary", "doi": "https://doi.org/10.11647/OBP.0035", "publicationDate": "2013-09-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Mathew Owen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "4d4168d9-dfd8-4f28-af3d-586f0ad6b0e5", "work": {"workId": "a03ba4d1-1576-41d0-9e8b-d74eccb682e2", "fullTitle": "Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation", "doi": "https://doi.org/10.11647/OBP.0045", "publicationDate": "2014-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Louise Hodgson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "91860e97-ef4e-4924-a204-ccd59df63370", "work": {"workId": "a292bc0f-f026-4759-acd0-da081c2b9f1d", "fullTitle": "Ovid, Metamorphoses, 3.511-733: Latin Text with Introduction, Commentary, Glossary of Terms, Vocabulary Aid and Study Questions", "doi": "https://doi.org/10.11647/OBP.0073", "publicationDate": "2016-09-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andrew Zissos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "0bf32777-2185-4596-85da-e0c8fda987d0", "work": {"workId": "7e753cbc-c74b-4214-a565-2300f544be77", "fullTitle": "Cicero, Philippic 2, 44\u201350, 78\u201392, 100\u2013119: Latin Text, Study Aids with Vocabulary, and Commentary", "doi": "https://doi.org/10.11647/OBP.0156", "publicationDate": "2018-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "42f28391-75d2-4b3c-b746-bf40255f5d9d", "work": {"workId": "85cc4bb1-a397-4904-9213-36f1e71e334c", "fullTitle": "Virgil, Aeneid 11, Pallas and Camilla, 1\u2013224, 498\u2013521, 532\u2013596, 648\u2013689, 725\u2013835: Latin Text, Study Aids with Vocabulary, and Commentary", "doi": "https://doi.org/10.11647/OBP.0158", "publicationDate": "2018-12-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "John Henderson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}}], "__typename": "Series"}, {"seriesId": "4051770d-6aa3-4ac5-a49c-029e4aa90f3d", "seriesType": "BOOK_SERIES", "seriesName": "Dickinson College Commentaries", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}, "issues": [{"issueId": "3c776175-61d4-433b-a6b9-2491913d16fa", "work": {"workId": "e5ade02a-2f32-495a-b879-98b54df04c0a", "fullTitle": "Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary", "doi": "https://doi.org/10.11647/OBP.0068", "publicationDate": "2015-10-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Bret Mulligan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "1fa54ac9-becc-47b3-8878-2234a14421dc", "work": {"workId": "f47b7d98-56cb-4d8c-a313-0d0e09d06352", "fullTitle": "Ovid, Amores (Book 1)", "doi": "https://doi.org/10.11647/OBP.0067", "publicationDate": "2016-05-15", "place": "Cambridge, UK", "contributions": [{"fullName": "William Turpin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}}], "__typename": "Series"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json new file mode 100644 index 0000000..ebf03f3 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json @@ -0,0 +1 @@ +{"data": {"serieses": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 682d02f..390e8ff 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -25,4 +25,5 @@ bash -c "python3 -m thothlibrary.cli imprints --version=0.4.2 --serialize > thot bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle" bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle" bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle" -bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle" +bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index feaedbe..7be5641 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -24,6 +24,7 @@ bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a2 bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.json" bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json" bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json" +bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -37,4 +38,5 @@ bash -c "echo '{\"data\": {\"imprints\": [\"1\"] } }' > thothlibrary/thoth-0_4_ bash -c "echo '{\"data\": {\"imprint\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/imprint_bad.json" bash -c "echo '{\"data\": {\"contributors\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json" bash -c "echo '{\"data\": {\"contributor\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json" -bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json" +bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 0b70d6f..2427741 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -526,6 +526,36 @@ def test_contributors_raw(self): self.raw_tester(mock_response, thoth_client.contributors) return None + def test_serieses(self): + """ + Tests that good input to serieses produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('serieses', m) + self.pickle_tester('serieses', thoth_client.serieses) + return None + + def test_serieses_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('serieses_bad', m) + self.pickle_tester('serieses', thoth_client.serieses, + negative=True) + + def test_serieses_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('serieses', m) + self.raw_tester(mock_response, thoth_client.serieses) + return None + def raw_tester(self, mock_response, method_to_call, lambda_mode=False): """ An echo test that ensures the client returns accurate raw responses From ca0aecba798dff1ace0cb49851d361142accd77e Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 18:54:33 +0100 Subject: [PATCH 062/115] Add series endpoint, CLI, and tests --- README.md | 1 + thothlibrary/cli.py | 24 ++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 32 +++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/series.json | 1 + .../thoth-0_4_2/tests/fixtures/series.pickle | 1 + .../tests/fixtures/series_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 44 +++++++++++++++++++ 10 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/series.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json diff --git a/README.md b/README.md index e5d01f0..b75b197 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9adf979c3b python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli series --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index fbbdbd3..93a4e00 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -292,6 +292,30 @@ def contribution(self, contribution_id, raw=False, version=None, else: print(json.dumps(contribution)) + @fire.decorators.SetParseFn(_raw_parse) + def series(self, series_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a series by ID from a Thoth instance + :param str series_id: the series to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + series = self._client().series(series_id=series_id, raw=raw) + + if not serialize: + print(series) + else: + print(json.dumps(series)) + @fire.decorators.SetParseFn(_raw_parse) def imprint(self, imprint_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 94a9856..0a8379c 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -307,6 +307,23 @@ class ThothClient0_4_2(ThothClient): ] }, + "series": { + "parameters": [ + "seriesId" + ], + "fields": [ + "seriesId", + "seriesType", + "seriesName", + "updatedAt", + "createdAt", + "imprintId", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "issues { issueId work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } } }", + "__typename" + ] + }, + "imprints": { "parameters": [ "limit", @@ -422,7 +439,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', - 'QUERIES'] + 'series', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -440,6 +457,19 @@ def contributor(self, contributor_id: str, raw: bool = False): return self._api_request("contributor", parameters, return_raw=raw) + def series(self, series_id: str, raw: bool = False): + """ + Returns a series by ID + @param series_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'seriesId': '"' + series_id + '"' + } + + return self._api_request("series", parameters, return_raw=raw) + def publication(self, publication_id: str, raw: bool = False): """ Returns a publication by ID diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 653a6de..b0bc83e 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -86,6 +86,8 @@ def __price_parser(prices): f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', 'serieses': lambda self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', + 'series': lambda + self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/series.json b/thothlibrary/thoth-0_4_2/tests/fixtures/series.json new file mode 100644 index 0000000..5fb590e --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/series.json @@ -0,0 +1 @@ +{"data":{"series":{"seriesId":"d4b47a76-abff-4047-a3c7-d44d85ccf009","seriesType":"BOOK_SERIES","seriesName":"Open Book Classics","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}},"issues":[{"issueId":"8511e97e-fc52-43ea-9d1e-f733f557c12f","work":{"workId":"f8a1849c-0be0-4600-9653-83b0dc6de3ae","fullTitle":"On History: Introduction to World History (1831); Opening Address at the Faculty of Letters, 9 January 1834; Preface to History of France (1869)","doi":"https://doi.org/10.11647/OBP.0036","publicationDate":"2013-10-09","place":"Cambridge, UK","contributions":[{"fullName":"Jules Michelet","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Lionel Gossman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Edward K. Kaplan","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]}},{"issueId":"a76d90e8-1483-4767-952d-545152119c58","work":{"workId":"5da7830b-6d55-4eb4-899e-cb2a13b30111","fullTitle":"Fiesco's Conspiracy at Genoa","doi":"https://doi.org/10.11647/OBP.0058","publicationDate":"2015-05-27","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"John Guthrie","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]}},{"issueId":"3efbb0f3-bae4-4cce-93d1-845f6f553ae2","work":{"workId":"90aa9d84-a940-4812-bcd8-0d3f2587b41a","fullTitle":"Tolerance: The Beacon of the Enlightenment","doi":"https://doi.org/10.11647/OBP.0088","publicationDate":"2016-01-04","place":"Cambridge, UK","contributions":[{"fullName":"Caroline Warman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"15111d18-899e-435b-b219-29cff3223ef8","work":{"workId":"60450f84-3e18-4beb-bafe-87c78b5a0159","fullTitle":"Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition","doi":"https://doi.org/10.11647/OBP.0098","publicationDate":"2016-06-20","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]}},{"issueId":"e1a1e805-717c-4b21-a9f8-165fc9df7858","work":{"workId":"3047a8b4-d669-4067-8b8a-c908c348c408","fullTitle":"Wallenstein: A Dramatic Poem","doi":"https://doi.org/10.11647/OBP.0101","publicationDate":"2017-02-20","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Roger Paulin","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]}},{"issueId":"ded677d9-26af-4d6c-8505-e649967058c4","work":{"workId":"c699f257-f3e4-4c98-9a3f-741c6a40b62a","fullTitle":"L’idée de l’Europe: au Siècle des Lumières","doi":"https://doi.org/10.11647/OBP.0116","publicationDate":"2017-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"6ca3148c-6b52-4296-8219-3b8e94a24d89","work":{"workId":"fff33c6a-ed8c-49b5-af9d-5a7fca366bc4","fullTitle":"The Idea of Europe: Enlightenment Perspectives","doi":"https://doi.org/10.11647/OBP.0123","publicationDate":"2017-06-23","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"245ab0e0-38cf-4f8f-b2d6-49d104e4523f","work":{"workId":"364c223d-9c90-4ceb-90e2-51be7d84e923","fullTitle":"Die Europaidee im Zeitalter der Aufklärung","doi":"https://doi.org/10.11647/OBP.0127","publicationDate":"2017-08-21","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"ded32745-22ea-45a9-876e-6cd82e8d3093","work":{"workId":"2d74b1a9-c3b0-4278-8cad-856fadc6a19d","fullTitle":"Don Carlos Infante of Spain: A Dramatic Poem","doi":"https://doi.org/10.11647/OBP.0134","publicationDate":"2018-06-04","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]}},{"issueId":"37972a4b-4934-4c64-b8db-eb6803d4f243","work":{"workId":"859a1313-7b02-4c66-8010-dbe533c4412a","fullTitle":"Hyperion or the Hermit in Greece","doi":"https://doi.org/10.11647/OBP.0160","publicationDate":"2019-02-25","place":"Cambridge, UK","contributions":[{"fullName":"Howard Gaskill","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1}]}},{"issueId":"bdef6be4-b7d9-4503-b1a8-326beaa8bcf0","work":{"workId":"734b7fea-08d8-41a9-aa78-ff28a796db9b","fullTitle":"Love and Intrigue: A Bourgeois Tragedy","doi":"https://doi.org/10.11647/OBP.0175","publicationDate":"2019-05-21","place":"Cambridge, UK","contributions":[{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1}]}}],"__typename":"Series"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle new file mode 100644 index 0000000..f40c97c --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle @@ -0,0 +1 @@ +{"seriesId": "d4b47a76-abff-4047-a3c7-d44d85ccf009", "seriesType": "BOOK_SERIES", "seriesName": "Open Book Classics", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}, "issues": [{"issueId": "8511e97e-fc52-43ea-9d1e-f733f557c12f", "work": {"workId": "f8a1849c-0be0-4600-9653-83b0dc6de3ae", "fullTitle": "On History: Introduction to World History (1831); Opening Address at the Faculty of Letters, 9 January 1834; Preface to History of France (1869)", "doi": "https://doi.org/10.11647/OBP.0036", "publicationDate": "2013-10-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Jules Michelet", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Lionel Gossman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Edward K. Kaplan", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}}, {"issueId": "a76d90e8-1483-4767-952d-545152119c58", "work": {"workId": "5da7830b-6d55-4eb4-899e-cb2a13b30111", "fullTitle": "Fiesco's Conspiracy at Genoa", "doi": "https://doi.org/10.11647/OBP.0058", "publicationDate": "2015-05-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "John Guthrie", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}}, {"issueId": "3efbb0f3-bae4-4cce-93d1-845f6f553ae2", "work": {"workId": "90aa9d84-a940-4812-bcd8-0d3f2587b41a", "fullTitle": "Tolerance: The Beacon of the Enlightenment", "doi": "https://doi.org/10.11647/OBP.0088", "publicationDate": "2016-01-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Caroline Warman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "15111d18-899e-435b-b219-29cff3223ef8", "work": {"workId": "60450f84-3e18-4beb-bafe-87c78b5a0159", "fullTitle": "Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition", "doi": "https://doi.org/10.11647/OBP.0098", "publicationDate": "2016-06-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}}, {"issueId": "e1a1e805-717c-4b21-a9f8-165fc9df7858", "work": {"workId": "3047a8b4-d669-4067-8b8a-c908c348c408", "fullTitle": "Wallenstein: A Dramatic Poem", "doi": "https://doi.org/10.11647/OBP.0101", "publicationDate": "2017-02-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Roger Paulin", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}}, {"issueId": "ded677d9-26af-4d6c-8505-e649967058c4", "work": {"workId": "c699f257-f3e4-4c98-9a3f-741c6a40b62a", "fullTitle": "L\u2019id\u00e9e de l\u2019Europe: au Si\u00e8cle des Lumi\u00e8res", "doi": "https://doi.org/10.11647/OBP.0116", "publicationDate": "2017-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "6ca3148c-6b52-4296-8219-3b8e94a24d89", "work": {"workId": "fff33c6a-ed8c-49b5-af9d-5a7fca366bc4", "fullTitle": "The Idea of Europe: Enlightenment Perspectives", "doi": "https://doi.org/10.11647/OBP.0123", "publicationDate": "2017-06-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "245ab0e0-38cf-4f8f-b2d6-49d104e4523f", "work": {"workId": "364c223d-9c90-4ceb-90e2-51be7d84e923", "fullTitle": "Die Europaidee im Zeitalter der Aufkl\u00e4rung", "doi": "https://doi.org/10.11647/OBP.0127", "publicationDate": "2017-08-21", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "ded32745-22ea-45a9-876e-6cd82e8d3093", "work": {"workId": "2d74b1a9-c3b0-4278-8cad-856fadc6a19d", "fullTitle": "Don Carlos Infante of Spain: A Dramatic Poem", "doi": "https://doi.org/10.11647/OBP.0134", "publicationDate": "2018-06-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}}, {"issueId": "37972a4b-4934-4c64-b8db-eb6803d4f243", "work": {"workId": "859a1313-7b02-4c66-8010-dbe533c4412a", "fullTitle": "Hyperion or the Hermit in Greece", "doi": "https://doi.org/10.11647/OBP.0160", "publicationDate": "2019-02-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Howard Gaskill", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}]}}, {"issueId": "bdef6be4-b7d9-4503-b1a8-326beaa8bcf0", "work": {"workId": "734b7fea-08d8-41a9-aa78-ff28a796db9b", "fullTitle": "Love and Intrigue: A Bourgeois Tragedy", "doi": "https://doi.org/10.11647/OBP.0175", "publicationDate": "2019-05-21", "place": "Cambridge, UK", "contributions": [{"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}]}}], "__typename": "Series"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json new file mode 100644 index 0000000..78d7021 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json @@ -0,0 +1 @@ +{"data": {"series": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 390e8ff..f583214 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -26,4 +26,5 @@ bash -c "python3 -m thothlibrary.cli imprint --version=0.4.2 --imprint_id=78b0a2 bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributors.pickle" bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle" bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle" -bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle" +bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 7be5641..583fa6c 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -25,6 +25,7 @@ bash -c "python3 -m thothlibrary.cli contributors --version=0.4.2 --limit=4 --ra bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json" bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json" bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json" +bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/series.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -39,4 +40,5 @@ bash -c "echo '{\"data\": {\"imprint\": [\"1\"] } }' > thothlibrary/thoth-0_4_2 bash -c "echo '{\"data\": {\"contributors\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributors_bad.json" bash -c "echo '{\"data\": {\"contributor\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json" bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json" -bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json" +bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 2427741..b91918e 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -451,6 +451,50 @@ def test_contributor_raw(self): lambda_mode=True) return None + def test_series(self): + """ + Tests that good input to series produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('series', m) + self.pickle_tester('series', + lambda: + thoth_client.series( + series_id='d4b47a76-abff-4047-a3c7-' + 'd44d85ccf009')) + return None + + def test_series_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('series_bad', + m) + self.pickle_tester('series', + lambda: thoth_client.series( + series_id='d4b47a76-abff-4047-a3c7-' + 'd44d85ccf009'), + negative=True) + return None + + def test_series_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('series', m) + self.raw_tester(mock_response, + lambda: thoth_client.series( + series_id='d4b47a76-abff-4047-a3c7-' + 'd44d85ccf009', + raw=True), + lambda_mode=True) + return None + def test_contribution(self): """ Tests that good input to contribution produces saved good output From d641770a685597265623acab37ee11450a7c4b18 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 19:02:12 +0100 Subject: [PATCH 063/115] Add seriesCount endpoint --- README.md | 1 + thothlibrary/cli.py | 22 ++++++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 25 ++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b75b197..ecdd40e 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli series --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" +python3 -m thothlibrary.cli series_count --series_type=BOOK_SERIES python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 93a4e00..8700530 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -540,6 +540,28 @@ def work_count(self, publishers=None, filter=None, raw=False, work_status=work_status, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def series_count(self, publishers=None, filter=None, raw=False, + series_type=None, version=None, endpoint=None): + """ + Retrieves a count of publications from a Thoth instance + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str series_type: the work type (e.g. BOOK_SERIES) + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().series_count(publishers=publishers, filter=filter, + series_type=series_type, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def publication_count(self, publishers=None, filter=None, raw=False, publication_type=None, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 0a8379c..db31bcf 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -421,6 +421,14 @@ class ThothClient0_4_2(ThothClient): "publishers", "contributionType" ], + }, + + "seriesCount": { + "parameters": [ + "filter", + "publishers", + "seriesType" + ], } } @@ -439,7 +447,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', - 'series', 'QUERIES'] + 'series', 'series_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -761,6 +769,21 @@ def work_count(self, filter: str = "", publishers: str = None, return self._api_request("workCount", parameters, return_raw=raw) + def series_count(self, filter: str = "", publishers: str = None, + series_type: str = None, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'seriesType', + series_type) + + return self._api_request("seriesCount", parameters, return_raw=raw) + def contribution_count(self, filter: str = "", publishers: str = None, contribution_type: str = None, raw: bool = False): """Construct and trigger a query to count contribution count""" From d2d63c3a2d64b89b3f3a94aa96c18b018829b366 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 19:33:27 +0100 Subject: [PATCH 064/115] Add issues endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 36 +++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 39 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/issues.json | 1 + .../thoth-0_4_2/tests/fixtures/issues.pickle | 1 + .../tests/fixtures/issues_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 5 ++- thothlibrary/thoth-0_4_2/tests/tests.py | 30 ++++++++++++++ 10 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/issues.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json diff --git a/README.md b/README.md index ecdd40e..bb26b5c 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ python3 -m thothlibrary.cli contributor_count --filter="Vincent" python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli issues --limit=10 python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 8700530..1aeb143 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -376,6 +376,42 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, else: print(found_publishers) + @fire.decorators.SetParseFn(_raw_parse) + def issues(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves imprints from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + issues = self._client().issues(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + raw=raw) + + if not raw and not serialize: + print(*issues, sep='\n') + elif serialize: + print(json.dumps(issues)) + else: + print(issues) + @fire.decorators.SetParseFn(_raw_parse) def imprints(self, limit=100, order=None, offset=0, publishers=None, filter=None, raw=False, version=None, endpoint=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index db31bcf..81e39bf 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -324,6 +324,26 @@ class ThothClient0_4_2(ThothClient): ] }, + "issues": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + ], + "fields": [ + "issueId", + "seriesId", + "issueOrdinal", + "updatedAt", + "createdAt", + "series { seriesId seriesType seriesName imprintId imprint { __typename publisher { publisherName publisherId __typename } }}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "imprints": { "parameters": [ "limit", @@ -447,7 +467,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', - 'series', 'series_count', 'QUERIES'] + 'series', 'series_count', 'issues', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -730,6 +750,23 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("imprints", parameters, return_raw=raw) + def issues(self, limit: int = 100, offset: int = 0, order: str = None, + filter: str = "", publishers: str = None, raw: bool = False): + """Construct and trigger a query to obtain all publishers""" + parameters = { + "limit": limit, + "offset": offset, + } + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("issues", parameters, return_raw=raw) + def publisher_count(self, filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index b0bc83e..8b9119d 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -88,6 +88,8 @@ def __price_parser(prices): self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', 'series': lambda self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', + 'issues': lambda + self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/issues.json b/thothlibrary/thoth-0_4_2/tests/fixtures/issues.json new file mode 100644 index 0000000..37e0e80 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/issues.json @@ -0,0 +1 @@ +{"data":{"issues":[{"issueId":"0d4687f9-3d86-4518-9437-e3e1832bd779","seriesId":"7c662a4d-14ac-44cc-8325-5dc0e207cb96","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"7c662a4d-14ac-44cc-8325-5dc0e207cb96","seriesType":"BOOK_SERIES","seriesName":"Applied Theatre Praxis","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"41aed95c-de6c-4b37-b533-fe79af56cf82","fullTitle":"Theatre and War: Notes from the Field","doi":"https://doi.org/10.11647/OBP.0099","publicationDate":"2016-07-27","place":"Cambridge, UK","contributions":[{"fullName":"Nandita Dinesh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"},{"issueId":"18d849a6-973d-4dd9-8e86-67a8e7872b5c","seriesId":"2811f289-cfa1-41e0-96a0-08512c691e72","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"2811f289-cfa1-41e0-96a0-08512c691e72","seriesType":"BOOK_SERIES","seriesName":"Open Field Guides Series","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"67a02374-4e51-43b5-830b-c85e4c3a7b08","fullTitle":"Remote Capture: Digitising Documentary Heritage in Challenging Locations","doi":"https://doi.org/10.11647/OBP.0138","publicationDate":"2018-04-16","place":"Cambridge, UK","contributions":[{"fullName":"Adam Farquhar","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Patrick Sutherland","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andrew Pearson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Jody Butterworth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},"__typename":"Issue"},{"issueId":"c69b8d30-cb16-403e-bd10-cf43197082d5","seriesId":"c4827787-5c88-40aa-92c3-6c75b3049379","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"c4827787-5c88-40aa-92c3-6c75b3049379","seriesType":"BOOK_SERIES","seriesName":"OBP Series in Mathematics","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"31aea193-58de-43eb-aadb-23300ba5ee40","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0075","publicationDate":"2016-01-25","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"},{"issueId":"8511e97e-fc52-43ea-9d1e-f733f557c12f","seriesId":"d4b47a76-abff-4047-a3c7-d44d85ccf009","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"d4b47a76-abff-4047-a3c7-d44d85ccf009","seriesType":"BOOK_SERIES","seriesName":"Open Book Classics","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"f8a1849c-0be0-4600-9653-83b0dc6de3ae","fullTitle":"On History: Introduction to World History (1831); Opening Address at the Faculty of Letters, 9 January 1834; Preface to History of France (1869)","doi":"https://doi.org/10.11647/OBP.0036","publicationDate":"2013-10-09","place":"Cambridge, UK","contributions":[{"fullName":"Jules Michelet","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Lionel Gossman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Edward K. Kaplan","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},"__typename":"Issue"},{"issueId":"ce247ac8-1ab7-4915-b334-caacf1cbda21","seriesId":"85c48355-467d-436d-90c9-fe97626c22c8","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"85c48355-467d-436d-90c9-fe97626c22c8","seriesType":"BOOK_SERIES","seriesName":"Open Reports Series","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"25c7dcab-45e2-4625-9d2f-de09ccc01668","fullTitle":"Peace and Democratic Society","doi":"https://doi.org/10.11647/OBP.0014","publicationDate":"2011-06-20","place":"Cambridge, UK","contributions":[{"fullName":"Amartya Sen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"},{"issueId":"7f4e7485-022b-4f9d-9f30-345a6ac5b5e4","seriesId":"b108be7f-669f-4873-891b-d83209e5626f","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"b108be7f-669f-4873-891b-d83209e5626f","seriesType":"JOURNAL","seriesName":"What Works in Conservation","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"7988a2ba-7f1c-4754-943d-07dc4d2dc109","fullTitle":"What Works in Conservation: 2015","doi":"https://doi.org/10.11647/OBP.0060","publicationDate":"2015-07-01","place":"Cambridge, UK","contributions":[{"fullName":"Nancy Ockendon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"William J. Sutherland","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Lynn V. Dicks","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Rebecca K. Smith","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4}]},"__typename":"Issue"},{"issueId":"8f949497-8f84-4776-8c17-7663a1e1b871","seriesId":"1bcf2c4d-e047-46a3-b61a-2bcf76af4018","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"1bcf2c4d-e047-46a3-b61a-2bcf76af4018","seriesType":"BOOK_SERIES","seriesName":"World Oral Literature Series","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"80204dff-c8a9-4155-a539-7ee980102875","fullTitle":"Oral Literature in Africa","doi":"https://doi.org/10.11647/OBP.0025","publicationDate":"2012-09-17","place":"Cambridge, UK","contributions":[{"fullName":"Ruth Finnegan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},"__typename":"Issue"},{"issueId":"3c776175-61d4-433b-a6b9-2491913d16fa","seriesId":"4051770d-6aa3-4ac5-a49c-029e4aa90f3d","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"4051770d-6aa3-4ac5-a49c-029e4aa90f3d","seriesType":"BOOK_SERIES","seriesName":"Dickinson College Commentaries","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"e5ade02a-2f32-495a-b879-98b54df04c0a","fullTitle":"Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary","doi":"https://doi.org/10.11647/OBP.0068","publicationDate":"2015-10-05","place":"Cambridge, UK","contributions":[{"fullName":"Bret Mulligan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"},{"issueId":"658e0d3d-8bf1-4086-b054-d001fe6ad7b0","seriesId":"ca4b4ff7-f461-464b-8768-dfad8ce20968","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"ca4b4ff7-f461-464b-8768-dfad8ce20968","seriesType":"BOOK_SERIES","seriesName":"Classics Textbooks","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"c5fe7f09-7dfb-4637-82c8-653a6cb683e7","fullTitle":"Cicero, Against Verres, 2.1.53–86: Latin Text with Introduction, Study Questions, Commentary and English Translation","doi":"https://doi.org/10.11647/OBP.0016","publicationDate":"2011-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"},{"issueId":"6bd31b4c-35a9-4177-8074-dab4896a4a3d","seriesId":"14ed3dbf-c135-4bae-9b23-a7704eafe446","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"14ed3dbf-c135-4bae-9b23-a7704eafe446","seriesType":"BOOK_SERIES","seriesName":"Semitic Languages and Cultures","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"151cad12-4981-4bbe-923f-f65c9c2c6eb0","fullTitle":"The Tiberian Pronunciation Tradition of Biblical Hebrew, Volume 1","doi":"https://doi.org/10.11647/OBP.0163","publicationDate":"2020-02-20","place":"Cambridge, UK","contributions":[{"fullName":"Geoffrey Khan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle new file mode 100644 index 0000000..fd61f71 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle @@ -0,0 +1 @@ +[{"issueId": "0d4687f9-3d86-4518-9437-e3e1832bd779", "seriesId": "7c662a4d-14ac-44cc-8325-5dc0e207cb96", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "7c662a4d-14ac-44cc-8325-5dc0e207cb96", "seriesType": "BOOK_SERIES", "seriesName": "Applied Theatre Praxis", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "41aed95c-de6c-4b37-b533-fe79af56cf82", "fullTitle": "Theatre and War: Notes from the Field", "doi": "https://doi.org/10.11647/OBP.0099", "publicationDate": "2016-07-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Nandita Dinesh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"}, {"issueId": "18d849a6-973d-4dd9-8e86-67a8e7872b5c", "seriesId": "2811f289-cfa1-41e0-96a0-08512c691e72", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "2811f289-cfa1-41e0-96a0-08512c691e72", "seriesType": "BOOK_SERIES", "seriesName": "Open Field Guides Series", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "67a02374-4e51-43b5-830b-c85e4c3a7b08", "fullTitle": "Remote Capture: Digitising Documentary Heritage in Challenging Locations", "doi": "https://doi.org/10.11647/OBP.0138", "publicationDate": "2018-04-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Adam Farquhar", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Patrick Sutherland", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andrew Pearson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Jody Butterworth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, "__typename": "Issue"}, {"issueId": "c69b8d30-cb16-403e-bd10-cf43197082d5", "seriesId": "c4827787-5c88-40aa-92c3-6c75b3049379", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "c4827787-5c88-40aa-92c3-6c75b3049379", "seriesType": "BOOK_SERIES", "seriesName": "OBP Series in Mathematics", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "31aea193-58de-43eb-aadb-23300ba5ee40", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0075", "publicationDate": "2016-01-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"}, {"issueId": "8511e97e-fc52-43ea-9d1e-f733f557c12f", "seriesId": "d4b47a76-abff-4047-a3c7-d44d85ccf009", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "d4b47a76-abff-4047-a3c7-d44d85ccf009", "seriesType": "BOOK_SERIES", "seriesName": "Open Book Classics", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "f8a1849c-0be0-4600-9653-83b0dc6de3ae", "fullTitle": "On History: Introduction to World History (1831); Opening Address at the Faculty of Letters, 9 January 1834; Preface to History of France (1869)", "doi": "https://doi.org/10.11647/OBP.0036", "publicationDate": "2013-10-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Jules Michelet", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Lionel Gossman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Edward K. Kaplan", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, "__typename": "Issue"}, {"issueId": "ce247ac8-1ab7-4915-b334-caacf1cbda21", "seriesId": "85c48355-467d-436d-90c9-fe97626c22c8", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "85c48355-467d-436d-90c9-fe97626c22c8", "seriesType": "BOOK_SERIES", "seriesName": "Open Reports Series", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "25c7dcab-45e2-4625-9d2f-de09ccc01668", "fullTitle": "Peace and Democratic Society", "doi": "https://doi.org/10.11647/OBP.0014", "publicationDate": "2011-06-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Amartya Sen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"}, {"issueId": "7f4e7485-022b-4f9d-9f30-345a6ac5b5e4", "seriesId": "b108be7f-669f-4873-891b-d83209e5626f", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "b108be7f-669f-4873-891b-d83209e5626f", "seriesType": "JOURNAL", "seriesName": "What Works in Conservation", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "7988a2ba-7f1c-4754-943d-07dc4d2dc109", "fullTitle": "What Works in Conservation: 2015", "doi": "https://doi.org/10.11647/OBP.0060", "publicationDate": "2015-07-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Nancy Ockendon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "William J. Sutherland", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Lynn V. Dicks", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Rebecca K. Smith", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}]}, "__typename": "Issue"}, {"issueId": "8f949497-8f84-4776-8c17-7663a1e1b871", "seriesId": "1bcf2c4d-e047-46a3-b61a-2bcf76af4018", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "1bcf2c4d-e047-46a3-b61a-2bcf76af4018", "seriesType": "BOOK_SERIES", "seriesName": "World Oral Literature Series", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "80204dff-c8a9-4155-a539-7ee980102875", "fullTitle": "Oral Literature in Africa", "doi": "https://doi.org/10.11647/OBP.0025", "publicationDate": "2012-09-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Ruth Finnegan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, "__typename": "Issue"}, {"issueId": "3c776175-61d4-433b-a6b9-2491913d16fa", "seriesId": "4051770d-6aa3-4ac5-a49c-029e4aa90f3d", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "4051770d-6aa3-4ac5-a49c-029e4aa90f3d", "seriesType": "BOOK_SERIES", "seriesName": "Dickinson College Commentaries", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "e5ade02a-2f32-495a-b879-98b54df04c0a", "fullTitle": "Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary", "doi": "https://doi.org/10.11647/OBP.0068", "publicationDate": "2015-10-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Bret Mulligan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"}, {"issueId": "658e0d3d-8bf1-4086-b054-d001fe6ad7b0", "seriesId": "ca4b4ff7-f461-464b-8768-dfad8ce20968", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "ca4b4ff7-f461-464b-8768-dfad8ce20968", "seriesType": "BOOK_SERIES", "seriesName": "Classics Textbooks", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "c5fe7f09-7dfb-4637-82c8-653a6cb683e7", "fullTitle": "Cicero, Against Verres, 2.1.53\u201386: Latin Text with Introduction, Study Questions, Commentary and English Translation", "doi": "https://doi.org/10.11647/OBP.0016", "publicationDate": "2011-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"}, {"issueId": "6bd31b4c-35a9-4177-8074-dab4896a4a3d", "seriesId": "14ed3dbf-c135-4bae-9b23-a7704eafe446", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "14ed3dbf-c135-4bae-9b23-a7704eafe446", "seriesType": "BOOK_SERIES", "seriesName": "Semitic Languages and Cultures", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "151cad12-4981-4bbe-923f-f65c9c2c6eb0", "fullTitle": "The Tiberian Pronunciation Tradition of Biblical Hebrew, Volume 1", "doi": "https://doi.org/10.11647/OBP.0163", "publicationDate": "2020-02-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Geoffrey Khan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json new file mode 100644 index 0000000..8d76fe0 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json @@ -0,0 +1 @@ +{"data": {"issues": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index f583214..76465cc 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -28,3 +28,4 @@ bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_i bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle" bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle" bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle" +bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 583fa6c..ac55648 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -26,6 +26,8 @@ bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_i bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.json" bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json" bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/series.json" +bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issues.json" + bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -41,4 +43,5 @@ bash -c "echo '{\"data\": {\"contributors\": [\"1\"] } }' > thothlibrary/thoth- bash -c "echo '{\"data\": {\"contributor\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributor_bad.json" bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json" bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json" -bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json" +bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index b91918e..9badc6e 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -600,6 +600,36 @@ def test_serieses_raw(self): self.raw_tester(mock_response, thoth_client.serieses) return None + def test_issues(self): + """ + Tests that good input to issues produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('issues', m) + self.pickle_tester('issues', thoth_client.issues) + return None + + def test_issues_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('issues_bad', m) + self.pickle_tester('issues', thoth_client.issues, + negative=True) + + def issues_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('issues', m) + self.raw_tester(mock_response, thoth_client.issues) + return None + def raw_tester(self, mock_response, method_to_call, lambda_mode=False): """ An echo test that ensures the client returns accurate raw responses From 7282feec73588462af7526e8af432c4fe704fe50 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 19:43:00 +0100 Subject: [PATCH 065/115] Add issue endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 24 +++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 32 +++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 4 +- .../thoth-0_4_2/tests/fixtures/issue.json | 1 + .../thoth-0_4_2/tests/fixtures/issue.pickle | 1 + .../thoth-0_4_2/tests/fixtures/issue_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 5 ++- thothlibrary/thoth-0_4_2/tests/tests.py | 42 +++++++++++++++++++ 10 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/issue.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json diff --git a/README.md b/README.md index bb26b5c..eaa1542 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ python3 -m thothlibrary.cli contributor_count --filter="Vincent" python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' +python3 -m thothlibrary.cli issue --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d python3 -m thothlibrary.cli issues --limit=10 python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 1aeb143..1026bee 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -340,6 +340,30 @@ def imprint(self, imprint_id, raw=False, version=None, endpoint=None, else: print(json.dumps(imprint)) + @fire.decorators.SetParseFn(_raw_parse) + def issue(self, issue_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves an issue by ID from a Thoth instance + :param str issue_id: the issue to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + issue = self._client().issue(issue_id=issue_id, raw=raw) + + if not serialize: + print(issue) + else: + print(json.dumps(issue)) + @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, filter=None, raw=False, version=None, endpoint=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 81e39bf..1bf3695 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -324,6 +324,22 @@ class ThothClient0_4_2(ThothClient): ] }, + "issue": { + "parameters": [ + "issueId", + ], + "fields": [ + "issueId", + "seriesId", + "issueOrdinal", + "updatedAt", + "createdAt", + "series { seriesId seriesType seriesName imprintId imprint { __typename publisher { publisherName publisherId __typename } }}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "issues": { "parameters": [ "limit", @@ -467,7 +483,8 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'publication_count', 'publication', 'imprints', 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', - 'series', 'series_count', 'issues', 'QUERIES'] + 'series', 'series_count', 'issues', + 'issue', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -695,6 +712,19 @@ def imprint(self, imprint_id: str, raw: bool = False): return self._api_request("imprint", parameters, return_raw=raw) + def issue(self, issue_id: str, raw: bool = False): + """ + Returns an issue by ID + @param issue_id: the imprint + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'issueId': '"' + issue_id + '"' + } + + return self._api_request("issue", parameters, return_raw=raw) + def publishers(self, limit: int = 100, offset: int = 0, order: str = None, filter: str = "", publishers: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 8b9119d..a972b5e 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -89,7 +89,9 @@ def __price_parser(prices): 'series': lambda self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', 'issues': lambda - self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', + self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', + 'issue': lambda + self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/issue.json b/thothlibrary/thoth-0_4_2/tests/fixtures/issue.json new file mode 100644 index 0000000..267d454 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/issue.json @@ -0,0 +1 @@ +{"data":{"issue":{"issueId":"6bd31b4c-35a9-4177-8074-dab4896a4a3d","seriesId":"14ed3dbf-c135-4bae-9b23-a7704eafe446","issueOrdinal":1,"updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","series":{"seriesId":"14ed3dbf-c135-4bae-9b23-a7704eafe446","seriesType":"BOOK_SERIES","seriesName":"Semitic Languages and Cultures","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprint":{"__typename":"Imprint","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","__typename":"Publisher"}}},"work":{"workId":"151cad12-4981-4bbe-923f-f65c9c2c6eb0","fullTitle":"The Tiberian Pronunciation Tradition of Biblical Hebrew, Volume 1","doi":"https://doi.org/10.11647/OBP.0163","publicationDate":"2020-02-20","place":"Cambridge, UK","contributions":[{"fullName":"Geoffrey Khan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Issue"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle new file mode 100644 index 0000000..c770e86 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle @@ -0,0 +1 @@ +{"issueId": "6bd31b4c-35a9-4177-8074-dab4896a4a3d", "seriesId": "14ed3dbf-c135-4bae-9b23-a7704eafe446", "issueOrdinal": 1, "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "series": {"seriesId": "14ed3dbf-c135-4bae-9b23-a7704eafe446", "seriesType": "BOOK_SERIES", "seriesName": "Semitic Languages and Cultures", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "__typename": "Publisher"}}}, "work": {"workId": "151cad12-4981-4bbe-923f-f65c9c2c6eb0", "fullTitle": "The Tiberian Pronunciation Tradition of Biblical Hebrew, Volume 1", "doi": "https://doi.org/10.11647/OBP.0163", "publicationDate": "2020-02-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Geoffrey Khan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Issue"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json new file mode 100644 index 0000000..cf7e466 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json @@ -0,0 +1 @@ +{"data": {"issue": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 76465cc..302e586 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -28,4 +28,5 @@ bash -c "python3 -m thothlibrary.cli contributor --version=0.4.2 --contributor_i bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution_id=29e4f46b-851a-4d7b-bb41-e6f305fc2b11 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/contribution.pickle" bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle" bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle" -bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle" +bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index ac55648..59812a9 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -27,7 +27,7 @@ bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.json" bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/series.json" bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issues.json" - +bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issue.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -44,4 +44,5 @@ bash -c "echo '{\"data\": {\"contributor\": [\"1\"] } }' > thothlibrary/thoth-0 bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contribution_bad.json" bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json" bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json" -bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json" +bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 9badc6e..2b919cf 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -495,6 +495,48 @@ def test_series_raw(self): lambda_mode=True) return None + def test_issue(self): + """ + Tests that good input to issue produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('issue', m) + self.pickle_tester('issue', + lambda: + thoth_client.issue( + issue_id='6bd31b4c-35a9-4177-8074-' + 'dab4896a4a3d')) + return None + + def test_issue_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('issue_bad', m) + self.pickle_tester('issue', + lambda: thoth_client.issue( + issue_id='6bd31b4c-35a9-4177-8074-' + 'dab4896a4a3d'), + negative=True) + return None + + def issue_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('contributioissue', m) + self.raw_tester(mock_response, + lambda: thoth_client.issue( + issue_id='6bd31b4c-35a9-4177-8074-dab4896a4a3d', + raw=True), + lambda_mode=True) + return None + def test_contribution(self): """ Tests that good input to contribution produces saved good output From 27428e0846a1059ed6e96279119eb39adce8d66d Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 19:48:16 +0100 Subject: [PATCH 066/115] Add issueCount endpoint --- README.md | 1 + thothlibrary/cli.py | 17 +++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 11 ++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eaa1542..fd17175 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd9 python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli issue --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d python3 -m thothlibrary.cli issues --limit=10 +python3 -m thothlibrary.cli issue_count python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 1026bee..7b1c009 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -670,6 +670,23 @@ def contribution_count(self, publishers=None, filter=None, raw=False, contribution_type=contribution_type, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def issue_count(self, raw=False, version=None, endpoint=None): + """ + Retrieves a count of issues from a Thoth instance + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().issue_count(raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, filter=None, publication_type=None, raw=False, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 1bf3695..5f4c54e 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -459,6 +459,8 @@ class ThothClient0_4_2(ThothClient): ], }, + "issuesCount": None, + "seriesCount": { "parameters": [ "filter", @@ -484,7 +486,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', - 'issue', 'QUERIES'] + 'issue', 'issue_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -893,3 +895,10 @@ def contributor_count(self, filter: str = "", raw: bool = False): return self._api_request("contributorCount", parameters, return_raw=raw) + + def issue_count(self, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + return self._api_request("issueCount", parameters, + return_raw=raw) \ No newline at end of file From 99da08875f43ba2c26366aedaf1f7181b0378642 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 20:03:42 +0100 Subject: [PATCH 067/115] Add languages endpoint, CLI, and tests --- README.md | 1 + thothlibrary/cli.py | 40 +++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 45 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/languages.json | 1 + .../tests/fixtures/languages.pickle | 1 + .../tests/fixtures/languages_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 31 +++++++++++++ 10 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/languages.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json diff --git a/README.md b/README.md index fd17175..7beeb9b 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b64 python3 -m thothlibrary.cli issue --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d python3 -m thothlibrary.cli issues --limit=10 python3 -m thothlibrary.cli issue_count +python3 -m thothlibrary.cli languages --limit=10 --language_code=CHI python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 7b1c009..8a67161 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -472,6 +472,46 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, else: print(imprints) + @fire.decorators.SetParseFn(_raw_parse) + def languages(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False, language_code=None, language_relation=None): + """ + Retrieves languages from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param language_relation: select by language relation (e.g. ORIGINAL) + :param language_code: select by lanmguage code (e.g. ADA) + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + langs = self._client().languages(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + language_code=language_code, + language_relation=language_relation, + raw=raw) + + if not raw and not serialize: + print(*langs, sep='\n') + elif serialize: + print(json.dumps(langs)) + else: + print(langs) + @fire.decorators.SetParseFn(_raw_parse) def serieses(self, limit=100, order=None, offset=0, publishers=None, filter=None, series_type=None, raw=False, version=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 5f4c54e..5af5e2f 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -381,6 +381,28 @@ class ThothClient0_4_2(ThothClient): ] }, + "languages": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "languageCode", + "languageRelation" + ], + "fields": [ + "languageId", + "workId", + "languageCode", + "languageRelation", + "createdAt", + "mainLanguage", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "imprint": { "parameters": [ "imprintId", @@ -486,7 +508,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', - 'issue', 'issue_count', 'QUERIES'] + 'issue', 'issue_count', 'languages', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -782,6 +804,27 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("imprints", parameters, return_raw=raw) + def languages(self, limit: int = 100, offset: int = 0, order: str = None, + filter: str = "", publishers: str = None, raw: bool = False, + language_code: str = "", language_relation: str = ""): + """Construct and trigger a query to obtain all publishers""" + parameters = { + "limit": limit, + "offset": offset, + } + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'languageCode', language_code) + self._dictionary_append(parameters, 'languageRelation', + language_relation) + + return self._api_request("languages", parameters, return_raw=raw) + def issues(self, limit: int = 100, offset: int = 0, order: str = None, filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index a972b5e..f8a7f60 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -92,6 +92,8 @@ def __price_parser(prices): self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', 'issue': lambda self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', + 'languages': lambda + self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/languages.json b/thothlibrary/thoth-0_4_2/tests/fixtures/languages.json new file mode 100644 index 0000000..4016a25 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/languages.json @@ -0,0 +1 @@ +{"data":{"languages":[{"languageId":"a14bbf05-944d-41c3-9a48-7c5ae6c49fcf","workId":"c21f4155-1d84-4590-9c08-f67ac39f3d97","languageCode":"ALB","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"c21f4155-1d84-4590-9c08-f67ac39f3d97","fullTitle":"Workers Leaving the Studio: Looking Away from Socialist Realism","doi":"https://doi.org/10.21983/P3.0115.1.00","publicationDate":"2015-10-01","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Jonida Gashi","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Genti Gjikola","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Artan Shabani","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":5}]},"__typename":"Language"},{"languageId":"cb184c5e-710e-4063-9cf6-a0d91b423759","workId":"d8284a1f-51ac-4ecd-99a6-45e5644db4c8","languageCode":"ALB","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"d8284a1f-51ac-4ecd-99a6-45e5644db4c8","fullTitle":"Pedagogies of Disaster","doi":"https://doi.org/10.21983/P3.0050.1.00","publicationDate":"2013-10-07","place":"Brooklyn, NY","contributions":[{"fullName":"Nico Jenkins","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Adam Staley Groves","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Language"},{"languageId":"3350596d-2d0a-4cce-b130-b09a2d7d5831","workId":"1a71ecd5-c868-44af-9b53-b45888fb241c","languageCode":"ALB","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"1a71ecd5-c868-44af-9b53-b45888fb241c","fullTitle":"Lapidari 1: Texts","doi":"https://doi.org/10.21983/P3.0094.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonida Gashi","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},"__typename":"Language"},{"languageId":"3180a6e5-0c2b-4191-a7e6-9719d755845c","workId":"637566b3-dca3-4a8b-b5bd-01fcbb77ca09","languageCode":"ANG","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"637566b3-dca3-4a8b-b5bd-01fcbb77ca09","fullTitle":"Beowulf: A Translation","doi":"https://doi.org/10.21983/P3.0009.1.00","publicationDate":"2012-08-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Hadbawnik","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Thomas Meyer","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel C. Remein","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"David Hadbawnik","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},"__typename":"Language"},{"languageId":"34700649-08eb-4b88-b8f7-8ed1c9a17b30","workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","languageCode":"CHI","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea","doi":"https://doi.org/10.21983/P3.0269.1.00","publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Language"},{"languageId":"c19e68dd-c5a3-48f1-bd56-089ee732604c","workId":"a603437d-578e-4577-9800-645614b28b4b","languageCode":"CHI","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},"__typename":"Language"},{"languageId":"8a4b8458-4c89-4598-bd06-3db2d686403f","workId":"9787df40-8b86-4d8c-8a23-8260ec90011a","languageCode":"ENG","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"9787df40-8b86-4d8c-8a23-8260ec90011a","fullTitle":"That Greece Might Still Be Free: The Philhellenes in the War of Independence","doi":"https://doi.org/10.11647/OBP.0001","publicationDate":"2008-11-01","place":"Cambridge, UK","contributions":[{"fullName":"William St Clair","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Roderick Beaton","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},"__typename":"Language"},{"languageId":"1eac67ca-94af-4653-a602-c4d8eb41cbb4","workId":"c6125a74-2801-4255-afe9-89cdb8d253f4","languageCode":"ENG","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"c6125a74-2801-4255-afe9-89cdb8d253f4","fullTitle":"John Gardner: A Tiny Eulogy","doi":"https://doi.org/10.21983/P3.0013.1.00","publicationDate":"2012-11-29","place":"Brooklyn, NY","contributions":[{"fullName":"Phil Jourdan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Language"},{"languageId":"380bb8a3-e316-494f-a682-bbb59b472109","workId":"77e1fa52-1938-47dd-b8a5-2a57bfbc91d1","languageCode":"ENG","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"77e1fa52-1938-47dd-b8a5-2a57bfbc91d1","fullTitle":"What Is Philosophy?","doi":"https://doi.org/10.21983/P3.0011.1.00","publicationDate":"2012-10-09","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Language"},{"languageId":"1eaf2d87-5402-4720-9de4-a66515c835b9","workId":"456b46b9-bbec-4832-95ca-b23dcb975df1","languageCode":"ENG","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"456b46b9-bbec-4832-95ca-b23dcb975df1","fullTitle":"Brownshirt Princess: A Study of the 'Nazi Conscience'","doi":"https://doi.org/10.11647/OBP.0003","publicationDate":"2009-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Lionel Gossman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Language"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle new file mode 100644 index 0000000..2cf0948 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle @@ -0,0 +1 @@ +[{"languageId": "a14bbf05-944d-41c3-9a48-7c5ae6c49fcf", "workId": "c21f4155-1d84-4590-9c08-f67ac39f3d97", "languageCode": "ALB", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "c21f4155-1d84-4590-9c08-f67ac39f3d97", "fullTitle": "Workers Leaving the Studio: Looking Away from Socialist Realism", "doi": "https://doi.org/10.21983/P3.0115.1.00", "publicationDate": "2015-10-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Jonida Gashi", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Genti Gjikola", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Artan Shabani", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 5}]}, "__typename": "Language"}, {"languageId": "cb184c5e-710e-4063-9cf6-a0d91b423759", "workId": "d8284a1f-51ac-4ecd-99a6-45e5644db4c8", "languageCode": "ALB", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "d8284a1f-51ac-4ecd-99a6-45e5644db4c8", "fullTitle": "Pedagogies of Disaster", "doi": "https://doi.org/10.21983/P3.0050.1.00", "publicationDate": "2013-10-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Adam Staley Groves", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Language"}, {"languageId": "3350596d-2d0a-4cce-b130-b09a2d7d5831", "workId": "1a71ecd5-c868-44af-9b53-b45888fb241c", "languageCode": "ALB", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "1a71ecd5-c868-44af-9b53-b45888fb241c", "fullTitle": "Lapidari 1: Texts", "doi": "https://doi.org/10.21983/P3.0094.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonida Gashi", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, "__typename": "Language"}, {"languageId": "3180a6e5-0c2b-4191-a7e6-9719d755845c", "workId": "637566b3-dca3-4a8b-b5bd-01fcbb77ca09", "languageCode": "ANG", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "637566b3-dca3-4a8b-b5bd-01fcbb77ca09", "fullTitle": "Beowulf: A Translation", "doi": "https://doi.org/10.21983/P3.0009.1.00", "publicationDate": "2012-08-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Hadbawnik", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Thomas Meyer", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel C. Remein", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "David Hadbawnik", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, "__typename": "Language"}, {"languageId": "34700649-08eb-4b88-b8f7-8ed1c9a17b30", "workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "languageCode": "CHI", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea", "doi": "https://doi.org/10.21983/P3.0269.1.00", "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Language"}, {"languageId": "c19e68dd-c5a3-48f1-bd56-089ee732604c", "workId": "a603437d-578e-4577-9800-645614b28b4b", "languageCode": "CHI", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, "__typename": "Language"}, {"languageId": "8a4b8458-4c89-4598-bd06-3db2d686403f", "workId": "9787df40-8b86-4d8c-8a23-8260ec90011a", "languageCode": "ENG", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "9787df40-8b86-4d8c-8a23-8260ec90011a", "fullTitle": "That Greece Might Still Be Free: The Philhellenes in the War of Independence", "doi": "https://doi.org/10.11647/OBP.0001", "publicationDate": "2008-11-01", "place": "Cambridge, UK", "contributions": [{"fullName": "William St Clair", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Roderick Beaton", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, "__typename": "Language"}, {"languageId": "1eac67ca-94af-4653-a602-c4d8eb41cbb4", "workId": "c6125a74-2801-4255-afe9-89cdb8d253f4", "languageCode": "ENG", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "c6125a74-2801-4255-afe9-89cdb8d253f4", "fullTitle": "John Gardner: A Tiny Eulogy", "doi": "https://doi.org/10.21983/P3.0013.1.00", "publicationDate": "2012-11-29", "place": "Brooklyn, NY", "contributions": [{"fullName": "Phil Jourdan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Language"}, {"languageId": "380bb8a3-e316-494f-a682-bbb59b472109", "workId": "77e1fa52-1938-47dd-b8a5-2a57bfbc91d1", "languageCode": "ENG", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "77e1fa52-1938-47dd-b8a5-2a57bfbc91d1", "fullTitle": "What Is Philosophy?", "doi": "https://doi.org/10.21983/P3.0011.1.00", "publicationDate": "2012-10-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Language"}, {"languageId": "1eaf2d87-5402-4720-9de4-a66515c835b9", "workId": "456b46b9-bbec-4832-95ca-b23dcb975df1", "languageCode": "ENG", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "456b46b9-bbec-4832-95ca-b23dcb975df1", "fullTitle": "Brownshirt Princess: A Study of the 'Nazi Conscience'", "doi": "https://doi.org/10.11647/OBP.0003", "publicationDate": "2009-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Lionel Gossman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Language"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json new file mode 100644 index 0000000..02a9ccc --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json @@ -0,0 +1 @@ +{"data": {"languages": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 302e586..8e8fecf 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -29,4 +29,5 @@ bash -c "python3 -m thothlibrary.cli contribution --version=0.4.2 --contribution bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/serieses.pickle" bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle" bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle" -bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle" +bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 59812a9..23fe4f1 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -28,6 +28,7 @@ bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --raw > bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/series.json" bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issues.json" bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issue.json" +bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/languages.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -45,4 +46,5 @@ bash -c "echo '{\"data\": {\"contribution\": [\"1\"] } }' > thothlibrary/thoth- bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/serieses_bad.json" bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json" bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json" -bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json" +bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 2b919cf..e2fdafd 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -376,6 +376,37 @@ def test_imprints_raw(self): self.raw_tester(mock_response, thoth_client.imprints) return None + def test_languages(self): + """ + Tests that good input to languages produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('languages', m) + self.pickle_tester('languages', thoth_client.languages) + return None + + def test_languages_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('languages_bad', + m) + self.pickle_tester('languages', thoth_client.languages, + negative=True) + + def test_languages_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('languages', m) + self.raw_tester(mock_response, thoth_client.languages) + return None + def test_contributions(self): """ Tests that good input to contributions produces saved good output From a628bb896eb88b9d8e46648585d449e04a0461b2 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 20:12:49 +0100 Subject: [PATCH 068/115] Add language endpoint, CLI, and tests --- README.md | 1 + thothlibrary/cli.py | 24 +++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 32 +++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/language.json | 1 + .../tests/fixtures/language.pickle | 1 + .../tests/fixtures/language_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 43 +++++++++++++++++++ 10 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/language.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json diff --git a/README.md b/README.md index 7beeb9b..5ae0778 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b64 python3 -m thothlibrary.cli issue --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d python3 -m thothlibrary.cli issues --limit=10 python3 -m thothlibrary.cli issue_count +python3 -m thothlibrary.cli language --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c python3 -m thothlibrary.cli languages --limit=10 --language_code=CHI python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 8a67161..8bca4d8 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -316,6 +316,30 @@ def series(self, series_id, raw=False, version=None, endpoint=None, else: print(json.dumps(series)) + @fire.decorators.SetParseFn(_raw_parse) + def language(self, language_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a language by ID from a Thoth instance + :param str language_id: the series to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + lang = self._client().language(language_id=language_id, raw=raw) + + if not serialize: + print(lang) + else: + print(json.dumps(lang)) + @fire.decorators.SetParseFn(_raw_parse) def imprint(self, imprint_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 5af5e2f..72b10aa 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -381,6 +381,22 @@ class ThothClient0_4_2(ThothClient): ] }, + "language": { + "parameters": [ + "languageId", + ], + "fields": [ + "languageId", + "workId", + "languageCode", + "languageRelation", + "createdAt", + "mainLanguage", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "languages": { "parameters": [ "limit", @@ -508,7 +524,8 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'imprint', 'imprint_count', 'contributors', 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', - 'issue', 'issue_count', 'languages', 'QUERIES'] + 'issue', 'issue_count', 'languages', 'language', + 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -526,6 +543,19 @@ def contributor(self, contributor_id: str, raw: bool = False): return self._api_request("contributor", parameters, return_raw=raw) + def language(self, language_id: str, raw: bool = False): + """ + Returns a series by ID + @param language_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'languageId': '"' + language_id + '"' + } + + return self._api_request("language", parameters, return_raw=raw) + def series(self, series_id: str, raw: bool = False): """ Returns a series by ID diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index f8a7f60..7a1e983 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -94,6 +94,8 @@ def __price_parser(prices): self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', 'languages': lambda self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', + 'language': lambda + self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', 'publisher': lambda self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/language.json b/thothlibrary/thoth-0_4_2/tests/fixtures/language.json new file mode 100644 index 0000000..187b5f8 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/language.json @@ -0,0 +1 @@ +{"data":{"language":{"languageId":"c19e68dd-c5a3-48f1-bd56-089ee732604c","workId":"a603437d-578e-4577-9800-645614b28b4b","languageCode":"CHI","languageRelation":"ORIGINAL","createdAt":"2021-01-07T16:32:40.853895+00:00","mainLanguage":true,"work":{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},"__typename":"Language"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle new file mode 100644 index 0000000..30b2eb4 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle @@ -0,0 +1 @@ +{"languageId": "c19e68dd-c5a3-48f1-bd56-089ee732604c", "workId": "a603437d-578e-4577-9800-645614b28b4b", "languageCode": "CHI", "languageRelation": "ORIGINAL", "createdAt": "2021-01-07T16:32:40.853895+00:00", "mainLanguage": true, "work": {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, "__typename": "Language"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json new file mode 100644 index 0000000..9b11756 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json @@ -0,0 +1 @@ +{"data": {"language": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 8e8fecf..739892c 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -30,4 +30,5 @@ bash -c "python3 -m thothlibrary.cli serieses --version=0.4.2 --limit=3 --serial bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/series.pickle" bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle" bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle" -bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle" +bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 23fe4f1..877f7b2 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -29,6 +29,7 @@ bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76 bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issues.json" bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issue.json" bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/languages.json" +bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --raw > thothlibrary/thoth-0_4_2/tests/fixtures/language.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -47,4 +48,5 @@ bash -c "echo '{\"data\": {\"serieses\": [\"1\"] } }' > thothlibrary/thoth-0_4_ bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/series_bad.json" bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json" bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json" -bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json" +bash -c "echo '{\"data\": {\"language\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index e2fdafd..078501a 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -303,6 +303,49 @@ def test_publishers_raw(self): self.raw_tester(mock_response, thoth_client.publishers) return None + def test_language(self): + """ + Tests that good input to language produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('language', m) + self.pickle_tester('language', + lambda: + thoth_client.language( + language_id='c19e68dd-c5a3-48f1-bd56-' + '089ee732604c')) + return None + + def test_language_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('language_bad', m) + self.pickle_tester('language', + lambda: thoth_client.language( + language_id='c19e68dd-c5a3-48f1-bd56-' + '089ee732604c'), + negative=True) + return None + + def test_language_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('language', m) + self.raw_tester(mock_response, + lambda: thoth_client.language( + language_id='c19e68dd-c5a3-48f1-bd56-' + '089ee732604c', + raw=True), + lambda_mode=True) + return None + def test_imprint(self): """ Tests that good input to imprint produces saved good output From 0461d5cabf7926ce7bdff619e86223496590fdde Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 20:20:54 +0100 Subject: [PATCH 069/115] Add languageCount --- README.md | 1 + thothlibrary/cli.py | 22 ++++++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 20 +++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ae0778..c5c9fbb 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ python3 -m thothlibrary.cli issues --limit=10 python3 -m thothlibrary.cli issue_count python3 -m thothlibrary.cli language --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c python3 -m thothlibrary.cli languages --limit=10 --language_code=CHI +python3 -m thothlibrary.cli language_count --language_code=CHI python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 8bca4d8..faf9aa3 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -574,6 +574,28 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, else: print(serieses) + @fire.decorators.SetParseFn(_raw_parse) + def language_count(self, language_code=None, raw=False, version=None, + endpoint=None, language_relation=None): + """ + Retrieves a count of contributors from a Thoth instance + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param language_code: the code to retrieve (e.g. CHI) + :param language_relation: the relation (e.g. ORIGINAL) + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().language_count(language_code=language_code, + language_relation=language_relation, + raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def contributor_count(self, filter=None, raw=False, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 72b10aa..ca6f69a 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -499,6 +499,13 @@ class ThothClient0_4_2(ThothClient): "issuesCount": None, + "languageCount": { + "parameters": [ + "languageCode", + "languageRelation", + ], + }, + "seriesCount": { "parameters": [ "filter", @@ -525,7 +532,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', - 'QUERIES'] + 'language_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -969,6 +976,17 @@ def contributor_count(self, filter: str = "", raw: bool = False): return self._api_request("contributorCount", parameters, return_raw=raw) + def language_count(self, language_code: str = "", + language_relation: str = "", raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + self._dictionary_append(parameters, 'languageCode', language_code) + self._dictionary_append(parameters, 'languageRelation', + language_relation) + + return self._api_request("languageCount", parameters, return_raw=raw) + def issue_count(self, raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} From 3a6a9c61b50624486faf76f536f91b66cb54d167 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 20:41:37 +0100 Subject: [PATCH 070/115] Add prices endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 36 ++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 49 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 7 ++- .../thoth-0_4_2/tests/fixtures/prices.json | 1 + .../thoth-0_4_2/tests/fixtures/prices.pickle | 1 + .../tests/fixtures/prices_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 30 ++++++++++++ 10 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/prices.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json diff --git a/README.md b/README.md index c5c9fbb..761d019 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ python3 -m thothlibrary.cli issue_count python3 -m thothlibrary.cli language --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c python3 -m thothlibrary.cli languages --limit=10 --language_code=CHI python3 -m thothlibrary.cli language_count --language_code=CHI +python3 -m thothlibrary.cli prices --limit=10 --currency_code=GBP python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index faf9aa3..38d2190 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -536,6 +536,42 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, else: print(langs) + @fire.decorators.SetParseFn(_raw_parse) + def prices(self, limit=100, order=None, offset=0, publishers=None, + currency_code=None, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves serieses from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param str currency_code: the currency code (e.g. GBP) + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + prices = self._client().prices(limit=limit, order=order, + offset=offset, + publishers=publishers, + currency_code=currency_code, + raw=raw) + + if not raw and not serialize: + print(*prices, sep='\n') + elif serialize: + print(json.dumps(prices)) + else: + print(prices) + @fire.decorators.SetParseFn(_raw_parse) def serieses(self, limit=100, order=None, offset=0, publishers=None, filter=None, series_type=None, raw=False, version=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index ca6f69a..438ff16 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -60,6 +60,27 @@ class ThothClient0_4_2(ThothClient): ] }, + "prices": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "currencyCode", + ], + "fields": [ + "currencyCode", + "publicationId", + "priceId", + "unitPrice", + "publication { work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "createdAt", + "updatedAt", + "__typename" + ] + }, + "publications": { "parameters": [ "limit", @@ -532,7 +553,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', - 'language_count', 'QUERIES'] + 'language_count', 'prices', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -589,6 +610,32 @@ def publication(self, publication_id: str, raw: bool = False): return self._api_request("publication", parameters, return_raw=raw) + def prices(self, limit: int = 100, offset: int = 0, order: str = None, + publishers: str = None, currency_code: str = None, + raw: bool = False): + """ + Returns a price list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param currency_code: the currency code (e.g. GBP) + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'currencyCode', currency_code) + + return self._api_request("prices", parameters, return_raw=raw) + def publications(self, limit: int = 100, offset: int = 0, filter: str = "", order: str = None, publishers: str = None, publication_type: str = None, diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 7a1e983..3fecd94 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -48,8 +48,10 @@ def _parse_authors(obj): def __price_parser(prices): - if len(prices) > 0: + if len(prices) > 0 and 'currencyCode' not in prices: return '({0}{1})'.format(prices[0].unitPrice, prices[0].currencyCode) + elif 'currencyCode' in prices: + return '{0}{1}'.format(prices.unitPrice, prices.currencyCode) else: return '' @@ -60,6 +62,9 @@ def __price_parser(prices): # of objects, such as books default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', + 'prices': lambda + self: f'{_parse_authors(self.publication.work)}{self.publication.work.fullTitle} ({self.publication.work.place}: {self.publication.work.imprint.publisher.publisherName}, {datetime.strptime(self.publication.work.publicationDate, "%Y-%m-%d").year if self.publication.work.publicationDate else "n.d."}) ' + f'costs {__price_parser(self)} [{self.priceId}]' if '__typename' in self and self.__typename == 'Price' else f'{_muncher_repr(self)}', 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/prices.json b/thothlibrary/thoth-0_4_2/tests/fixtures/prices.json new file mode 100644 index 0000000..f540218 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/prices.json @@ -0,0 +1 @@ +{"data":{"prices":[{"currencyCode":"AUD","publicationId":"252f8233-24b1-4160-8981-e9a8db60689d","priceId":"5c2ee3d0-4063-4790-8c9c-89e3e5a4696f","unitPrice":18.95,"publication":{"work":{"workId":"25c7dcab-45e2-4625-9d2f-de09ccc01668","fullTitle":"Peace and Democratic Society","doi":"https://doi.org/10.11647/OBP.0014","publicationDate":"2011-06-20","place":"Cambridge, UK","contributions":[{"fullName":"Amartya Sen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"f532b049-2213-4668-9183-bf07965f36c3","priceId":"961a7d82-8f9d-4d18-8e4e-12004eff547d","unitPrice":9.95,"publication":{"work":{"workId":"6ed799de-77a5-44fd-80aa-5a9940b3a44c","fullTitle":"The End of the World: Apocalypse and its Aftermath in Western Culture","doi":"https://doi.org/10.11647/OBP.0015","publicationDate":"2011-09-20","place":"Cambridge, UK","contributions":[{"fullName":"Maria Manuel Lisboa","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"62e7bafe-072f-462a-b9a6-177cfbbe06f7","priceId":"4f044897-81d6-4d4a-bf61-2234b74d3be8","unitPrice":29.95,"publication":{"work":{"workId":"4f7f2103-6569-48fc-b782-00d0e724386a","fullTitle":"Why Do We Quote? The Culture and History of Quotation","doi":"https://doi.org/10.11647/OBP.0012","publicationDate":"2011-03-01","place":"Cambridge, UK","contributions":[{"fullName":"Ruth Finnegan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"44c1d0ac-b912-42a4-9d22-28bd5ff949e7","priceId":"5449a0ca-aeff-43fa-a564-150bb5582b39","unitPrice":54.95,"publication":{"work":{"workId":"9d5ac1c6-a763-49b4-98b2-355d888169be","fullTitle":"Henry James's Europe: Heritage and Transfer","doi":"https://doi.org/10.11647/OBP.0013","publicationDate":"2011-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Adrian Harding","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Annick Duperray","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dennis Tredy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"c114bcad-95e3-4675-9a00-6b0b5271dca1","priceId":"0a98e1ee-79d5-4c3b-9fb3-4cd8ca87d962","unitPrice":29.95,"publication":{"work":{"workId":"6ed799de-77a5-44fd-80aa-5a9940b3a44c","fullTitle":"The End of the World: Apocalypse and its Aftermath in Western Culture","doi":"https://doi.org/10.11647/OBP.0015","publicationDate":"2011-09-20","place":"Cambridge, UK","contributions":[{"fullName":"Maria Manuel Lisboa","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"a52d6230-d226-4053-b200-ef95f90c7fb1","priceId":"e1200826-b7e4-4edd-aa37-2d432e9f2525","unitPrice":29.95,"publication":{"work":{"workId":"9ea10b68-b23c-4562-b0ca-03ba548889a3","fullTitle":"Coleridge's Laws: A Study of Coleridge in Malta","doi":"https://doi.org/10.11647/OBP.0005","publicationDate":"2010-01-01","place":"Cambridge, UK","contributions":[{"fullName":"Barry Hough","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Howard Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Lydia Davis","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Micheal John Kooy","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":4}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"353c366a-0e7a-430c-8a6a-73bc80adaddc","priceId":"7b7c566d-1447-4493-bead-01bbe1be0874","unitPrice":54.95,"publication":{"work":{"workId":"74d1a9f7-7fb9-4767-a406-5e5aa162228c","fullTitle":"The Theatre of Shelley","doi":"https://doi.org/10.11647/OBP.0011","publicationDate":"2010-12-01","place":"Cambridge, UK","contributions":[{"fullName":"Jacqueline Mulhallen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"01df8006-24ae-4b25-9430-562eac2bca19","priceId":"b05332aa-2c15-4b15-a5ba-7eb35b45769d","unitPrice":54.95,"publication":{"work":{"workId":"9ea10b68-b23c-4562-b0ca-03ba548889a3","fullTitle":"Coleridge's Laws: A Study of Coleridge in Malta","doi":"https://doi.org/10.11647/OBP.0005","publicationDate":"2010-01-01","place":"Cambridge, UK","contributions":[{"fullName":"Barry Hough","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Howard Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Lydia Davis","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Micheal John Kooy","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":4}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"d7147d3a-6f0a-4383-8da6-6db47ba53903","priceId":"15ab12dc-bb7e-4520-a32c-6158abfd9df8","unitPrice":29.95,"publication":{"work":{"workId":"9d5ac1c6-a763-49b4-98b2-355d888169be","fullTitle":"Henry James's Europe: Heritage and Transfer","doi":"https://doi.org/10.11647/OBP.0013","publicationDate":"2011-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Adrian Harding","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Annick Duperray","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dennis Tredy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"},{"currencyCode":"AUD","publicationId":"bc7badee-80fa-4745-908a-b889855f8b02","priceId":"b077448a-2f71-4f1c-8cd7-9aa48812f233","unitPrice":9.95,"publication":{"work":{"workId":"c5fe7f09-7dfb-4637-82c8-653a6cb683e7","fullTitle":"Cicero, Against Verres, 2.1.53–86: Latin Text with Introduction, Study Questions, Commentary and English Translation","doi":"https://doi.org/10.11647/OBP.0016","publicationDate":"2011-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle new file mode 100644 index 0000000..4d0d75f --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle @@ -0,0 +1 @@ +[{"currencyCode": "AUD", "publicationId": "252f8233-24b1-4160-8981-e9a8db60689d", "priceId": "5c2ee3d0-4063-4790-8c9c-89e3e5a4696f", "unitPrice": 18.95, "publication": {"work": {"workId": "25c7dcab-45e2-4625-9d2f-de09ccc01668", "fullTitle": "Peace and Democratic Society", "doi": "https://doi.org/10.11647/OBP.0014", "publicationDate": "2011-06-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Amartya Sen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "f532b049-2213-4668-9183-bf07965f36c3", "priceId": "961a7d82-8f9d-4d18-8e4e-12004eff547d", "unitPrice": 9.95, "publication": {"work": {"workId": "6ed799de-77a5-44fd-80aa-5a9940b3a44c", "fullTitle": "The End of the World: Apocalypse and its Aftermath in Western Culture", "doi": "https://doi.org/10.11647/OBP.0015", "publicationDate": "2011-09-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Maria Manuel Lisboa", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "62e7bafe-072f-462a-b9a6-177cfbbe06f7", "priceId": "4f044897-81d6-4d4a-bf61-2234b74d3be8", "unitPrice": 29.95, "publication": {"work": {"workId": "4f7f2103-6569-48fc-b782-00d0e724386a", "fullTitle": "Why Do We Quote? The Culture and History of Quotation", "doi": "https://doi.org/10.11647/OBP.0012", "publicationDate": "2011-03-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Ruth Finnegan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "44c1d0ac-b912-42a4-9d22-28bd5ff949e7", "priceId": "5449a0ca-aeff-43fa-a564-150bb5582b39", "unitPrice": 54.95, "publication": {"work": {"workId": "9d5ac1c6-a763-49b4-98b2-355d888169be", "fullTitle": "Henry James's Europe: Heritage and Transfer", "doi": "https://doi.org/10.11647/OBP.0013", "publicationDate": "2011-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Adrian Harding", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Annick Duperray", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dennis Tredy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "c114bcad-95e3-4675-9a00-6b0b5271dca1", "priceId": "0a98e1ee-79d5-4c3b-9fb3-4cd8ca87d962", "unitPrice": 29.95, "publication": {"work": {"workId": "6ed799de-77a5-44fd-80aa-5a9940b3a44c", "fullTitle": "The End of the World: Apocalypse and its Aftermath in Western Culture", "doi": "https://doi.org/10.11647/OBP.0015", "publicationDate": "2011-09-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Maria Manuel Lisboa", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "a52d6230-d226-4053-b200-ef95f90c7fb1", "priceId": "e1200826-b7e4-4edd-aa37-2d432e9f2525", "unitPrice": 29.95, "publication": {"work": {"workId": "9ea10b68-b23c-4562-b0ca-03ba548889a3", "fullTitle": "Coleridge's Laws: A Study of Coleridge in Malta", "doi": "https://doi.org/10.11647/OBP.0005", "publicationDate": "2010-01-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Barry Hough", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Howard Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Lydia Davis", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Micheal John Kooy", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 4}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "353c366a-0e7a-430c-8a6a-73bc80adaddc", "priceId": "7b7c566d-1447-4493-bead-01bbe1be0874", "unitPrice": 54.95, "publication": {"work": {"workId": "74d1a9f7-7fb9-4767-a406-5e5aa162228c", "fullTitle": "The Theatre of Shelley", "doi": "https://doi.org/10.11647/OBP.0011", "publicationDate": "2010-12-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Jacqueline Mulhallen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "01df8006-24ae-4b25-9430-562eac2bca19", "priceId": "b05332aa-2c15-4b15-a5ba-7eb35b45769d", "unitPrice": 54.95, "publication": {"work": {"workId": "9ea10b68-b23c-4562-b0ca-03ba548889a3", "fullTitle": "Coleridge's Laws: A Study of Coleridge in Malta", "doi": "https://doi.org/10.11647/OBP.0005", "publicationDate": "2010-01-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Barry Hough", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Howard Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Lydia Davis", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Micheal John Kooy", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 4}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "d7147d3a-6f0a-4383-8da6-6db47ba53903", "priceId": "15ab12dc-bb7e-4520-a32c-6158abfd9df8", "unitPrice": 29.95, "publication": {"work": {"workId": "9d5ac1c6-a763-49b4-98b2-355d888169be", "fullTitle": "Henry James's Europe: Heritage and Transfer", "doi": "https://doi.org/10.11647/OBP.0013", "publicationDate": "2011-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Adrian Harding", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Annick Duperray", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dennis Tredy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}, {"currencyCode": "AUD", "publicationId": "bc7badee-80fa-4745-908a-b889855f8b02", "priceId": "b077448a-2f71-4f1c-8cd7-9aa48812f233", "unitPrice": 9.95, "publication": {"work": {"workId": "c5fe7f09-7dfb-4637-82c8-653a6cb683e7", "fullTitle": "Cicero, Against Verres, 2.1.53\u201386: Latin Text with Introduction, Study Questions, Commentary and English Translation", "doi": "https://doi.org/10.11647/OBP.0016", "publicationDate": "2011-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json new file mode 100644 index 0000000..941cf81 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json @@ -0,0 +1 @@ +{"data": {"prices": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 739892c..837e48b 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -31,4 +31,5 @@ bash -c "python3 -m thothlibrary.cli series --version=0.4.2 --series_id=d4b47a76 bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issues.pickle" bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/issue.pickle" bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle" -bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle" +bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 877f7b2..8870082 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -30,6 +30,7 @@ bash -c "python3 -m thothlibrary.cli issues --version=0.4.2 --limit=10 --raw > t bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-35a9-4177-8074-dab4896a4a3d --raw > thothlibrary/thoth-0_4_2/tests/fixtures/issue.json" bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/languages.json" bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --raw > thothlibrary/thoth-0_4_2/tests/fixtures/language.json" +bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/prices.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -49,4 +50,5 @@ bash -c "echo '{\"data\": {\"series\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/ bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issues_bad.json" bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json" bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json" -bash -c "echo '{\"data\": {\"language\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"language\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json" +bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 078501a..e688509 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -419,6 +419,36 @@ def test_imprints_raw(self): self.raw_tester(mock_response, thoth_client.imprints) return None + def test_prices(self): + """ + Tests that good input to prices produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('prices', m) + self.pickle_tester('prices', thoth_client.prices) + return None + + def test_prices_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('prices_bad', m) + self.pickle_tester('prices', thoth_client.prices, + negative=True) + + def test_prices_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('prices', m) + self.raw_tester(mock_response, thoth_client.prices) + return None + def test_languages(self): """ Tests that good input to languages produces saved good output From 56f81a21a09cf7b01ad401fde1d85b75e0c2dd97 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 20:54:17 +0100 Subject: [PATCH 071/115] Add price endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 24 +++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 31 ++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 5 ++- .../thoth-0_4_2/tests/fixtures/price.json | 1 + .../thoth-0_4_2/tests/fixtures/price.pickle | 1 + .../thoth-0_4_2/tests/fixtures/price_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 43 +++++++++++++++++++ 10 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/price.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json diff --git a/README.md b/README.md index 761d019..dc2767c 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ python3 -m thothlibrary.cli issue_count python3 -m thothlibrary.cli language --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c python3 -m thothlibrary.cli languages --limit=10 --language_code=CHI python3 -m thothlibrary.cli language_count --language_code=CHI +python3 -m thothlibrary.cli price --price_id=818567dd-7d3a-4963-8704-3381b5432877 python3 -m thothlibrary.cli prices --limit=10 --currency_code=GBP python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 38d2190..f734e51 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -364,6 +364,30 @@ def imprint(self, imprint_id, raw=False, version=None, endpoint=None, else: print(json.dumps(imprint)) + @fire.decorators.SetParseFn(_raw_parse) + def price(self, price_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a price by ID from a Thoth instance + :param str price_id: the price to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + price = self._client().price(price_id=price_id, raw=raw) + + if not serialize: + print(price) + else: + print(json.dumps(price)) + @fire.decorators.SetParseFn(_raw_parse) def issue(self, issue_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 438ff16..6978d9a 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -81,6 +81,22 @@ class ThothClient0_4_2(ThothClient): ] }, + "price": { + "parameters": [ + "priceId", + ], + "fields": [ + "currencyCode", + "publicationId", + "priceId", + "unitPrice", + "publication { work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "createdAt", + "updatedAt", + "__typename" + ] + }, + "publications": { "parameters": [ "limit", @@ -553,7 +569,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', - 'language_count', 'prices', 'QUERIES'] + 'language_count', 'prices', 'price', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -597,6 +613,19 @@ def series(self, series_id: str, raw: bool = False): return self._api_request("series", parameters, return_raw=raw) + def price(self, price_id: str, raw: bool = False): + """ + Returns a price by ID + @param price_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'priceId': '"' + price_id + '"' + } + + return self._api_request("price", parameters, return_raw=raw) + def publication(self, publication_id: str, raw: bool = False): """ Returns a publication by ID diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 3fecd94..70bf68a 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -63,7 +63,10 @@ def __price_parser(prices): default_fields = {'works': lambda self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', 'prices': lambda - self: f'{_parse_authors(self.publication.work)}{self.publication.work.fullTitle} ({self.publication.work.place}: {self.publication.work.imprint.publisher.publisherName}, {datetime.strptime(self.publication.work.publicationDate, "%Y-%m-%d").year if self.publication.work.publicationDate else "n.d."}) ' + self: f'{self.publication.work.fullTitle} ({self.publication.work.place}: {self.publication.work.imprint.publisher.publisherName}, {datetime.strptime(self.publication.work.publicationDate, "%Y-%m-%d").year if self.publication.work.publicationDate else "n.d."}) ' + f'costs {__price_parser(self)} [{self.priceId}]' if '__typename' in self and self.__typename == 'Price' else f'{_muncher_repr(self)}', + 'price': lambda + self: f'{self.publication.work.fullTitle} ({self.publication.work.place}: {self.publication.work.imprint.publisher.publisherName}, {datetime.strptime(self.publication.work.publicationDate, "%Y-%m-%d").year if self.publication.work.publicationDate else "n.d."}) ' f'costs {__price_parser(self)} [{self.priceId}]' if '__typename' in self and self.__typename == 'Price' else f'{_muncher_repr(self)}', 'publications': lambda self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/price.json b/thothlibrary/thoth-0_4_2/tests/fixtures/price.json new file mode 100644 index 0000000..8fe7bbc --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/price.json @@ -0,0 +1 @@ +{"data":{"price":{"currencyCode":"GBP","publicationId":"2222b922-8ed6-4a3b-aa94-e5a445a7eab9","priceId":"818567dd-7d3a-4963-8704-3381b5432877","unitPrice":29.95,"publication":{"work":{"workId":"e613eee4-f939-4530-9a95-64cebb5fac4e","fullTitle":"The End and the Beginning: The Book of My Life","doi":"https://doi.org/10.11647/OBP.0010","publicationDate":"2010-10-01","place":"Cambridge, UK","contributions":[{"fullName":"Hermynia Zur Mühlen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Lionel Gossman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"}}}},"createdAt":"2021-01-07T16:32:40.853895+00:00","updatedAt":"2021-01-07T16:32:40.853895+00:00","__typename":"Price"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle new file mode 100644 index 0000000..a34cc98 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle @@ -0,0 +1 @@ +{"currencyCode": "GBP", "publicationId": "2222b922-8ed6-4a3b-aa94-e5a445a7eab9", "priceId": "818567dd-7d3a-4963-8704-3381b5432877", "unitPrice": 29.95, "publication": {"work": {"workId": "e613eee4-f939-4530-9a95-64cebb5fac4e", "fullTitle": "The End and the Beginning: The Book of My Life", "doi": "https://doi.org/10.11647/OBP.0010", "publicationDate": "2010-10-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Hermynia Zur M\u00fchlen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Lionel Gossman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}}}}, "createdAt": "2021-01-07T16:32:40.853895+00:00", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "__typename": "Price"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json new file mode 100644 index 0000000..d7053d0 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json @@ -0,0 +1 @@ +{"data": {"price": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 837e48b..b15f6e2 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -33,3 +33,4 @@ bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-3 bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle" bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle" bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle" +bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 8870082..81c05eb 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -31,6 +31,7 @@ bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-3 bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/languages.json" bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --raw > thothlibrary/thoth-0_4_2/tests/fixtures/language.json" bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/prices.json" +bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/price.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -51,4 +52,5 @@ bash -c "echo '{\"data\": {\"issues\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/ bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/issue_bad.json" bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json" bash -c "echo '{\"data\": {\"language\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json" -bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json" +bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index e688509..a71fa3d 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -555,6 +555,49 @@ def test_contributor_raw(self): lambda_mode=True) return None + def test_price(self): + """ + Tests that good input to price produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('price', m) + self.pickle_tester('price', + lambda: + thoth_client.price( + price_id='818567dd-7d3a-4963-8704-' + '3381b5432877')) + return None + + def test_price_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('price_bad', + m) + self.pickle_tester('price', + lambda: thoth_client.price( + price_id='818567dd-7d3a-4963-8704-' + '3381b5432877'), + negative=True) + return None + + def test_price_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('price', m) + self.raw_tester(mock_response, + lambda: thoth_client.price( + price_id='818567dd-7d3a-4963-8704-3381b5432877', + raw=True), + lambda_mode=True) + return None + def test_series(self): """ Tests that good input to series produces saved good output From f64f6129f7f96959f79135ecc109ae2aad35c88b Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 20:59:31 +0100 Subject: [PATCH 072/115] Add priceCount endpoint --- README.md | 1 + thothlibrary/cli.py | 19 +++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 17 ++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc2767c..29bfd24 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ python3 -m thothlibrary.cli languages --limit=10 --language_code=CHI python3 -m thothlibrary.cli language_count --language_code=CHI python3 -m thothlibrary.cli price --price_id=818567dd-7d3a-4963-8704-3381b5432877 python3 -m thothlibrary.cli prices --limit=10 --currency_code=GBP +python3 -m thothlibrary.cli price_count --currency_code=GBP python3 -m thothlibrary.cli publication --publication_id=34712b75-dcdd-408b-8d0c-cf29a35be2e5 python3 -m thothlibrary.cli publications --limit=10 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b"]' python3 -m thothlibrary.cli publication_count --publication_type="HARDBACK" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index f734e51..d8a093a 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -719,6 +719,25 @@ def imprint_count(self, publishers=None, filter=None, raw=False, filter=filter, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def price_count(self, currency_code=None, raw=False, version=None, + endpoint=None): + """ + Retrieves a count of imprints from a Thoth instance + :param str currency_code: the currency to filter by (e.g. GBP) + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().price_count(currency_code=currency_code, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def work_count(self, publishers=None, filter=None, raw=False, work_type=None, work_status=None, version=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 6978d9a..eb8cbbb 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -543,6 +543,12 @@ class ThothClient0_4_2(ThothClient): ], }, + "priceCount": { + "parameters": [ + "currencyCode", + ], + }, + "seriesCount": { "parameters": [ "filter", @@ -569,7 +575,8 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'contributor', 'contributor_count', 'serieses', 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', - 'language_count', 'prices', 'price', 'QUERIES'] + 'language_count', 'prices', 'price', 'price_count', + 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -968,6 +975,14 @@ def publisher_count(self, filter: str = "", publishers: str = None, return self._api_request("publisherCount", parameters, return_raw=raw) + def price_count(self, currency_code: str = None, raw: bool = False): + """Construct and trigger a query to count publishers""" + parameters = {} + + self._dictionary_append(parameters, 'currencyCode', currency_code) + + return self._api_request("priceCount", parameters, return_raw=raw) + def imprint_count(self, filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" From 141f76912d0f072c1af48f22868c29ee48bb9548 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 21:27:13 +0100 Subject: [PATCH 073/115] Add subjects endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 38 +++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 42 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/subjects.json | 1 + .../tests/fixtures/subjects.pickle | 1 + .../tests/fixtures/subjects_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 32 +++++++++++++- 10 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json diff --git a/README.md b/README.md index 29bfd24..a793c34 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b python3 -m thothlibrary.cli series --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" python3 -m thothlibrary.cli series_count --series_type=BOOK_SERIES +python3 -m thothlibrary.cli subjects --limit=10 python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index d8a093a..3805154 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -560,6 +560,44 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, else: print(langs) + @fire.decorators.SetParseFn(_raw_parse) + def subjects(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False, subject_type=None): + """ + Retrieves languages from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param subject_type: select by subject code (e.g. BIC) + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + subj = self._client().subjects(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + subject_type=subject_type, + raw=raw) + + if not raw and not serialize: + print(*subj, sep='\n') + elif serialize: + print(json.dumps(subj)) + else: + print(subj) + @fire.decorators.SetParseFn(_raw_parse) def prices(self, limit=100, order=None, offset=0, publishers=None, currency_code=None, raw=False, version=None, endpoint=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index eb8cbbb..c2f295b 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -434,6 +434,27 @@ class ThothClient0_4_2(ThothClient): ] }, + "subjects": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "subjectType", + ], + "fields": [ + "subjectId", + "workId", + "subjectCode", + "subjectType", + "subjectOrdinal", + "createdAt", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "languages": { "parameters": [ "limit", @@ -576,7 +597,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', - 'QUERIES'] + 'subjects', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -945,6 +966,25 @@ def languages(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("languages", parameters, return_raw=raw) + def subjects(self, limit: int = 100, offset: int = 0, order: str = None, + filter: str = "", publishers: str = None, raw: bool = False, + subject_type: str = ""): + """Construct and trigger a query to obtain all publishers""" + parameters = { + "limit": limit, + "offset": offset, + } + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'subjectType', subject_type) + + return self._api_request("subjects", parameters, return_raw=raw) + def issues(self, limit: int = 100, offset: int = 0, order: str = None, filter: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 70bf68a..5b8351c 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -100,6 +100,8 @@ def __price_parser(prices): self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', 'issue': lambda self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', + 'subjects': lambda + self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', 'languages': lambda self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', 'language': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json b/thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json new file mode 100644 index 0000000..fc80421 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json @@ -0,0 +1 @@ +{"data":{"subjects":[{"subjectId":"bdb7a441-e3e0-4124-b890-52213d3a5ca1","workId":"3c91221f-4381-4ff1-bdde-ab7aa4fe3daf","subjectCode":"1D","subjectType":"BIC","subjectOrdinal":3,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"3c91221f-4381-4ff1-bdde-ab7aa4fe3daf","fullTitle":"Waltzing Through Europe: Attitudes towards Couple Dances in the Long Nineteenth Century","doi":"https://doi.org/10.11647/OBP.0174","publicationDate":"2020-09-10","place":"Cambridge, UK","contributions":[{"fullName":"Anne von Bibra Wharton","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Helena Saarikoski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Egil Bakka","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Theresa Jill Buckland","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},"__typename":"Subject"},{"subjectId":"f94d7833-6b68-452d-b2f3-b64b5fe160dd","workId":"aeed0683-e022-42d0-a954-f9f36afc4bbf","subjectCode":"1DBR","subjectType":"BIC","subjectOrdinal":1,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"aeed0683-e022-42d0-a954-f9f36afc4bbf","fullTitle":"Incomparable Poetry: An Essay on the Financial Crisis of 2007–2008 and Irish Literature","doi":"https://doi.org/10.21983/P3.0286.1.00","publicationDate":"2020-05-14","place":"Earth, Milky Way","contributions":[{"fullName":"Robert Kiely","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"},{"subjectId":"eb79bc46-8466-4335-8920-baac1bd8c536","workId":"8e8c0b3e-76eb-4c1c-b335-1a481cec1ae0","subjectCode":"1DF","subjectType":"BIC","subjectOrdinal":4,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"8e8c0b3e-76eb-4c1c-b335-1a481cec1ae0","fullTitle":"Undocumented Migrants and Healthcare: Eight Stories from Switzerland","doi":"https://doi.org/10.11647/OBP.0139","publicationDate":"2018-05-30","place":"Cambridge, UK","contributions":[{"fullName":"Marianne Jossen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"},{"subjectId":"4ce98ac0-51c9-4102-9ad0-9e3a18830f51","workId":"3eaa2b26-1c54-4527-8b97-3c34f4856e5b","subjectCode":"1DFA","subjectType":"BIC","subjectOrdinal":2,"createdAt":"2021-05-03T08:23:04.629159+00:00","work":{"workId":"3eaa2b26-1c54-4527-8b97-3c34f4856e5b","fullTitle":"Siting Futurity: The “Feel Good” Tactical Radicalism of Contemporary Culture in and around Vienna","doi":"https://doi.org/10.21983/P3.0317.1.00","publicationDate":"2021-05-06","place":"Earth","contributions":[{"fullName":"Susan Ingram","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"},{"subjectId":"84f600fc-0501-423f-9b3e-939f379dd637","workId":"b56b58e5-a98c-4eb8-826d-b3a7e515eef8","subjectCode":"1DFG","subjectType":"BIC","subjectOrdinal":4,"createdAt":"2021-05-05T15:45:37.317850+00:00","work":{"workId":"b56b58e5-a98c-4eb8-826d-b3a7e515eef8","fullTitle":"Mendl Mann’s 'The Fall of Berlin'","doi":"https://doi.org/10.11647/OBP.0233","publicationDate":"2020-12-03","place":"Cambridge, UK","contributions":[{"fullName":"Maurice Wolfthal","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"},{"subjectId":"53407879-b0ee-49f9-8e05-ce132b7540b8","workId":"d16896b7-691e-4620-9adb-1d7a42c69bde","subjectCode":"1DFG","subjectType":"BIC","subjectOrdinal":5,"createdAt":"2021-07-29T12:15:02.903549+00:00","work":{"workId":"d16896b7-691e-4620-9adb-1d7a42c69bde","fullTitle":"From Goethe to Gundolf: Essays on German Literature and Culture","doi":"https://doi.org/10.11647/OBP.0258","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Roger Paulin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"},{"subjectId":"58ee1571-75a1-4d00-a1dc-472fda0206ca","workId":"0229f930-1e01-40b8-b4a8-03ab57624ced","subjectCode":"1DN","subjectType":"BIC","subjectOrdinal":1,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"0229f930-1e01-40b8-b4a8-03ab57624ced","fullTitle":"A Lexicon of Medieval Nordic Law","doi":"https://doi.org/10.11647/OBP.0188","publicationDate":"2020-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Christine Peel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Jeffrey Love","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Erik Simensen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Inger Larsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ulrika Djärv","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},"__typename":"Subject"},{"subjectId":"fdec728b-9149-4123-9153-3a4af286654a","workId":"7b9888c3-ccb1-41a2-aff9-a2103e688ae3","subjectCode":"1DN","subjectType":"BIC","subjectOrdinal":2,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"7b9888c3-ccb1-41a2-aff9-a2103e688ae3","fullTitle":"Measuring the Master Race: Physical Anthropology in Norway 1890-1945","doi":"https://doi.org/10.11647/OBP.0051","publicationDate":"2014-12-22","place":"Cambridge, UK","contributions":[{"fullName":"Jon Røyne Kyllingstad","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"},{"subjectId":"7ffe98f5-ca7c-4115-9795-dbe6d6bd9753","workId":"6092f859-05fe-475d-b914-3c1a6534e6b9","subjectCode":"1DNC","subjectType":"BIC","subjectOrdinal":3,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"6092f859-05fe-475d-b914-3c1a6534e6b9","fullTitle":"Down to Earth: A Memoir","doi":"https://doi.org/10.21983/P3.0306.1.00","publicationDate":"2020-10-22","place":"Earth, Milky Way","contributions":[{"fullName":"Gísli Pálsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna Yates","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrina Downs-Rose","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},"__typename":"Subject"},{"subjectId":"1291208f-fc43-47a4-a8e6-e132477ad57b","workId":"1b3a402c-796d-4cdf-b6c8-ce204b2d19e6","subjectCode":"1DNC","subjectType":"BIC","subjectOrdinal":1,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"1b3a402c-796d-4cdf-b6c8-ce204b2d19e6","fullTitle":"Útrásarvíkingar! The Literature of the Icelandic Financial Crisis (2008–2014)","doi":"https://doi.org/10.21983/P3.0272.1.00","publicationDate":"2020-04-16","place":"Earth, Milky Way","contributions":[{"fullName":"Alaric Hall","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle new file mode 100644 index 0000000..e120d8b --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle @@ -0,0 +1 @@ +[{"subjectId": "bdb7a441-e3e0-4124-b890-52213d3a5ca1", "workId": "3c91221f-4381-4ff1-bdde-ab7aa4fe3daf", "subjectCode": "1D", "subjectType": "BIC", "subjectOrdinal": 3, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "3c91221f-4381-4ff1-bdde-ab7aa4fe3daf", "fullTitle": "Waltzing Through Europe: Attitudes towards Couple Dances in the Long Nineteenth Century", "doi": "https://doi.org/10.11647/OBP.0174", "publicationDate": "2020-09-10", "place": "Cambridge, UK", "contributions": [{"fullName": "Anne von Bibra Wharton", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Helena Saarikoski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Egil Bakka", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Theresa Jill Buckland", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, "__typename": "Subject"}, {"subjectId": "f94d7833-6b68-452d-b2f3-b64b5fe160dd", "workId": "aeed0683-e022-42d0-a954-f9f36afc4bbf", "subjectCode": "1DBR", "subjectType": "BIC", "subjectOrdinal": 1, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "aeed0683-e022-42d0-a954-f9f36afc4bbf", "fullTitle": "Incomparable Poetry: An Essay on the Financial Crisis of 2007\u20132008 and Irish Literature", "doi": "https://doi.org/10.21983/P3.0286.1.00", "publicationDate": "2020-05-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Robert Kiely", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}, {"subjectId": "eb79bc46-8466-4335-8920-baac1bd8c536", "workId": "8e8c0b3e-76eb-4c1c-b335-1a481cec1ae0", "subjectCode": "1DF", "subjectType": "BIC", "subjectOrdinal": 4, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "8e8c0b3e-76eb-4c1c-b335-1a481cec1ae0", "fullTitle": "Undocumented Migrants and Healthcare: Eight Stories from Switzerland", "doi": "https://doi.org/10.11647/OBP.0139", "publicationDate": "2018-05-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Marianne Jossen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}, {"subjectId": "4ce98ac0-51c9-4102-9ad0-9e3a18830f51", "workId": "3eaa2b26-1c54-4527-8b97-3c34f4856e5b", "subjectCode": "1DFA", "subjectType": "BIC", "subjectOrdinal": 2, "createdAt": "2021-05-03T08:23:04.629159+00:00", "work": {"workId": "3eaa2b26-1c54-4527-8b97-3c34f4856e5b", "fullTitle": "Siting Futurity: The \u201cFeel Good\u201d Tactical Radicalism of Contemporary Culture in and around Vienna", "doi": "https://doi.org/10.21983/P3.0317.1.00", "publicationDate": "2021-05-06", "place": "Earth", "contributions": [{"fullName": "Susan Ingram", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}, {"subjectId": "84f600fc-0501-423f-9b3e-939f379dd637", "workId": "b56b58e5-a98c-4eb8-826d-b3a7e515eef8", "subjectCode": "1DFG", "subjectType": "BIC", "subjectOrdinal": 4, "createdAt": "2021-05-05T15:45:37.317850+00:00", "work": {"workId": "b56b58e5-a98c-4eb8-826d-b3a7e515eef8", "fullTitle": "Mendl Mann\u2019s 'The Fall of Berlin'", "doi": "https://doi.org/10.11647/OBP.0233", "publicationDate": "2020-12-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Maurice Wolfthal", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}, {"subjectId": "53407879-b0ee-49f9-8e05-ce132b7540b8", "workId": "d16896b7-691e-4620-9adb-1d7a42c69bde", "subjectCode": "1DFG", "subjectType": "BIC", "subjectOrdinal": 5, "createdAt": "2021-07-29T12:15:02.903549+00:00", "work": {"workId": "d16896b7-691e-4620-9adb-1d7a42c69bde", "fullTitle": "From Goethe to Gundolf: Essays on German Literature and Culture", "doi": "https://doi.org/10.11647/OBP.0258", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Roger Paulin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}, {"subjectId": "58ee1571-75a1-4d00-a1dc-472fda0206ca", "workId": "0229f930-1e01-40b8-b4a8-03ab57624ced", "subjectCode": "1DN", "subjectType": "BIC", "subjectOrdinal": 1, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "0229f930-1e01-40b8-b4a8-03ab57624ced", "fullTitle": "A Lexicon of Medieval Nordic Law", "doi": "https://doi.org/10.11647/OBP.0188", "publicationDate": "2020-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Christine Peel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Jeffrey Love", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Erik Simensen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Inger Larsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ulrika Dj\u00e4rv", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, "__typename": "Subject"}, {"subjectId": "fdec728b-9149-4123-9153-3a4af286654a", "workId": "7b9888c3-ccb1-41a2-aff9-a2103e688ae3", "subjectCode": "1DN", "subjectType": "BIC", "subjectOrdinal": 2, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "7b9888c3-ccb1-41a2-aff9-a2103e688ae3", "fullTitle": "Measuring the Master Race: Physical Anthropology in Norway 1890-1945", "doi": "https://doi.org/10.11647/OBP.0051", "publicationDate": "2014-12-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Jon R\u00f8yne Kyllingstad", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}, {"subjectId": "7ffe98f5-ca7c-4115-9795-dbe6d6bd9753", "workId": "6092f859-05fe-475d-b914-3c1a6534e6b9", "subjectCode": "1DNC", "subjectType": "BIC", "subjectOrdinal": 3, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "6092f859-05fe-475d-b914-3c1a6534e6b9", "fullTitle": "Down to Earth: A Memoir", "doi": "https://doi.org/10.21983/P3.0306.1.00", "publicationDate": "2020-10-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "G\u00edsli P\u00e1lsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna Yates", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrina Downs-Rose", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, "__typename": "Subject"}, {"subjectId": "1291208f-fc43-47a4-a8e6-e132477ad57b", "workId": "1b3a402c-796d-4cdf-b6c8-ce204b2d19e6", "subjectCode": "1DNC", "subjectType": "BIC", "subjectOrdinal": 1, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "1b3a402c-796d-4cdf-b6c8-ce204b2d19e6", "fullTitle": "\u00datr\u00e1sarv\u00edkingar! The Literature of the Icelandic Financial Crisis (2008\u20132014)", "doi": "https://doi.org/10.21983/P3.0272.1.00", "publicationDate": "2020-04-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alaric Hall", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json new file mode 100644 index 0000000..d5b0767 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json @@ -0,0 +1 @@ +{"data": {"subjects": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index b15f6e2..92591f7 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -33,4 +33,5 @@ bash -c "python3 -m thothlibrary.cli issue --version=0.4.2 --issue_id=6bd31b4c-3 bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/languages.pickle" bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle" bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle" -bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle" +bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 81c05eb..154f45c 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -32,6 +32,7 @@ bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --raw bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --raw > thothlibrary/thoth-0_4_2/tests/fixtures/language.json" bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/prices.json" bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/price.json" +bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -53,4 +54,5 @@ bash -c "echo '{\"data\": {\"issue\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/t bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/languages_bad.json" bash -c "echo '{\"data\": {\"language\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json" bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json" -bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json" +bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index a71fa3d..eaab5c8 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -779,7 +779,7 @@ def test_serieses_bad_input(self): self.pickle_tester('serieses', thoth_client.serieses, negative=True) - def test_serieses_raw(self): + def test_subjects_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful @@ -789,6 +789,36 @@ def test_serieses_raw(self): self.raw_tester(mock_response, thoth_client.serieses) return None + def test_subjects(self): + """ + Tests that good input to serieses produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('subjects', m) + self.pickle_tester('subjects', thoth_client.subjects) + return None + + def test_subjects_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('subjects_bad', m) + self.pickle_tester('subjects', thoth_client.subjects, + negative=True) + + def test_subjects_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('subjects', m) + self.raw_tester(mock_response, thoth_client.subjects) + return None + def test_issues(self): """ Tests that good input to issues produces saved good output From cc3043936168c07b9a76b1e125e73ed205455bb1 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 21:37:33 +0100 Subject: [PATCH 074/115] Add subject endpoint, tests, and CLI --- README.md | 3 +- thothlibrary/cli.py | 24 +++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 31 ++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/subject.json | 1 + .../thoth-0_4_2/tests/fixtures/subject.pickle | 1 + .../tests/fixtures/subject_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 43 +++++++++++++++++++ 10 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/subject.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json diff --git a/README.md b/README.md index a793c34..354e0ac 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b python3 -m thothlibrary.cli series --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" python3 -m thothlibrary.cli series_count --series_type=BOOK_SERIES -python3 -m thothlibrary.cli subjects --limit=10 +python3 -m thothlibrary.cli subject --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b +python3 -m thothlibrary.cli subjects --limit=10 --subject_type=BIC python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 3805154..13a2d6d 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -340,6 +340,30 @@ def language(self, language_id, raw=False, version=None, endpoint=None, else: print(json.dumps(lang)) + @fire.decorators.SetParseFn(_raw_parse) + def subject(self, subject_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a subject by ID from a Thoth instance + :param str subject_id: the series to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + subj = self._client().subject(subject_id=subject_id, raw=raw) + + if not serialize: + print(subj) + else: + print(json.dumps(subj)) + @fire.decorators.SetParseFn(_raw_parse) def imprint(self, imprint_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index c2f295b..87cfe80 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -455,6 +455,22 @@ class ThothClient0_4_2(ThothClient): ] }, + "subject": { + "parameters": [ + "subjectId", + ], + "fields": [ + "subjectId", + "workId", + "subjectCode", + "subjectType", + "subjectOrdinal", + "createdAt", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" + "__typename" + ] + }, + "languages": { "parameters": [ "limit", @@ -597,7 +613,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', - 'subjects', 'QUERIES'] + 'subjects', 'subject', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -628,6 +644,19 @@ def language(self, language_id: str, raw: bool = False): return self._api_request("language", parameters, return_raw=raw) + def subject(self, subject_id: str, raw: bool = False): + """ + Returns a subject by ID + @param subject_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'subjectId': '"' + subject_id + '"' + } + + return self._api_request("subject", parameters, return_raw=raw) + def series(self, series_id: str, raw: bool = False): """ Returns a series by ID diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 5b8351c..30a7412 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -102,6 +102,8 @@ def __price_parser(prices): self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', 'subjects': lambda self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', + 'subject': lambda + self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', 'languages': lambda self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', 'language': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/subject.json b/thothlibrary/thoth-0_4_2/tests/fixtures/subject.json new file mode 100644 index 0000000..bce61ab --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/subject.json @@ -0,0 +1 @@ +{"data":{"subject":{"subjectId":"1291208f-fc43-47a4-a8e6-e132477ad57b","workId":"1b3a402c-796d-4cdf-b6c8-ce204b2d19e6","subjectCode":"1DNC","subjectType":"BIC","subjectOrdinal":1,"createdAt":"2021-01-07T16:32:40.853895+00:00","work":{"workId":"1b3a402c-796d-4cdf-b6c8-ce204b2d19e6","fullTitle":"Útrásarvíkingar! The Literature of the Icelandic Financial Crisis (2008–2014)","doi":"https://doi.org/10.21983/P3.0272.1.00","publicationDate":"2020-04-16","place":"Earth, Milky Way","contributions":[{"fullName":"Alaric Hall","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},"__typename":"Subject"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle new file mode 100644 index 0000000..4e121bd --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle @@ -0,0 +1 @@ +{"subjectId": "1291208f-fc43-47a4-a8e6-e132477ad57b", "workId": "1b3a402c-796d-4cdf-b6c8-ce204b2d19e6", "subjectCode": "1DNC", "subjectType": "BIC", "subjectOrdinal": 1, "createdAt": "2021-01-07T16:32:40.853895+00:00", "work": {"workId": "1b3a402c-796d-4cdf-b6c8-ce204b2d19e6", "fullTitle": "\u00datr\u00e1sarv\u00edkingar! The Literature of the Icelandic Financial Crisis (2008\u20132014)", "doi": "https://doi.org/10.21983/P3.0272.1.00", "publicationDate": "2020-04-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alaric Hall", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, "__typename": "Subject"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json new file mode 100644 index 0000000..0b96cf6 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json @@ -0,0 +1 @@ +{"data": {"subject": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 92591f7..375e2fa 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -34,4 +34,5 @@ bash -c "python3 -m thothlibrary.cli languages --version=0.4.2 --limit=10 --seri bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e68dd-c5a3-48f1-bd56-089ee732604c --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/language.pickle" bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle" bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle" -bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle" +bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 154f45c..5f20706 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -33,6 +33,7 @@ bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/prices.json" bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/price.json" bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json" +bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subject.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -55,4 +56,5 @@ bash -c "echo '{\"data\": {\"languages\": [\"1\"] } }' > thothlibrary/thoth-0_4 bash -c "echo '{\"data\": {\"language\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/language_bad.json" bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/prices_bad.json" bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json" -bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json" +bash -c "echo '{\"data\": {\"subject\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index eaab5c8..adf21b5 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -346,6 +346,49 @@ def test_language_raw(self): lambda_mode=True) return None + def test_subject(self): + """ + Tests that good input to subject produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('subject', m) + self.pickle_tester('subject', + lambda: + thoth_client.subject( + subject_id='1291208f-fc43-47a4-a8e6-' + 'e132477ad57b')) + return None + + def test_subject_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('subject_bad', m) + self.pickle_tester('subject', + lambda: thoth_client.subject( + subject_id='1291208f-fc43-47a4-a8e6-' + 'e132477ad57b'), + negative=True) + return None + + def test_subject_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('subject', m) + self.raw_tester(mock_response, + lambda: thoth_client.subject( + subject_id='1291208f-fc43-47a4-a8e6-' + 'e132477ad57b', + raw=True), + lambda_mode=True) + return None + def test_imprint(self): """ Tests that good input to imprint produces saved good output From a588645828349590afc4c053e130b2eeb0ddd3cb Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 21:47:06 +0100 Subject: [PATCH 075/115] Add subject_count endpoint --- README.md | 1 + thothlibrary/cli.py | 21 +++++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 26 +++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 354e0ac..350712c 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" python3 -m thothlibrary.cli series_count --series_type=BOOK_SERIES python3 -m thothlibrary.cli subject --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b python3 -m thothlibrary.cli subjects --limit=10 --subject_type=BIC +python3 -m thothlibrary.cli subject_count --subject_type=THEMA python3 -m thothlibrary.cli supported_versions python3 -m thothlibrary.cli work --doi="https://doi.org/10.11647/OBP.0222" python3 -m thothlibrary.cli work --work_id="e0f748b2-984f-45cc-8b9e-13989c31dda4" diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 13a2d6d..51524de 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -718,6 +718,27 @@ def language_count(self, language_code=None, raw=False, version=None, language_relation=language_relation, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def subject_count(self, subject_type=None, raw=False, version=None, + endpoint=None, filter=None): + """ + Retrieves a count of contributors from a Thoth instance + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param str subject_type: the type to retrieve (e.g. BIC) + :param str filter: a search + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().subject_count(subject_type=subject_type, + filter=filter, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def contributor_count(self, filter=None, raw=False, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 87cfe80..567931d 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -580,6 +580,13 @@ class ThothClient0_4_2(ThothClient): ], }, + "subjectCount": { + "parameters": [ + "filter", + "subjectType" + ], + }, + "priceCount": { "parameters": [ "currencyCode", @@ -613,7 +620,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', - 'subjects', 'subject', 'QUERIES'] + 'subjects', 'subject', 'subject_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -1147,6 +1154,23 @@ def language_count(self, language_code: str = "", return self._api_request("languageCount", parameters, return_raw=raw) + def subject_count(self, subject_type: str = "", filter: str = "", + raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + # there is a bug in this version of Thoth. Filter is REQUIRED. + if not filter: + filter = '""' + + self._dictionary_append(parameters, 'subjectType', subject_type) + self._dictionary_append(parameters, 'filter', filter) + + return self._api_request("subjectCount", parameters, return_raw=raw) + def issue_count(self, raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} From 70acc5f0b4f3e984a4e77684bf69815b2dbbdcf6 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 22:05:06 +0100 Subject: [PATCH 076/115] Add funders endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 31 ++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 35 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 ++ .../thoth-0_4_2/tests/fixtures/funders.json | 1 + .../thoth-0_4_2/tests/fixtures/funders.pickle | 1 + .../tests/fixtures/funders_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 2 ++ thothlibrary/thoth-0_4_2/tests/tests.py | 30 ++++++++++++++++ 10 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funders.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json diff --git a/README.md b/README.md index 350712c..91e2570 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ python3 -m thothlibrary.cli contribution_count python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 python3 -m thothlibrary.cli contributors --limit=10 python3 -m thothlibrary.cli contributor_count --filter="Vincent" +python3 -m thothlibrary.cli funders --limit=10 python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 51524de..e3e91aa 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -584,6 +584,37 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, else: print(langs) + @fire.decorators.SetParseFn(_raw_parse) + def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, + version=None, endpoint=None, serialize=False): + """ + Retrieves funders from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + funders = self._client().funders(limit=limit, order=order, + offset=offset, filter=filter, raw=raw) + + if not raw and not serialize: + print(*funders, sep='\n') + elif serialize: + print(json.dumps(funders)) + else: + print(funders) + @fire.decorators.SetParseFn(_raw_parse) def subjects(self, limit=100, order=None, offset=0, publishers=None, filter=None, raw=False, version=None, endpoint=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 567931d..d9fc5f2 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -97,6 +97,22 @@ class ThothClient0_4_2(ThothClient): ] }, + "funders": { + "parameters": [ + "limit", + "offset", + "filter", + "order", + ], + "fields": [ + "funderId", + "funderName", + "funderDoi", + "fundings { grantNumber program projectName jurisdiction work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "__typename" + ] + }, + "publications": { "parameters": [ "limit", @@ -620,7 +636,8 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'series', 'series_count', 'issues', 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', - 'subjects', 'subject', 'subject_count', 'QUERIES'] + 'subjects', 'subject', 'subject_count', 'funders', + 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -1002,6 +1019,22 @@ def languages(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("languages", parameters, return_raw=raw) + def funders(self, limit: int = 100, offset: int = 0, order: str = None, + filter: str = "", raw: bool = False): + """Construct and trigger a query to obtain all funders""" + parameters = { + "limit": limit, + "offset": offset, + } + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'order', order) + + return self._api_request("funders", parameters, return_raw=raw) + def subjects(self, limit: int = 100, offset: int = 0, order: str = None, filter: str = "", publishers: str = None, raw: bool = False, subject_type: str = ""): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 30a7412..3b3010d 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -104,6 +104,8 @@ def __price_parser(prices): self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', 'subject': lambda self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', + 'funders': lambda + self: f'{self.funderName} funded {len(self.fundings)} books [{self.funderId}]' if '__typename' in self and self.__typename == 'Funder' else f'{_muncher_repr(self)}', 'languages': lambda self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', 'language': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funders.json b/thothlibrary/thoth-0_4_2/tests/fixtures/funders.json new file mode 100644 index 0000000..d6a5ffc --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funders.json @@ -0,0 +1 @@ +{"data":{"funders":[{"funderId":"edd39890-b476-4bb7-87a4-9e0e949733f0","funderName":"Dutch Foundation for Literature","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"30fa2ca0-d82f-4981-bf56-0481ac6c58be","fullTitle":"Of Great Importance","doi":"https://doi.org/10.21983/P3.0195.1.00","publicationDate":"2018-02-08","place":"Earth, Milky Way","contributions":[{"fullName":"Nachoem M. Wijnberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"David Colmer","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"240b9e84-caba-4462-b58a-34b869ff1ecb","funderName":"Fondation Universitaire de Belgique","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"c50aaf19-44e5-43ca-85bd-a3e9efe412f0","funderName":"Frankfurt Humanities Research Centre, Goethe University Frankfurt","funderDoi":null,"fundings":[{"grantNumber":null,"program":"ProPostDoc","projectName":null,"jurisdiction":null,"work":{"workId":"36f7480e-ca45-452c-a5c0-ba1dccf135ec","fullTitle":"Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices","doi":"https://doi.org/10.14619/1860","publicationDate":"2021-05-17","place":"Lueneburg","contributions":[{"fullName":"Wanda Strauven","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"meson press","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b"}}}}],"__typename":"Funder"},{"funderId":"cff96cbb-b0fe-4ed0-9761-2c59e84bbc40","funderName":"Henry Luce Foundation","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"4009b316-9098-4130-aa70-d644d798278b","fullTitle":"Northeast Asia and the American Northwest: Treasures from the Los Angeles County Museum of Art and the Daryl S. Paulson Collection","doi":"https://doi.org/10.53288/0383.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Stephen Little","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Todd Larkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"1edd9444-cf63-4e7c-983c-882842248503","funderName":"IDS Leibniz-Institut für Deutsche Sprache","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"22c74596-3585-4f6a-b98b-3083bb8b11e1","fullTitle":"Trickbox of Memory: Essays on Power and Disorderly Pasts","doi":"https://doi.org/10.21983/P3.0298.1.00","publicationDate":"2020-12-08","place":"Earth, Milky Way","contributions":[{"fullName":"Rosalie Metro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Felicitas Macgilchrist","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"df3a3245-5ad4-4701-a989-e2aff97174ce","funderName":"Marriott Library, University of Utah","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"f8b57164-89e6-48b1-bd70-9d360b53a453","fullTitle":"Helicography","doi":"https://doi.org/10.53288/0352.1.00","publicationDate":"2021-07-22","place":"Earth, Milky Way","contributions":[{"fullName":"Craig Dworkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"9decb3ba-90ed-4690-8986-8a1de5da75ef","funderName":"Oberlin College, Ohio","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"11eb327c-40fa-496d-9af5-3be8bdb95e93","fullTitle":"Suture: Trauma and Trans Becoming","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"KJ Cerankowski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","funderName":"Terra Foundation for American Art","funderDoi":null,"fundings":[{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea","doi":"https://doi.org/10.21983/P3.0269.1.00","publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}},{"grantNumber":null,"program":null,"projectName":null,"jurisdiction":null,"work":{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}],"__typename":"Funder"},{"funderId":"194614ac-d189-4a74-8bf4-74c0c9de4a81","funderName":"The Danish Independent Research Council","funderDoi":null,"fundings":[{"grantNumber":"0602-02551B","program":"FSE","projectName":"Marine Renewable Energy as Alien","jurisdiction":"DK","work":{"workId":"95e15115-4009-4cb0-8824-011038e3c116","fullTitle":"Energy Worlds: In Experiment","doi":"https://doi.org/10.28938/9781912729098","publicationDate":"2021-05-01","place":"Manchester","contributions":[{"fullName":"Brit Ross Winthereik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Laura Watts","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"James Maguire","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Mattering Press","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6"}}}}],"__typename":"Funder"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle new file mode 100644 index 0000000..79077e8 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle @@ -0,0 +1 @@ +[{"funderId": "edd39890-b476-4bb7-87a4-9e0e949733f0", "funderName": "Dutch Foundation for Literature", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "30fa2ca0-d82f-4981-bf56-0481ac6c58be", "fullTitle": "Of Great Importance", "doi": "https://doi.org/10.21983/P3.0195.1.00", "publicationDate": "2018-02-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nachoem M. Wijnberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "David Colmer", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "240b9e84-caba-4462-b58a-34b869ff1ecb", "funderName": "Fondation Universitaire de Belgique", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "c50aaf19-44e5-43ca-85bd-a3e9efe412f0", "funderName": "Frankfurt Humanities Research Centre, Goethe University Frankfurt", "funderDoi": null, "fundings": [{"grantNumber": null, "program": "ProPostDoc", "projectName": null, "jurisdiction": null, "work": {"workId": "36f7480e-ca45-452c-a5c0-ba1dccf135ec", "fullTitle": "Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices", "doi": "https://doi.org/10.14619/1860", "publicationDate": "2021-05-17", "place": "Lueneburg", "contributions": [{"fullName": "Wanda Strauven", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "meson press", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b"}}}}], "__typename": "Funder"}, {"funderId": "cff96cbb-b0fe-4ed0-9761-2c59e84bbc40", "funderName": "Henry Luce Foundation", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "4009b316-9098-4130-aa70-d644d798278b", "fullTitle": "Northeast Asia and the American Northwest: Treasures from the Los Angeles County Museum of Art and the Daryl S. Paulson Collection", "doi": "https://doi.org/10.53288/0383.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Stephen Little", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Todd Larkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "1edd9444-cf63-4e7c-983c-882842248503", "funderName": "IDS Leibniz-Institut f\u00fcr Deutsche Sprache", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "22c74596-3585-4f6a-b98b-3083bb8b11e1", "fullTitle": "Trickbox of Memory: Essays on Power and Disorderly Pasts", "doi": "https://doi.org/10.21983/P3.0298.1.00", "publicationDate": "2020-12-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Rosalie Metro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Felicitas Macgilchrist", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "df3a3245-5ad4-4701-a989-e2aff97174ce", "funderName": "Marriott Library, University of Utah", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "f8b57164-89e6-48b1-bd70-9d360b53a453", "fullTitle": "Helicography", "doi": "https://doi.org/10.53288/0352.1.00", "publicationDate": "2021-07-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Craig Dworkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "9decb3ba-90ed-4690-8986-8a1de5da75ef", "funderName": "Oberlin College, Ohio", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "11eb327c-40fa-496d-9af5-3be8bdb95e93", "fullTitle": "Suture: Trauma and Trans Becoming", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "KJ Cerankowski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "funderName": "Terra Foundation for American Art", "funderDoi": null, "fundings": [{"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea", "doi": "https://doi.org/10.21983/P3.0269.1.00", "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}, {"grantNumber": null, "program": null, "projectName": null, "jurisdiction": null, "work": {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}}], "__typename": "Funder"}, {"funderId": "194614ac-d189-4a74-8bf4-74c0c9de4a81", "funderName": "The Danish Independent Research Council", "funderDoi": null, "fundings": [{"grantNumber": "0602-02551B", "program": "FSE", "projectName": "Marine Renewable Energy as Alien", "jurisdiction": "DK", "work": {"workId": "95e15115-4009-4cb0-8824-011038e3c116", "fullTitle": "Energy Worlds: In Experiment", "doi": "https://doi.org/10.28938/9781912729098", "publicationDate": "2021-05-01", "place": "Manchester", "contributions": [{"fullName": "Brit Ross Winthereik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Laura Watts", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "James Maguire", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Mattering Press", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6"}}}}], "__typename": "Funder"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json new file mode 100644 index 0000000..ae8125d --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json @@ -0,0 +1 @@ +{"data": {"funders": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 375e2fa..bc5e813 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -35,4 +35,5 @@ bash -c "python3 -m thothlibrary.cli language --version=0.4.2 --language_id=c19e bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/prices.pickle" bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle" bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle" -bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle" +bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 5f20706..791cced 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -34,6 +34,7 @@ bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --raw > t bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/price.json" bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json" bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subject.json" +bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funders.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -58,3 +59,4 @@ bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/ bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json" bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json" bash -c "echo '{\"data\": {\"subject\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json" +bash -c "echo '{\"data\": {\"funders\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index adf21b5..60dca2e 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -523,6 +523,36 @@ def test_languages_raw(self): self.raw_tester(mock_response, thoth_client.languages) return None + def test_funders(self): + """ + Tests that good input to funders produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funders', m) + self.pickle_tester('funders', thoth_client.funders) + return None + + def test_funders_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funders_bad', m) + self.pickle_tester('funders', thoth_client.funders, + negative=True) + + def test_funders_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funders', m) + self.raw_tester(mock_response, thoth_client.funders) + return None + def test_contributions(self): """ Tests that good input to contributions produces saved good output From 8c7d90d5f2210d9fc6e873dd1adbf8e85fb6b192 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 22:15:35 +0100 Subject: [PATCH 077/115] Add funder endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 24 +++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 28 +++++++++++- thothlibrary/thoth-0_4_2/structures.py | 2 + .../thoth-0_4_2/tests/fixtures/funder.json | 1 + .../thoth-0_4_2/tests/fixtures/funder.pickle | 1 + .../tests/fixtures/funder_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 43 +++++++++++++++++++ 10 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funder.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json diff --git a/README.md b/README.md index 91e2570..db96074 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ python3 -m thothlibrary.cli contribution_count python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 python3 -m thothlibrary.cli contributors --limit=10 python3 -m thothlibrary.cli contributor_count --filter="Vincent" +python3 -m thothlibrary.cli funder --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 python3 -m thothlibrary.cli funders --limit=10 python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index e3e91aa..d2ad6b8 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -340,6 +340,30 @@ def language(self, language_id, raw=False, version=None, endpoint=None, else: print(json.dumps(lang)) + @fire.decorators.SetParseFn(_raw_parse) + def funder(self, funder_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a funder by ID from a Thoth instance + :param str funder_id: the series to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + funder = self._client().funder(funder_id=funder_id, raw=raw) + + if not serialize: + print(funder) + else: + print(json.dumps(funder)) + @fire.decorators.SetParseFn(_raw_parse) def subject(self, subject_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index d9fc5f2..6a68066 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -113,6 +113,19 @@ class ThothClient0_4_2(ThothClient): ] }, + "funder": { + "parameters": [ + "funderId", + ], + "fields": [ + "funderId", + "funderName", + "funderDoi", + "fundings { grantNumber program projectName jurisdiction work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "__typename" + ] + }, + "publications": { "parameters": [ "limit", @@ -637,7 +650,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', 'subjects', 'subject', 'subject_count', 'funders', - 'QUERIES'] + 'funder', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -668,6 +681,19 @@ def language(self, language_id: str, raw: bool = False): return self._api_request("language", parameters, return_raw=raw) + def funder(self, funder_id: str, raw: bool = False): + """ + Returns a funder by ID + @param funder_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'funderId': '"' + funder_id + '"' + } + + return self._api_request("funder", parameters, return_raw=raw) + def subject(self, subject_id: str, raw: bool = False): """ Returns a subject by ID diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 3b3010d..1898439 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -106,6 +106,8 @@ def __price_parser(prices): self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', 'funders': lambda self: f'{self.funderName} funded {len(self.fundings)} books [{self.funderId}]' if '__typename' in self and self.__typename == 'Funder' else f'{_muncher_repr(self)}', + 'funder': lambda + self: f'{self.funderName} funded {len(self.fundings)} books [{self.funderId}]' if '__typename' in self and self.__typename == 'Funder' else f'{_muncher_repr(self)}', 'languages': lambda self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', 'language': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funder.json b/thothlibrary/thoth-0_4_2/tests/fixtures/funder.json new file mode 100644 index 0000000..e997133 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funder.json @@ -0,0 +1 @@ +{"data":{"funder":{"funderId":"194614ac-d189-4a74-8bf4-74c0c9de4a81","funderName":"The Danish Independent Research Council","funderDoi":null,"fundings":[{"grantNumber":"0602-02551B","program":"FSE","projectName":"Marine Renewable Energy as Alien","jurisdiction":"DK","work":{"workId":"95e15115-4009-4cb0-8824-011038e3c116","fullTitle":"Energy Worlds: In Experiment","doi":"https://doi.org/10.28938/9781912729098","publicationDate":"2021-05-01","place":"Manchester","contributions":[{"fullName":"Brit Ross Winthereik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Laura Watts","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"James Maguire","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Mattering Press","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6"}}}}],"__typename":"Funder"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle new file mode 100644 index 0000000..361fbcc --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle @@ -0,0 +1 @@ +{"funderId": "194614ac-d189-4a74-8bf4-74c0c9de4a81", "funderName": "The Danish Independent Research Council", "funderDoi": null, "fundings": [{"grantNumber": "0602-02551B", "program": "FSE", "projectName": "Marine Renewable Energy as Alien", "jurisdiction": "DK", "work": {"workId": "95e15115-4009-4cb0-8824-011038e3c116", "fullTitle": "Energy Worlds: In Experiment", "doi": "https://doi.org/10.28938/9781912729098", "publicationDate": "2021-05-01", "place": "Manchester", "contributions": [{"fullName": "Brit Ross Winthereik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Laura Watts", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "James Maguire", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Mattering Press", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6"}}}}], "__typename": "Funder"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json new file mode 100644 index 0000000..986ac96 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json @@ -0,0 +1 @@ +{"data": {"funder": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index bc5e813..6295919 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -36,4 +36,5 @@ bash -c "python3 -m thothlibrary.cli prices --version=0.4.2 --limit=10 --seriali bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7d3a-4963-8704-3381b5432877 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/price.pickle" bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.pickle" bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle" -bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle" +bash -c "python3 -m thothlibrary.cli funder --version=0.4.2 --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle" diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 791cced..7e45dc6 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -35,6 +35,7 @@ bash -c "python3 -m thothlibrary.cli price --version=0.4.2 --price_id=818567dd-7 bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subjects.json" bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subject.json" bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funders.json" +bash -c "python3 -m thothlibrary.cli funder --version=0.4.2 --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funder.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -59,4 +60,5 @@ bash -c "echo '{\"data\": {\"prices\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/ bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/price_bad.json" bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json" bash -c "echo '{\"data\": {\"subject\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json" -bash -c "echo '{\"data\": {\"funders\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"funders\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json" +bash -c "echo '{\"data\": {\"funder\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 60dca2e..f0d1df5 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -346,6 +346,49 @@ def test_language_raw(self): lambda_mode=True) return None + def test_funder(self): + """ + Tests that good input to funder produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funder', m) + self.pickle_tester('funder', + lambda: + thoth_client.funder( + funder_id='194614ac-d189-4a74-8bf4-' + '74c0c9de4a81')) + return None + + def test_funder_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funder_bad', m) + self.pickle_tester('funder', + lambda: thoth_client.funder( + funder_id='194614ac-d189-4a74-8bf4-' + '74c0c9de4a81'), + negative=True) + return None + + def test_funder_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funder', m) + self.raw_tester(mock_response, + lambda: thoth_client.funder( + funder_id='194614ac-d189-4a74-8bf4-' + '74c0c9de4a81', + raw=True), + lambda_mode=True) + return None + def test_subject(self): """ Tests that good input to subject produces saved good output From 6114b9e0e5e45dc472e03b5de2ffcd26f9e8fd3c Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 8 Aug 2021 22:19:27 +0100 Subject: [PATCH 078/115] Add funderCount endpoint --- README.md | 1 + thothlibrary/cli.py | 19 +++++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 19 ++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db96074..8cdac6c 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ python3 -m thothlibrary.cli contributors --limit=10 python3 -m thothlibrary.cli contributor_count --filter="Vincent" python3 -m thothlibrary.cli funder --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 python3 -m thothlibrary.cli funders --limit=10 +python3 -m thothlibrary.cli funder_count python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index d2ad6b8..bd1adb4 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -949,6 +949,25 @@ def publication_count(self, publishers=None, filter=None, raw=False, publication_type=publication_type, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def funder_count(self, filter=None, raw=False, version=None, + endpoint=None): + """ + Retrieves a count of publications from a Thoth instance + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().funder_count(filter=filter, raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def contribution_count(self, publishers=None, filter=None, raw=False, contribution_type=None, version=None, endpoint=None): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 6a68066..6e1c501 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -584,6 +584,12 @@ class ThothClient0_4_2(ThothClient): ], }, + "funderCount": { + "parameters": [ + "filter" + ], + }, + "publicationCount": { "parameters": [ "filter", @@ -650,7 +656,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', 'subjects', 'subject', 'subject_count', 'funders', - 'funder', 'QUERIES'] + 'funder', 'funder_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -1190,6 +1196,17 @@ def publication_count(self, filter: str = "", publishers: str = None, return self._api_request("publicationCount", parameters, return_raw=raw) + def funder_count(self, filter: str = "", raw: bool = False): + """Construct and trigger a query to count publications""" + parameters = {} + + if filter and not filter.startswith('"'): + filter = '"{0}"'.format(filter) + + self._dictionary_append(parameters, 'filter', filter) + + return self._api_request("funderCount", parameters, return_raw=raw) + def contributor_count(self, filter: str = "", raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} From 4b02e6e34cddf7c90fdcae516a747b722f486614 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 14:34:47 +0100 Subject: [PATCH 079/115] Add funderings endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 32 +++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 47 ++++++++++++++++++- thothlibrary/thoth-0_4_2/structures.py | 4 ++ .../thoth-0_4_2/tests/fixtures/fundings.json | 1 + .../tests/fixtures/fundings.pickle | 1 + .../tests/fixtures/fundings_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 1 + thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 30 ++++++++++++ 10 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/fundings.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json diff --git a/README.md b/README.md index 8cdac6c..74e6011 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ python3 -m thothlibrary.cli contributor_count --filter="Vincent" python3 -m thothlibrary.cli funder --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 python3 -m thothlibrary.cli funders --limit=10 python3 -m thothlibrary.cli funder_count +python3 -m thothlibrary.cli fundings --limit=10 python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli imprint_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index bd1adb4..d71add3 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -713,6 +713,38 @@ def prices(self, limit=100, order=None, offset=0, publishers=None, else: print(prices) + @fire.decorators.SetParseFn(_raw_parse) + def fundings(self, limit=100, order=None, offset=0, publishers=None, + raw=False, version=None, endpoint=None, serialize=False): + """ + Retrieves fundings from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + fundings = self._client().fundings(limit=limit, order=order, + offset=offset, publishers=publishers, + raw=raw) + + if not raw and not serialize: + print(*fundings, sep='\n') + elif serialize: + print(json.dumps(fundings)) + else: + print(fundings) + @fire.decorators.SetParseFn(_raw_parse) def serieses(self, limit=100, order=None, offset=0, publishers=None, filter=None, series_type=None, raw=False, version=None, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 6e1c501..2ed1e0c 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -97,6 +97,28 @@ class ThothClient0_4_2(ThothClient): ] }, + "fundings": { + "parameters": [ + "limit", + "offset", + "publishers", + "order", + ], + "fields": [ + "fundingId", + "workId", + "funderId", + "program", + "grantNumber", + "projectName", + "projectShortname", + "jurisdiction", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "funder { funderId funderName funderDoi }", + "__typename" + ] + }, + "funders": { "parameters": [ "limit", @@ -656,7 +678,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', 'subjects', 'subject', 'subject_count', 'funders', - 'funder', 'funder_count', 'QUERIES'] + 'funder', 'funder_count', 'fundings', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -752,6 +774,29 @@ def publication(self, publication_id: str, raw: bool = False): return self._api_request("publication", parameters, return_raw=raw) + def fundings(self, limit: int = 100, offset: int = 0, order: str = None, + publishers: str = None, raw: bool = False): + """ + Returns a fundings list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("fundings", parameters, return_raw=raw) + def prices(self, limit: int = 100, offset: int = 0, order: str = None, publishers: str = None, currency_code: str = None, raw: bool = False): diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 1898439..4084679 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -104,6 +104,10 @@ def __price_parser(prices): self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', 'subject': lambda self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', + 'fundings': lambda + self: f'{self.funder.funderName} funded {self.work.fullTitle} [{self.fundingId}]' if '__typename' in self and self.__typename == 'Funding' else f'{_muncher_repr(self)}', + 'funding': lambda + self: f'{self.funder.funderName} funded {self.work.fullTitle} [{self.fundingId}]' if '__typename' in self and self.__typename == 'Funding' else f'{_muncher_repr(self)}', 'funders': lambda self: f'{self.funderName} funded {len(self.fundings)} books [{self.funderId}]' if '__typename' in self and self.__typename == 'Funder' else f'{_muncher_repr(self)}', 'funder': lambda diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/fundings.json b/thothlibrary/thoth-0_4_2/tests/fixtures/fundings.json new file mode 100644 index 0000000..e4b668f --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/fundings.json @@ -0,0 +1 @@ +{"data":{"fundings":[{"fundingId":"915508b1-15a4-4777-8a22-a8793f6bb429","workId":"95e15115-4009-4cb0-8824-011038e3c116","funderId":"194614ac-d189-4a74-8bf4-74c0c9de4a81","program":"FSE","grantNumber":"0602-02551B","projectName":"Marine Renewable Energy as Alien","projectShortname":"Alien Energy","jurisdiction":"DK","work":{"workId":"95e15115-4009-4cb0-8824-011038e3c116","fullTitle":"Energy Worlds: In Experiment","doi":"https://doi.org/10.28938/9781912729098","publicationDate":"2021-05-01","place":"Manchester","contributions":[{"fullName":"Brit Ross Winthereik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Laura Watts","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"James Maguire","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"Mattering Press","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6"}}},"funder":{"funderId":"194614ac-d189-4a74-8bf4-74c0c9de4a81","funderName":"The Danish Independent Research Council","funderDoi":null},"__typename":"Funding"},{"fundingId":"12c8e1e9-9403-4020-93dc-701a244cb180","workId":"36f7480e-ca45-452c-a5c0-ba1dccf135ec","funderId":"c50aaf19-44e5-43ca-85bd-a3e9efe412f0","program":"ProPostDoc","grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"36f7480e-ca45-452c-a5c0-ba1dccf135ec","fullTitle":"Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices","doi":"https://doi.org/10.14619/1860","publicationDate":"2021-05-17","place":"Lueneburg","contributions":[{"fullName":"Wanda Strauven","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"meson press","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b"}}},"funder":{"funderId":"c50aaf19-44e5-43ca-85bd-a3e9efe412f0","funderName":"Frankfurt Humanities Research Centre, Goethe University Frankfurt","funderDoi":null},"__typename":"Funding"},{"fundingId":"2d8e27db-e696-437d-87a9-cb701f2cd726","workId":"30fa2ca0-d82f-4981-bf56-0481ac6c58be","funderId":"edd39890-b476-4bb7-87a4-9e0e949733f0","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"30fa2ca0-d82f-4981-bf56-0481ac6c58be","fullTitle":"Of Great Importance","doi":"https://doi.org/10.21983/P3.0195.1.00","publicationDate":"2018-02-08","place":"Earth, Milky Way","contributions":[{"fullName":"Nachoem M. Wijnberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"David Colmer","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"edd39890-b476-4bb7-87a4-9e0e949733f0","funderName":"Dutch Foundation for Literature","funderDoi":null},"__typename":"Funding"},{"fundingId":"0c853a01-63a8-4ee0-a1f9-7244b8efedc1","workId":"22c74596-3585-4f6a-b98b-3083bb8b11e1","funderId":"1edd9444-cf63-4e7c-983c-882842248503","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"22c74596-3585-4f6a-b98b-3083bb8b11e1","fullTitle":"Trickbox of Memory: Essays on Power and Disorderly Pasts","doi":"https://doi.org/10.21983/P3.0298.1.00","publicationDate":"2020-12-08","place":"Earth, Milky Way","contributions":[{"fullName":"Rosalie Metro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Felicitas Macgilchrist","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"1edd9444-cf63-4e7c-983c-882842248503","funderName":"IDS Leibniz-Institut für Deutsche Sprache","funderDoi":null},"__typename":"Funding"},{"fundingId":"425ba3e1-148f-4ae2-be00-c1b98a660326","workId":"f8b57164-89e6-48b1-bd70-9d360b53a453","funderId":"df3a3245-5ad4-4701-a989-e2aff97174ce","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"f8b57164-89e6-48b1-bd70-9d360b53a453","fullTitle":"Helicography","doi":"https://doi.org/10.53288/0352.1.00","publicationDate":"2021-07-22","place":"Earth, Milky Way","contributions":[{"fullName":"Craig Dworkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"df3a3245-5ad4-4701-a989-e2aff97174ce","funderName":"Marriott Library, University of Utah","funderDoi":null},"__typename":"Funding"},{"fundingId":"ff7a9726-8fec-4a4c-ad19-c33d87686628","workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","funderId":"240b9e84-caba-4462-b58a-34b869ff1ecb","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"240b9e84-caba-4462-b58a-34b869ff1ecb","funderName":"Fondation Universitaire de Belgique","funderDoi":null},"__typename":"Funding"},{"fundingId":"f510c549-74c9-43d2-916f-2788d6f27046","workId":"11eb327c-40fa-496d-9af5-3be8bdb95e93","funderId":"9decb3ba-90ed-4690-8986-8a1de5da75ef","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"11eb327c-40fa-496d-9af5-3be8bdb95e93","fullTitle":"Suture: Trauma and Trans Becoming","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"KJ Cerankowski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"9decb3ba-90ed-4690-8986-8a1de5da75ef","funderName":"Oberlin College, Ohio","funderDoi":null},"__typename":"Funding"},{"fundingId":"6fdc28fc-ac27-4872-9cb0-a0c645070b1f","workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea","doi":"https://doi.org/10.21983/P3.0269.1.00","publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","funderName":"Terra Foundation for American Art","funderDoi":null},"__typename":"Funding"},{"fundingId":"9c68cd84-ec58-4a02-be3b-a8abc12a8d00","workId":"4009b316-9098-4130-aa70-d644d798278b","funderId":"cff96cbb-b0fe-4ed0-9761-2c59e84bbc40","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"4009b316-9098-4130-aa70-d644d798278b","fullTitle":"Northeast Asia and the American Northwest: Treasures from the Los Angeles County Museum of Art and the Daryl S. Paulson Collection","doi":"https://doi.org/10.53288/0383.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Stephen Little","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Todd Larkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"cff96cbb-b0fe-4ed0-9761-2c59e84bbc40","funderName":"Henry Luce Foundation","funderDoi":null},"__typename":"Funding"},{"fundingId":"5323d3e7-3ae9-4778-8464-9400fbbb959e","workId":"a603437d-578e-4577-9800-645614b28b4b","funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","funderName":"Terra Foundation for American Art","funderDoi":null},"__typename":"Funding"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle new file mode 100644 index 0000000..3f2c791 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle @@ -0,0 +1 @@ +[{"fundingId": "915508b1-15a4-4777-8a22-a8793f6bb429", "workId": "95e15115-4009-4cb0-8824-011038e3c116", "funderId": "194614ac-d189-4a74-8bf4-74c0c9de4a81", "program": "FSE", "grantNumber": "0602-02551B", "projectName": "Marine Renewable Energy as Alien", "projectShortname": "Alien Energy", "jurisdiction": "DK", "work": {"workId": "95e15115-4009-4cb0-8824-011038e3c116", "fullTitle": "Energy Worlds: In Experiment", "doi": "https://doi.org/10.28938/9781912729098", "publicationDate": "2021-05-01", "place": "Manchester", "contributions": [{"fullName": "Brit Ross Winthereik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Laura Watts", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "James Maguire", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "Mattering Press", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6"}}}, "funder": {"funderId": "194614ac-d189-4a74-8bf4-74c0c9de4a81", "funderName": "The Danish Independent Research Council", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "12c8e1e9-9403-4020-93dc-701a244cb180", "workId": "36f7480e-ca45-452c-a5c0-ba1dccf135ec", "funderId": "c50aaf19-44e5-43ca-85bd-a3e9efe412f0", "program": "ProPostDoc", "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "36f7480e-ca45-452c-a5c0-ba1dccf135ec", "fullTitle": "Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices", "doi": "https://doi.org/10.14619/1860", "publicationDate": "2021-05-17", "place": "Lueneburg", "contributions": [{"fullName": "Wanda Strauven", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "meson press", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b"}}}, "funder": {"funderId": "c50aaf19-44e5-43ca-85bd-a3e9efe412f0", "funderName": "Frankfurt Humanities Research Centre, Goethe University Frankfurt", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "2d8e27db-e696-437d-87a9-cb701f2cd726", "workId": "30fa2ca0-d82f-4981-bf56-0481ac6c58be", "funderId": "edd39890-b476-4bb7-87a4-9e0e949733f0", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "30fa2ca0-d82f-4981-bf56-0481ac6c58be", "fullTitle": "Of Great Importance", "doi": "https://doi.org/10.21983/P3.0195.1.00", "publicationDate": "2018-02-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nachoem M. Wijnberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "David Colmer", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "edd39890-b476-4bb7-87a4-9e0e949733f0", "funderName": "Dutch Foundation for Literature", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "0c853a01-63a8-4ee0-a1f9-7244b8efedc1", "workId": "22c74596-3585-4f6a-b98b-3083bb8b11e1", "funderId": "1edd9444-cf63-4e7c-983c-882842248503", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "22c74596-3585-4f6a-b98b-3083bb8b11e1", "fullTitle": "Trickbox of Memory: Essays on Power and Disorderly Pasts", "doi": "https://doi.org/10.21983/P3.0298.1.00", "publicationDate": "2020-12-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Rosalie Metro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Felicitas Macgilchrist", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "1edd9444-cf63-4e7c-983c-882842248503", "funderName": "IDS Leibniz-Institut f\u00fcr Deutsche Sprache", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "425ba3e1-148f-4ae2-be00-c1b98a660326", "workId": "f8b57164-89e6-48b1-bd70-9d360b53a453", "funderId": "df3a3245-5ad4-4701-a989-e2aff97174ce", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "f8b57164-89e6-48b1-bd70-9d360b53a453", "fullTitle": "Helicography", "doi": "https://doi.org/10.53288/0352.1.00", "publicationDate": "2021-07-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Craig Dworkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "df3a3245-5ad4-4701-a989-e2aff97174ce", "funderName": "Marriott Library, University of Utah", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "ff7a9726-8fec-4a4c-ad19-c33d87686628", "workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "funderId": "240b9e84-caba-4462-b58a-34b869ff1ecb", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "240b9e84-caba-4462-b58a-34b869ff1ecb", "funderName": "Fondation Universitaire de Belgique", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "f510c549-74c9-43d2-916f-2788d6f27046", "workId": "11eb327c-40fa-496d-9af5-3be8bdb95e93", "funderId": "9decb3ba-90ed-4690-8986-8a1de5da75ef", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "11eb327c-40fa-496d-9af5-3be8bdb95e93", "fullTitle": "Suture: Trauma and Trans Becoming", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "KJ Cerankowski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "9decb3ba-90ed-4690-8986-8a1de5da75ef", "funderName": "Oberlin College, Ohio", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "6fdc28fc-ac27-4872-9cb0-a0c645070b1f", "workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea", "doi": "https://doi.org/10.21983/P3.0269.1.00", "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "funderName": "Terra Foundation for American Art", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "9c68cd84-ec58-4a02-be3b-a8abc12a8d00", "workId": "4009b316-9098-4130-aa70-d644d798278b", "funderId": "cff96cbb-b0fe-4ed0-9761-2c59e84bbc40", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "4009b316-9098-4130-aa70-d644d798278b", "fullTitle": "Northeast Asia and the American Northwest: Treasures from the Los Angeles County Museum of Art and the Daryl S. Paulson Collection", "doi": "https://doi.org/10.53288/0383.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Stephen Little", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Todd Larkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "cff96cbb-b0fe-4ed0-9761-2c59e84bbc40", "funderName": "Henry Luce Foundation", "funderDoi": null}, "__typename": "Funding"}, {"fundingId": "5323d3e7-3ae9-4778-8464-9400fbbb959e", "workId": "a603437d-578e-4577-9800-645614b28b4b", "funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "funderName": "Terra Foundation for American Art", "funderDoi": null}, "__typename": "Funding"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json new file mode 100644 index 0000000..b31867a --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json @@ -0,0 +1 @@ +{"data": {"fundings": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index 6295919..d156900 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -38,3 +38,4 @@ bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --seria bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle" bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle" bash -c "python3 -m thothlibrary.cli funder --version=0.4.2 --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle" +bash -c "python3 -m thothlibrary.cli fundings --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index 7e45dc6..d04ef43 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -36,6 +36,7 @@ bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --raw > bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --raw > thothlibrary/thoth-0_4_2/tests/fixtures/subject.json" bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funders.json" bash -c "python3 -m thothlibrary.cli funder --version=0.4.2 --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funder.json" +bash -c "python3 -m thothlibrary.cli fundings --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/fundings.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -61,4 +62,5 @@ bash -c "echo '{\"data\": {\"price\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/t bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subjects_bad.json" bash -c "echo '{\"data\": {\"subject\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json" bash -c "echo '{\"data\": {\"funders\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json" -bash -c "echo '{\"data\": {\"funder\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"funder\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json" +bash -c "echo '{\"data\": {\"fundings\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index f0d1df5..3a08281 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -596,6 +596,36 @@ def test_funders_raw(self): self.raw_tester(mock_response, thoth_client.funders) return None + def test_fundings(self): + """ + Tests that good input to fundings produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('fundings', m) + self.pickle_tester('fundings', thoth_client.fundings) + return None + + def test_fundings_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('fundings_bad', m) + self.pickle_tester('fundings', thoth_client.fundings, + negative=True) + + def test_fundings_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('fundings', m) + self.raw_tester(mock_response, thoth_client.fundings) + return None + def test_contributions(self): """ Tests that good input to contributions produces saved good output From a3d3080c46d5e03aaaf6efaf5a736f3cc34b8ebf Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 15:03:24 +0100 Subject: [PATCH 080/115] Add funding endpoint, tests, and CLI --- README.md | 1 + thothlibrary/cli.py | 24 ++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 35 ++++++++++++++- .../thoth-0_4_2/tests/fixtures/funding.json | 1 + .../thoth-0_4_2/tests/fixtures/funding.pickle | 1 + .../tests/fixtures/funding_bad.json | 1 + thothlibrary/thoth-0_4_2/tests/genfixtures.sh | 3 +- thothlibrary/thoth-0_4_2/tests/genjson.sh | 4 +- thothlibrary/thoth-0_4_2/tests/tests.py | 44 +++++++++++++++++++ 9 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funding.json create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funding.pickle create mode 100644 thothlibrary/thoth-0_4_2/tests/fixtures/funding_bad.json diff --git a/README.md b/README.md index 74e6011..a5b7ea0 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ python3 -m thothlibrary.cli contributor_count --filter="Vincent" python3 -m thothlibrary.cli funder --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 python3 -m thothlibrary.cli funders --limit=10 python3 -m thothlibrary.cli funder_count +python3 -m thothlibrary.cli funding --funding_id=5323d3e7-3ae9-4778-8464-9400fbbb959e python3 -m thothlibrary.cli fundings --limit=10 python3 -m thothlibrary.cli imprint --imprint_id=78b0a283-9be3-4fed-a811-a7d4b9df7b25 python3 -m thothlibrary.cli imprints --limit=25 --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index d71add3..595dbd7 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -266,6 +266,30 @@ def contributor(self, contributor_id, raw=False, version=None, else: print(json.dumps(contributor)) + @fire.decorators.SetParseFn(_raw_parse) + def funding(self, funding_id, raw=False, version=None, endpoint=None, + serialize=False): + """ + Retrieves a funding by ID from a Thoth instance + :param str funding_id: the contributor to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + funding = self._client().funding(funding_id=funding_id, raw=raw) + + if not serialize: + print(funding) + else: + print(json.dumps(funding)) + @fire.decorators.SetParseFn(_raw_parse) def contribution(self, contribution_id, raw=False, version=None, endpoint=None, serialize=False): diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 2ed1e0c..edb5ed1 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -97,6 +97,25 @@ class ThothClient0_4_2(ThothClient): ] }, + "funding": { + "parameters": [ + "fundingId", + ], + "fields": [ + "fundingId", + "workId", + "funderId", + "program", + "grantNumber", + "projectName", + "projectShortname", + "jurisdiction", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "funder { funderId funderName funderDoi }", + "__typename" + ] + }, + "fundings": { "parameters": [ "limit", @@ -678,11 +697,25 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'issue', 'issue_count', 'languages', 'language', 'language_count', 'prices', 'price', 'price_count', 'subjects', 'subject', 'subject_count', 'funders', - 'funder', 'funder_count', 'fundings', 'QUERIES'] + 'funder', 'funder_count', 'fundings', 'funding', + 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) + def funding(self, funding_id: str, raw: bool = False): + """ + Returns a funding by ID + @param funding_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'fundingId': '"' + funding_id + '"' + } + + return self._api_request("funding", parameters, return_raw=raw) + def contributor(self, contributor_id: str, raw: bool = False): """ Returns a contributor by ID diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funding.json b/thothlibrary/thoth-0_4_2/tests/fixtures/funding.json new file mode 100644 index 0000000..68f967c --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funding.json @@ -0,0 +1 @@ +{"data":{"funding":{"fundingId":"5323d3e7-3ae9-4778-8464-9400fbbb959e","workId":"a603437d-578e-4577-9800-645614b28b4b","funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","program":null,"grantNumber":null,"projectName":null,"projectShortname":null,"jurisdiction":null,"work":{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}],"imprint":{"publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"}}},"funder":{"funderId":"0de2da0d-5d83-4fdf-9021-adf8e586a632","funderName":"Terra Foundation for American Art","funderDoi":null},"__typename":"Funding"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funding.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/funding.pickle new file mode 100644 index 0000000..dbd6fd6 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funding.pickle @@ -0,0 +1 @@ +{"fundingId": "5323d3e7-3ae9-4778-8464-9400fbbb959e", "workId": "a603437d-578e-4577-9800-645614b28b4b", "funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "program": null, "grantNumber": null, "projectName": null, "projectShortname": null, "jurisdiction": null, "work": {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}], "imprint": {"publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}}}, "funder": {"funderId": "0de2da0d-5d83-4fdf-9021-adf8e586a632", "funderName": "Terra Foundation for American Art", "funderDoi": null}, "__typename": "Funding"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/funding_bad.json b/thothlibrary/thoth-0_4_2/tests/fixtures/funding_bad.json new file mode 100644 index 0000000..3d35390 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/funding_bad.json @@ -0,0 +1 @@ +{"data": {"funding": ["1"] } } diff --git a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh index d156900..b013e57 100755 --- a/thothlibrary/thoth-0_4_2/tests/genfixtures.sh +++ b/thothlibrary/thoth-0_4_2/tests/genfixtures.sh @@ -38,4 +38,5 @@ bash -c "python3 -m thothlibrary.cli subjects --version=0.4.2 --limit=10 --seria bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/subject.pickle" bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funders.pickle" bash -c "python3 -m thothlibrary.cli funder --version=0.4.2 --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funder.pickle" -bash -c "python3 -m thothlibrary.cli fundings --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle" \ No newline at end of file +bash -c "python3 -m thothlibrary.cli fundings --version=0.4.2 --limit=10 --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/fundings.pickle" +bash -c "python3 -m thothlibrary.cli funding --version=0.4.2 --funding_id=5323d3e7-3ae9-4778-8464-9400fbbb959e --serialize > thothlibrary/thoth-0_4_2/tests/fixtures/funding.pickle" \ No newline at end of file diff --git a/thothlibrary/thoth-0_4_2/tests/genjson.sh b/thothlibrary/thoth-0_4_2/tests/genjson.sh index d04ef43..90b17b3 100755 --- a/thothlibrary/thoth-0_4_2/tests/genjson.sh +++ b/thothlibrary/thoth-0_4_2/tests/genjson.sh @@ -37,6 +37,7 @@ bash -c "python3 -m thothlibrary.cli subject --version=0.4.2 --subject_id=129120 bash -c "python3 -m thothlibrary.cli funders --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funders.json" bash -c "python3 -m thothlibrary.cli funder --version=0.4.2 --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funder.json" bash -c "python3 -m thothlibrary.cli fundings --version=0.4.2 --limit=10 --raw > thothlibrary/thoth-0_4_2/tests/fixtures/fundings.json" +bash -c "python3 -m thothlibrary.cli funding --version=0.4.2 --funding_id=5323d3e7-3ae9-4778-8464-9400fbbb959e --raw > thothlibrary/thoth-0_4_2/tests/fixtures/funding.json" bash -c "echo '{\"data\": {\"contributions\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/contributions_bad.json" bash -c "echo '{\"data\": {\"works\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/works_bad.json" @@ -63,4 +64,5 @@ bash -c "echo '{\"data\": {\"subjects\": [\"1\"] } }' > thothlibrary/thoth-0_4_ bash -c "echo '{\"data\": {\"subject\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/subject_bad.json" bash -c "echo '{\"data\": {\"funders\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funders_bad.json" bash -c "echo '{\"data\": {\"funder\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funder_bad.json" -bash -c "echo '{\"data\": {\"fundings\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json" \ No newline at end of file +bash -c "echo '{\"data\": {\"fundings\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/fundings_bad.json" +bash -c "echo '{\"data\": {\"funding\": [\"1\"] } }' > thothlibrary/thoth-0_4_2/tests/fixtures/funding_bad.json" diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 3a08281..649a165 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -874,6 +874,50 @@ def test_contribution_raw(self): lambda_mode=True) return None + def test_funding(self): + """ + Tests that good input to funding produces saved good output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funding', m) + self.pickle_tester('funding', + lambda: + thoth_client.funding( + funding_id='5323d3e7-3ae9-4778-8464-' + '9400fbbb959e]')) + return None + + def test_funding_bad_input(self): + """ + Tests that bad input produces bad output + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funding_bad', m) + + self.pickle_tester('funding', + lambda: thoth_client.funding( + funding_id='5323d3e7-3ae9-4778-8464-' + '9400fbbb959e]'), + negative=True) + return None + + def test_funding_raw(self): + """ + A test to ensure valid passthrough of raw json + @return: None if successful + """ + with requests_mock.Mocker() as m: + mock_response, thoth_client = self.setup_mocker('funding', m) + self.raw_tester(mock_response, + lambda: thoth_client.funding( + funding_id='5323d3e7-3ae9-4778-8464-' + '9400fbbb959e]', + raw=True), + lambda_mode=True) + return None + def test_contributors(self): """ Tests that good input to contributors produces saved good output From 15d619b9bbfe398c0a2acf709beb9890ea202244 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 15:08:45 +0100 Subject: [PATCH 081/115] Add fundingCount endpoint --- thothlibrary/cli.py | 17 +++++++++++++++++ thothlibrary/thoth-0_4_2/endpoints.py | 14 +++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 595dbd7..156ff6e 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -1065,6 +1065,23 @@ def issue_count(self, raw=False, version=None, endpoint=None): print(self._client().issue_count(raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) + def funding_count(self, raw=False, version=None, endpoint=None): + """ + Retrieves a count of fundings from a Thoth instance + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().funding_count(raw=raw)) + @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, filter=None, publication_type=None, raw=False, diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index edb5ed1..0cff2d6 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -647,7 +647,9 @@ class ThothClient0_4_2(ThothClient): ], }, - "issuesCount": None, + "issuesCount": {}, + + "fundingCount": {}, "languageCount": { "parameters": [ @@ -698,7 +700,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): 'language_count', 'prices', 'price', 'price_count', 'subjects', 'subject', 'subject_count', 'funders', 'funder', 'funder_count', 'fundings', 'funding', - 'QUERIES'] + 'funding_count', 'QUERIES'] super().__init__(thoth_endpoint=thoth_endpoint, version=version) @@ -1330,4 +1332,10 @@ def issue_count(self, raw: bool = False): parameters = {} return self._api_request("issueCount", parameters, - return_raw=raw) \ No newline at end of file + return_raw=raw) + + def funding_count(self, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + return self._api_request("fundingCount", parameters, return_raw=raw) From 063b19e470fb06da657cdad80d10921e0208b589 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 15:41:58 +0100 Subject: [PATCH 082/115] Reorder CLI --- thothlibrary/cli.py | 866 ++++++++++++++++++++++---------------------- 1 file changed, 435 insertions(+), 431 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 156ff6e..98fe78b 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -41,6 +41,33 @@ def _client(self): from .client import ThothClient return ThothClient(version=self.version, thoth_endpoint=self.endpoint) + @fire.decorators.SetParseFn(_raw_parse) + def contribution(self, contribution_id, raw=False, version=None, + endpoint=None, serialize=False): + """ + Retrieves a contribution by ID from a Thoth instance + :param str contribution_id: the contributor to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + contribution = self._client().contribution(contribution_id= + contribution_id, + raw=raw) + + if not serialize: + print(contribution) + else: + print(json.dumps(contribution)) + + @fire.decorators.SetParseFn(_raw_parse) def contributions(self, limit=100, order=None, offset=0, publishers=None, contribution_type=None, raw=False, version=None, @@ -78,16 +105,37 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, print(contribs) @fire.decorators.SetParseFn(_raw_parse) - def contributors(self, limit=100, order=None, offset=0, filter=None, - raw=False, version=None, endpoint=None, serialize=False): + def contribution_count(self, publishers=None, filter=None, raw=False, + contribution_type=None, version=None, endpoint=None): """ - Retrieves contributors from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + Retrieves a count of publications from a Thoth instance + :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version + :param str contribution_type: the work type (e.g. AUTHOR) + :param str endpoint: a custom Thoth endpoint + """ + + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + print(self._client().contribution_count(publishers=publishers, + filter=filter, + contribution_type=contribution_type, + raw=raw)) + + @fire.decorators.SetParseFn(_raw_parse) + def contributor(self, contributor_id, raw=False, version=None, + endpoint=None, serialize=False): + """ + Retrieves a contriibutor by ID from a Thoth instance + :param str contributor_id: the contributor to fetch + :param bool raw: whether to return a python object or the raw server result + :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ @@ -97,31 +145,23 @@ def contributors(self, limit=100, order=None, offset=0, filter=None, if version: self.version = version - contribs = self._client().contributors(limit=limit, order=order, - offset=offset, - filter=filter, - raw=raw) + contributor = self._client().contributor(contributor_id=contributor_id, + raw=raw) - if not raw and not serialize: - print(*contribs, sep='\n') - elif serialize: - print(json.dumps(contribs)) + if not serialize: + print(contributor) else: - print(contribs) + print(json.dumps(contributor)) @fire.decorators.SetParseFn(_raw_parse) - def works(self, limit=100, order=None, offset=0, publishers=None, - filter=None, work_type=None, work_status=None, raw=False, - version=None, endpoint=None, serialize=False): + def contributors(self, limit=100, order=None, offset=0, filter=None, + raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves works from a Thoth instance + Retrieves contributors from a Thoth instance :param int limit: the maximum number of results to return (default: 100) :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) - :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param str work_type: the work type (e.g. MONOGRAPH) - :param str work_status: the work status (e.g. ACTIVE) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -133,64 +173,47 @@ def works(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - works = self._client().works(limit=limit, order=order, offset=offset, - publishers=publishers, - filter=filter, - work_type=work_type, - work_status=work_status, - raw=raw) + contribs = self._client().contributors(limit=limit, order=order, + offset=offset, + filter=filter, + raw=raw) if not raw and not serialize: - print(*works, sep='\n') + print(*contribs, sep='\n') elif serialize: - print(json.dumps(works)) - elif raw: - print(works) - - def supported_versions(self): - """ - Retrieves a list of supported Thoth versions - @return: a list of supported Thoth versions - """ - return self._client().supported_versions() + print(json.dumps(contribs)) + else: + print(contribs) @fire.decorators.SetParseFn(_raw_parse) - def publication(self, publication_id, raw=False, - version=None, endpoint=None, serialize=False): + def contributor_count(self, filter=None, raw=False, version=None, + endpoint=None): """ - Retrieves a publication by id from a Thoth instance + Retrieves a count of contributors from a Thoth instance + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object - :param str publication_id: a publicationId to retrieve """ + if endpoint: self.endpoint = endpoint if version: self.version = version - publication = self._client().publication(publication_id=publication_id, - raw=raw) - - if not serialize: - print(publication) - else: - print(json.dumps(publication)) + print(self._client().contributor_count(filter=filter, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def work(self, doi=None, work_id=None, raw=False, version=None, - endpoint=None, serialize=False, cover_ascii=False): + def funder(self, funder_id, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a work by DOI from a Thoth instance - :param str doi: the doi to fetch + Retrieves a funder by ID from a Thoth instance + :param str funder_id: the series to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object - :param str work_id: a workId to retrieve - :param bool cover_ascii: whether to render an ASCII art cover """ if endpoint: self.endpoint = endpoint @@ -198,73 +221,62 @@ def work(self, doi=None, work_id=None, raw=False, version=None, if version: self.version = version - if not doi and not work_id: - print("You must specify either workId or doi.") - return - elif doi: - work = self._client().work_by_doi(doi=doi, raw=raw) - else: - work = self._client().work_by_id(work_id=work_id, raw=raw) + funder = self._client().funder(funder_id=funder_id, raw=raw) if not serialize: - print(work) + print(funder) else: - print(json.dumps(work)) - - if cover_ascii: - # just for lolz - import ascii_magic - output = ascii_magic.from_url(work.coverUrl, columns=85) - ascii_magic.to_terminal(output) + print(json.dumps(funder)) @fire.decorators.SetParseFn(_raw_parse) - def publisher(self, publisher_id, raw=False, version=None, endpoint=None, - serialize=False): + def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, + version=None, endpoint=None, serialize=False): """ - Retrieves a publisher by ID from a Thoth instance - :param str publisher_id: the publisher to fetch - :param bool raw: whether to return a python object or the raw server result + Retrieves funders from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ + if endpoint: self.endpoint = endpoint if version: self.version = version - publisher = self._client().publisher(publisher_id=publisher_id, raw=raw) + funders = self._client().funders(limit=limit, order=order, + offset=offset, filter=filter, raw=raw) - if not serialize: - print(publisher) + if not raw and not serialize: + print(*funders, sep='\n') + elif serialize: + print(json.dumps(funders)) else: - print(json.dumps(publisher)) + print(funders) @fire.decorators.SetParseFn(_raw_parse) - def contributor(self, contributor_id, raw=False, version=None, - endpoint=None, serialize=False): + def funder_count(self, filter=None, raw=False, version=None, + endpoint=None): """ - Retrieves a contriibutor by ID from a Thoth instance - :param str contributor_id: the contributor to fetch - :param bool raw: whether to return a python object or the raw server result + Retrieves a count of publications from a Thoth instance + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object """ + if endpoint: self.endpoint = endpoint if version: self.version = version - contributor = self._client().contributor(contributor_id=contributor_id, - raw=raw) - - if not serialize: - print(contributor) - else: - print(json.dumps(contributor)) + print(self._client().funder_count(filter=filter, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def funding(self, funding_id, raw=False, version=None, endpoint=None, @@ -291,62 +303,61 @@ def funding(self, funding_id, raw=False, version=None, endpoint=None, print(json.dumps(funding)) @fire.decorators.SetParseFn(_raw_parse) - def contribution(self, contribution_id, raw=False, version=None, - endpoint=None, serialize=False): + def fundings(self, limit=100, order=None, offset=0, publishers=None, + raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves a contribution by ID from a Thoth instance - :param str contribution_id: the contributor to fetch - :param bool raw: whether to return a python object or the raw server result + Retrieves fundings from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ + if endpoint: self.endpoint = endpoint if version: self.version = version - contribution = self._client().contribution(contribution_id= - contribution_id, - raw=raw) + fundings = self._client().fundings(limit=limit, order=order, + offset=offset, publishers=publishers, + raw=raw) - if not serialize: - print(contribution) + if not raw and not serialize: + print(*fundings, sep='\n') + elif serialize: + print(json.dumps(fundings)) else: - print(json.dumps(contribution)) + print(fundings) @fire.decorators.SetParseFn(_raw_parse) - def series(self, series_id, raw=False, version=None, endpoint=None, - serialize=False): + def funding_count(self, raw=False, version=None, endpoint=None): """ - Retrieves a series by ID from a Thoth instance - :param str series_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result + Retrieves a count of fundings from a Thoth instance + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object """ + if endpoint: self.endpoint = endpoint if version: self.version = version - series = self._client().series(series_id=series_id, raw=raw) - - if not serialize: - print(series) - else: - print(json.dumps(series)) + print(self._client().funding_count(raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def language(self, language_id, raw=False, version=None, endpoint=None, - serialize=False): + def imprint(self, imprint_id, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a language by ID from a Thoth instance - :param str language_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result + Retrieves a publisher by ID from a Thoth instance + :param str imprint_id: the imprint to fetch + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -357,108 +368,70 @@ def language(self, language_id, raw=False, version=None, endpoint=None, if version: self.version = version - lang = self._client().language(language_id=language_id, raw=raw) + imprint = self._client().imprint(imprint_id=imprint_id, raw=raw) if not serialize: - print(lang) + print(imprint) else: - print(json.dumps(lang)) + print(json.dumps(imprint)) @fire.decorators.SetParseFn(_raw_parse) - def funder(self, funder_id, raw=False, version=None, endpoint=None, - serialize=False): + def imprints(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a funder by ID from a Thoth instance - :param str funder_id: the series to fetch + Retrieves imprints from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version - - funder = self._client().funder(funder_id=funder_id, raw=raw) - - if not serialize: - print(funder) - else: - print(json.dumps(funder)) - @fire.decorators.SetParseFn(_raw_parse) - def subject(self, subject_id, raw=False, version=None, endpoint=None, - serialize=False): - """ - Retrieves a subject by ID from a Thoth instance - :param str subject_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result - :param str version: a custom Thoth version - :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object - """ if endpoint: self.endpoint = endpoint if version: self.version = version - subj = self._client().subject(subject_id=subject_id, raw=raw) + imprints = self._client().imprints(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + raw=raw) - if not serialize: - print(subj) + if not raw and not serialize: + print(*imprints, sep='\n') + elif serialize: + print(json.dumps(imprints)) else: - print(json.dumps(subj)) + print(imprints) @fire.decorators.SetParseFn(_raw_parse) - def imprint(self, imprint_id, raw=False, version=None, endpoint=None, - serialize=False): + def imprint_count(self, publishers=None, filter=None, raw=False, + version=None, endpoint=None): """ - Retrieves a publisher by ID from a Thoth instance - :param str imprint_id: the imprint to fetch + Retrieves a count of imprints from a Thoth instance + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version - - imprint = self._client().imprint(imprint_id=imprint_id, raw=raw) - if not serialize: - print(imprint) - else: - print(json.dumps(imprint)) - - @fire.decorators.SetParseFn(_raw_parse) - def price(self, price_id, raw=False, version=None, endpoint=None, - serialize=False): - """ - Retrieves a price by ID from a Thoth instance - :param str price_id: the price to fetch - :param bool raw: whether to return a python object or the raw server result - :param str version: a custom Thoth version - :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object - """ if endpoint: self.endpoint = endpoint if version: self.version = version - price = self._client().price(price_id=price_id, raw=raw) - - if not serialize: - print(price) - else: - print(json.dumps(price)) + print(self._client().imprint_count(publishers=publishers, + filter=filter, + raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def issue(self, issue_id, raw=False, version=None, endpoint=None, @@ -485,11 +458,11 @@ def issue(self, issue_id, raw=False, version=None, endpoint=None, print(json.dumps(issue)) @fire.decorators.SetParseFn(_raw_parse) - def publishers(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, - serialize=False): + def issues(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves publishers from a Thoth instance + Retrieves imprints from a Thoth instance :param int limit: the maximum number of results to return (default: 100) :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) @@ -507,34 +480,26 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - found_publishers = self._client().publishers(limit=limit, order=order, - offset=offset, - publishers=publishers, - filter=filter, - raw=raw) + issues = self._client().issues(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + raw=raw) if not raw and not serialize: - print(*found_publishers, sep='\n') + print(*issues, sep='\n') elif serialize: - print(json.dumps(found_publishers)) + print(json.dumps(issues)) else: - print(found_publishers) + print(issues) @fire.decorators.SetParseFn(_raw_parse) - def issues(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, - serialize=False): + def issue_count(self, raw=False, version=None, endpoint=None): """ - Retrieves imprints from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) - :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + Retrieves a count of issues from a Thoth instance :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object """ if endpoint: @@ -543,54 +508,32 @@ def issues(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - issues = self._client().issues(limit=limit, order=order, - offset=offset, - publishers=publishers, - filter=filter, - raw=raw) + print(self._client().issue_count(raw=raw)) - if not raw and not serialize: - print(*issues, sep='\n') - elif serialize: - print(json.dumps(issues)) - else: - print(issues) @fire.decorators.SetParseFn(_raw_parse) - def imprints(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, + def language(self, language_id, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves imprints from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) - :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + Retrieves a language by ID from a Thoth instance + :param str language_id: the series to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: self.endpoint = endpoint if version: self.version = version - imprints = self._client().imprints(limit=limit, order=order, - offset=offset, - publishers=publishers, - filter=filter, - raw=raw) + lang = self._client().language(language_id=language_id, raw=raw) - if not raw and not serialize: - print(*imprints, sep='\n') - elif serialize: - print(json.dumps(imprints)) + if not serialize: + print(lang) else: - print(imprints) + print(json.dumps(lang)) @fire.decorators.SetParseFn(_raw_parse) def languages(self, limit=100, order=None, offset=0, publishers=None, @@ -633,18 +576,15 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, print(langs) @fire.decorators.SetParseFn(_raw_parse) - def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, - version=None, endpoint=None, serialize=False): + def language_count(self, language_code=None, raw=False, version=None, + endpoint=None, language_relation=None): """ - Retrieves funders from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) - :param str filter: a filter string to search + Retrieves a count of contributors from a Thoth instance :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object + :param language_code: the code to retrieve (e.g. CHI) + :param language_relation: the relation (e.g. ORIGINAL) """ if endpoint: @@ -653,53 +593,33 @@ def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, if version: self.version = version - funders = self._client().funders(limit=limit, order=order, - offset=offset, filter=filter, raw=raw) - - if not raw and not serialize: - print(*funders, sep='\n') - elif serialize: - print(json.dumps(funders)) - else: - print(funders) + print(self._client().language_count(language_code=language_code, + language_relation=language_relation, + raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def subjects(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, - serialize=False, subject_type=None): + def price(self, price_id, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves languages from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) - :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw result + Retrieves a price by ID from a Thoth instance + :param str price_id: the price to fetch + :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object - :param subject_type: select by subject code (e.g. BIC) """ - if endpoint: self.endpoint = endpoint if version: self.version = version - subj = self._client().subjects(limit=limit, order=order, - offset=offset, - publishers=publishers, - filter=filter, - subject_type=subject_type, - raw=raw) + price = self._client().price(price_id=price_id, raw=raw) - if not raw and not serialize: - print(*subj, sep='\n') - elif serialize: - print(json.dumps(subj)) + if not serialize: + print(price) else: - print(subj) + print(json.dumps(price)) @fire.decorators.SetParseFn(_raw_parse) def prices(self, limit=100, order=None, offset=0, publishers=None, @@ -738,18 +658,14 @@ def prices(self, limit=100, order=None, offset=0, publishers=None, print(prices) @fire.decorators.SetParseFn(_raw_parse) - def fundings(self, limit=100, order=None, offset=0, publishers=None, - raw=False, version=None, endpoint=None, serialize=False): + def price_count(self, currency_code=None, raw=False, version=None, + endpoint=None): """ - Retrieves fundings from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) - :param str publishers: a list of publishers to limit by + Retrieves a count of imprints from a Thoth instance + :param str currency_code: the currency to filter by (e.g. GBP) :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object """ if endpoint: @@ -758,65 +674,80 @@ def fundings(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - fundings = self._client().fundings(limit=limit, order=order, - offset=offset, publishers=publishers, - raw=raw) - - if not raw and not serialize: - print(*fundings, sep='\n') - elif serialize: - print(json.dumps(fundings)) - else: - print(fundings) + print(self._client().price_count(currency_code=currency_code, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def serieses(self, limit=100, order=None, offset=0, publishers=None, - filter=None, series_type=None, raw=False, version=None, - endpoint=None, serialize=False): + def publication(self, publication_id, raw=False, + version=None, endpoint=None, serialize=False): """ - Retrieves serieses from a Thoth instance + Retrieves a publication by id from a Thoth instance + :param bool raw: whether to return a python object or the raw result + :param str version: a custom Thoth version + :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param str publication_id: a publicationId to retrieve + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + publication = self._client().publication(publication_id=publication_id, + raw=raw) + + if not serialize: + print(publication) + else: + print(json.dumps(publication)) + + @fire.decorators.SetParseFn(_raw_parse) + def publications(self, limit=100, order=None, offset=0, publishers=None, + filter=None, publication_type=None, raw=False, + version=None, endpoint=None, serialize=False): + """ + Retrieves publications from a Thoth instance :param int limit: the maximum number of results to return (default: 100) :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by :param str filter: a filter string to search + :param str publication_type: the work type (e.g. PAPERBACK) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object - :param series_type: the type of serieses to return (e.g. BOOK_SERIES) """ - if endpoint: self.endpoint = endpoint if version: self.version = version - serieses = self._client().serieses(limit=limit, order=order, - offset=offset, - publishers=publishers, + pubs = self._client().publications(limit=limit, order=order, + offset=offset, publishers=publishers, filter=filter, - series_type=series_type, + publication_type=publication_type, raw=raw) - if not raw and not serialize: - print(*serieses, sep='\n') + print(*pubs, sep='\n') elif serialize: - print(json.dumps(serieses)) + print(json.dumps(pubs)) else: - print(serieses) + print(pubs) + @fire.decorators.SetParseFn(_raw_parse) - def language_count(self, language_code=None, raw=False, version=None, - endpoint=None, language_relation=None): + def publication_count(self, publishers=None, filter=None, raw=False, + publication_type=None, version=None, endpoint=None): """ - Retrieves a count of contributors from a Thoth instance - :param bool raw: whether to return a python object or the raw result + Retrieves a count of publications from a Thoth instance + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version + :param str publication_type: the work type (e.g. MONOGRAPH) :param str endpoint: a custom Thoth endpoint - :param language_code: the code to retrieve (e.g. CHI) - :param language_relation: the relation (e.g. ORIGINAL) """ if endpoint: @@ -825,40 +756,50 @@ def language_count(self, language_code=None, raw=False, version=None, if version: self.version = version - print(self._client().language_count(language_code=language_code, - language_relation=language_relation, - raw=raw)) + print(self._client().publication_count(publishers=publishers, + filter=filter, + publication_type=publication_type, + raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def subject_count(self, subject_type=None, raw=False, version=None, - endpoint=None, filter=None): + def publisher(self, publisher_id, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a count of contributors from a Thoth instance - :param bool raw: whether to return a python object or the raw result + Retrieves a publisher by ID from a Thoth instance + :param str publisher_id: the publisher to fetch + :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint - :param str subject_type: the type to retrieve (e.g. BIC) - :param str filter: a search + :param bool serialize: return a pickled python object """ - if endpoint: self.endpoint = endpoint if version: self.version = version - print(self._client().subject_count(subject_type=subject_type, - filter=filter, raw=raw)) + publisher = self._client().publisher(publisher_id=publisher_id, raw=raw) + + if not serialize: + print(publisher) + else: + print(json.dumps(publisher)) @fire.decorators.SetParseFn(_raw_parse) - def contributor_count(self, filter=None, raw=False, version=None, - endpoint=None): + def publishers(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a count of contributors from a Thoth instance + Retrieves publishers from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw result + :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ if endpoint: @@ -867,7 +808,18 @@ def contributor_count(self, filter=None, raw=False, version=None, if version: self.version = version - print(self._client().contributor_count(filter=filter, raw=raw)) + found_publishers = self._client().publishers(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + raw=raw) + + if not raw and not serialize: + print(*found_publishers, sep='\n') + elif serialize: + print(json.dumps(found_publishers)) + else: + print(found_publishers) @fire.decorators.SetParseFn(_raw_parse) def publisher_count(self, publishers=None, filter=None, raw=False, @@ -892,59 +844,45 @@ def publisher_count(self, publishers=None, filter=None, raw=False, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def imprint_count(self, publishers=None, filter=None, raw=False, - version=None, endpoint=None): + def series(self, series_id, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a count of imprints from a Thoth instance - :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + Retrieves a series by ID from a Thoth instance + :param str series_id: the series to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ - if endpoint: self.endpoint = endpoint if version: self.version = version - print(self._client().imprint_count(publishers=publishers, - filter=filter, - raw=raw)) - - @fire.decorators.SetParseFn(_raw_parse) - def price_count(self, currency_code=None, raw=False, version=None, - endpoint=None): - """ - Retrieves a count of imprints from a Thoth instance - :param str currency_code: the currency to filter by (e.g. GBP) - :param bool raw: whether to return a python object or the raw result - :param str version: a custom Thoth version - :param str endpoint: a custom Thoth endpoint - """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + series = self._client().series(series_id=series_id, raw=raw) - print(self._client().price_count(currency_code=currency_code, raw=raw)) + if not serialize: + print(series) + else: + print(json.dumps(series)) @fire.decorators.SetParseFn(_raw_parse) - def work_count(self, publishers=None, filter=None, raw=False, - work_type=None, work_status=None, version=None, - endpoint=None): + def serieses(self, limit=100, order=None, offset=0, publishers=None, + filter=None, series_type=None, raw=False, version=None, + endpoint=None, serialize=False): """ - Retrieves a count of works from a Thoth instance + Retrieves serieses from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version - :param str work_type: the work type (e.g. MONOGRAPH) - :param str work_status: the work status (e.g. ACTIVE) :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param series_type: the type of serieses to return (e.g. BOOK_SERIES) """ if endpoint: @@ -953,11 +891,19 @@ def work_count(self, publishers=None, filter=None, raw=False, if version: self.version = version - print(self._client().work_count(publishers=publishers, - filter=filter, - work_type=work_type, - work_status=work_status, - raw=raw)) + serieses = self._client().serieses(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + series_type=series_type, + raw=raw) + + if not raw and not serialize: + print(*serieses, sep='\n') + elif serialize: + print(json.dumps(serieses)) + else: + print(serieses) @fire.decorators.SetParseFn(_raw_parse) def series_count(self, publishers=None, filter=None, raw=False, @@ -982,38 +928,45 @@ def series_count(self, publishers=None, filter=None, raw=False, series_type=series_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) - def publication_count(self, publishers=None, filter=None, raw=False, - publication_type=None, version=None, endpoint=None): + def subject(self, subject_id, raw=False, version=None, endpoint=None, + serialize=False): """ - Retrieves a count of publications from a Thoth instance - :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + Retrieves a subject by ID from a Thoth instance + :param str subject_id: the series to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version - :param str publication_type: the work type (e.g. MONOGRAPH) :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ - if endpoint: self.endpoint = endpoint if version: self.version = version - print(self._client().publication_count(publishers=publishers, - filter=filter, - publication_type=publication_type, - raw=raw)) + subj = self._client().subject(subject_id=subject_id, raw=raw) + + if not serialize: + print(subj) + else: + print(json.dumps(subj)) @fire.decorators.SetParseFn(_raw_parse) - def funder_count(self, filter=None, raw=False, version=None, - endpoint=None): + def subjects(self, limit=100, order=None, offset=0, publishers=None, + filter=None, raw=False, version=None, endpoint=None, + serialize=False, subject_type=None): """ - Retrieves a count of publications from a Thoth instance + Retrieves languages from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param subject_type: select by subject code (e.g. BIC) """ if endpoint: @@ -1022,19 +975,30 @@ def funder_count(self, filter=None, raw=False, version=None, if version: self.version = version - print(self._client().funder_count(filter=filter, raw=raw)) + subj = self._client().subjects(limit=limit, order=order, + offset=offset, + publishers=publishers, + filter=filter, + subject_type=subject_type, + raw=raw) + + if not raw and not serialize: + print(*subj, sep='\n') + elif serialize: + print(json.dumps(subj)) + else: + print(subj) @fire.decorators.SetParseFn(_raw_parse) - def contribution_count(self, publishers=None, filter=None, raw=False, - contribution_type=None, version=None, endpoint=None): + def subject_count(self, subject_type=None, raw=False, version=None, + endpoint=None, filter=None): """ - Retrieves a count of publications from a Thoth instance - :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + Retrieves a count of contributors from a Thoth instance + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version - :param str contribution_type: the work type (e.g. AUTHOR) :param str endpoint: a custom Thoth endpoint + :param str subject_type: the type to retrieve (e.g. BIC) + :param str filter: a search """ if endpoint: @@ -1043,80 +1007,120 @@ def contribution_count(self, publishers=None, filter=None, raw=False, if version: self.version = version - print(self._client().contribution_count(publishers=publishers, - filter=filter, - contribution_type=contribution_type, - raw=raw)) + print(self._client().subject_count(subject_type=subject_type, + filter=filter, raw=raw)) + + + def supported_versions(self): + """ + Retrieves a list of supported Thoth versions + @return: a list of supported Thoth versions + """ + return self._client().supported_versions() @fire.decorators.SetParseFn(_raw_parse) - def issue_count(self, raw=False, version=None, endpoint=None): + def work(self, doi=None, work_id=None, raw=False, version=None, + endpoint=None, serialize=False, cover_ascii=False): """ - Retrieves a count of issues from a Thoth instance + Retrieves a work by DOI from a Thoth instance + :param str doi: the doi to fetch :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object + :param str work_id: a workId to retrieve + :param bool cover_ascii: whether to render an ASCII art cover """ - if endpoint: self.endpoint = endpoint if version: self.version = version - print(self._client().issue_count(raw=raw)) + if not doi and not work_id: + print("You must specify either workId or doi.") + return + elif doi: + work = self._client().work_by_doi(doi=doi, raw=raw) + else: + work = self._client().work_by_id(work_id=work_id, raw=raw) + + if not serialize: + print(work) + else: + print(json.dumps(work)) + + if cover_ascii: + # just for lolz + import ascii_magic + output = ascii_magic.from_url(work.coverUrl, columns=85) + ascii_magic.to_terminal(output) + @fire.decorators.SetParseFn(_raw_parse) - def funding_count(self, raw=False, version=None, endpoint=None): + def works(self, limit=100, order=None, offset=0, publishers=None, + filter=None, work_type=None, work_status=None, raw=False, + version=None, endpoint=None, serialize=False): """ - Retrieves a count of fundings from a Thoth instance - :param bool raw: whether to return a python object or the raw result + Retrieves works from a Thoth instance + :param int limit: the maximum number of results to return (default: 100) + :param int order: a GraphQL order query statement + :param int offset: the offset from which to retrieve results (default: 0) + :param str publishers: a list of publishers to limit by + :param str filter: a filter string to search + :param str work_type: the work type (e.g. MONOGRAPH) + :param str work_status: the work status (e.g. ACTIVE) + :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint + :param bool serialize: return a pickled python object """ - if endpoint: self.endpoint = endpoint if version: self.version = version - print(self._client().funding_count(raw=raw)) + works = self._client().works(limit=limit, order=order, offset=offset, + publishers=publishers, + filter=filter, + work_type=work_type, + work_status=work_status, + raw=raw) + + if not raw and not serialize: + print(*works, sep='\n') + elif serialize: + print(json.dumps(works)) + elif raw: + print(works) @fire.decorators.SetParseFn(_raw_parse) - def publications(self, limit=100, order=None, offset=0, publishers=None, - filter=None, publication_type=None, raw=False, - version=None, endpoint=None, serialize=False): + def work_count(self, publishers=None, filter=None, raw=False, + work_type=None, work_status=None, version=None, + endpoint=None): """ - Retrieves publications from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) - :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + Retrieves a count of works from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param str publication_type: the work type (e.g. PAPERBACK) :param bool raw: whether to return a python object or the raw server result :param str version: a custom Thoth version + :param str work_type: the work type (e.g. MONOGRAPH) + :param str work_status: the work status (e.g. ACTIVE) :param str endpoint: a custom Thoth endpoint - :param bool serialize: return a pickled python object """ + if endpoint: self.endpoint = endpoint if version: self.version = version - pubs = self._client().publications(limit=limit, order=order, - offset=offset, publishers=publishers, - filter=filter, - publication_type=publication_type, - raw=raw) - if not raw and not serialize: - print(*pubs, sep='\n') - elif serialize: - print(json.dumps(pubs)) - else: - print(pubs) - + print(self._client().work_count(publishers=publishers, + filter=filter, + work_type=work_type, + work_status=work_status, + raw=raw)) if __name__ == '__main__': fire.Fire(ThothAPI) From efe57d67835db68543b63cdb7b923f64ad3cb855 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 16:03:47 +0100 Subject: [PATCH 083/115] Docstrings and PEP8 cleanup in CLI --- thothlibrary/cli.py | 179 +++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 95 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 98fe78b..012c9cf 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -47,7 +47,7 @@ def contribution(self, contribution_id, raw=False, version=None, """ Retrieves a contribution by ID from a Thoth instance :param str contribution_id: the contributor to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -58,28 +58,26 @@ def contribution(self, contribution_id, raw=False, version=None, if version: self.version = version - contribution = self._client().contribution(contribution_id= - contribution_id, - raw=raw) + contribution = self._client().contribution( + contribution_id=contribution_id, raw=raw) if not serialize: print(contribution) else: print(json.dumps(contribution)) - @fire.decorators.SetParseFn(_raw_parse) def contributions(self, limit=100, order=None, offset=0, publishers=None, contribution_type=None, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves works from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + Retrieves contributions from a Thoth instance + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str contribution_type: the contribution type (e.g. AUTHOR) - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -90,12 +88,9 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, if version: self.version = version - contribs = self._client().contributions(limit=limit, order=order, - offset=offset, - publishers=publishers, - contribution_type= - contribution_type, - raw=raw) + contribs = self._client().contributions( + limit=limit, order=order, offset=offset, publishers=publishers, + contribution_type=contribution_type, raw=raw) if not raw and not serialize: print(*contribs, sep='\n') @@ -108,10 +103,10 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, def contribution_count(self, publishers=None, filter=None, raw=False, contribution_type=None, version=None, endpoint=None): """ - Retrieves a count of publications from a Thoth instance + Retrieves a count of contributions from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str contribution_type: the work type (e.g. AUTHOR) :param str endpoint: a custom Thoth endpoint @@ -123,18 +118,17 @@ def contribution_count(self, publishers=None, filter=None, raw=False, if version: self.version = version - print(self._client().contribution_count(publishers=publishers, - filter=filter, - contribution_type=contribution_type, - raw=raw)) + print(self._client().contribution_count( + publishers=publishers, filter=filter, + contribution_type=contribution_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def contributor(self, contributor_id, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves a contriibutor by ID from a Thoth instance + Retrieves a contributor by ID from a Thoth instance :param str contributor_id: the contributor to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -158,11 +152,11 @@ def contributors(self, limit=100, order=None, offset=0, filter=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves contributors from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -209,8 +203,8 @@ def funder(self, funder_id, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves a funder by ID from a Thoth instance - :param str funder_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result + :param str funder_id: the funder to fetch + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -233,9 +227,9 @@ def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves funders from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version @@ -260,10 +254,9 @@ def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, print(funders) @fire.decorators.SetParseFn(_raw_parse) - def funder_count(self, filter=None, raw=False, version=None, - endpoint=None): + def funder_count(self, filter=None, raw=False, version=None, endpoint=None): """ - Retrieves a count of publications from a Thoth instance + Retrieves a count of funders from a Thoth instance :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version @@ -283,8 +276,8 @@ def funding(self, funding_id, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves a funding by ID from a Thoth instance - :param str funding_id: the contributor to fetch - :param bool raw: whether to return a python object or the raw server result + :param str funding_id: the funding to fetch + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -307,9 +300,9 @@ def fundings(self, limit=100, order=None, offset=0, publishers=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves fundings from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version @@ -355,7 +348,7 @@ def funding_count(self, raw=False, version=None, endpoint=None): def imprint(self, imprint_id, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves a publisher by ID from a Thoth instance + Retrieves an imprint by ID from a Thoth instance :param str imprint_id: the imprint to fetch :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version @@ -381,12 +374,12 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, serialize=False): """ Retrieves imprints from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -418,7 +411,7 @@ def imprint_count(self, publishers=None, filter=None, raw=False, Retrieves a count of imprints from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ @@ -439,7 +432,7 @@ def issue(self, issue_id, raw=False, version=None, endpoint=None, """ Retrieves an issue by ID from a Thoth instance :param str issue_id: the issue to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -462,13 +455,13 @@ def issues(self, limit=100, order=None, offset=0, publishers=None, filter=None, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves imprints from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + Retrieves issues from a Thoth instance + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -497,7 +490,7 @@ def issues(self, limit=100, order=None, offset=0, publishers=None, def issue_count(self, raw=False, version=None, endpoint=None): """ Retrieves a count of issues from a Thoth instance - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ @@ -510,14 +503,13 @@ def issue_count(self, raw=False, version=None, endpoint=None): print(self._client().issue_count(raw=raw)) - @fire.decorators.SetParseFn(_raw_parse) def language(self, language_id, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves a language by ID from a Thoth instance - :param str language_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result + :param str language_id: the language to fetch + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -541,9 +533,9 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, serialize=False, language_code=None, language_relation=None): """ Retrieves languages from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw result @@ -551,7 +543,7 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object :param language_relation: select by language relation (e.g. ORIGINAL) - :param language_code: select by lanmguage code (e.g. ADA) + :param language_code: select by language code (e.g. ADA) """ if endpoint: @@ -579,7 +571,7 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, def language_count(self, language_code=None, raw=False, version=None, endpoint=None, language_relation=None): """ - Retrieves a count of contributors from a Thoth instance + Retrieves a count of languages from a Thoth instance :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -603,7 +595,7 @@ def price(self, price_id, raw=False, version=None, endpoint=None, """ Retrieves a price by ID from a Thoth instance :param str price_id: the price to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -626,12 +618,12 @@ def prices(self, limit=100, order=None, offset=0, publishers=None, currency_code=None, raw=False, version=None, endpoint=None, serialize=False): """ - Retrieves serieses from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + Retrieves prices from a Thoth instance + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -661,7 +653,7 @@ def prices(self, limit=100, order=None, offset=0, publishers=None, def price_count(self, currency_code=None, raw=False, version=None, endpoint=None): """ - Retrieves a count of imprints from a Thoth instance + Retrieves a count of prices from a Thoth instance :param str currency_code: the currency to filter by (e.g. GBP) :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version @@ -707,13 +699,13 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, version=None, endpoint=None, serialize=False): """ Retrieves publications from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param str publication_type: the work type (e.g. PAPERBACK) - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -736,7 +728,6 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, else: print(pubs) - @fire.decorators.SetParseFn(_raw_parse) def publication_count(self, publishers=None, filter=None, raw=False, publication_type=None, version=None, endpoint=None): @@ -744,7 +735,7 @@ def publication_count(self, publishers=None, filter=None, raw=False, Retrieves a count of publications from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str publication_type: the work type (e.g. MONOGRAPH) :param str endpoint: a custom Thoth endpoint @@ -756,10 +747,9 @@ def publication_count(self, publishers=None, filter=None, raw=False, if version: self.version = version - print(self._client().publication_count(publishers=publishers, - filter=filter, - publication_type=publication_type, - raw=raw)) + print(self._client().publication_count( + publishers=publishers, filter=filter, + publication_type=publication_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def publisher(self, publisher_id, raw=False, version=None, endpoint=None, @@ -767,7 +757,7 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None, """ Retrieves a publisher by ID from a Thoth instance :param str publisher_id: the publisher to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -791,12 +781,12 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, serialize=False): """ Retrieves publishers from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -828,7 +818,7 @@ def publisher_count(self, publishers=None, filter=None, raw=False, Retrieves a count of publishers from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ @@ -849,7 +839,7 @@ def series(self, series_id, raw=False, version=None, endpoint=None, """ Retrieves a series by ID from a Thoth instance :param str series_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -873,12 +863,12 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, endpoint=None, serialize=False): """ Retrieves serieses from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -909,10 +899,10 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, def series_count(self, publishers=None, filter=None, raw=False, series_type=None, version=None, endpoint=None): """ - Retrieves a count of publications from a Thoth instance + Retrieves a count of serieses from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str series_type: the work type (e.g. BOOK_SERIES) :param str endpoint: a custom Thoth endpoint @@ -932,8 +922,8 @@ def subject(self, subject_id, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves a subject by ID from a Thoth instance - :param str subject_id: the series to fetch - :param bool raw: whether to return a python object or the raw server result + :param str subject_id: the subject to fetch + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -956,10 +946,10 @@ def subjects(self, limit=100, order=None, offset=0, publishers=None, filter=None, raw=False, version=None, endpoint=None, serialize=False, subject_type=None): """ - Retrieves languages from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + Retrieves subjects from a Thoth instance + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param bool raw: whether to return a python object or the raw result @@ -993,7 +983,7 @@ def subjects(self, limit=100, order=None, offset=0, publishers=None, def subject_count(self, subject_type=None, raw=False, version=None, endpoint=None, filter=None): """ - Retrieves a count of contributors from a Thoth instance + Retrieves a count of subjects from a Thoth instance :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -1010,7 +1000,6 @@ def subject_count(self, subject_type=None, raw=False, version=None, print(self._client().subject_count(subject_type=subject_type, filter=filter, raw=raw)) - def supported_versions(self): """ Retrieves a list of supported Thoth versions @@ -1022,9 +1011,9 @@ def supported_versions(self): def work(self, doi=None, work_id=None, raw=False, version=None, endpoint=None, serialize=False, cover_ascii=False): """ - Retrieves a work by DOI from a Thoth instance + Retrieves a work by DOI or ID from a Thoth instance :param str doi: the doi to fetch - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -1056,21 +1045,20 @@ def work(self, doi=None, work_id=None, raw=False, version=None, output = ascii_magic.from_url(work.coverUrl, columns=85) ascii_magic.to_terminal(output) - @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, filter=None, work_type=None, work_status=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves works from a Thoth instance - :param int limit: the maximum number of results to return (default: 100) + :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement - :param int offset: the offset from which to retrieve results (default: 0) + :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by :param str filter: a filter string to search :param str work_type: the work type (e.g. MONOGRAPH) :param str work_status: the work status (e.g. ACTIVE) - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object @@ -1103,7 +1091,7 @@ def work_count(self, publishers=None, filter=None, raw=False, Retrieves a count of works from a Thoth instance :param str publishers: a list of publishers to limit by :param str filter: a filter string to search - :param bool raw: whether to return a python object or the raw server result + :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str work_type: the work type (e.g. MONOGRAPH) :param str work_status: the work status (e.g. ACTIVE) @@ -1122,5 +1110,6 @@ def work_count(self, publishers=None, filter=None, raw=False, work_status=work_status, raw=raw)) + if __name__ == '__main__': fire.Fire(ThothAPI) From e1dc428a1272be0d43672ed23d711e066ee5d9bb Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 16:08:58 +0100 Subject: [PATCH 084/115] Rename "filter" to "search" to avoid shadowing python builtin --- README.md | 4 +- thothlibrary/cli.py | 116 +++++++++---------- thothlibrary/thoth-0_4_2/endpoints.py | 154 +++++++++++++------------- 3 files changed, 137 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index a5b7ea0..c78b884 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ python3 -m thothlibrary.cli contributions --limit=10 python3 -m thothlibrary.cli contribution_count python3 -m thothlibrary.cli contributor --contributor_id=e8def8cf-0dfe-4da9-b7fa-f77e7aec7524 python3 -m thothlibrary.cli contributors --limit=10 -python3 -m thothlibrary.cli contributor_count --filter="Vincent" +python3 -m thothlibrary.cli contributor_count --search="Vincent" python3 -m thothlibrary.cli funder --funder_id=194614ac-d189-4a74-8bf4-74c0c9de4a81 python3 -m thothlibrary.cli funders --limit=10 python3 -m thothlibrary.cli funder_count @@ -59,7 +59,7 @@ python3 -m thothlibrary.cli publisher --publisher_id=85fd969a-a16c-480b-b641-cb9 python3 -m thothlibrary.cli publishers --limit=10 --order='{field: PUBLISHER_ID, direction: ASC}' --offset=0 --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli publisher_count --publishers='["85fd969a-a16c-480b-b641-cb9adf979c3b" "9c41b13c-cecc-4f6a-a151-be4682915ef5"]' python3 -m thothlibrary.cli series --series_id=d4b47a76-abff-4047-a3c7-d44d85ccf009 -python3 -m thothlibrary.cli serieses --limit=3 --filter="Classics" +python3 -m thothlibrary.cli serieses --limit=3 --search="Classics" python3 -m thothlibrary.cli series_count --series_type=BOOK_SERIES python3 -m thothlibrary.cli subject --subject_id=1291208f-fc43-47a4-a8e6-e132477ad57b python3 -m thothlibrary.cli subjects --limit=10 --subject_type=BIC diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 012c9cf..3900c3a 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -100,12 +100,12 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, print(contribs) @fire.decorators.SetParseFn(_raw_parse) - def contribution_count(self, publishers=None, filter=None, raw=False, + def contribution_count(self, publishers=None, search=None, raw=False, contribution_type=None, version=None, endpoint=None): """ Retrieves a count of contributions from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str contribution_type: the work type (e.g. AUTHOR) @@ -119,7 +119,7 @@ def contribution_count(self, publishers=None, filter=None, raw=False, self.version = version print(self._client().contribution_count( - publishers=publishers, filter=filter, + publishers=publishers, search=search, contribution_type=contribution_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) @@ -148,14 +148,14 @@ def contributor(self, contributor_id, raw=False, version=None, print(json.dumps(contributor)) @fire.decorators.SetParseFn(_raw_parse) - def contributors(self, limit=100, order=None, offset=0, filter=None, + def contributors(self, limit=100, order=None, offset=0, search=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves contributors from a Thoth instance :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -169,7 +169,7 @@ def contributors(self, limit=100, order=None, offset=0, filter=None, contribs = self._client().contributors(limit=limit, order=order, offset=offset, - filter=filter, + search=search, raw=raw) if not raw and not serialize: @@ -180,11 +180,11 @@ def contributors(self, limit=100, order=None, offset=0, filter=None, print(contribs) @fire.decorators.SetParseFn(_raw_parse) - def contributor_count(self, filter=None, raw=False, version=None, + def contributor_count(self, search=None, raw=False, version=None, endpoint=None): """ Retrieves a count of contributors from a Thoth instance - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -196,7 +196,7 @@ def contributor_count(self, filter=None, raw=False, version=None, if version: self.version = version - print(self._client().contributor_count(filter=filter, raw=raw)) + print(self._client().contributor_count(search=search, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def funder(self, funder_id, raw=False, version=None, endpoint=None, @@ -223,14 +223,14 @@ def funder(self, funder_id, raw=False, version=None, endpoint=None, print(json.dumps(funder)) @fire.decorators.SetParseFn(_raw_parse) - def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, + def funders(self, limit=100, order=None, offset=0, search=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves funders from a Thoth instance :param int limit: the maximum number of results to return :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -244,7 +244,7 @@ def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, self.version = version funders = self._client().funders(limit=limit, order=order, - offset=offset, filter=filter, raw=raw) + offset=offset, search=search, raw=raw) if not raw and not serialize: print(*funders, sep='\n') @@ -254,10 +254,10 @@ def funders(self, limit=100, order=None, offset=0, filter=None, raw=False, print(funders) @fire.decorators.SetParseFn(_raw_parse) - def funder_count(self, filter=None, raw=False, version=None, endpoint=None): + def funder_count(self, search=None, raw=False, version=None, endpoint=None): """ Retrieves a count of funders from a Thoth instance - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -269,7 +269,7 @@ def funder_count(self, filter=None, raw=False, version=None, endpoint=None): if version: self.version = version - print(self._client().funder_count(filter=filter, raw=raw)) + print(self._client().funder_count(search=search, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) def funding(self, funding_id, raw=False, version=None, endpoint=None, @@ -370,7 +370,7 @@ def imprint(self, imprint_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def imprints(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, + search=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves imprints from a Thoth instance @@ -378,7 +378,7 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -394,7 +394,7 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, imprints = self._client().imprints(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, raw=raw) if not raw and not serialize: @@ -405,12 +405,12 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, print(imprints) @fire.decorators.SetParseFn(_raw_parse) - def imprint_count(self, publishers=None, filter=None, raw=False, + def imprint_count(self, publishers=None, search=None, raw=False, version=None, endpoint=None): """ Retrieves a count of imprints from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -423,7 +423,7 @@ def imprint_count(self, publishers=None, filter=None, raw=False, self.version = version print(self._client().imprint_count(publishers=publishers, - filter=filter, + search=search, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) @@ -452,7 +452,7 @@ def issue(self, issue_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def issues(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, + search=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves issues from a Thoth instance @@ -460,7 +460,7 @@ def issues(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -476,7 +476,7 @@ def issues(self, limit=100, order=None, offset=0, publishers=None, issues = self._client().issues(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, raw=raw) if not raw and not serialize: @@ -529,7 +529,7 @@ def language(self, language_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def languages(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, + search=None, raw=False, version=None, endpoint=None, serialize=False, language_code=None, language_relation=None): """ Retrieves languages from a Thoth instance @@ -537,7 +537,7 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -555,7 +555,7 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, langs = self._client().languages(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, language_code=language_code, language_relation=language_relation, raw=raw) @@ -654,7 +654,7 @@ def price_count(self, currency_code=None, raw=False, version=None, endpoint=None): """ Retrieves a count of prices from a Thoth instance - :param str currency_code: the currency to filter by (e.g. GBP) + :param str currency_code: the currency to search by (e.g. GBP) :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -695,7 +695,7 @@ def publication(self, publication_id, raw=False, @fire.decorators.SetParseFn(_raw_parse) def publications(self, limit=100, order=None, offset=0, publishers=None, - filter=None, publication_type=None, raw=False, + search=None, publication_type=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves publications from a Thoth instance @@ -703,7 +703,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param str publication_type: the work type (e.g. PAPERBACK) :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version @@ -718,7 +718,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, pubs = self._client().publications(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, publication_type=publication_type, raw=raw) if not raw and not serialize: @@ -729,12 +729,12 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, print(pubs) @fire.decorators.SetParseFn(_raw_parse) - def publication_count(self, publishers=None, filter=None, raw=False, + def publication_count(self, publishers=None, search=None, raw=False, publication_type=None, version=None, endpoint=None): """ Retrieves a count of publications from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str publication_type: the work type (e.g. MONOGRAPH) @@ -748,7 +748,7 @@ def publication_count(self, publishers=None, filter=None, raw=False, self.version = version print(self._client().publication_count( - publishers=publishers, filter=filter, + publishers=publishers, search=search, publication_type=publication_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) @@ -777,7 +777,7 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def publishers(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, + search=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves publishers from a Thoth instance @@ -785,7 +785,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -801,7 +801,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, found_publishers = self._client().publishers(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, raw=raw) if not raw and not serialize: @@ -812,12 +812,12 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, print(found_publishers) @fire.decorators.SetParseFn(_raw_parse) - def publisher_count(self, publishers=None, filter=None, raw=False, + def publisher_count(self, publishers=None, search=None, raw=False, version=None, endpoint=None): """ Retrieves a count of publishers from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -830,7 +830,7 @@ def publisher_count(self, publishers=None, filter=None, raw=False, self.version = version print(self._client().publisher_count(publishers=publishers, - filter=filter, + search=search, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) @@ -859,7 +859,7 @@ def series(self, series_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def serieses(self, limit=100, order=None, offset=0, publishers=None, - filter=None, series_type=None, raw=False, version=None, + search=None, series_type=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves serieses from a Thoth instance @@ -867,7 +867,7 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -884,7 +884,7 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, serieses = self._client().serieses(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, series_type=series_type, raw=raw) @@ -896,12 +896,12 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, print(serieses) @fire.decorators.SetParseFn(_raw_parse) - def series_count(self, publishers=None, filter=None, raw=False, + def series_count(self, publishers=None, search=None, raw=False, series_type=None, version=None, endpoint=None): """ Retrieves a count of serieses from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str series_type: the work type (e.g. BOOK_SERIES) @@ -914,7 +914,7 @@ def series_count(self, publishers=None, filter=None, raw=False, if version: self.version = version - print(self._client().series_count(publishers=publishers, filter=filter, + print(self._client().series_count(publishers=publishers, search=search, series_type=series_type, raw=raw)) @fire.decorators.SetParseFn(_raw_parse) @@ -943,7 +943,7 @@ def subject(self, subject_id, raw=False, version=None, endpoint=None, @fire.decorators.SetParseFn(_raw_parse) def subjects(self, limit=100, order=None, offset=0, publishers=None, - filter=None, raw=False, version=None, endpoint=None, + search=None, raw=False, version=None, endpoint=None, serialize=False, subject_type=None): """ Retrieves subjects from a Thoth instance @@ -951,7 +951,7 @@ def subjects(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint @@ -968,7 +968,7 @@ def subjects(self, limit=100, order=None, offset=0, publishers=None, subj = self._client().subjects(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, subject_type=subject_type, raw=raw) @@ -981,14 +981,14 @@ def subjects(self, limit=100, order=None, offset=0, publishers=None, @fire.decorators.SetParseFn(_raw_parse) def subject_count(self, subject_type=None, raw=False, version=None, - endpoint=None, filter=None): + endpoint=None, search=None): """ Retrieves a count of subjects from a Thoth instance :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint :param str subject_type: the type to retrieve (e.g. BIC) - :param str filter: a search + :param str search: a search """ if endpoint: @@ -998,7 +998,7 @@ def subject_count(self, subject_type=None, raw=False, version=None, self.version = version print(self._client().subject_count(subject_type=subject_type, - filter=filter, raw=raw)) + search=search, raw=raw)) def supported_versions(self): """ @@ -1047,7 +1047,7 @@ def work(self, doi=None, work_id=None, raw=False, version=None, @fire.decorators.SetParseFn(_raw_parse) def works(self, limit=100, order=None, offset=0, publishers=None, - filter=None, work_type=None, work_status=None, raw=False, + search=None, work_type=None, work_status=None, raw=False, version=None, endpoint=None, serialize=False): """ Retrieves works from a Thoth instance @@ -1055,7 +1055,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, :param int order: a GraphQL order query statement :param int offset: the offset from which to retrieve results :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param str work_type: the work type (e.g. MONOGRAPH) :param str work_status: the work status (e.g. ACTIVE) :param bool raw: whether to return a python object or the raw result @@ -1071,7 +1071,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, works = self._client().works(limit=limit, order=order, offset=offset, publishers=publishers, - filter=filter, + search=search, work_type=work_type, work_status=work_status, raw=raw) @@ -1084,13 +1084,13 @@ def works(self, limit=100, order=None, offset=0, publishers=None, print(works) @fire.decorators.SetParseFn(_raw_parse) - def work_count(self, publishers=None, filter=None, raw=False, + def work_count(self, publishers=None, search=None, raw=False, work_type=None, work_status=None, version=None, endpoint=None): """ Retrieves a count of works from a Thoth instance :param str publishers: a list of publishers to limit by - :param str filter: a filter string to search + :param str search: a search string to search :param bool raw: whether to return a python object or the raw result :param str version: a custom Thoth version :param str work_type: the work type (e.g. MONOGRAPH) @@ -1105,7 +1105,7 @@ def work_count(self, publishers=None, filter=None, raw=False, self.version = version print(self._client().work_count(publishers=publishers, - filter=filter, + search=search, work_type=work_type, work_status=work_status, raw=raw)) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 0cff2d6..050276d 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -859,7 +859,7 @@ def prices(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("prices", parameters, return_raw=raw) def publications(self, limit: int = 100, offset: int = 0, - filter: str = "", order: str = None, + search: str = "", order: str = None, publishers: str = None, publication_type: str = None, raw: bool = False): """ @@ -868,7 +868,7 @@ def publications(self, limit: int = 100, offset: int = 0, @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param filter: a filter string to search + @param search: a filter string to search @param publication_type: the work type (e.g. PAPERBACK) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response @@ -880,10 +880,10 @@ def publications(self, limit: int = 100, offset: int = 0, "limit": limit, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'publicationType', publication_type) @@ -918,14 +918,14 @@ def contributions(self, limit: int = 100, offset: int = 0, return self._api_request("contributions", parameters, return_raw=raw) def contributors(self, limit: int = 100, offset: int = 0, - filter: str = "", order: str = None, + search: str = "", order: str = None, raw: bool = False): """ Returns a contributions list @param limit: the maximum number of results to return (default: 100) @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) - @param filter: a filter string to search + @param search: a filter string to search @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ @@ -936,15 +936,15 @@ def contributors(self, limit: int = 100, offset: int = 0, "limit": limit, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) return self._api_request("contributors", parameters, return_raw=raw) - def works(self, limit: int = 100, offset: int = 0, filter: str = "", + def works(self, limit: int = 100, offset: int = 0, search: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): """ @@ -953,7 +953,7 @@ def works(self, limit: int = 100, offset: int = 0, filter: str = "", @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param filter: a filter string to search + @param search: a filter string to search @param work_type: the work type (e.g. MONOGRAPH) @param work_status: the work status (e.g. ACTIVE) @param raw: whether to return a python object or the raw server result @@ -966,10 +966,10 @@ def works(self, limit: int = 100, offset: int = 0, filter: str = "", "limit": limit, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'workType', work_type) @@ -1056,7 +1056,7 @@ def issue(self, issue_id: str, raw: bool = False): return self._api_request("issue", parameters, return_raw=raw) def publishers(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", publishers: str = None, + search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" parameters = { @@ -1064,17 +1064,17 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publishers", parameters, return_raw=raw) def serieses(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", publishers: str = None, + search: str = "", publishers: str = None, series_type: str = "", raw: bool = False): """Construct and trigger a query to obtain all serieses""" parameters = { @@ -1082,10 +1082,10 @@ def serieses(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'seriesType', series_type) @@ -1093,7 +1093,7 @@ def serieses(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("serieses", parameters, return_raw=raw) def imprints(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", publishers: str = None, + search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" parameters = { @@ -1101,17 +1101,17 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("imprints", parameters, return_raw=raw) def languages(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", publishers: str = None, raw: bool = False, + search: str = "", publishers: str = None, raw: bool = False, language_code: str = "", language_relation: str = ""): """Construct and trigger a query to obtain all publishers""" parameters = { @@ -1119,10 +1119,10 @@ def languages(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'languageCode', language_code) @@ -1132,23 +1132,23 @@ def languages(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("languages", parameters, return_raw=raw) def funders(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", raw: bool = False): + search: str = "", raw: bool = False): """Construct and trigger a query to obtain all funders""" parameters = { "limit": limit, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) return self._api_request("funders", parameters, return_raw=raw) def subjects(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", publishers: str = None, raw: bool = False, + search: str = "", publishers: str = None, raw: bool = False, subject_type: str = ""): """Construct and trigger a query to obtain all publishers""" parameters = { @@ -1156,10 +1156,10 @@ def subjects(self, limit: int = 100, offset: int = 0, order: str = None, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'subjectType', subject_type) @@ -1167,31 +1167,31 @@ def subjects(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("subjects", parameters, return_raw=raw) def issues(self, limit: int = 100, offset: int = 0, order: str = None, - filter: str = "", publishers: str = None, raw: bool = False): + search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" parameters = { "limit": limit, "offset": offset, } - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("issues", parameters, return_raw=raw) - def publisher_count(self, filter: str = "", publishers: str = None, + def publisher_count(self, search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publisherCount", parameters, return_raw=raw) @@ -1204,56 +1204,56 @@ def price_count(self, currency_code: str = None, raw: bool = False): return self._api_request("priceCount", parameters, return_raw=raw) - def imprint_count(self, filter: str = "", publishers: str = None, + def imprint_count(self, search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to count publishers""" parameters = {} - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("imprintCount", parameters, return_raw=raw) - def work_count(self, filter: str = "", publishers: str = None, + def work_count(self, search: str = "", publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): """Construct and trigger a query to count works""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'workType', work_type) self._dictionary_append(parameters, 'workStatus', work_status) return self._api_request("workCount", parameters, return_raw=raw) - def series_count(self, filter: str = "", publishers: str = None, + def series_count(self, search: str = "", publishers: str = None, series_type: str = None, raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'seriesType', series_type) return self._api_request("seriesCount", parameters, return_raw=raw) - def contribution_count(self, filter: str = "", publishers: str = None, + def contribution_count(self, search: str = "", publishers: str = None, contribution_type: str = None, raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'contributionType', contribution_type) @@ -1261,40 +1261,40 @@ def contribution_count(self, filter: str = "", publishers: str = None, return self._api_request("contributionCount", parameters, return_raw=raw) - def publication_count(self, filter: str = "", publishers: str = None, + def publication_count(self, search: str = "", publishers: str = None, publication_type: str = None, raw: bool = False): """Construct and trigger a query to count publications""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'publicationType', publication_type) return self._api_request("publicationCount", parameters, return_raw=raw) - def funder_count(self, filter: str = "", raw: bool = False): + def funder_count(self, search: str = "", raw: bool = False): """Construct and trigger a query to count publications""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) return self._api_request("funderCount", parameters, return_raw=raw) - def contributor_count(self, filter: str = "", raw: bool = False): + def contributor_count(self, search: str = "", raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) return self._api_request("contributorCount", parameters, return_raw=raw) @@ -1310,20 +1310,20 @@ def language_count(self, language_code: str = "", return self._api_request("languageCount", parameters, return_raw=raw) - def subject_count(self, subject_type: str = "", filter: str = "", + def subject_count(self, subject_type: str = "", search: str = "", raw: bool = False): """Construct and trigger a query to count contribution count""" parameters = {} - if filter and not filter.startswith('"'): - filter = '"{0}"'.format(filter) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) # there is a bug in this version of Thoth. Filter is REQUIRED. if not filter: filter = '""' self._dictionary_append(parameters, 'subjectType', subject_type) - self._dictionary_append(parameters, 'filter', filter) + self._dictionary_append(parameters, 'filter', search) return self._api_request("subjectCount", parameters, return_raw=raw) From 455b38de4da9cce688ed831a39744c2afc42b7c0 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 16:37:25 +0100 Subject: [PATCH 085/115] Reorder tests, fix docstrings, PEP8 --- thothlibrary/thoth-0_4_2/tests/tests.py | 998 ++++++++++++------------ 1 file changed, 500 insertions(+), 498 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 649a165..735a5c2 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -15,524 +15,495 @@ class Thoth042Tests(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # we set this fake endpoint to ensure that the tests are definitely - # running against the local objects, rather than the remote server + # running against the local objects, rather than any remote server self.endpoint = "https://api.test042.thoth.pub" self.version = "0.4.2" - def test_works(self): + def test_contribution(self): """ - Tests that good input to works produces saved good output + Tests that good input to contribution produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('works', m) - self.pickle_tester('works', thoth_client.works) + mock_response, thoth_client = self._setup_mocker('contribution', m) + self._pickle_tester('contribution', + lambda: + thoth_client.contribution( + contribution_id='29e4f46b-851a-4d7b-bb41-' + 'e6f305fc2b11')) return None - def test_works_bad_input(self): + def test_contribution_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('works_bad', m) - self.pickle_tester('works', thoth_client.works, negative=True) + mock_response, thoth_client = self._setup_mocker('contribution_bad', + m) + self._pickle_tester('contribution', + lambda: thoth_client.contribution( + contribution_id='29e4f46b-851a-4d7b-bb41-' + 'e6f305fc2b11'), + negative=True) return None - def test_works_raw(self): + def test_contribution_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('works', m) - self.raw_tester(mock_response, thoth_client.works) + mock_response, thoth_client = self._setup_mocker('contribution', m) + self._raw_tester(mock_response, + lambda: thoth_client.contribution( + contribution_id='29e4f46b-851a-4d7b-bb41-' + 'e6f305fc2b11', + raw=True), + lambda_mode=True) return None - def test_work_by_doi(self): + def test_contributions(self): """ - Tests that good input to work_by_doi produces saved good output + Tests that good input to contributions produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('workByDoi', m) - self.pickle_tester('workByDoi', - lambda: - thoth_client.work_by_doi(doi='https://doi.org/' - '10.21983/P3.0314.1' - '.00')) + mock_response, thoth_client = self._setup_mocker('contributions', m) + self._pickle_tester('contributions', thoth_client.contributions) return None - def test_work_by_doi_bad_input(self): + def test_contributions_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('workByDoi_bad', m) - self.pickle_tester('work', - lambda: thoth_client.work_by_doi(doi='https://' - 'doi.org/10' - '.21983/P3' - '.0314.1.' - '00'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker( + 'contributions_bad', + m) + self._pickle_tester('contributions', thoth_client.contributions, + negative=True) - def test_work_by_doi_raw(self): + def test_contributions_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('workByDoi', m) - self.raw_tester(mock_response, - lambda: thoth_client.work_by_doi(doi='https://doi.' - 'org/10.21983' - '/P3.0314.1.' - '00', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('contributions', m) + self._raw_tester(mock_response, thoth_client.contributions) return None - def test_work_by_id(self): + def test_contributor(self): """ - Tests that good input to work_by_id produces saved good output + Tests that good input to contributor produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('work', m) - self.pickle_tester('work', - lambda: - thoth_client.work_by_id(work_id='e0f748b2-984f-' - '45cc-8b9e-' - '13989c31dda4')) + mock_response, thoth_client = self._setup_mocker('contributor', m) + self._pickle_tester('contributor', + lambda: + thoth_client.contributor( + contributor_id='e8def8cf-0dfe-4da9-b7fa-' + 'f77e7aec7524')) return None - def test_work_by_id_bad_input(self): + def test_contributor_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('work_bad', m) - self.pickle_tester('work', - lambda: thoth_client.work_by_id( - work_id='e0f748b2' - '-' - '984f-' - '45cc-' - '8b9e-' - '13989c31' - 'dda4'), - negative=True) + mock_response, thoth_client = self._setup_mocker('contributor_bad', + m) + self._pickle_tester('contributor', + lambda: thoth_client.contributor( + contributor_id='e8def8cf-0dfe-4da9-b7fa-' + 'f77e7aec7524'), + negative=True) return None - def test_work_by_id_raw(self): + def test_contributor_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('work', m) - self.raw_tester(mock_response, - lambda: thoth_client.work_by_id(work_id='e0f748b2' - '-' - '984f-' - '45cc-' - '8b9e-' - '13989c31' - 'dda4', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('contributor', m) + self._raw_tester(mock_response, + lambda: thoth_client.contributor( + contributor_id='e8def8cf-0dfe-4da9-b7fa-' + 'f77e7aec7524', + raw=True), + lambda_mode=True) return None - def test_publication(self): + def test_contributors(self): """ - Tests that good input to publication produces saved good output + Tests that good input to contributors produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publication', m) - self.pickle_tester('publication', - lambda: - thoth_client.publication(publication_id= - '34712b75' - '-dcdd' - '-408b' - '-8d0c' - '-cf29a35' - 'be2e5')) + mock_response, thoth_client = self._setup_mocker('contributors', m) + self._pickle_tester('contributors', thoth_client.contributors) return None - def test_publication_bad_input(self): + def test_contributors_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publication_bad', - m) - self.pickle_tester('publication', - lambda: thoth_client.publication( - publication_id='34712b75-dcdd-408b-8d0c-' - 'cf29a35be2e5'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker('contributors_bad', + m) + self._pickle_tester('contributors', thoth_client.contributors, + negative=True) - def test_publication_raw(self): + def test_contributors_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publication', m) - self.raw_tester(mock_response, - lambda: thoth_client.publication(publication_id= - '34712b75' - '-dcdd' - '-408b' - '-8d0c' - '-cf29a' - '35be2e5', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('contributors', m) + self._raw_tester(mock_response, thoth_client.contributors) return None - def test_publications(self): + def test_funder(self): """ - Tests that good input to publications produces saved good output + Tests that good input to funder produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publications', m) - self.pickle_tester('publications', thoth_client.publications) + mock_response, thoth_client = self._setup_mocker('funder', m) + self._pickle_tester('funder', + lambda: + thoth_client.funder( + funder_id='194614ac-d189-4a74-8bf4-' + '74c0c9de4a81')) return None - def test_publications_bad_input(self): + def test_funder_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publications_bad', - m) - self.pickle_tester('publications', thoth_client.publications, - negative=True) + mock_response, thoth_client = self._setup_mocker('funder_bad', m) + self._pickle_tester('funder', + lambda: thoth_client.funder( + funder_id='194614ac-d189-4a74-8bf4-' + '74c0c9de4a81'), + negative=True) return None - def test_publications_raw(self): + def test_funder_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publications', m) - self.raw_tester(mock_response, thoth_client.publications) + mock_response, thoth_client = self._setup_mocker('funder', m) + self._raw_tester(mock_response, + lambda: thoth_client.funder( + funder_id='194614ac-d189-4a74-8bf4-' + '74c0c9de4a81', + raw=True), + lambda_mode=True) return None - def test_publisher(self): + def test_funders(self): """ - Tests that good input to publisher produces saved good output + Tests that good input to funders produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publisher', m) - self.pickle_tester('publisher', - lambda: - thoth_client.publisher( - publisher_id='85fd969a-a16c-480b-b641-cb9adf979c3b')) + mock_response, thoth_client = self._setup_mocker('funders', m) + self._pickle_tester('funders', thoth_client.funders) return None - def test_publisher_bad_input(self): + def test_funders_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publisher_bad', m) - self.pickle_tester('publisher', - lambda: thoth_client.publisher( - publisher_id='85fd969a-a16c-480b-b641-' - 'cb9adf979c3b'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker('funders_bad', m) + self._pickle_tester('funders', thoth_client.funders, + negative=True) - def test_publisher_raw(self): + def test_funders_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publisher', m) - self.raw_tester(mock_response, - lambda: thoth_client.publisher( - publisher_id='85fd969a-a16c-480b-b641-' - 'cb9adf979c3b', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('funders', m) + self._raw_tester(mock_response, thoth_client.funders) return None - def test_publishers(self): + def test_funding(self): """ - Tests that good input to publishers produces saved good output + Tests that good input to funding produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publishers', m) - self.pickle_tester('publishers', thoth_client.publishers) + mock_response, thoth_client = self._setup_mocker('funding', m) + self._pickle_tester('funding', + lambda: + thoth_client.funding( + funding_id='5323d3e7-3ae9-4778-8464-' + '9400fbbb959e]')) return None - def test_publishers_bad_input(self): + def test_funding_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publishers_bad', m) - self.pickle_tester('publishers', thoth_client.publishers, - negative=True) + mock_response, thoth_client = self._setup_mocker('funding_bad', m) - def test_publishers_raw(self): + self._pickle_tester('funding', + lambda: thoth_client.funding( + funding_id='5323d3e7-3ae9-4778-8464-' + '9400fbbb959e]'), + negative=True) + return None + + def test_funding_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('publishers', m) - self.raw_tester(mock_response, thoth_client.publishers) + mock_response, thoth_client = self._setup_mocker('funding', m) + self._raw_tester(mock_response, + lambda: thoth_client.funding( + funding_id='5323d3e7-3ae9-4778-8464-' + '9400fbbb959e]', + raw=True), + lambda_mode=True) return None - def test_language(self): + def test_fundings(self): """ - Tests that good input to language produces saved good output + Tests that good input to fundings produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('language', m) - self.pickle_tester('language', - lambda: - thoth_client.language( - language_id='c19e68dd-c5a3-48f1-bd56-' - '089ee732604c')) + mock_response, thoth_client = self._setup_mocker('fundings', m) + self._pickle_tester('fundings', thoth_client.fundings) return None - def test_language_bad_input(self): + def test_fundings_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('language_bad', m) - self.pickle_tester('language', - lambda: thoth_client.language( - language_id='c19e68dd-c5a3-48f1-bd56-' - '089ee732604c'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker('fundings_bad', m) + self._pickle_tester('fundings', thoth_client.fundings, + negative=True) - def test_language_raw(self): + def test_fundings_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('language', m) - self.raw_tester(mock_response, - lambda: thoth_client.language( - language_id='c19e68dd-c5a3-48f1-bd56-' - '089ee732604c', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('fundings', m) + self._raw_tester(mock_response, thoth_client.fundings) return None - def test_funder(self): + def test_imprint(self): """ - Tests that good input to funder produces saved good output + Tests that good input to imprint produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funder', m) - self.pickle_tester('funder', - lambda: - thoth_client.funder( - funder_id='194614ac-d189-4a74-8bf4-' - '74c0c9de4a81')) + mock_response, thoth_client = self._setup_mocker('imprint', m) + self._pickle_tester('imprint', + lambda: + thoth_client.imprint( + imprint_id='78b0a283-9be3-4fed-a811-' + 'a7d4b9df7b25')) return None - def test_funder_bad_input(self): + def test_imprint_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funder_bad', m) - self.pickle_tester('funder', - lambda: thoth_client.funder( - funder_id='194614ac-d189-4a74-8bf4-' - '74c0c9de4a81'), - negative=True) + mock_response, thoth_client = self._setup_mocker('imprint_bad', m) + self._pickle_tester('imprint', + lambda: thoth_client.imprint( + imprint_id='78b0a283-9be3-4fed-a811-' + 'a7d4b9df7b25'), + negative=True) return None - def test_funder_raw(self): + def test_imprint_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funder', m) - self.raw_tester(mock_response, - lambda: thoth_client.funder( - funder_id='194614ac-d189-4a74-8bf4-' - '74c0c9de4a81', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('imprint', m) + self._raw_tester(mock_response, + lambda: thoth_client.imprint( + imprint_id='78b0a283-9be3-4fed-a811-' + 'a7d4b9df7b25', + raw=True), + lambda_mode=True) return None - def test_subject(self): + def test_imprints(self): """ - Tests that good input to subject produces saved good output + Tests that good input to imprints produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('subject', m) - self.pickle_tester('subject', - lambda: - thoth_client.subject( - subject_id='1291208f-fc43-47a4-a8e6-' - 'e132477ad57b')) + mock_response, thoth_client = self._setup_mocker('imprints', m) + self._pickle_tester('imprints', thoth_client.imprints) return None - def test_subject_bad_input(self): + def test_imprints_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('subject_bad', m) - self.pickle_tester('subject', - lambda: thoth_client.subject( - subject_id='1291208f-fc43-47a4-a8e6-' - 'e132477ad57b'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker('imprints_bad', m) + self._pickle_tester('imprints', thoth_client.imprints, + negative=True) - def test_subject_raw(self): + def test_imprints_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('subject', m) - self.raw_tester(mock_response, - lambda: thoth_client.subject( - subject_id='1291208f-fc43-47a4-a8e6-' - 'e132477ad57b', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('imprints', m) + self._raw_tester(mock_response, thoth_client.imprints) return None - def test_imprint(self): + def test_issue(self): """ - Tests that good input to imprint produces saved good output + Tests that good input to issue produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('imprint', m) - self.pickle_tester('imprint', - lambda: - thoth_client.imprint( - imprint_id='78b0a283-9be3-4fed-a811-' - 'a7d4b9df7b25')) + mock_response, thoth_client = self._setup_mocker('issue', m) + self._pickle_tester('issue', + lambda: + thoth_client.issue( + issue_id='6bd31b4c-35a9-4177-8074-' + 'dab4896a4a3d')) return None - def test_imprint_bad_input(self): + def test_issue_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('imprint_bad', m) - self.pickle_tester('imprint', - lambda: thoth_client.imprint( - imprint_id='78b0a283-9be3-4fed-a811-' - 'a7d4b9df7b25'), - negative=True) + mock_response, thoth_client = self._setup_mocker('issue_bad', m) + self._pickle_tester('issue', + lambda: thoth_client.issue( + issue_id='6bd31b4c-35a9-4177-8074-' + 'dab4896a4a3d'), + negative=True) return None - def test_imprint_raw(self): + def test_issue_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('imprint', m) - self.raw_tester(mock_response, - lambda: thoth_client.imprint( - imprint_id='78b0a283-9be3-4fed-a811-' - 'a7d4b9df7b25', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('issue', m) + self._raw_tester(mock_response, + lambda: thoth_client.issue( + issue_id='6bd31b4c-35a9-4177-8074-' + 'dab4896a4a3d', + raw=True), + lambda_mode=True) return None - def test_imprints(self): + def test_issues(self): """ - Tests that good input to publishers produces saved good output + Tests that good input to issues produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('imprints', m) - self.pickle_tester('imprints', thoth_client.imprints) + mock_response, thoth_client = self._setup_mocker('issues', m) + self._pickle_tester('issues', thoth_client.issues) return None - def test_imprints_bad_input(self): + def test_issues_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('imprints_bad', m) - self.pickle_tester('imprints', thoth_client.imprints, - negative=True) + mock_response, thoth_client = self._setup_mocker('issues_bad', m) + self._pickle_tester('issues', thoth_client.issues, + negative=True) - def test_imprints_raw(self): + def test_issues_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('imprints', m) - self.raw_tester(mock_response, thoth_client.imprints) + mock_response, thoth_client = self._setup_mocker('issues', m) + self._raw_tester(mock_response, thoth_client.issues) return None - def test_prices(self): + def test_language(self): """ - Tests that good input to prices produces saved good output + Tests that good input to language produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('prices', m) - self.pickle_tester('prices', thoth_client.prices) + mock_response, thoth_client = self._setup_mocker('language', m) + self._pickle_tester('language', + lambda: + thoth_client.language( + language_id='c19e68dd-c5a3-48f1-bd56-' + '089ee732604c')) return None - def test_prices_bad_input(self): + def test_language_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('prices_bad', m) - self.pickle_tester('prices', thoth_client.prices, - negative=True) + mock_response, thoth_client = self._setup_mocker('language_bad', m) + self._pickle_tester('language', + lambda: thoth_client.language( + language_id='c19e68dd-c5a3-48f1-bd56-' + '089ee732604c'), + negative=True) + return None - def test_prices_raw(self): + def test_language_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('prices', m) - self.raw_tester(mock_response, thoth_client.prices) + mock_response, thoth_client = self._setup_mocker('language', m) + self._raw_tester(mock_response, + lambda: thoth_client.language( + language_id='c19e68dd-c5a3-48f1-bd56-' + '089ee732604c', + raw=True), + lambda_mode=True) return None def test_languages(self): @@ -541,8 +512,8 @@ def test_languages(self): @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('languages', m) - self.pickle_tester('languages', thoth_client.languages) + mock_response, thoth_client = self._setup_mocker('languages', m) + self._pickle_tester('languages', thoth_client.languages) return None def test_languages_bad_input(self): @@ -551,10 +522,10 @@ def test_languages_bad_input(self): @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('languages_bad', - m) - self.pickle_tester('languages', thoth_client.languages, - negative=True) + mock_response, thoth_client = self._setup_mocker('languages_bad', + m) + self._pickle_tester('languages', thoth_client.languages, + negative=True) def test_languages_raw(self): """ @@ -562,484 +533,515 @@ def test_languages_raw(self): @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('languages', m) - self.raw_tester(mock_response, thoth_client.languages) + mock_response, thoth_client = self._setup_mocker('languages', m) + self._raw_tester(mock_response, thoth_client.languages) return None - def test_funders(self): + def test_price(self): """ - Tests that good input to funders produces saved good output + Tests that good input to price produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funders', m) - self.pickle_tester('funders', thoth_client.funders) + mock_response, thoth_client = self._setup_mocker('price', m) + self._pickle_tester('price', + lambda: + thoth_client.price( + price_id='818567dd-7d3a-4963-8704-' + '3381b5432877')) return None - def test_funders_bad_input(self): + def test_price_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funders_bad', m) - self.pickle_tester('funders', thoth_client.funders, - negative=True) + mock_response, thoth_client = self._setup_mocker('price_bad', + m) + self._pickle_tester('price', + lambda: thoth_client.price( + price_id='818567dd-7d3a-4963-8704-' + '3381b5432877'), + negative=True) + return None - def test_funders_raw(self): + def test_price_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funders', m) - self.raw_tester(mock_response, thoth_client.funders) + mock_response, thoth_client = self._setup_mocker('price', m) + self._raw_tester(mock_response, + lambda: thoth_client.price( + price_id='818567dd-7d3a-4963-8704-' + '3381b5432877', + raw=True), + lambda_mode=True) return None - def test_fundings(self): + def test_prices(self): """ - Tests that good input to fundings produces saved good output + Tests that good input to prices produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('fundings', m) - self.pickle_tester('fundings', thoth_client.fundings) + mock_response, thoth_client = self._setup_mocker('prices', m) + self._pickle_tester('prices', thoth_client.prices) return None - def test_fundings_bad_input(self): + def test_prices_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('fundings_bad', m) - self.pickle_tester('fundings', thoth_client.fundings, - negative=True) + mock_response, thoth_client = self._setup_mocker('prices_bad', m) + self._pickle_tester('prices', thoth_client.prices, + negative=True) - def test_fundings_raw(self): + def test_prices_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('fundings', m) - self.raw_tester(mock_response, thoth_client.fundings) + mock_response, thoth_client = self._setup_mocker('prices', m) + self._raw_tester(mock_response, thoth_client.prices) return None - def test_contributions(self): + def test_publication(self): """ - Tests that good input to contributions produces saved good output + Tests that good input to publication produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributions', m) - self.pickle_tester('contributions', thoth_client.contributions) + mock_response, thoth_client = self._setup_mocker('publication', m) + self._pickle_tester('publication', + lambda: + thoth_client.publication( + publication_id='34712b75' + '-dcdd' + '-408b' + '-8d0c' + '-cf29a35' + 'be2e5')) return None - def test_contributions_bad_input(self): + def test_publication_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributions_bad', - m) - self.pickle_tester('contributions', thoth_client.contributions, - negative=True) + mock_response, thoth_client = self._setup_mocker('publication_bad', + m) + self._pickle_tester('publication', + lambda: thoth_client.publication( + publication_id='34712b75-dcdd-408b-8d0c-' + 'cf29a35be2e5'), + negative=True) + return None - def test_contributions_raw(self): + def test_publication_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributions', m) - self.raw_tester(mock_response, thoth_client.contributions) + mock_response, thoth_client = self._setup_mocker('publication', m) + self._raw_tester(mock_response, + lambda: thoth_client.publication( + publication_id='34712b75-dcdd-408b-8d0c' + '-cf29a' + '35be2e5', + raw=True), + lambda_mode=True) return None - def test_contributor(self): + def test_publications(self): """ - Tests that good input to contributor produces saved good output + Tests that good input to publications produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributor', m) - self.pickle_tester('contributor', - lambda: - thoth_client.contributor( - contributor_id='e8def8cf-0dfe-4da9-b7fa-' - 'f77e7aec7524')) + mock_response, thoth_client = self._setup_mocker('publications', m) + self._pickle_tester('publications', thoth_client.publications) return None - def test_contributor_bad_input(self): + def test_publications_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributor_bad', - m) - self.pickle_tester('contributor', - lambda: thoth_client.contributor( - contributor_id='e8def8cf-0dfe-4da9-b7fa-' - 'f77e7aec7524'), - negative=True) + mock_response, thoth_client = self._setup_mocker('publications_bad', + m) + self._pickle_tester('publications', thoth_client.publications, + negative=True) return None - def test_contributor_raw(self): + def test_publications_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributor', m) - self.raw_tester(mock_response, - lambda: thoth_client.contributor( - contributor_id='e8def8cf-0dfe-4da9-b7fa-' - 'f77e7aec7524', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('publications', m) + self._raw_tester(mock_response, thoth_client.publications) return None - def test_price(self): + def test_publisher(self): """ - Tests that good input to price produces saved good output + Tests that good input to publisher produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('price', m) - self.pickle_tester('price', - lambda: - thoth_client.price( - price_id='818567dd-7d3a-4963-8704-' - '3381b5432877')) + mock_response, thoth_client = self._setup_mocker('publisher', m) + self._pickle_tester('publisher', + lambda: + thoth_client.publisher( + publisher_id='85fd969a-a16c-480b-b641-' + 'cb9adf979c3b')) return None - def test_price_bad_input(self): + def test_publisher_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('price_bad', - m) - self.pickle_tester('price', - lambda: thoth_client.price( - price_id='818567dd-7d3a-4963-8704-' - '3381b5432877'), - negative=True) + mock_response, thoth_client = self._setup_mocker('publisher_bad', m) + self._pickle_tester('publisher', + lambda: thoth_client.publisher( + publisher_id='85fd969a-a16c-480b-b641-' + 'cb9adf979c3b'), + negative=True) return None - def test_price_raw(self): + def test_publisher_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('price', m) - self.raw_tester(mock_response, - lambda: thoth_client.price( - price_id='818567dd-7d3a-4963-8704-3381b5432877', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('publisher', m) + self._raw_tester(mock_response, + lambda: thoth_client.publisher( + publisher_id='85fd969a-a16c-480b-b641-' + 'cb9adf979c3b', + raw=True), + lambda_mode=True) return None - def test_series(self): + def test_publishers(self): """ - Tests that good input to series produces saved good output + Tests that good input to publishers produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('series', m) - self.pickle_tester('series', - lambda: - thoth_client.series( - series_id='d4b47a76-abff-4047-a3c7-' - 'd44d85ccf009')) + mock_response, thoth_client = self._setup_mocker('publishers', m) + self._pickle_tester('publishers', thoth_client.publishers) return None - def test_series_bad_input(self): + def test_publishers_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('series_bad', - m) - self.pickle_tester('series', - lambda: thoth_client.series( - series_id='d4b47a76-abff-4047-a3c7-' - 'd44d85ccf009'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker('publishers_bad', + m) + self._pickle_tester('publishers', thoth_client.publishers, + negative=True) - def test_series_raw(self): + def test_publishers_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('series', m) - self.raw_tester(mock_response, - lambda: thoth_client.series( - series_id='d4b47a76-abff-4047-a3c7-' - 'd44d85ccf009', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('publishers', m) + self._raw_tester(mock_response, thoth_client.publishers) return None - def test_issue(self): + def test_series(self): """ - Tests that good input to issue produces saved good output + Tests that good input to series produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('issue', m) - self.pickle_tester('issue', - lambda: - thoth_client.issue( - issue_id='6bd31b4c-35a9-4177-8074-' - 'dab4896a4a3d')) + mock_response, thoth_client = self._setup_mocker('series', m) + self._pickle_tester('series', + lambda: + thoth_client.series( + series_id='d4b47a76-abff-4047-a3c7-' + 'd44d85ccf009')) return None - def test_issue_bad_input(self): + def test_series_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('issue_bad', m) - self.pickle_tester('issue', - lambda: thoth_client.issue( - issue_id='6bd31b4c-35a9-4177-8074-' - 'dab4896a4a3d'), - negative=True) + mock_response, thoth_client = self._setup_mocker('series_bad', + m) + self._pickle_tester('series', + lambda: thoth_client.series( + series_id='d4b47a76-abff-4047-a3c7-' + 'd44d85ccf009'), + negative=True) return None - def issue_raw(self): + def test_series_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributioissue', m) - self.raw_tester(mock_response, - lambda: thoth_client.issue( - issue_id='6bd31b4c-35a9-4177-8074-dab4896a4a3d', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('series', m) + self._raw_tester(mock_response, + lambda: thoth_client.series( + series_id='d4b47a76-abff-4047-a3c7-' + 'd44d85ccf009', + raw=True), + lambda_mode=True) return None - def test_contribution(self): + def test_serieses(self): """ - Tests that good input to contribution produces saved good output + Tests that good input to serieses produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contribution', m) - self.pickle_tester('contribution', - lambda: - thoth_client.contribution( - contribution_id='29e4f46b-851a-4d7b-bb41-' - 'e6f305fc2b11')) + mock_response, thoth_client = self._setup_mocker('serieses', m) + self._pickle_tester('serieses', thoth_client.serieses) return None - def test_contribution_bad_input(self): + def test_serieses_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contribution_bad', - m) - self.pickle_tester('contribution', - lambda: thoth_client.contribution( - contribution_id='29e4f46b-851a-4d7b-bb41-' - 'e6f305fc2b11'), - negative=True) - return None + mock_response, thoth_client = self._setup_mocker('serieses_bad', m) + self._pickle_tester('serieses', thoth_client.serieses, + negative=True) - def test_contribution_raw(self): + def test_serieses_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contribution', m) - self.raw_tester(mock_response, - lambda: thoth_client.contribution( - contribution_id='29e4f46b-851a-4d7b-bb41-' - 'e6f305fc2b11', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('serieses', m) + self._raw_tester(mock_response, thoth_client.serieses) return None - def test_funding(self): + def test_subject(self): """ - Tests that good input to funding produces saved good output + Tests that good input to subject produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funding', m) - self.pickle_tester('funding', - lambda: - thoth_client.funding( - funding_id='5323d3e7-3ae9-4778-8464-' - '9400fbbb959e]')) + mock_response, thoth_client = self._setup_mocker('subject', m) + self._pickle_tester('subject', + lambda: + thoth_client.subject( + subject_id='1291208f-fc43-47a4-a8e6-' + 'e132477ad57b')) return None - def test_funding_bad_input(self): + def test_subject_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funding_bad', m) - - self.pickle_tester('funding', - lambda: thoth_client.funding( - funding_id='5323d3e7-3ae9-4778-8464-' - '9400fbbb959e]'), - negative=True) + mock_response, thoth_client = self._setup_mocker('subject_bad', m) + self._pickle_tester('subject', + lambda: thoth_client.subject( + subject_id='1291208f-fc43-47a4-a8e6-' + 'e132477ad57b'), + negative=True) return None - def test_funding_raw(self): + def test_subject_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('funding', m) - self.raw_tester(mock_response, - lambda: thoth_client.funding( - funding_id='5323d3e7-3ae9-4778-8464-' - '9400fbbb959e]', - raw=True), - lambda_mode=True) + mock_response, thoth_client = self._setup_mocker('subject', m) + self._raw_tester(mock_response, + lambda: thoth_client.subject( + subject_id='1291208f-fc43-47a4-a8e6-' + 'e132477ad57b', + raw=True), + lambda_mode=True) return None - def test_contributors(self): + def test_subjects(self): """ - Tests that good input to contributors produces saved good output + Tests that good input to subjects produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributors', m) - self.pickle_tester('contributors', thoth_client.contributors) + mock_response, thoth_client = self._setup_mocker('subjects', m) + self._pickle_tester('subjects', thoth_client.subjects) return None - def test_contributors_bad_input(self): + def test_subjects_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributors_bad', - m) - self.pickle_tester('contributors', thoth_client.contributors, - negative=True) + mock_response, thoth_client = self._setup_mocker('subjects_bad', m) + self._pickle_tester('subjects', thoth_client.subjects, + negative=True) - def test_contributors_raw(self): + def test_subjects_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('contributors', m) - self.raw_tester(mock_response, thoth_client.contributors) + mock_response, thoth_client = self._setup_mocker('subjects', m) + self._raw_tester(mock_response, thoth_client.subjects) return None - def test_serieses(self): + def test_work_by_doi(self): """ - Tests that good input to serieses produces saved good output + Tests that good input to work_by_doi produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('serieses', m) - self.pickle_tester('serieses', thoth_client.serieses) + mock_response, thoth_client = self._setup_mocker('workByDoi', m) + self._pickle_tester('workByDoi', + lambda: + thoth_client.work_by_doi(doi='https://doi.org/' + '10.21983/P3.0314.' + '1.00')) return None - def test_serieses_bad_input(self): + def test_work_by_doi_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('serieses_bad', m) - self.pickle_tester('serieses', thoth_client.serieses, - negative=True) + mock_response, thoth_client = self._setup_mocker('workByDoi_bad', m) + self._pickle_tester('work', + lambda: thoth_client.work_by_doi(doi='https://' + 'doi.org/1' + '0.21983/P' + '3.0314.1.' + '00'), + negative=True) + return None - def test_subjects_raw(self): + def test_work_by_doi_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('serieses', m) - self.raw_tester(mock_response, thoth_client.serieses) + mock_response, thoth_client = self._setup_mocker('workByDoi', m) + self._raw_tester(mock_response, + lambda: thoth_client.work_by_doi(doi='https://doi.' + 'org/10.21983' + '/P3.0314.1.' + '00', + raw=True), + lambda_mode=True) return None - def test_subjects(self): + def test_work_by_id(self): """ - Tests that good input to serieses produces saved good output + Tests that good input to work_by_id produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('subjects', m) - self.pickle_tester('subjects', thoth_client.subjects) + mock_response, thoth_client = self._setup_mocker('work', m) + self._pickle_tester('work', + lambda: + thoth_client.work_by_id(work_id='e0f748b2-984f-' + '45cc-8b9e-' + '13989c31dda4')) return None - def test_subjects_bad_input(self): + def test_work_by_id_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('subjects_bad', m) - self.pickle_tester('subjects', thoth_client.subjects, - negative=True) + mock_response, thoth_client = self._setup_mocker('work_bad', m) + self._pickle_tester('work', + lambda: thoth_client.work_by_id( + work_id='e0f748b2' + '-' + '984f-' + '45cc-' + '8b9e-' + '13989c31' + 'dda4'), + negative=True) + return None - def test_subjects_raw(self): + def test_work_by_id_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('subjects', m) - self.raw_tester(mock_response, thoth_client.subjects) + mock_response, thoth_client = self._setup_mocker('work', m) + self._raw_tester(mock_response, + lambda: thoth_client.work_by_id(work_id='e0f748b2' + '-' + '984f-' + '45cc-' + '8b9e-' + '13989c31' + 'dda4', + raw=True), + lambda_mode=True) return None - def test_issues(self): + def test_works(self): """ - Tests that good input to issues produces saved good output + Tests that good input to works produces saved good output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('issues', m) - self.pickle_tester('issues', thoth_client.issues) + mock_response, thoth_client = self._setup_mocker('works', m) + self._pickle_tester('works', thoth_client.works) return None - def test_issues_bad_input(self): + def test_works_bad_input(self): """ Tests that bad input produces bad output @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('issues_bad', m) - self.pickle_tester('issues', thoth_client.issues, - negative=True) + mock_response, thoth_client = self._setup_mocker('works_bad', m) + self._pickle_tester('works', thoth_client.works, negative=True) + return None - def issues_raw(self): + def test_works_raw(self): """ A test to ensure valid passthrough of raw json @return: None if successful """ with requests_mock.Mocker() as m: - mock_response, thoth_client = self.setup_mocker('issues', m) - self.raw_tester(mock_response, thoth_client.issues) + mock_response, thoth_client = self._setup_mocker('works', m) + self._raw_tester(mock_response, thoth_client.works) return None - def raw_tester(self, mock_response, method_to_call, lambda_mode=False): + def _raw_tester(self, mock_response, method_to_call, lambda_mode=False): """ An echo test that ensures the client returns accurate raw responses @param lambda_mode: whether the passed function is a complete lambda @@ -1055,7 +1057,7 @@ def raw_tester(self, mock_response, method_to_call, lambda_mode=False): self.assertEqual(mock_response, response, 'Raw response was not echoed back correctly.') - def pickle_tester(self, pickle_name, endpoint, negative=False): + def _pickle_tester(self, pickle_name, endpoint, negative=False): """ A test of a function's output against a stored pickle (JSON) @param pickle_name: the .pickle file in the fixtures directory @@ -1073,7 +1075,7 @@ def pickle_tester(self, pickle_name, endpoint, negative=False): else: self.assertNotEqual(loaded_response, response) - def setup_mocker(self, endpoint, m): + def _setup_mocker(self, endpoint, m): """ Sets up a mocker object by reading a json fixture @param endpoint: the file to read in the fixtures dir (no extension) From 95c3023f2ffc4600ee64e108f8d38843ef969517 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 17:06:29 +0100 Subject: [PATCH 086/115] Add workId to work endpoint --- thothlibrary/thoth-0_4_2/endpoints.py | 1 + 1 file changed, 1 insertion(+) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 050276d..7d426f5 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -241,6 +241,7 @@ class ThothClient0_4_2(ThothClient): "longAbstract", "generalNote", "toc", + "workId", "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", From 4c1c585cdd51619db19e5d6cb8cb7d4452e19f89 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 17:22:35 +0100 Subject: [PATCH 087/115] Add workId to workByDoi endpoint --- thothlibrary/thoth-0_4_2/endpoints.py | 1 + 1 file changed, 1 insertion(+) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 7d426f5..6b9813e 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -256,6 +256,7 @@ class ThothClient0_4_2(ThothClient): "doi" ], "fields": [ + "workId", "workType", "workStatus", "fullTitle", From 6021a641153fe26f18fa27ea67a148d62f1807fe Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 18:18:58 +0100 Subject: [PATCH 088/115] Rewrite of structures.py for readability and PEP8 --- thothlibrary/thoth-0_4_2/structures.py | 298 +++++++++++++++++++------ 1 file changed, 233 insertions(+), 65 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/structures.py b/thothlibrary/thoth-0_4_2/structures.py index 4084679..2cfc913 100644 --- a/thothlibrary/thoth-0_4_2/structures.py +++ b/thothlibrary/thoth-0_4_2/structures.py @@ -9,7 +9,7 @@ from datetime import datetime -def _muncher_repr(obj): +def _munch_repr(obj): """ This is a hacky munch context switcher. It passes the original __repr__ pointer back @@ -20,13 +20,13 @@ def _muncher_repr(obj): return obj.__repr__() -def _parse_authors(obj): +def _author_parser(obj): """ This parses a list of contributors into authors and editors @param obj: the Work to parse @return: a string representation of authors """ - if not 'contributions' in obj: + if 'contributions' not in obj: return None author_dict = {} @@ -42,12 +42,24 @@ def _parse_authors(obj): od_authors = collections.OrderedDict(sorted(author_dict.items())) for k, v in od_authors.items(): - authors += contributor.fullName + ', ' + authors += v + ', ' return authors -def __price_parser(prices): +def _date_parser(date): + """ + Formats a date nicely + @param date: the date string or None + @return: a formatted date string + """ + if date: + return datetime.strptime(date, "%Y-%m-%d").year + else: + return "n.d." + + +def _price_parser(prices): if len(prices) > 0 and 'currencyCode' not in prices: return '({0}{1})'.format(prices[0].unitPrice, prices[0].currencyCode) elif 'currencyCode' in prices: @@ -56,71 +68,227 @@ def __price_parser(prices): return '' -# these are lambda function formatting statements for the endpoints +# these are formatting statements for the endpoints # they are injected to replace the default dictionary (Munch) __repr__ and # __str__ methods. They let us create nice-looking string representations # of objects, such as books -default_fields = {'works': lambda - self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."}) [{self.workId}]' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'prices': lambda - self: f'{self.publication.work.fullTitle} ({self.publication.work.place}: {self.publication.work.imprint.publisher.publisherName}, {datetime.strptime(self.publication.work.publicationDate, "%Y-%m-%d").year if self.publication.work.publicationDate else "n.d."}) ' - f'costs {__price_parser(self)} [{self.priceId}]' if '__typename' in self and self.__typename == 'Price' else f'{_muncher_repr(self)}', - 'price': lambda - self: f'{self.publication.work.fullTitle} ({self.publication.work.place}: {self.publication.work.imprint.publisher.publisherName}, {datetime.strptime(self.publication.work.publicationDate, "%Y-%m-%d").year if self.publication.work.publicationDate else "n.d."}) ' - f'costs {__price_parser(self)} [{self.priceId}]' if '__typename' in self and self.__typename == 'Price' else f'{_muncher_repr(self)}', - 'publications': lambda - self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' - f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', - 'workByDoi': lambda - self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'work': lambda - self: f'{_parse_authors(self)}{self.fullTitle} ({self.place}: {self.imprint.publisher.publisherName}, {datetime.strptime(self.publicationDate, "%Y-%m-%d").year if self.publicationDate else "n.d."})' if '__typename' in self and self.__typename == 'Work' else f'{_muncher_repr(self)}', - 'publishers': lambda - self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}', - 'imprints': lambda - self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', - 'imprint': lambda - self: f'{self.imprintName} ({self.publisher.publisherName}/{self.publisherId}) [{self.imprintId}]' if '__typename' in self and self.__typename == 'Imprint' else f'{_muncher_repr(self)}', - 'contributions': lambda - self: f'{self.fullName} ({self.contributionType} of {self.work.fullTitle}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', - 'contribution': lambda - self: f'{self.fullName} ({self.contributionType} of {self.work.fullTitle}) [{self.contributionId}]' if '__typename' in self and self.__typename == 'Contribution' else f'{_muncher_repr(self)}', - 'contributors': lambda - self: f'{self.fullName} ({self.contributions[0].contributionType} of {self.contributions[0].work.fullTitle}) [{self.contributorId}]' if '__typename' in self and self.__typename == 'Contributor' else f'{_muncher_repr(self)}', - 'contributor': lambda - self: f'{self.fullName} ({self.contributions[0].contributionType} of {self.contributions[0].work.fullTitle}) [{self.contributorId}]' if '__typename' in self and self.__typename == 'Contributor' else f'{_muncher_repr(self)}', - 'publication': lambda - self: f'{_parse_authors(self.work)}{self.work.fullTitle} ({self.work.place}: {self.work.imprint.publisher.publisherName}, {datetime.strptime(self.work.publicationDate, "%Y-%m-%d").year if self.work.publicationDate else "n.d."}) ' - f'[{self.publicationType}] {__price_parser(self.prices)} [{self.publicationId}]' if '__typename' in self and self.__typename == 'Publication' else f'{_muncher_repr(self)}', - 'serieses': lambda - self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', - 'series': lambda - self: f'{self.seriesName} ({self.imprint.publisher.publisherName}) [{self.seriesId}]' if '__typename' in self and self.__typename == 'Series' else f'{_muncher_repr(self)}', - 'issues': lambda - self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', - 'issue': lambda - self: f'{self.work.fullTitle} in {self.series.seriesName} ({self.series.imprint.publisher.publisherName}) [{self.issueId}]' if '__typename' in self and self.__typename == 'Issue' else f'{_muncher_repr(self)}', - 'subjects': lambda - self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', - 'subject': lambda - self: f'{self.work.fullTitle} is in the {self.subjectCode} subject area ({self.subjectType}) [{self.subjectId}]' if '__typename' in self and self.__typename == 'Subject' else f'{_muncher_repr(self)}', - 'fundings': lambda - self: f'{self.funder.funderName} funded {self.work.fullTitle} [{self.fundingId}]' if '__typename' in self and self.__typename == 'Funding' else f'{_muncher_repr(self)}', - 'funding': lambda - self: f'{self.funder.funderName} funded {self.work.fullTitle} [{self.fundingId}]' if '__typename' in self and self.__typename == 'Funding' else f'{_muncher_repr(self)}', - 'funders': lambda - self: f'{self.funderName} funded {len(self.fundings)} books [{self.funderId}]' if '__typename' in self and self.__typename == 'Funder' else f'{_muncher_repr(self)}', - 'funder': lambda - self: f'{self.funderName} funded {len(self.fundings)} books [{self.funderId}]' if '__typename' in self and self.__typename == 'Funder' else f'{_muncher_repr(self)}', - 'languages': lambda - self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', - 'language': lambda - self: f'{self.work.fullTitle} is in {self.languageCode} ({self.languageRelation}) [{self.languageId}]' if '__typename' in self and self.__typename == 'Language' else f'{_muncher_repr(self)}', - 'publisher': lambda - self: f'{self.publisherName} ({self.publisherId})' if '__typename' in self and self.__typename == 'Publisher' else f'{_muncher_repr(self)}'} + +def _generic_formatter(format_object, type_name, output): + """ + A generic formatter that returns either the input or the stored munch repr + @param format_object: the object on which to operate + @param type_name: the expected type name + @param output: the f-string to substitute + @return: a formatted string + """ + if "__typename" in format_object and format_object.__typename == type_name: + return output + else: + return f"{_munch_repr(format_object)}" + + +def _contribution_formatter(contribution): + """ + A formatting string for contributions + @param contribution: The contribution object + @return: A formatted contribution object + """ + format_str = f"{contribution.fullName} " \ + f"({contribution.contributionType} of " \ + f"{contribution.work.fullTitle}) " \ + f"[{contribution.contributionId}]" + return _generic_formatter(contribution, 'Contribution', format_str) + + +def _contributor_formatter(contributor): + """ + A formatting string for contributors + @param contributor: The contributor object + @return: A formatted contributor object + """ + format_str = f"{contributor.fullName} " \ + f"({contributor.contributions[0].contributionType} of " \ + f"{contributor.contributions[0].work.fullTitle}) " \ + f"[{contributor.contributorId}]" + return _generic_formatter(contributor, 'Contributor', format_str) + + +def _funder_formatter(funder): + """ + A formatting string for funders + @param funder: The funder object + @return: A formatted funder object + """ + format_str = f"{funder.funderName} " \ + f"funded {len(funder.fundings)} books " \ + f"[{funder.funderId}]" + return _generic_formatter(funder, 'Funder', format_str) + + +def _funding_formatter(funding): + """ + A formatting string for fundings + @param funding: The funding object + @return: A formatted funding object + """ + format_str = f"{funding.funder.funderName} " \ + f"funded {funding.work.fullTitle} " \ + f"[{funding.fundingId}]" + return _generic_formatter(funding, 'Funding', format_str) + + +def _imprint_formatter(imprint): + """ + A formatting string for imprints + @param imprint: The imprint object + @return: A formatted imprint object + """ + format_str = f"{imprint.imprintName} " \ + f"({imprint.publisher.publisherName}/{imprint.publisherId}) " \ + f"[{imprint.imprintId}]" + return _generic_formatter(imprint, 'Imprint', format_str) + + +def _issue_formatter(issues): + """ + A formatting string for issues + @param issues: The issues object + @return: A formatted issue object + """ + format_str = f"{issues.work.fullTitle} " \ + f"in {issues.series.seriesName} " \ + f"({issues.series.imprint.publisher.publisherName}) " \ + f"[{issues.issueId}]" + return _generic_formatter(issues, 'Issue', format_str) + + +def _language_formatter(language): + """ + A formatting string for languages + @param language: The language object + @return: A formatted language object + """ + format_str = f"{language.work.fullTitle} " \ + f"is in {language.languageCode} " \ + f"({language.languageRelation}) " \ + f"[{language.languageId}]" + return _generic_formatter(language, 'Language', format_str) + + +def _price_formatter(price): + """ + A formatting string for prices + @param price: The price object + @return: A formatted price object + """ + format_str = f'{price.publication.work.fullTitle} ' \ + f'({price.publication.work.place}: ' \ + f'{price.publication.work.imprint.publisher.publisherName}, ' \ + f'{_date_parser(price.publication.work.publicationDate)}) ' \ + f"costs {_price_parser(price)} [{price.priceId}]" + return _generic_formatter(price, 'Price', format_str) + + +def _publication_formatter(publication): + """ + A formatting string for publications + @param publication: the publication on which to operate + @return: a formatted publication string + """ + format_str = f'{_author_parser(publication.work)}' \ + f'{publication.work.fullTitle} ' \ + f'({publication.work.place}: ' \ + f'{publication.work.imprint.publisher.publisherName}, ' \ + f'{_date_parser(publication.work.publicationDate)}) ' \ + f"[{publication.publicationType}] " \ + f"{_price_parser(publication.prices)} " \ + f"[{publication.publicationId}]" + return _generic_formatter(publication, 'Publication', format_str) + + +def _publisher_formatter(publisher): + """ + A formatting string for publishers + @param publisher: the publisher on which to operate + @return: a formatted publisher string + """ + format_str = f"{publisher.publisherName} ({publisher.publisherId})" + return _generic_formatter(publisher, 'Publisher', format_str) + + +def _series_formatter(series): + """ + A formatting string for series + @param series: the series on which to operate + @return: a formatted series string + """ + format_str = f"{series.seriesName} " \ + f"({series.imprint.publisher.publisherName}) " \ + f"[{series.seriesId}]" + return _generic_formatter(series, 'Series', format_str) + + +def _subject_formatter(subject): + """ + A formatting string for subjects + @param subject: the subject on which to operate + @return: a formatted subject string + """ + format_str = f"{subject.work.fullTitle} " \ + f"is in the {subject.subjectCode} " \ + f"subject area " \ + f"({subject.subjectType}) " \ + f"[{subject.subjectId}]" + return _generic_formatter(subject, 'Subject', format_str) + + +def _work_formatter(work): + """ + A formatting string for works + @param work: the work on which to operate + @return: a formatted work string + """ + format_str = f'{_author_parser(work)}' \ + f'{work.fullTitle} ' \ + f'({work.place}: ' \ + f'{work.imprint.publisher.publisherName}, ' \ + f'{_date_parser(work.publicationDate)}) ' \ + f'[{work.workId}]' + return _generic_formatter(work, 'Work', format_str) + + +default_fields = { + "contribution": _contribution_formatter, + "contributions": _contribution_formatter, + "contributor": _contributor_formatter, + "contributors": _contributor_formatter, + "funder": _funder_formatter, + "funders": _funder_formatter, + "funding": _funding_formatter, + "fundings": _funding_formatter, + "imprint": _imprint_formatter, + "imprints": _imprint_formatter, + "issue": _issue_formatter, + "issues": _issue_formatter, + "language": _language_formatter, + "languages": _language_formatter, + "price": _price_formatter, + "prices": _price_formatter, + "publication": _publication_formatter, + "publications": _publication_formatter, + "publisher": _publisher_formatter, + "publishers": _publisher_formatter, + "series": _series_formatter, + "serieses": _series_formatter, + "subject": _subject_formatter, + "subjects": _subject_formatter, + "work": _work_formatter, + "workByDoi": _work_formatter, + "works": _work_formatter, +} # this stores the original function pointer of Munch.__repr__ so that we can -# re-inject it above in "_muncher_repr" +# re-inject it above in "_munch_repr" munch_local = Munch.__repr__ From f74329cfb5bf1145ed8e458b754971796650937e Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 18:28:51 +0100 Subject: [PATCH 089/115] PEP8 fixes for client.py --- thothlibrary/client.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/thothlibrary/client.py b/thothlibrary/client.py index 3f957f0..d589ae4 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -35,14 +35,12 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): # subclass (e.g. thoth_0_4_2) to this class, thereby providing the # methods that can be called for any API version if issubclass(ThothClient, type(self)): - endpoints = \ - importlib.import_module('thothlibrary.thoth-{0}.' - 'endpoints'.format(self.version)) - version_endpoints = \ - getattr(endpoints, - 'ThothClient{0}'.format(self.version))\ - (version=version, - thoth_endpoint=thoth_endpoint) + module = 'thothlibrary.thoth-{0}.endpoints'.format(self.version) + endpoints = importlib.import_module(module) + + version_endpoints = getattr( + endpoints, 'ThothClient{0}'.format(self.version))( + version=version, thoth_endpoint=thoth_endpoint) [setattr(self, x, @@ -109,8 +107,13 @@ def create_contribution(self, contribution): """Construct and trigger a mutation to add a new contribution object""" return self.mutation("createContribution", contribution) - def supported_versions(self): - regex = 'thoth-(\d+_\d+_\d+)' + @staticmethod + def supported_versions(): + """ + Shows the versions of Thoth that this API supports + @return: a list of version strings + """ + regex = r'thoth-(\d+_\d+_\d+)' versions = [] @@ -145,14 +148,21 @@ def _build_structure(self, endpoint_name, data): @param data: the data @return: an object form of the output """ - structures = \ - importlib.import_module( - 'thothlibrary.thoth-{0}.structures'.format(self.version)) - builder = structures.StructureBuilder(endpoint_name, data) + module = 'thothlibrary.thoth-{0}.structures'.format(self.version) + structures = importlib.import_module(module) + builder = getattr(structures, 'StructureBuilder')(endpoint_name, data) + return builder.create_structure() @staticmethod def _dictionary_append(input_dict, key, value): + """ + Either adds a value to a dictionary or doesn't if it's null + @param input_dict: the dictionary to modify + @param key: the key to add + @param value: the value to add + @return: the dictionary + """ if value: input_dict[key] = value return input_dict From d49f306edf4c6fbbd23ca89e78cb502680057603 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 18:59:25 +0100 Subject: [PATCH 090/115] Move GraphQL query to separate file for maintainability --- thothlibrary/thoth-0_4_2/endpoints.py | 687 +--------------------- thothlibrary/thoth-0_4_2/fixtures/QUERIES | 622 ++++++++++++++++++++ 2 files changed, 635 insertions(+), 674 deletions(-) create mode 100644 thothlibrary/thoth-0_4_2/fixtures/QUERIES diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 6b9813e..0975340 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -3,684 +3,15 @@ This program is free software; you may redistribute and/or modify it under the terms of the Apache License v2.0. """ +import json + from thothlibrary.client import ThothClient class ThothClient0_4_2(ThothClient): - # the QUERIES field defines the fields that GraphQL will return - # note: every query should contain the field "__typename" if auto-object - # __str__ representation is to work - QUERIES = { - "works": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "workType", - "workStatus" - ], - "fields": [ - "workType", - "workStatus", - "fullTitle", - "title", - "subtitle", - "reference", - "edition", - "imprintId", - "doi", - "publicationDate", - "place", - "width", - "height", - "pageCount", - "pageBreakdown", - "imageCount", - "tableCount", - "audioCount", - "videoCount", - "license", - "copyrightHolder", - "landingPage", - "lccn", - "oclc", - "shortAbstract", - "longAbstract", - "generalNote", - "toc", - "workId", - "coverUrl", - "coverCaption", - "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", - "imprint { __typename publisher { publisherName publisherId __typename } }", - "__typename" - ] - }, - - "prices": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "currencyCode", - ], - "fields": [ - "currencyCode", - "publicationId", - "priceId", - "unitPrice", - "publication { work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", - "createdAt", - "updatedAt", - "__typename" - ] - }, - - "price": { - "parameters": [ - "priceId", - ], - "fields": [ - "currencyCode", - "publicationId", - "priceId", - "unitPrice", - "publication { work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", - "createdAt", - "updatedAt", - "__typename" - ] - }, - - "funding": { - "parameters": [ - "fundingId", - ], - "fields": [ - "fundingId", - "workId", - "funderId", - "program", - "grantNumber", - "projectName", - "projectShortname", - "jurisdiction", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", - "funder { funderId funderName funderDoi }", - "__typename" - ] - }, - - "fundings": { - "parameters": [ - "limit", - "offset", - "publishers", - "order", - ], - "fields": [ - "fundingId", - "workId", - "funderId", - "program", - "grantNumber", - "projectName", - "projectShortname", - "jurisdiction", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", - "funder { funderId funderName funderDoi }", - "__typename" - ] - }, - - "funders": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - ], - "fields": [ - "funderId", - "funderName", - "funderDoi", - "fundings { grantNumber program projectName jurisdiction work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", - "__typename" - ] - }, - - "funder": { - "parameters": [ - "funderId", - ], - "fields": [ - "funderId", - "funderName", - "funderDoi", - "fundings { grantNumber program projectName jurisdiction work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", - "__typename" - ] - }, - - "publications": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "publicationType", - ], - "fields": [ - "publicationId", - "publicationType", - "workId", - "isbn", - "publicationUrl", - "createdAt", - "updatedAt", - "prices { currencyCode unitPrice __typename}", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", - "__typename" - ] - }, - - "publication": { - "parameters": [ - "publicationId", - ], - "fields": [ - "publicationId", - "publicationType", - "workId", - "isbn", - "publicationUrl", - "createdAt", - "updatedAt", - "prices { currencyCode unitPrice __typename}", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", - "__typename" - ] - }, - - "work": { - "parameters": [ - "workId" - ], - "fields": [ - "workType", - "workStatus", - "fullTitle", - "title", - "subtitle", - "reference", - "edition", - "imprintId", - "doi", - "publicationDate", - "place", - "width", - "height", - "pageCount", - "pageBreakdown", - "imageCount", - "tableCount", - "audioCount", - "videoCount", - "license", - "copyrightHolder", - "landingPage", - "lccn", - "oclc", - "shortAbstract", - "longAbstract", - "generalNote", - "toc", - "workId", - "coverUrl", - "coverCaption", - "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", - "imprint { __typename publisher { publisherName publisherId __typename } }", - "__typename" - ] - }, - - "workByDoi": { - "parameters": [ - "doi" - ], - "fields": [ - "workId", - "workType", - "workStatus", - "fullTitle", - "title", - "subtitle", - "reference", - "edition", - "imprintId", - "doi", - "publicationDate", - "place", - "width", - "height", - "pageCount", - "pageBreakdown", - "imageCount", - "tableCount", - "audioCount", - "videoCount", - "license", - "copyrightHolder", - "landingPage", - "lccn", - "oclc", - "shortAbstract", - "longAbstract", - "generalNote", - "toc", - "coverUrl", - "coverCaption", - "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", - "imprint { __typename publisher { publisherName publisherId __typename } }", - "__typename" - ] - }, - - "contributions": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "contributionType", - ], - "fields": [ - "contributionId", - "contributionType", - "mainContribution", - "biography", - "institution", - "__typename", - "firstName", - "lastName", - "fullName", - "contributionOrdinal", - "workId", - "work { fullTitle }", - "contributor {firstName lastName fullName orcid __typename website contributorId}" - ] - }, - - "contribution": { - "parameters": [ - "contributionId", - ], - "fields": [ - "contributionId", - "contributionType", - "mainContribution", - "biography", - "institution", - "__typename", - "firstName", - "lastName", - "fullName", - "contributionOrdinal", - "workId", - "work { fullTitle }", - "contributor {firstName lastName fullName orcid __typename website contributorId}" - ] - }, - - "contributors": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - ], - "fields": [ - "contributorId", - "firstName", - "lastName", - "fullName", - "orcid", - "__typename", - "contributions { contributionId contributionType work { workId fullTitle} }" - ] - }, - - "contributor": { - "parameters": [ - "contributorId" - ], - "fields": [ - "contributorId", - "firstName", - "lastName", - "fullName", - "orcid", - "__typename", - "contributions { contributionId contributionType work { workId fullTitle} }" - ] - }, - - "publishers": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - ], - "fields": [ - "imprints { imprintUrl imprintId imprintName __typename}" - "updatedAt", - "createdAt", - "publisherId", - "publisherName", - "publisherShortname", - "publisherUrl", - "__typename" - ] - }, - - "serieses": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "seriesType" - ], - "fields": [ - "seriesId", - "seriesType", - "seriesName", - "updatedAt", - "createdAt", - "imprintId", - "imprint { __typename publisher { publisherName publisherId __typename } }", - "issues { issueId work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } } }", - "__typename" - ] - }, - - "series": { - "parameters": [ - "seriesId" - ], - "fields": [ - "seriesId", - "seriesType", - "seriesName", - "updatedAt", - "createdAt", - "imprintId", - "imprint { __typename publisher { publisherName publisherId __typename } }", - "issues { issueId work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } } }", - "__typename" - ] - }, - - "issue": { - "parameters": [ - "issueId", - ], - "fields": [ - "issueId", - "seriesId", - "issueOrdinal", - "updatedAt", - "createdAt", - "series { seriesId seriesType seriesName imprintId imprint { __typename publisher { publisherName publisherId __typename } }}", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "issues": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - ], - "fields": [ - "issueId", - "seriesId", - "issueOrdinal", - "updatedAt", - "createdAt", - "series { seriesId seriesType seriesName imprintId imprint { __typename publisher { publisherName publisherId __typename } }}", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "imprints": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - ], - "fields": [ - "imprintUrl", - "imprintId", - "imprintName", - "updatedAt", - "createdAt", - "publisherId", - "publisher { publisherName publisherId }", - "works { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "language": { - "parameters": [ - "languageId", - ], - "fields": [ - "languageId", - "workId", - "languageCode", - "languageRelation", - "createdAt", - "mainLanguage", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "subjects": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "subjectType", - ], - "fields": [ - "subjectId", - "workId", - "subjectCode", - "subjectType", - "subjectOrdinal", - "createdAt", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "subject": { - "parameters": [ - "subjectId", - ], - "fields": [ - "subjectId", - "workId", - "subjectCode", - "subjectType", - "subjectOrdinal", - "createdAt", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "languages": { - "parameters": [ - "limit", - "offset", - "filter", - "order", - "publishers", - "languageCode", - "languageRelation" - ], - "fields": [ - "languageId", - "workId", - "languageCode", - "languageRelation", - "createdAt", - "mainLanguage", - "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "imprint": { - "parameters": [ - "imprintId", - ], - "fields": [ - "imprintUrl", - "imprintId", - "imprintName", - "updatedAt", - "createdAt", - "publisherId", - "publisher { publisherName publisherId }", - "works { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }" - "__typename" - ] - }, - - "publisher": { - "parameters": [ - "publisherId", - ], - "fields": [ - "imprints { imprintUrl imprintId imprintName __typename}" - "updatedAt", - "createdAt", - "publisherId", - "publisherName", - "publisherShortname", - "publisherUrl", - "__typename" - ] - }, - - "publisherCount": { - "parameters": [ - "filter", - "publishers", - ], - }, - - "imprintCount": { - "parameters": [ - "filter", - "publishers", - ], - }, - - "contributorCount": { - "parameters": [ - "filter", - ], - }, - - "workCount": { - "parameters": [ - "filter", - "publishers", - "workType", - "workStatus", - ], - }, - - "funderCount": { - "parameters": [ - "filter" - ], - }, - - "publicationCount": { - "parameters": [ - "filter", - "publishers", - "publicationType" - ], - }, - - "contributionCount": { - "parameters": [ - "filter", - "publishers", - "contributionType" - ], - }, - - "issuesCount": {}, - - "fundingCount": {}, - - "languageCount": { - "parameters": [ - "languageCode", - "languageRelation", - ], - }, - - "subjectCount": { - "parameters": [ - "filter", - "subjectType" - ], - }, - - "priceCount": { - "parameters": [ - "currencyCode", - ], - }, - - "seriesCount": { - "parameters": [ - "filter", - "publishers", - "seriesType" - ], - } - } + """ + The client for Thoth 0.4.2 + """ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """ @@ -688,6 +19,14 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): @param input_class: the ThothClient instance to be versioned """ + # the QUERIES field defines the fields that GraphQL will return + # note: every query should contain the field "__typename" if auto-object + # __str__ representation is to work. These are stored in the + # fixtures/QUERIES file + path = 'thothlibrary/thoth-{0}/fixtures/QUERIES' + with open(path.format(version.replace('.', '_')), 'r') as query_file: + self.QUERIES = json.loads(query_file.read()) + # this list should specify all API endpoints by method name in this # class. Note, it should always, also, contain the QUERIES list self.endpoints = ['works', 'work_by_doi', 'work_by_id', diff --git a/thothlibrary/thoth-0_4_2/fixtures/QUERIES b/thothlibrary/thoth-0_4_2/fixtures/QUERIES new file mode 100644 index 0000000..d855607 --- /dev/null +++ b/thothlibrary/thoth-0_4_2/fixtures/QUERIES @@ -0,0 +1,622 @@ +{ + "contribution": { + "fields": [ + "contributionId", + "contributionType", + "mainContribution", + "biography", + "institution", + "__typename", + "firstName", + "lastName", + "fullName", + "contributionOrdinal", + "workId", + "work { fullTitle }", + "contributor {firstName lastName fullName orcid __typename website contributorId}" + ], + "parameters": [ + "contributionId" + ] + }, + "contributionCount": { + "parameters": [ + "filter", + "publishers", + "contributionType" + ] + }, + "contributions": { + "fields": [ + "contributionId", + "contributionType", + "mainContribution", + "biography", + "institution", + "__typename", + "firstName", + "lastName", + "fullName", + "contributionOrdinal", + "workId", + "work { fullTitle }", + "contributor {firstName lastName fullName orcid __typename website contributorId}" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "contributionType" + ] + }, + "contributor": { + "fields": [ + "contributorId", + "firstName", + "lastName", + "fullName", + "orcid", + "__typename", + "contributions { contributionId contributionType work { workId fullTitle} }" + ], + "parameters": [ + "contributorId" + ] + }, + "contributorCount": { + "parameters": [ + "filter" + ] + }, + "contributors": { + "fields": [ + "contributorId", + "firstName", + "lastName", + "fullName", + "orcid", + "__typename", + "contributions { contributionId contributionType work { workId fullTitle} }" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order" + ] + }, + "funder": { + "fields": [ + "funderId", + "funderName", + "funderDoi", + "fundings { grantNumber program projectName jurisdiction work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "__typename" + ], + "parameters": [ + "funderId" + ] + }, + "funderCount": { + "parameters": [ + "filter" + ] + }, + "funders": { + "fields": [ + "funderId", + "funderName", + "funderDoi", + "fundings { grantNumber program projectName jurisdiction work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order" + ] + }, + "funding": { + "fields": [ + "fundingId", + "workId", + "funderId", + "program", + "grantNumber", + "projectName", + "projectShortname", + "jurisdiction", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "funder { funderId funderName funderDoi }", + "__typename" + ], + "parameters": [ + "fundingId" + ] + }, + "fundingCount": {}, + "fundings": { + "fields": [ + "fundingId", + "workId", + "funderId", + "program", + "grantNumber", + "projectName", + "projectShortname", + "jurisdiction", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "funder { funderId funderName funderDoi }", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "publishers", + "order" + ] + }, + "imprint": { + "fields": [ + "imprintUrl", + "imprintId", + "imprintName", + "updatedAt", + "createdAt", + "publisherId", + "publisher { publisherName publisherId }", + "works { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "imprintId" + ] + }, + "imprintCount": { + "parameters": [ + "filter", + "publishers" + ] + }, + "imprints": { + "fields": [ + "imprintUrl", + "imprintId", + "imprintName", + "updatedAt", + "createdAt", + "publisherId", + "publisher { publisherName publisherId }", + "works { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers" + ] + }, + "issue": { + "fields": [ + "issueId", + "seriesId", + "issueOrdinal", + "updatedAt", + "createdAt", + "series { seriesId seriesType seriesName imprintId imprint { __typename publisher { publisherName publisherId __typename } }}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "issueId" + ] + }, + "issues": { + "fields": [ + "issueId", + "seriesId", + "issueOrdinal", + "updatedAt", + "createdAt", + "series { seriesId seriesType seriesName imprintId imprint { __typename publisher { publisherName publisherId __typename } }}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers" + ] + }, + "issuesCount": {}, + "language": { + "fields": [ + "languageId", + "workId", + "languageCode", + "languageRelation", + "createdAt", + "mainLanguage", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "languageId" + ] + }, + "languageCount": { + "parameters": [ + "languageCode", + "languageRelation" + ] + }, + "languages": { + "fields": [ + "languageId", + "workId", + "languageCode", + "languageRelation", + "createdAt", + "mainLanguage", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "languageCode", + "languageRelation" + ] + }, + "price": { + "fields": [ + "currencyCode", + "publicationId", + "priceId", + "unitPrice", + "publication { work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "createdAt", + "updatedAt", + "__typename" + ], + "parameters": [ + "priceId" + ] + }, + "priceCount": { + "parameters": [ + "currencyCode" + ] + }, + "prices": { + "fields": [ + "currencyCode", + "publicationId", + "priceId", + "unitPrice", + "publication { work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } } }", + "createdAt", + "updatedAt", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "currencyCode" + ] + }, + "publication": { + "fields": [ + "publicationId", + "publicationType", + "workId", + "isbn", + "publicationUrl", + "createdAt", + "updatedAt", + "prices { currencyCode unitPrice __typename}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "__typename" + ], + "parameters": [ + "publicationId" + ] + }, + "publicationCount": { + "parameters": [ + "filter", + "publishers", + "publicationType" + ] + }, + "publications": { + "fields": [ + "publicationId", + "publicationType", + "workId", + "isbn", + "publicationUrl", + "createdAt", + "updatedAt", + "prices { currencyCode unitPrice __typename}", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } imprint { publisher { publisherName publisherId } } }", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "publicationType" + ] + }, + "publisher": { + "fields": [ + "imprints { imprintUrl imprintId imprintName __typename}updatedAt", + "createdAt", + "publisherId", + "publisherName", + "publisherShortname", + "publisherUrl", + "__typename" + ], + "parameters": [ + "publisherId" + ] + }, + "publisherCount": { + "parameters": [ + "filter", + "publishers" + ] + }, + "publishers": { + "fields": [ + "imprints { imprintUrl imprintId imprintName __typename}updatedAt", + "createdAt", + "publisherId", + "publisherName", + "publisherShortname", + "publisherUrl", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers" + ] + }, + "series": { + "fields": [ + "seriesId", + "seriesType", + "seriesName", + "updatedAt", + "createdAt", + "imprintId", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "issues { issueId work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } } }", + "__typename" + ], + "parameters": [ + "seriesId" + ] + }, + "seriesCount": { + "parameters": [ + "filter", + "publishers", + "seriesType" + ] + }, + "serieses": { + "fields": [ + "seriesId", + "seriesType", + "seriesName", + "updatedAt", + "createdAt", + "imprintId", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "issues { issueId work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } } }", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "seriesType" + ] + }, + "subject": { + "fields": [ + "subjectId", + "workId", + "subjectCode", + "subjectType", + "subjectOrdinal", + "createdAt", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "subjectId" + ] + }, + "subjectCount": { + "parameters": [ + "filter", + "subjectType" + ] + }, + "subjects": { + "fields": [ + "subjectId", + "workId", + "subjectCode", + "subjectType", + "subjectOrdinal", + "createdAt", + "work { workId fullTitle doi publicationDate place contributions { fullName contributionType mainContribution contributionOrdinal } }__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "subjectType" + ] + }, + "work": { + "fields": [ + "workType", + "workStatus", + "fullTitle", + "title", + "subtitle", + "reference", + "edition", + "imprintId", + "doi", + "publicationDate", + "place", + "width", + "height", + "pageCount", + "pageBreakdown", + "imageCount", + "tableCount", + "audioCount", + "videoCount", + "license", + "copyrightHolder", + "landingPage", + "lccn", + "oclc", + "shortAbstract", + "longAbstract", + "generalNote", + "toc", + "workId", + "coverUrl", + "coverCaption", + "publications { isbn publicationType __typename }", + "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "__typename" + ], + "parameters": [ + "workId" + ] + }, + "workByDoi": { + "fields": [ + "workId", + "workType", + "workStatus", + "fullTitle", + "title", + "subtitle", + "reference", + "edition", + "imprintId", + "doi", + "publicationDate", + "place", + "width", + "height", + "pageCount", + "pageBreakdown", + "imageCount", + "tableCount", + "audioCount", + "videoCount", + "license", + "copyrightHolder", + "landingPage", + "lccn", + "oclc", + "shortAbstract", + "longAbstract", + "generalNote", + "toc", + "coverUrl", + "coverCaption", + "publications { isbn publicationType __typename }", + "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "__typename" + ], + "parameters": [ + "doi" + ] + }, + "workCount": { + "parameters": [ + "filter", + "publishers", + "workType", + "workStatus" + ] + }, + "works": { + "fields": [ + "workType", + "workStatus", + "fullTitle", + "title", + "subtitle", + "reference", + "edition", + "imprintId", + "doi", + "publicationDate", + "place", + "width", + "height", + "pageCount", + "pageBreakdown", + "imageCount", + "tableCount", + "audioCount", + "videoCount", + "license", + "copyrightHolder", + "landingPage", + "lccn", + "oclc", + "shortAbstract", + "longAbstract", + "generalNote", + "toc", + "workId", + "coverUrl", + "coverCaption", + "publications { isbn publicationType __typename }", + "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "imprint { __typename publisher { publisherName publisherId __typename } }", + "__typename" + ], + "parameters": [ + "limit", + "offset", + "filter", + "order", + "publishers", + "workType", + "workStatus" + ] + } +} From e1914ae9faea1f592d702c2b736ecc1f404fc42f Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:03:01 +0100 Subject: [PATCH 091/115] Change endpoints to read fixture from local relative directory --- thothlibrary/thoth-0_4_2/endpoints.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 0975340..c55c517 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -4,6 +4,7 @@ it under the terms of the Apache License v2.0. """ import json +import pathlib from thothlibrary.client import ThothClient @@ -13,7 +14,8 @@ class ThothClient0_4_2(ThothClient): The client for Thoth 0.4.2 """ - def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): + def __init__(self, thoth_endpoint="https://api.thoth.pub", + version="0.4.2b"): """ Creates an instance of Thoth 0.4.2 endpoints @param input_class: the ThothClient instance to be versioned @@ -23,8 +25,9 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): # note: every query should contain the field "__typename" if auto-object # __str__ representation is to work. These are stored in the # fixtures/QUERIES file - path = 'thothlibrary/thoth-{0}/fixtures/QUERIES' - with open(path.format(version.replace('.', '_')), 'r') as query_file: + path = '{0}/fixtures/QUERIES' + script_dir = pathlib.Path(__file__).parent.resolve() + with open(path.format(script_dir), 'r') as query_file: self.QUERIES = json.loads(query_file.read()) # this list should specify all API endpoints by method name in this From e29b075b83f1ff3868d59071d80746594f0b8576 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:04:33 +0100 Subject: [PATCH 092/115] Change file load to use platform independent model --- thothlibrary/thoth-0_4_2/endpoints.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index c55c517..67a070f 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -4,6 +4,7 @@ it under the terms of the Apache License v2.0. """ import json +import os import pathlib from thothlibrary.client import ThothClient @@ -14,8 +15,7 @@ class ThothClient0_4_2(ThothClient): The client for Thoth 0.4.2 """ - def __init__(self, thoth_endpoint="https://api.thoth.pub", - version="0.4.2b"): + def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """ Creates an instance of Thoth 0.4.2 endpoints @param input_class: the ThothClient instance to be versioned @@ -25,8 +25,9 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", # note: every query should contain the field "__typename" if auto-object # __str__ representation is to work. These are stored in the # fixtures/QUERIES file - path = '{0}/fixtures/QUERIES' script_dir = pathlib.Path(__file__).parent.resolve() + path = os.path.join(script_dir, 'fixtures', 'QUERIES') + with open(path.format(script_dir), 'r') as query_file: self.QUERIES = json.loads(query_file.read()) From 28414e682a28f9fd1dae94c7a1d2bee164b20f9f Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:08:49 +0100 Subject: [PATCH 093/115] Change file load to use platform independent model Update test pickles for works --- thothlibrary/thoth-0_4_2/endpoints.py | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/work.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/tests.py | 8 +++++--- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 67a070f..c356eb7 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -28,7 +28,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): script_dir = pathlib.Path(__file__).parent.resolve() path = os.path.join(script_dir, 'fixtures', 'QUERIES') - with open(path.format(script_dir), 'r') as query_file: + with open(path, 'r') as query_file: self.QUERIES = json.loads(query_file.read()) # this list should specify all API endpoints by method name in this diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work.json b/thothlibrary/thoth-0_4_2/tests/fixtures/work.json index 0fc7f4a..1646e51 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/work.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work.json @@ -1 +1 @@ -{"data":{"work":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} +{"data":{"work":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle index c1e3bee..a0ede26 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle @@ -1 +1 @@ -{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} +{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json index 2be2a7d..5a529e4 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json @@ -1 +1 @@ -{"data":{"workByDoi":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} +{"data":{"workByDoi":{"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle index c1e3bee..b7a1a49 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle @@ -1 +1 @@ -{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} +{"workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} diff --git a/thothlibrary/thoth-0_4_2/tests/tests.py b/thothlibrary/thoth-0_4_2/tests/tests.py index 735a5c2..98c96aa 100644 --- a/thothlibrary/thoth-0_4_2/tests/tests.py +++ b/thothlibrary/thoth-0_4_2/tests/tests.py @@ -4,6 +4,7 @@ it under the terms of the Apache License v2.0. """ import json +import os import unittest import requests_mock @@ -1065,8 +1066,8 @@ def _pickle_tester(self, pickle_name, endpoint, negative=False): @param negative: whether to assert equal (True) or unequal (False) @return: None or an assertion """ - with open("fixtures/{0}.pickle".format(pickle_name), - "rb") as pickle_file: + path = os.path.join("fixtures", "{0}.pickle".format(pickle_name)) + with open(path, "rb") as pickle_file: loaded_response = json.load(pickle_file) response = json.loads(json.dumps(endpoint())) @@ -1082,7 +1083,8 @@ def _setup_mocker(self, endpoint, m): @param m: the requests Mocker object @return: the mock string, a Thoth client for this version """ - with open("fixtures/{0}.json".format(endpoint), "r") as input_file: + path = os.path.join("fixtures", "{0}.json".format(endpoint)) + with open(path, "r") as input_file: mock_response = input_file.read() m.register_uri('POST', '{}/graphql'.format(self.endpoint), From 40f23f8ba888af70c1a0f723b35503d82fb46b89 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:39:18 +0100 Subject: [PATCH 094/115] Sort endpoints alphabetically --- thothlibrary/thoth-0_4_2/endpoints.py | 704 +++++++++++++------------- 1 file changed, 352 insertions(+), 352 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index c356eb7..ea526e5 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -50,18 +50,61 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): super().__init__(thoth_endpoint=thoth_endpoint, version=version) - def funding(self, funding_id: str, raw: bool = False): + def contribution(self, contribution_id: str, raw: bool = False): """ - Returns a funding by ID - @param funding_id: the ID to fetch + Returns a contribution by ID + @param contribution_id: the contribution ID @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ parameters = { - 'fundingId': '"' + funding_id + '"' + 'contributionId': '"' + contribution_id + '"' } - return self._api_request("funding", parameters, return_raw=raw) + return self._api_request("contribution", parameters, return_raw=raw) + + def contributions(self, limit: int = 100, offset: int = 0, + order: str = None, publishers: str = None, + contribution_type: str = None, raw: bool = False): + """ + Returns a contributions list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param contribution_type: the contribution type (e.g. AUTHOR) + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'contributionType', + contribution_type) + + return self._api_request("contributions", parameters, return_raw=raw) + + def contribution_count(self, search: str = "", publishers: str = None, + contribution_type: str = None, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + if search and not search.startswith('"'): + search = '"{0}"'.format(search) + + self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'contributionType', + contribution_type) + + return self._api_request("contributionCount", parameters, + return_raw=raw) def contributor(self, contributor_id: str, raw: bool = False): """ @@ -76,18 +119,44 @@ def contributor(self, contributor_id: str, raw: bool = False): return self._api_request("contributor", parameters, return_raw=raw) - def language(self, language_id: str, raw: bool = False): + def contributors(self, limit: int = 100, offset: int = 0, + search: str = "", order: str = None, + raw: bool = False): """ - Returns a series by ID - @param language_id: the ID to fetch + Returns a contributions list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param search: a filter string to search @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ + if order is None: + order = {} parameters = { - 'languageId': '"' + language_id + '"' + "offset": offset, + "limit": limit, } - return self._api_request("language", parameters, return_raw=raw) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) + + self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'order', order) + + return self._api_request("contributors", parameters, return_raw=raw) + + def contributor_count(self, search: str = "", raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + if search and not search.startswith('"'): + search = '"{0}"'.format(search) + + self._dictionary_append(parameters, 'filter', search) + + return self._api_request("contributorCount", parameters, + return_raw=raw) def funder(self, funder_id: str, raw: bool = False): """ @@ -102,57 +171,45 @@ def funder(self, funder_id: str, raw: bool = False): return self._api_request("funder", parameters, return_raw=raw) - def subject(self, subject_id: str, raw: bool = False): - """ - Returns a subject by ID - @param subject_id: the ID to fetch - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ + def funders(self, limit: int = 100, offset: int = 0, order: str = None, + search: str = "", raw: bool = False): + """Construct and trigger a query to obtain all funders""" parameters = { - 'subjectId': '"' + subject_id + '"' + "limit": limit, + "offset": offset, } - return self._api_request("subject", parameters, return_raw=raw) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - def series(self, series_id: str, raw: bool = False): - """ - Returns a series by ID - @param series_id: the ID to fetch - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ - parameters = { - 'seriesId': '"' + series_id + '"' - } + self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'order', order) - return self._api_request("series", parameters, return_raw=raw) + return self._api_request("funders", parameters, return_raw=raw) - def price(self, price_id: str, raw: bool = False): - """ - Returns a price by ID - @param price_id: the ID to fetch - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ - parameters = { - 'priceId': '"' + price_id + '"' - } + def funder_count(self, search: str = "", raw: bool = False): + """Construct and trigger a query to count publications""" + parameters = {} - return self._api_request("price", parameters, return_raw=raw) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - def publication(self, publication_id: str, raw: bool = False): + self._dictionary_append(parameters, 'filter', search) + + return self._api_request("funderCount", parameters, return_raw=raw) + + def funding(self, funding_id: str, raw: bool = False): """ - Returns a publication by ID - @param publication_id: the ID to fetch + Returns a funding by ID + @param funding_id: the ID to fetch @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ parameters = { - 'publicationId': '"' + publication_id + '"' + 'fundingId': '"' + funding_id + '"' } - return self._api_request("publication", parameters, return_raw=raw) + return self._api_request("funding", parameters, return_raw=raw) def fundings(self, limit: int = 100, offset: int = 0, order: str = None, publishers: str = None, raw: bool = False): @@ -177,52 +234,72 @@ def fundings(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("fundings", parameters, return_raw=raw) - def prices(self, limit: int = 100, offset: int = 0, order: str = None, - publishers: str = None, currency_code: str = None, - raw: bool = False): + def funding_count(self, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + return self._api_request("fundingCount", parameters, return_raw=raw) + + def imprint(self, imprint_id: str, raw: bool = False): """ - Returns a price list - @param limit: the maximum number of results to return (default: 100) - @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) - @param publishers: a list of publishers to limit by - @param currency_code: the currency code (e.g. GBP) + Returns a work by DOI + @param imprint_id: the imprint @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ - if order is None: - order = {} parameters = { - "offset": offset, + 'imprintId': '"' + imprint_id + '"' + } + + return self._api_request("imprint", parameters, return_raw=raw) + + def imprints(self, limit: int = 100, offset: int = 0, order: str = None, + search: str = "", publishers: str = None, + raw: bool = False): + """Construct and trigger a query to obtain all publishers""" + parameters = { "limit": limit, + "offset": offset, } + if search and not search.startswith('"'): + search = '"{0}"'.format(search) + + self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'currencyCode', currency_code) - return self._api_request("prices", parameters, return_raw=raw) + return self._api_request("imprints", parameters, return_raw=raw) - def publications(self, limit: int = 100, offset: int = 0, - search: str = "", order: str = None, - publishers: str = None, publication_type: str = None, - raw: bool = False): + def imprint_count(self, search: str = "", publishers: str = None, + raw: bool = False): + """Construct and trigger a query to count publishers""" + parameters = {} + + self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'publishers', publishers) + + return self._api_request("imprintCount", parameters, return_raw=raw) + + def issue(self, issue_id: str, raw: bool = False): """ - Returns a publications list - @param limit: the maximum number of results to return (default: 100) - @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) - @param publishers: a list of publishers to limit by - @param search: a filter string to search - @param publication_type: the work type (e.g. PAPERBACK) + Returns an issue by ID + @param issue_id: the imprint @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ - if order is None: - order = {} parameters = { - "offset": offset, + 'issueId': '"' + issue_id + '"' + } + + return self._api_request("issue", parameters, return_raw=raw) + + def issues(self, limit: int = 100, offset: int = 0, order: str = None, + search: str = "", publishers: str = None, raw: bool = False): + """Construct and trigger a query to obtain all publishers""" + parameters = { "limit": limit, + "offset": offset, } if search and not search.startswith('"'): @@ -231,54 +308,36 @@ def publications(self, limit: int = 100, offset: int = 0, self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'publicationType', publication_type) - return self._api_request("publications", parameters, return_raw=raw) + return self._api_request("issues", parameters, return_raw=raw) - def contributions(self, limit: int = 100, offset: int = 0, - order: str = None, publishers: str = None, - contribution_type: str = None, raw: bool = False): + def issue_count(self, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + return self._api_request("issueCount", parameters, + return_raw=raw) + + def language(self, language_id: str, raw: bool = False): """ - Returns a contributions list - @param limit: the maximum number of results to return (default: 100) - @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) - @param publishers: a list of publishers to limit by - @param contribution_type: the contribution type (e.g. AUTHOR) + Returns a series by ID + @param language_id: the ID to fetch @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ - if order is None: - order = {} parameters = { - "offset": offset, - "limit": limit, + 'languageId': '"' + language_id + '"' } - self._dictionary_append(parameters, 'order', order) - self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'contributionType', - contribution_type) - - return self._api_request("contributions", parameters, return_raw=raw) + return self._api_request("language", parameters, return_raw=raw) - def contributors(self, limit: int = 100, offset: int = 0, - search: str = "", order: str = None, - raw: bool = False): - """ - Returns a contributions list - @param limit: the maximum number of results to return (default: 100) - @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) - @param search: a filter string to search - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ - if order is None: - order = {} + def languages(self, limit: int = 100, offset: int = 0, order: str = None, + search: str = "", publishers: str = None, raw: bool = False, + language_code: str = "", language_relation: str = ""): + """Construct and trigger a query to obtain all publishers""" parameters = { - "offset": offset, "limit": limit, + "offset": offset, } if search and not search.startswith('"'): @@ -286,21 +345,47 @@ def contributors(self, limit: int = 100, offset: int = 0, self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'languageCode', language_code) + self._dictionary_append(parameters, 'languageRelation', + language_relation) - return self._api_request("contributors", parameters, return_raw=raw) + return self._api_request("languages", parameters, return_raw=raw) - def works(self, limit: int = 100, offset: int = 0, search: str = "", - order: str = None, publishers: str = None, work_type: str = None, - work_status: str = None, raw: bool = False): + def language_count(self, language_code: str = "", + language_relation: str = "", raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} + + self._dictionary_append(parameters, 'languageCode', language_code) + self._dictionary_append(parameters, 'languageRelation', + language_relation) + + return self._api_request("languageCount", parameters, return_raw=raw) + + def price(self, price_id: str, raw: bool = False): """ - Returns a works list + Returns a price by ID + @param price_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'priceId': '"' + price_id + '"' + } + + return self._api_request("price", parameters, return_raw=raw) + + def prices(self, limit: int = 100, offset: int = 0, order: str = None, + publishers: str = None, currency_code: str = None, + raw: bool = False): + """ + Returns a price list @param limit: the maximum number of results to return (default: 100) @param order: a GraphQL order query statement @param offset: the offset from which to retrieve results (default: 0) @param publishers: a list of publishers to limit by - @param search: a filter string to search - @param work_type: the work type (e.g. MONOGRAPH) - @param work_status: the work status (e.g. ACTIVE) + @param currency_code: the currency code (e.g. GBP) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ @@ -311,94 +396,92 @@ def works(self, limit: int = 100, offset: int = 0, search: str = "", "limit": limit, } - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'workType', work_type) - self._dictionary_append(parameters, 'workStatus', work_status) + self._dictionary_append(parameters, 'currencyCode', currency_code) - return self._api_request("works", parameters, return_raw=raw) + return self._api_request("prices", parameters, return_raw=raw) - def work_by_doi(self, doi: str, raw: bool = False): - """ - Returns a work by DOI - @param doi: the DOI to fetch - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ - parameters = { - 'doi': '"' + doi + '"' - } + def price_count(self, currency_code: str = None, raw: bool = False): + """Construct and trigger a query to count publishers""" + parameters = {} - return self._api_request("workByDoi", parameters, return_raw=raw) + self._dictionary_append(parameters, 'currencyCode', currency_code) - def work_by_id(self, work_id: str, raw: bool = False): + return self._api_request("priceCount", parameters, return_raw=raw) + + def publication(self, publication_id: str, raw: bool = False): """ - Returns a work by ID - @param work_id: the ID to fetch + Returns a publication by ID + @param publication_id: the ID to fetch @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ parameters = { - 'workId': '"' + work_id + '"' + 'publicationId': '"' + publication_id + '"' } - return self._api_request("work", parameters, return_raw=raw) + return self._api_request("publication", parameters, return_raw=raw) - def publisher(self, publisher_id: str, raw: bool = False): + def publications(self, limit: int = 100, offset: int = 0, + search: str = "", order: str = None, + publishers: str = None, publication_type: str = None, + raw: bool = False): """ - Returns a work by DOI - @param publisher_id: the publisher + Returns a publications list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param search: a filter string to search + @param publication_type: the work type (e.g. PAPERBACK) @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ + if order is None: + order = {} parameters = { - 'publisherId': '"' + publisher_id + '"' + "offset": offset, + "limit": limit, } - return self._api_request("publisher", parameters, return_raw=raw) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - def contribution(self, contribution_id: str, raw: bool = False): - """ - Returns a contribution by ID - @param contribution_id: the contribution ID - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ - parameters = { - 'contributionId': '"' + contribution_id + '"' - } + self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'order', order) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'publicationType', publication_type) - return self._api_request("contribution", parameters, return_raw=raw) + return self._api_request("publications", parameters, return_raw=raw) - def imprint(self, imprint_id: str, raw: bool = False): - """ - Returns a work by DOI - @param imprint_id: the imprint - @param raw: whether to return a python object or the raw server result - @return: either an object (default) or raw server response - """ - parameters = { - 'imprintId': '"' + imprint_id + '"' - } + def publication_count(self, search: str = "", publishers: str = None, + publication_type: str = None, raw: bool = False): + """Construct and trigger a query to count publications""" + parameters = {} - return self._api_request("imprint", parameters, return_raw=raw) + if search and not search.startswith('"'): + search = '"{0}"'.format(search) - def issue(self, issue_id: str, raw: bool = False): + self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'publicationType', publication_type) + + return self._api_request("publicationCount", parameters, + return_raw=raw) + + def publisher(self, publisher_id: str, raw: bool = False): """ - Returns an issue by ID - @param issue_id: the imprint + Returns a work by DOI + @param publisher_id: the publisher @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ parameters = { - 'issueId': '"' + issue_id + '"' + 'publisherId': '"' + publisher_id + '"' } - return self._api_request("issue", parameters, return_raw=raw) + return self._api_request("publisher", parameters, return_raw=raw) def publishers(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, @@ -418,29 +501,36 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("publishers", parameters, return_raw=raw) - def serieses(self, limit: int = 100, offset: int = 0, order: str = None, - search: str = "", publishers: str = None, - series_type: str = "", raw: bool = False): - """Construct and trigger a query to obtain all serieses""" - parameters = { - "limit": limit, - "offset": offset, - } + def publisher_count(self, search: str = "", publishers: str = None, + raw: bool = False): + """Construct and trigger a query to count publishers""" + parameters = {} if search and not search.startswith('"'): search = '"{0}"'.format(search) self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'seriesType', series_type) - return self._api_request("serieses", parameters, return_raw=raw) + return self._api_request("publisherCount", parameters, return_raw=raw) - def imprints(self, limit: int = 100, offset: int = 0, order: str = None, + def series(self, series_id: str, raw: bool = False): + """ + Returns a series by ID + @param series_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'seriesId': '"' + series_id + '"' + } + + return self._api_request("series", parameters, return_raw=raw) + + def serieses(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, - raw: bool = False): - """Construct and trigger a query to obtain all publishers""" + series_type: str = "", raw: bool = False): + """Construct and trigger a query to obtain all serieses""" parameters = { "limit": limit, "offset": offset, @@ -452,45 +542,37 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, self._dictionary_append(parameters, 'filter', search) self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'seriesType', series_type) - return self._api_request("imprints", parameters, return_raw=raw) + return self._api_request("serieses", parameters, return_raw=raw) - def languages(self, limit: int = 100, offset: int = 0, order: str = None, - search: str = "", publishers: str = None, raw: bool = False, - language_code: str = "", language_relation: str = ""): - """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } + def series_count(self, search: str = "", publishers: str = None, + series_type: str = None, raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} if search and not search.startswith('"'): search = '"{0}"'.format(search) self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'languageCode', language_code) - self._dictionary_append(parameters, 'languageRelation', - language_relation) + self._dictionary_append(parameters, 'seriesType', + series_type) - return self._api_request("languages", parameters, return_raw=raw) + return self._api_request("seriesCount", parameters, return_raw=raw) - def funders(self, limit: int = 100, offset: int = 0, order: str = None, - search: str = "", raw: bool = False): - """Construct and trigger a query to obtain all funders""" + def subject(self, subject_id: str, raw: bool = False): + """ + Returns a subject by ID + @param subject_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ parameters = { - "limit": limit, - "offset": offset, + 'subjectId': '"' + subject_id + '"' } - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) - - return self._api_request("funders", parameters, return_raw=raw) + return self._api_request("subject", parameters, return_raw=raw) def subjects(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False, @@ -511,53 +593,81 @@ def subjects(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("subjects", parameters, return_raw=raw) - def issues(self, limit: int = 100, offset: int = 0, order: str = None, - search: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } + def subject_count(self, subject_type: str = "", search: str = "", + raw: bool = False): + """Construct and trigger a query to count contribution count""" + parameters = {} if search and not search.startswith('"'): search = '"{0}"'.format(search) + # there is a bug in this version of Thoth. Filter is REQUIRED. + if not filter: + filter = '""' + + self._dictionary_append(parameters, 'subjectType', subject_type) self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) - self._dictionary_append(parameters, 'publishers', publishers) - return self._api_request("issues", parameters, return_raw=raw) + return self._api_request("subjectCount", parameters, return_raw=raw) - def publisher_count(self, search: str = "", publishers: str = None, - raw: bool = False): - """Construct and trigger a query to count publishers""" - parameters = {} + def works(self, limit: int = 100, offset: int = 0, search: str = "", + order: str = None, publishers: str = None, work_type: str = None, + work_status: str = None, raw: bool = False): + """ + Returns a works list + @param limit: the maximum number of results to return (default: 100) + @param order: a GraphQL order query statement + @param offset: the offset from which to retrieve results (default: 0) + @param publishers: a list of publishers to limit by + @param search: a filter string to search + @param work_type: the work type (e.g. MONOGRAPH) + @param work_status: the work status (e.g. ACTIVE) + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + if order is None: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } if search and not search.startswith('"'): search = '"{0}"'.format(search) self._dictionary_append(parameters, 'filter', search) + self._dictionary_append(parameters, 'order', order) self._dictionary_append(parameters, 'publishers', publishers) + self._dictionary_append(parameters, 'workType', work_type) + self._dictionary_append(parameters, 'workStatus', work_status) - return self._api_request("publisherCount", parameters, return_raw=raw) - - def price_count(self, currency_code: str = None, raw: bool = False): - """Construct and trigger a query to count publishers""" - parameters = {} - - self._dictionary_append(parameters, 'currencyCode', currency_code) + return self._api_request("works", parameters, return_raw=raw) - return self._api_request("priceCount", parameters, return_raw=raw) + def work_by_doi(self, doi: str, raw: bool = False): + """ + Returns a work by DOI + @param doi: the DOI to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'doi': '"' + doi + '"' + } - def imprint_count(self, search: str = "", publishers: str = None, - raw: bool = False): - """Construct and trigger a query to count publishers""" - parameters = {} + return self._api_request("workByDoi", parameters, return_raw=raw) - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'publishers', publishers) + def work_by_id(self, work_id: str, raw: bool = False): + """ + Returns a work by ID + @param work_id: the ID to fetch + @param raw: whether to return a python object or the raw server result + @return: either an object (default) or raw server response + """ + parameters = { + 'workId': '"' + work_id + '"' + } - return self._api_request("imprintCount", parameters, return_raw=raw) + return self._api_request("work", parameters, return_raw=raw) def work_count(self, search: str = "", publishers: str = None, work_type: str = None, work_status: str = None, @@ -574,113 +684,3 @@ def work_count(self, search: str = "", publishers: str = None, self._dictionary_append(parameters, 'workStatus', work_status) return self._api_request("workCount", parameters, return_raw=raw) - - def series_count(self, search: str = "", publishers: str = None, - series_type: str = None, raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'seriesType', - series_type) - - return self._api_request("seriesCount", parameters, return_raw=raw) - - def contribution_count(self, search: str = "", publishers: str = None, - contribution_type: str = None, raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'contributionType', - contribution_type) - - return self._api_request("contributionCount", parameters, - return_raw=raw) - - def publication_count(self, search: str = "", publishers: str = None, - publication_type: str = None, raw: bool = False): - """Construct and trigger a query to count publications""" - parameters = {} - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'publishers', publishers) - self._dictionary_append(parameters, 'publicationType', publication_type) - - return self._api_request("publicationCount", parameters, - return_raw=raw) - - def funder_count(self, search: str = "", raw: bool = False): - """Construct and trigger a query to count publications""" - parameters = {} - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - - return self._api_request("funderCount", parameters, return_raw=raw) - - def contributor_count(self, search: str = "", raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - - return self._api_request("contributorCount", parameters, - return_raw=raw) - - def language_count(self, language_code: str = "", - language_relation: str = "", raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - self._dictionary_append(parameters, 'languageCode', language_code) - self._dictionary_append(parameters, 'languageRelation', - language_relation) - - return self._api_request("languageCount", parameters, return_raw=raw) - - def subject_count(self, subject_type: str = "", search: str = "", - raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - # there is a bug in this version of Thoth. Filter is REQUIRED. - if not filter: - filter = '""' - - self._dictionary_append(parameters, 'subjectType', subject_type) - self._dictionary_append(parameters, 'filter', search) - - return self._api_request("subjectCount", parameters, return_raw=raw) - - def issue_count(self, raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - return self._api_request("issueCount", parameters, - return_raw=raw) - - def funding_count(self, raw: bool = False): - """Construct and trigger a query to count contribution count""" - parameters = {} - - return self._api_request("fundingCount", parameters, return_raw=raw) From 857bd184fe58c6cfbc46250d182e9e4312a6ab9c Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:39:50 +0100 Subject: [PATCH 095/115] Fix bug with subject_count --- thothlibrary/thoth-0_4_2/endpoints.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index ea526e5..9f64f8a 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -602,8 +602,8 @@ def subject_count(self, subject_type: str = "", search: str = "", search = '"{0}"'.format(search) # there is a bug in this version of Thoth. Filter is REQUIRED. - if not filter: - filter = '""' + if not search: + search = '""' self._dictionary_append(parameters, 'subjectType', subject_type) self._dictionary_append(parameters, 'filter', search) From 211881baa8b0d5677ebd9b12e1c9396f12ff0582 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:46:40 +0100 Subject: [PATCH 096/115] Deduplicate default parameter setup --- thothlibrary/client.py | 17 ++++ thothlibrary/thoth-0_4_2/endpoints.py | 116 +++++++------------------- 2 files changed, 49 insertions(+), 84 deletions(-) diff --git a/thothlibrary/client.py b/thothlibrary/client.py index d589ae4..73df802 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -154,6 +154,23 @@ def _build_structure(self, endpoint_name, data): return builder.create_structure() + @staticmethod + def _order_limit_filter_offset_setup(order, limit, search, offset): + if not order: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + if search and not search.startswith('"'): + search = '"{0}"'.format(search) + + ThothClient._dictionary_append(parameters, 'filter', search) + ThothClient._dictionary_append(parameters, 'order', order) + + return parameters + @staticmethod def _dictionary_append(input_dict, key, value): """ diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 9f64f8a..6f6d504 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -131,18 +131,10 @@ def contributors(self, limit: int = 100, offset: int = 0, @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ - if order is None: - order = {} - parameters = { - "offset": offset, - "limit": limit, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) return self._api_request("contributors", parameters, return_raw=raw) @@ -257,16 +249,10 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("imprints", parameters, return_raw=raw) @@ -297,16 +283,10 @@ def issue(self, issue_id: str, raw: bool = False): def issues(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("issues", parameters, return_raw=raw) @@ -335,16 +315,10 @@ def languages(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False, language_code: str = "", language_relation: str = ""): """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'languageCode', language_code) self._dictionary_append(parameters, 'languageRelation', @@ -438,18 +412,10 @@ def publications(self, limit: int = 100, offset: int = 0, @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response """ - if order is None: - order = {} - parameters = { - "offset": offset, - "limit": limit, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'publicationType', publication_type) @@ -487,16 +453,10 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False): """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) return self._api_request("publishers", parameters, return_raw=raw) @@ -531,16 +491,10 @@ def serieses(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, series_type: str = "", raw: bool = False): """Construct and trigger a query to obtain all serieses""" - parameters = { - "limit": limit, - "offset": offset, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'seriesType', series_type) @@ -578,16 +532,10 @@ def subjects(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False, subject_type: str = ""): """Construct and trigger a query to obtain all publishers""" - parameters = { - "limit": limit, - "offset": offset, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - self._dictionary_append(parameters, 'filter', search) - self._dictionary_append(parameters, 'order', order) + parameters = self._order_limit_filter_offset_setup(order=order, + search=search, + limit=limit, + offset=offset) self._dictionary_append(parameters, 'publishers', publishers) self._dictionary_append(parameters, 'subjectType', subject_type) From eb538582f276f60bbd0a32728bf262a081ac397f Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 19:48:03 +0100 Subject: [PATCH 097/115] Move helper class to version-specific client --- thothlibrary/client.py | 17 ----------------- thothlibrary/thoth-0_4_2/endpoints.py | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/thothlibrary/client.py b/thothlibrary/client.py index 73df802..d589ae4 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -154,23 +154,6 @@ def _build_structure(self, endpoint_name, data): return builder.create_structure() - @staticmethod - def _order_limit_filter_offset_setup(order, limit, search, offset): - if not order: - order = {} - parameters = { - "offset": offset, - "limit": limit, - } - - if search and not search.startswith('"'): - search = '"{0}"'.format(search) - - ThothClient._dictionary_append(parameters, 'filter', search) - ThothClient._dictionary_append(parameters, 'order', order) - - return parameters - @staticmethod def _dictionary_append(input_dict, key, value): """ diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 6f6d504..24a1c16 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -50,6 +50,23 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): super().__init__(thoth_endpoint=thoth_endpoint, version=version) + @staticmethod + def _order_limit_filter_offset_setup(order, limit, search, offset): + if not order: + order = {} + parameters = { + "offset": offset, + "limit": limit, + } + + if search and not search.startswith('"'): + search = '"{0}"'.format(search) + + ThothClient._dictionary_append(parameters, 'filter', search) + ThothClient._dictionary_append(parameters, 'order', order) + + return parameters + def contribution(self, contribution_id: str, raw: bool = False): """ Returns a contribution by ID From ec8e9b3b0523212c6db2601ccac56424e87f07d5 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 20:11:14 +0100 Subject: [PATCH 098/115] Add full docstrings to endpoints --- thothlibrary/thoth-0_4_2/endpoints.py | 265 ++++++++++++++++++++------ 1 file changed, 209 insertions(+), 56 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 24a1c16..882bdd2 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -18,7 +18,8 @@ class ThothClient0_4_2(ThothClient): def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """ Creates an instance of Thoth 0.4.2 endpoints - @param input_class: the ThothClient instance to be versioned + @param thoth_endpoint: the Thoth API instance endpoint + @param version: the version of the Thoth API to use """ # the QUERIES field defines the fields that GraphQL will return @@ -52,6 +53,15 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): @staticmethod def _order_limit_filter_offset_setup(order, limit, search, offset): + """ + The default setup for this version. Many methods use order, limit, + filter, and offset as parameters, so this de-duplicates that code. + @param order: the order + @param limit: the limit + @param search: the search + @param offset: the offset + @return: a parameters dictionary + """ if not order: order = {} parameters = { @@ -71,7 +81,7 @@ def contribution(self, contribution_id: str, raw: bool = False): """ Returns a contribution by ID @param contribution_id: the contribution ID - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -85,9 +95,9 @@ def contributions(self, limit: int = 100, offset: int = 0, contribution_type: str = None, raw: bool = False): """ Returns a contributions list - @param limit: the maximum number of results to return (default: 100) + @param limit: the maximum number of results to return @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) + @param offset: the offset from which to retrieve results @param publishers: a list of publishers to limit by @param contribution_type: the contribution type (e.g. AUTHOR) @param raw: whether to return a python object or the raw server result @@ -109,7 +119,14 @@ def contributions(self, limit: int = 100, offset: int = 0, def contribution_count(self, search: str = "", publishers: str = None, contribution_type: str = None, raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + Returns a count of contributions + @param search: a search string + @param publishers: a list of publishers + @param contribution_type: a contribution type (e.g. AUTHOR) + @param raw: whether to return a raw result + @return: a count of contributions + """ parameters = {} if search and not search.startswith('"'): @@ -127,7 +144,7 @@ def contributor(self, contributor_id: str, raw: bool = False): """ Returns a contributor by ID @param contributor_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -140,12 +157,12 @@ def contributors(self, limit: int = 100, offset: int = 0, search: str = "", order: str = None, raw: bool = False): """ - Returns a contributions list - @param limit: the maximum number of results to return (default: 100) + Returns contributors + @param limit: the maximum number of results to return @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) + @param offset: the offset from which to retrieve results @param search: a filter string to search - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = self._order_limit_filter_offset_setup(order=order, @@ -156,7 +173,12 @@ def contributors(self, limit: int = 100, offset: int = 0, return self._api_request("contributors", parameters, return_raw=raw) def contributor_count(self, search: str = "", raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + Return a count of contributors + @param search: a search string + @param raw: whether to return the raw result + @return: a count of contributors + """ parameters = {} if search and not search.startswith('"'): @@ -171,7 +193,7 @@ def funder(self, funder_id: str, raw: bool = False): """ Returns a funder by ID @param funder_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -182,7 +204,16 @@ def funder(self, funder_id: str, raw: bool = False): def funders(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", raw: bool = False): - """Construct and trigger a query to obtain all funders""" + """ + Return funders + @param limit: the limit on the number of results + @param offset: the offset from which to start + @param order: the order of results + @param search: a search string + @param raw: whether to return raw result + @return: an object or raw result + """ + parameters = { "limit": limit, "offset": offset, @@ -197,7 +228,12 @@ def funders(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("funders", parameters, return_raw=raw) def funder_count(self, search: str = "", raw: bool = False): - """Construct and trigger a query to count publications""" + """ + A count of funders + @param search: a search string + @param raw: whether to return raw result + @return: a count of funders + """ parameters = {} if search and not search.startswith('"'): @@ -211,7 +247,7 @@ def funding(self, funding_id: str, raw: bool = False): """ Returns a funding by ID @param funding_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -224,9 +260,9 @@ def fundings(self, limit: int = 100, offset: int = 0, order: str = None, publishers: str = None, raw: bool = False): """ Returns a fundings list - @param limit: the maximum number of results to return (default: 100) + @param limit: the maximum number of results to return @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) + @param offset: the offset from which to retrieve results @param publishers: a list of publishers to limit by @param raw: whether to return a python object or the raw server result @return: either an object (default) or raw server response @@ -244,16 +280,20 @@ def fundings(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("fundings", parameters, return_raw=raw) def funding_count(self, raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + A count of fundings + @param raw: whether to return a raw result + @return: a count of fundings + """ parameters = {} return self._api_request("fundingCount", parameters, return_raw=raw) def imprint(self, imprint_id: str, raw: bool = False): """ - Returns a work by DOI + Return an imprint @param imprint_id: the imprint - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -265,7 +305,16 @@ def imprint(self, imprint_id: str, raw: bool = False): def imprints(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to obtain all publishers""" + """ + Return imprints + @param limit: the limit on the number of results returned + @param offset: the offset from which to begin + @param order: the order in which to present results + @param search: a search string + @param publishers: a list of publishers by which to limit the query + @param raw: whether to return a raw result + @return: an object or raw result + """ parameters = self._order_limit_filter_offset_setup(order=order, search=search, limit=limit, @@ -276,7 +325,13 @@ def imprints(self, limit: int = 100, offset: int = 0, order: str = None, def imprint_count(self, search: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to count publishers""" + """ + A count of imprints + @param search: a search string + @param publishers: a list of publishers by which to limit the result + @param raw: whether to return a raw result + @return: a count of imprints + """ parameters = {} self._dictionary_append(parameters, 'filter', search) @@ -287,8 +342,8 @@ def imprint_count(self, search: str = "", publishers: str = None, def issue(self, issue_id: str, raw: bool = False): """ Returns an issue by ID - @param issue_id: the imprint - @param raw: whether to return a python object or the raw server result + @param issue_id: the issue + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -299,7 +354,16 @@ def issue(self, issue_id: str, raw: bool = False): def issues(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to obtain all publishers""" + """ + Return issues + @param limit: the limit on the number of results to return + @param offset: the offset from which to begin + @param order: the order in which to return results + @param search: a search string + @param publishers: a list of publishers by which to limit results + @param raw: whether to return a raw response + @return: an object or raw response + """ parameters = self._order_limit_filter_offset_setup(order=order, search=search, limit=limit, @@ -309,7 +373,11 @@ def issues(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("issues", parameters, return_raw=raw) def issue_count(self, raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + A count of issues + @param raw: whether to return a raw result + @return: a count of issues + """ parameters = {} return self._api_request("issueCount", parameters, @@ -317,9 +385,9 @@ def issue_count(self, raw: bool = False): def language(self, language_id: str, raw: bool = False): """ - Returns a series by ID + Returns a language by ID @param language_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -331,7 +399,18 @@ def language(self, language_id: str, raw: bool = False): def languages(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False, language_code: str = "", language_relation: str = ""): - """Construct and trigger a query to obtain all publishers""" + """ + Return languages + @param limit: the limit on the number of results to return + @param offset: the offset from which to begin + @param order: the order in which to return results + @param search: a search string + @param publishers: a list of publishers by which to limit the result + @param raw: whether to return a raw result + @param language_code: the language code to query + @param language_relation: the language relation to query (e.g. ORIGINAL) + @return: an object or raw result + """ parameters = self._order_limit_filter_offset_setup(order=order, search=search, limit=limit, @@ -345,7 +424,13 @@ def languages(self, limit: int = 100, offset: int = 0, order: str = None, def language_count(self, language_code: str = "", language_relation: str = "", raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + A count of languages + @param language_code: a language code (e.g. CHI) + @param language_relation: a language relation (e.g. ORIGINAL) + @param raw: whether to return a raw result + @return: a count of languages + """ parameters = {} self._dictionary_append(parameters, 'languageCode', language_code) @@ -358,7 +443,7 @@ def price(self, price_id: str, raw: bool = False): """ Returns a price by ID @param price_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -371,10 +456,10 @@ def prices(self, limit: int = 100, offset: int = 0, order: str = None, publishers: str = None, currency_code: str = None, raw: bool = False): """ - Returns a price list - @param limit: the maximum number of results to return (default: 100) + Returns prices + @param limit: the maximum number of results to return @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) + @param offset: the offset from which to retrieve results @param publishers: a list of publishers to limit by @param currency_code: the currency code (e.g. GBP) @param raw: whether to return a python object or the raw server result @@ -394,7 +479,12 @@ def prices(self, limit: int = 100, offset: int = 0, order: str = None, return self._api_request("prices", parameters, return_raw=raw) def price_count(self, currency_code: str = None, raw: bool = False): - """Construct and trigger a query to count publishers""" + """ + A count of prices + @param currency_code: a currency code (e.g. GBP) + @param raw: whether to return a raw result + @return: a count of prices + """ parameters = {} self._dictionary_append(parameters, 'currencyCode', currency_code) @@ -405,7 +495,7 @@ def publication(self, publication_id: str, raw: bool = False): """ Returns a publication by ID @param publication_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -419,10 +509,10 @@ def publications(self, limit: int = 100, offset: int = 0, publishers: str = None, publication_type: str = None, raw: bool = False): """ - Returns a publications list - @param limit: the maximum number of results to return (default: 100) + Returns publications + @param limit: the maximum number of results to return @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) + @param offset: the offset from which to retrieve results @param publishers: a list of publishers to limit by @param search: a filter string to search @param publication_type: the work type (e.g. PAPERBACK) @@ -440,7 +530,14 @@ def publications(self, limit: int = 100, offset: int = 0, def publication_count(self, search: str = "", publishers: str = None, publication_type: str = None, raw: bool = False): - """Construct and trigger a query to count publications""" + """ + A count of publications + @param search: a search string + @param publishers: a list of publishers by which to limit the result + @param publication_type: the publication type (e.g. PAPERBACK) + @param raw: whether to return a raw result + @return: a count of publications + """ parameters = {} if search and not search.startswith('"'): @@ -455,9 +552,9 @@ def publication_count(self, search: str = "", publishers: str = None, def publisher(self, publisher_id: str, raw: bool = False): """ - Returns a work by DOI + Returns a publisher by ID @param publisher_id: the publisher - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -469,7 +566,16 @@ def publisher(self, publisher_id: str, raw: bool = False): def publishers(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to obtain all publishers""" + """ + Return publishers + @param limit: the limit on the number of results + @param offset: the offset from which to begin + @param order: the order for the returned results + @param search: a search string + @param publishers: a list of publishers by which to limit the results + @param raw: whether to return a raw result + @return: an object or raw result + """ parameters = self._order_limit_filter_offset_setup(order=order, search=search, limit=limit, @@ -480,7 +586,13 @@ def publishers(self, limit: int = 100, offset: int = 0, order: str = None, def publisher_count(self, search: str = "", publishers: str = None, raw: bool = False): - """Construct and trigger a query to count publishers""" + """ + Return a count of publishers + @param search: a search string + @param publishers: a list of publishers by which to limit the result + @param raw: whether to return a raw result + @return: a count of publishers + """ parameters = {} if search and not search.startswith('"'): @@ -495,7 +607,7 @@ def series(self, series_id: str, raw: bool = False): """ Returns a series by ID @param series_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -507,7 +619,17 @@ def series(self, series_id: str, raw: bool = False): def serieses(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, series_type: str = "", raw: bool = False): - """Construct and trigger a query to obtain all serieses""" + """ + Return serieses + @param limit: the limit on the number of results to retrieve + @param offset: the offset from which to start + @param order: the order in which to present the results + @param search: a search string + @param publishers: a list of publishers by which to limit results + @param series_type: the series type (e.g. BOOK_SERIES) + @param raw: whether to return a raw result + @return: an object or raw result + """ parameters = self._order_limit_filter_offset_setup(order=order, search=search, limit=limit, @@ -519,7 +641,14 @@ def serieses(self, limit: int = 100, offset: int = 0, order: str = None, def series_count(self, search: str = "", publishers: str = None, series_type: str = None, raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + Return a count of serieses + @param search: a search string + @param publishers: a list of publishers by which to limit the results + @param series_type: the type of series (e.g. BOOK_SERIES) + @param raw: whether to return a raw result + @return: a count of serieses + """ parameters = {} if search and not search.startswith('"'): @@ -536,7 +665,7 @@ def subject(self, subject_id: str, raw: bool = False): """ Returns a subject by ID @param subject_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -548,7 +677,17 @@ def subject(self, subject_id: str, raw: bool = False): def subjects(self, limit: int = 100, offset: int = 0, order: str = None, search: str = "", publishers: str = None, raw: bool = False, subject_type: str = ""): - """Construct and trigger a query to obtain all publishers""" + """ + Return subjects + @param limit: a limit on the number of results + @param offset: the offset from which to retrieve results + @param order: the order in which to present results + @param search: a search string + @param publishers: a list of publishers + @param raw: whether to return a raw result + @param subject_type: the subject type (e.g. BIC) + @return: subjects + """ parameters = self._order_limit_filter_offset_setup(order=order, search=search, limit=limit, @@ -560,7 +699,13 @@ def subjects(self, limit: int = 100, offset: int = 0, order: str = None, def subject_count(self, subject_type: str = "", search: str = "", raw: bool = False): - """Construct and trigger a query to count contribution count""" + """ + A count of subjects + @param subject_type: the type of subject + @param search: a search string + @param raw: whether to return a raw result + @return: a count of subjects + """ parameters = {} if search and not search.startswith('"'): @@ -579,10 +724,10 @@ def works(self, limit: int = 100, offset: int = 0, search: str = "", order: str = None, publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): """ - Returns a works list - @param limit: the maximum number of results to return (default: 100) + Returns works + @param limit: the maximum number of results to return @param order: a GraphQL order query statement - @param offset: the offset from which to retrieve results (default: 0) + @param offset: the offset from which to retrieve results @param publishers: a list of publishers to limit by @param search: a filter string to search @param work_type: the work type (e.g. MONOGRAPH) @@ -612,7 +757,7 @@ def work_by_doi(self, doi: str, raw: bool = False): """ Returns a work by DOI @param doi: the DOI to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -625,7 +770,7 @@ def work_by_id(self, work_id: str, raw: bool = False): """ Returns a work by ID @param work_id: the ID to fetch - @param raw: whether to return a python object or the raw server result + @param raw: whether to return a python object or the raw result @return: either an object (default) or raw server response """ parameters = { @@ -637,7 +782,15 @@ def work_by_id(self, work_id: str, raw: bool = False): def work_count(self, search: str = "", publishers: str = None, work_type: str = None, work_status: str = None, raw: bool = False): - """Construct and trigger a query to count works""" + """ + A count of works + @param search: a search string + @param publishers: a list of publishers by which to limit results + @param work_type: the work type (e.g. MONOGRAPH) + @param work_status: the work status (e.g. ACTIVE) + @param raw: whether to return a raw result + @return: a count of works + """ parameters = {} if search and not search.startswith('"'): From e9294c890f048d845d4d612734c7ab03947f576c Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 20:13:40 +0100 Subject: [PATCH 099/115] Fix updated query to use requests --- thothlibrary/query.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index edece5b..320ef62 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -9,7 +9,8 @@ import json -import urllib + +import requests from .errors import ThothError @@ -66,7 +67,8 @@ def run(self, client): return result return json.loads(result)["data"][self.query_name] except (KeyError, TypeError, ValueError, AssertionError, - json.decoder.JSONDecodeError, urllib.error.HTTPError): + json.decoder.JSONDecodeError, + requests.exceptions.RequestException): raise ThothError(self.request, result) def prepare_parameters(self): From a6694943021f5f8bd3d855c4e52194c724423d96 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Mon, 9 Aug 2021 21:20:59 +0100 Subject: [PATCH 100/115] Update magic class delegation --- thothlibrary/cli.py | 276 ++++++-------------------- thothlibrary/client.py | 30 ++- thothlibrary/thoth-0_4_2/endpoints.py | 25 +-- 3 files changed, 81 insertions(+), 250 deletions(-) diff --git a/thothlibrary/cli.py b/thothlibrary/cli.py index 3900c3a..853a3fa 100644 --- a/thothlibrary/cli.py +++ b/thothlibrary/cli.py @@ -6,6 +6,9 @@ import json import fire +from graphqlclient import GraphQLClient + +import thothlibrary def _raw_parse(value): @@ -41,6 +44,25 @@ def _client(self): from .client import ThothClient return ThothClient(version=self.version, thoth_endpoint=self.endpoint) + def _override_version(self, endpoint, version): + """ + Allow an override of the version and endpoint on any request method + @param endpoint: the Thoth endpoint + @param version: the API version + @return: None + """ + if endpoint: + self.endpoint = endpoint + + if version: + self.version = version + + self.thoth_endpoint = self.endpoint + self.auth_endpoint = "{}/account/login".format(self.endpoint) + self.graphql_endpoint = "{}/graphql".format(self.endpoint) + self.client = GraphQLClient(self.graphql_endpoint) + self.version = self.version.replace('.', '_') + @fire.decorators.SetParseFn(_raw_parse) def contribution(self, contribution_id, raw=False, version=None, endpoint=None, serialize=False): @@ -52,11 +74,7 @@ def contribution(self, contribution_id, raw=False, version=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) contribution = self._client().contribution( contribution_id=contribution_id, raw=raw) @@ -82,11 +100,7 @@ def contributions(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) contribs = self._client().contributions( limit=limit, order=order, offset=offset, publishers=publishers, @@ -112,11 +126,7 @@ def contribution_count(self, publishers=None, search=None, raw=False, :param str endpoint: a custom Thoth endpoint """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().contribution_count( publishers=publishers, search=search, @@ -133,11 +143,7 @@ def contributor(self, contributor_id, raw=False, version=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) contributor = self._client().contributor(contributor_id=contributor_id, raw=raw) @@ -161,11 +167,7 @@ def contributors(self, limit=100, order=None, offset=0, search=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) contribs = self._client().contributors(limit=limit, order=order, offset=offset, @@ -190,11 +192,7 @@ def contributor_count(self, search=None, raw=False, version=None, :param str endpoint: a custom Thoth endpoint """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().contributor_count(search=search, raw=raw)) @@ -209,11 +207,7 @@ def funder(self, funder_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) funder = self._client().funder(funder_id=funder_id, raw=raw) @@ -236,12 +230,7 @@ def funders(self, limit=100, order=None, offset=0, search=None, raw=False, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) funders = self._client().funders(limit=limit, order=order, offset=offset, search=search, raw=raw) @@ -262,12 +251,7 @@ def funder_count(self, search=None, raw=False, version=None, endpoint=None): :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().funder_count(search=search, raw=raw)) @@ -282,11 +266,7 @@ def funding(self, funding_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) funding = self._client().funding(funding_id=funding_id, raw=raw) @@ -309,12 +289,7 @@ def fundings(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) fundings = self._client().fundings(limit=limit, order=order, offset=offset, publishers=publishers, @@ -335,12 +310,7 @@ def funding_count(self, raw=False, version=None, endpoint=None): :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().funding_count(raw=raw)) @@ -355,11 +325,7 @@ def imprint(self, imprint_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) imprint = self._client().imprint(imprint_id=imprint_id, raw=raw) @@ -384,12 +350,7 @@ def imprints(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) imprints = self._client().imprints(limit=limit, order=order, offset=offset, @@ -415,12 +376,7 @@ def imprint_count(self, publishers=None, search=None, raw=False, :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().imprint_count(publishers=publishers, search=search, @@ -437,11 +393,7 @@ def issue(self, issue_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) issue = self._client().issue(issue_id=issue_id, raw=raw) @@ -466,12 +418,7 @@ def issues(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) issues = self._client().issues(limit=limit, order=order, offset=offset, @@ -494,12 +441,7 @@ def issue_count(self, raw=False, version=None, endpoint=None): :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().issue_count(raw=raw)) @@ -514,11 +456,7 @@ def language(self, language_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) lang = self._client().language(language_id=language_id, raw=raw) @@ -545,12 +483,7 @@ def languages(self, limit=100, order=None, offset=0, publishers=None, :param language_relation: select by language relation (e.g. ORIGINAL) :param language_code: select by language code (e.g. ADA) """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) langs = self._client().languages(limit=limit, order=order, offset=offset, @@ -578,12 +511,7 @@ def language_count(self, language_code=None, raw=False, version=None, :param language_code: the code to retrieve (e.g. CHI) :param language_relation: the relation (e.g. ORIGINAL) """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().language_count(language_code=language_code, language_relation=language_relation, @@ -600,11 +528,7 @@ def price(self, price_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) price = self._client().price(price_id=price_id, raw=raw) @@ -629,12 +553,7 @@ def prices(self, limit=100, order=None, offset=0, publishers=None, :param bool serialize: return a pickled python object :param str currency_code: the currency code (e.g. GBP) """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) prices = self._client().prices(limit=limit, order=order, offset=offset, @@ -659,12 +578,7 @@ def price_count(self, currency_code=None, raw=False, version=None, :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().price_count(currency_code=currency_code, raw=raw)) @@ -679,11 +593,7 @@ def publication(self, publication_id, raw=False, :param bool serialize: return a pickled python object :param str publication_id: a publicationId to retrieve """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) publication = self._client().publication(publication_id=publication_id, raw=raw) @@ -710,11 +620,7 @@ def publications(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) pubs = self._client().publications(limit=limit, order=order, offset=offset, publishers=publishers, @@ -740,12 +646,7 @@ def publication_count(self, publishers=None, search=None, raw=False, :param str publication_type: the work type (e.g. MONOGRAPH) :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().publication_count( publishers=publishers, search=search, @@ -762,11 +663,7 @@ def publisher(self, publisher_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) publisher = self._client().publisher(publisher_id=publisher_id, raw=raw) @@ -791,12 +688,7 @@ def publishers(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) found_publishers = self._client().publishers(limit=limit, order=order, offset=offset, @@ -822,12 +714,7 @@ def publisher_count(self, publishers=None, search=None, raw=False, :param str version: a custom Thoth version :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().publisher_count(publishers=publishers, search=search, @@ -844,11 +731,7 @@ def series(self, series_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) series = self._client().series(series_id=series_id, raw=raw) @@ -874,12 +757,7 @@ def serieses(self, limit=100, order=None, offset=0, publishers=None, :param bool serialize: return a pickled python object :param series_type: the type of serieses to return (e.g. BOOK_SERIES) """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) serieses = self._client().serieses(limit=limit, order=order, offset=offset, @@ -907,12 +785,7 @@ def series_count(self, publishers=None, search=None, raw=False, :param str series_type: the work type (e.g. BOOK_SERIES) :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().series_count(publishers=publishers, search=search, series_type=series_type, raw=raw)) @@ -928,11 +801,7 @@ def subject(self, subject_id, raw=False, version=None, endpoint=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) subj = self._client().subject(subject_id=subject_id, raw=raw) @@ -958,12 +827,7 @@ def subjects(self, limit=100, order=None, offset=0, publishers=None, :param bool serialize: return a pickled python object :param subject_type: select by subject code (e.g. BIC) """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) subj = self._client().subjects(limit=limit, order=order, offset=offset, @@ -990,12 +854,7 @@ def subject_count(self, subject_type=None, raw=False, version=None, :param str subject_type: the type to retrieve (e.g. BIC) :param str search: a search """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().subject_count(subject_type=subject_type, search=search, raw=raw)) @@ -1020,11 +879,7 @@ def work(self, doi=None, work_id=None, raw=False, version=None, :param str work_id: a workId to retrieve :param bool cover_ascii: whether to render an ASCII art cover """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) if not doi and not work_id: print("You must specify either workId or doi.") @@ -1063,11 +918,7 @@ def works(self, limit=100, order=None, offset=0, publishers=None, :param str endpoint: a custom Thoth endpoint :param bool serialize: return a pickled python object """ - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) works = self._client().works(limit=limit, order=order, offset=offset, publishers=publishers, @@ -1097,12 +948,7 @@ def work_count(self, publishers=None, search=None, raw=False, :param str work_status: the work status (e.g. ACTIVE) :param str endpoint: a custom Thoth endpoint """ - - if endpoint: - self.endpoint = endpoint - - if version: - self.version = version + self._override_version(version=version, endpoint=endpoint) print(self._client().work_count(publishers=publishers, search=search, diff --git a/thothlibrary/client.py b/thothlibrary/client.py index d589ae4..6d73531 100644 --- a/thothlibrary/client.py +++ b/thothlibrary/client.py @@ -19,6 +19,19 @@ class ThothClient: """Client to Thoth's GraphQL API""" + def __new__(cls, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): + # this new call is the only bit of "magic" + # it basically subs in the sub-class of the correct version and returns + # an instance of that, instead of the generic class + version_replaced = version.replace('.', '_') + module = 'thothlibrary.thoth-{0}.endpoints'.format(version_replaced) + endpoints = importlib.import_module(module) + + version_endpoints = getattr( + endpoints, 'ThothClient{0}'.format(version_replaced)) + + return version_endpoints(thoth_endpoint=thoth_endpoint, version=version) + def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """Returns new ThothClient object at the specified GraphQL endpoint @@ -30,23 +43,6 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): self.client = GraphQLClient(self.graphql_endpoint) self.version = version.replace('.', '_') - # this is the only 'magic' part for queries - # it wires up the methods named in 'endpoints' list of a versioned - # subclass (e.g. thoth_0_4_2) to this class, thereby providing the - # methods that can be called for any API version - if issubclass(ThothClient, type(self)): - module = 'thothlibrary.thoth-{0}.endpoints'.format(self.version) - endpoints = importlib.import_module(module) - - version_endpoints = getattr( - endpoints, 'ThothClient{0}'.format(self.version))( - version=version, thoth_endpoint=thoth_endpoint) - - [setattr(self, - x, - getattr(version_endpoints, - x)) for x in version_endpoints.endpoints] - def login(self, email, password): """Obtain an authentication token""" auth = ThothAuthenticator(self.auth_endpoint, email, password) diff --git a/thothlibrary/thoth-0_4_2/endpoints.py b/thothlibrary/thoth-0_4_2/endpoints.py index 882bdd2..205c1ee 100644 --- a/thothlibrary/thoth-0_4_2/endpoints.py +++ b/thothlibrary/thoth-0_4_2/endpoints.py @@ -7,6 +7,7 @@ import os import pathlib +import thothlibrary from thothlibrary.client import ThothClient @@ -15,12 +16,17 @@ class ThothClient0_4_2(ThothClient): The client for Thoth 0.4.2 """ + def __new__(cls, *args, **kwargs): + return super(thothlibrary.ThothClient, ThothClient0_4_2).__new__(cls) + def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): """ Creates an instance of Thoth 0.4.2 endpoints @param thoth_endpoint: the Thoth API instance endpoint @param version: the version of the Thoth API to use """ + if hasattr(self, 'client'): + return # the QUERIES field defines the fields that GraphQL will return # note: every query should contain the field "__typename" if auto-object @@ -32,24 +38,7 @@ def __init__(self, thoth_endpoint="https://api.thoth.pub", version="0.4.2"): with open(path, 'r') as query_file: self.QUERIES = json.loads(query_file.read()) - # this list should specify all API endpoints by method name in this - # class. Note, it should always, also, contain the QUERIES list - self.endpoints = ['works', 'work_by_doi', 'work_by_id', - 'publishers', 'publisher', 'publications', - 'contributions', 'contribution', 'publisher_count', - 'contribution_count', 'work_count', - 'publication_count', 'publication', 'imprints', - 'imprint', 'imprint_count', 'contributors', - 'contributor', 'contributor_count', 'serieses', - 'series', 'series_count', 'issues', - 'issue', 'issue_count', 'languages', 'language', - 'language_count', 'prices', 'price', 'price_count', - 'subjects', 'subject', 'subject_count', 'funders', - 'funder', 'funder_count', 'fundings', 'funding', - 'funding_count', 'QUERIES'] - - super().__init__(thoth_endpoint=thoth_endpoint, - version=version) + super().__init__(thoth_endpoint=thoth_endpoint, version=version) @staticmethod def _order_limit_filter_offset_setup(order, limit, search, offset): From efb7f19b9cabaa522a1de86f125bc060926b341f Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 15 Aug 2021 12:28:39 +0100 Subject: [PATCH 101/115] Add additional fields to Work-related queries --- thothlibrary/thoth-0_4_2/fixtures/QUERIES | 6 +++--- thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/work.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/works.json | 2 +- thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/fixtures/QUERIES b/thothlibrary/thoth-0_4_2/fixtures/QUERIES index d855607..40b9fc8 100644 --- a/thothlibrary/thoth-0_4_2/fixtures/QUERIES +++ b/thothlibrary/thoth-0_4_2/fixtures/QUERIES @@ -513,7 +513,7 @@ "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ], @@ -555,7 +555,7 @@ "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ], @@ -605,7 +605,7 @@ "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution contributionOrdinal __typename }", + "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ], diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json index 3b86458..eaba1cb 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.json @@ -1 +1 @@ -{"data":{"contributor":{"contributorId":"e8def8cf-0dfe-4da9-b7fa-f77e7aec7524","firstName":"Martin Paul","lastName":"Eve","fullName":"Martin Paul Eve","orcid":"https://orcid.org/0000-0002-5589-8511","__typename":"Contributor","contributions":[{"contributionId":"4f1718e2-6ff3-4f65-a1bc-870da9f4ae9d","contributionType":"AUTHOR","work":{"workId":"9845c8a9-b283-4cb8-8961-d41e5fe795f1","fullTitle":"Literature Against Criticism: University English and Contemporary Fiction in Conflict"}}]}}} +{"data":{"contributor":{"contributorId":"e8def8cf-0dfe-4da9-b7fa-f77e7aec7524","firstName":"Martin Paul","lastName":"Eve","fullName":"Martin Paul Eve","orcid":"https://orcid.org/0000-0002-5589-8511","__typename":"Contributor","contributions":[{"contributionId":"4f1718e2-6ff3-4f65-a1bc-870da9f4ae9d","contributionType":"AUTHOR","work":{"workId":"9845c8a9-b283-4cb8-8961-d41e5fe795f1","fullTitle":"Literature Against Criticism: University English and Contemporary Fiction in Conflict"}},{"contributionId":"3c02574a-8a88-463a-87fa-2df120b2229b","contributionType":"EDITOR","work":{"workId":"b904a8eb-9c98-4bb1-bf25-3cb9d075b157","fullTitle":"Warez: The Infrastructure and Aesthetics of Piracy"}}]}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle index 5703b40..7a6a728 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/contributor.pickle @@ -1 +1 @@ -{"contributorId": "e8def8cf-0dfe-4da9-b7fa-f77e7aec7524", "firstName": "Martin Paul", "lastName": "Eve", "fullName": "Martin Paul Eve", "orcid": "https://orcid.org/0000-0002-5589-8511", "__typename": "Contributor", "contributions": [{"contributionId": "4f1718e2-6ff3-4f65-a1bc-870da9f4ae9d", "contributionType": "AUTHOR", "work": {"workId": "9845c8a9-b283-4cb8-8961-d41e5fe795f1", "fullTitle": "Literature Against Criticism: University English and Contemporary Fiction in Conflict"}}]} +{"contributorId": "e8def8cf-0dfe-4da9-b7fa-f77e7aec7524", "firstName": "Martin Paul", "lastName": "Eve", "fullName": "Martin Paul Eve", "orcid": "https://orcid.org/0000-0002-5589-8511", "__typename": "Contributor", "contributions": [{"contributionId": "4f1718e2-6ff3-4f65-a1bc-870da9f4ae9d", "contributionType": "AUTHOR", "work": {"workId": "9845c8a9-b283-4cb8-8961-d41e5fe795f1", "fullTitle": "Literature Against Criticism: University English and Contemporary Fiction in Conflict"}}, {"contributionId": "3c02574a-8a88-463a-87fa-2df120b2229b", "contributionType": "EDITOR", "work": {"workId": "b904a8eb-9c98-4bb1-bf25-3cb9d075b157", "fullTitle": "Warez: The Infrastructure and Aesthetics of Piracy"}}]} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json index e531da5..fa97750 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.json @@ -1 +1 @@ -{"data":{"imprint":{"imprintUrl":"https://punctumbooks.com/imprints/3ecologies-books/","imprintId":"78b0a283-9be3-4fed-a811-a7d4b9df7b25","imprintName":"3Ecologies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9","fullTitle":"A Manga Perfeita","doi":"https://doi.org/10.21983/P3.0270.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Christine Greiner","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Ernesto Filho","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"c3d008a2-b357-4886-acc4-a2c77f1749ee","fullTitle":"Last Year at Betty and Bob's: An Actual Occasion","doi":"https://doi.org/10.53288/0363.1.00","publicationDate":"2021-07-08","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"781b77bd-edf8-4688-937d-cc7cc47de89f","fullTitle":"Last Year at Betty and Bob's: An Adventure","doi":"https://doi.org/10.21983/P3.0234.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ce38f309-4438-479f-bd1c-b3690dbd7d8d","fullTitle":"Last Year at Betty and Bob's: A Novelty","doi":"https://doi.org/10.21983/P3.0233.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"edf31616-ea2a-4c51-b932-f510b9eb8848","fullTitle":"No Archive Will Restore You","doi":"https://doi.org/10.21983/P3.0231.1.00","publicationDate":"2018-11-13","place":"Earth, Milky Way","contributions":[{"fullName":"Julietta Singh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d4a3f6cb-3023-4088-a5f4-147fb4510874","fullTitle":"Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Matthew Goulish","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Will Dadario","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d9045f8-1d8f-479c-983d-383f3a289bec","fullTitle":"Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art","doi":"https://doi.org/10.21983/P3.0327.1.00","publicationDate":"2021-02-18","place":"Earth, Milky Way","contributions":[{"fullName":"Curt Cloninger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ffa5c5dd-ab4b-4739-8281-275d8c1fb504","fullTitle":"Sweet Spots: Writing the Connective Tissue of Relation","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mattie-Martha Sempert","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"757ff294-0fca-40f5-9f33-39a2d3fd5c8a","fullTitle":"Teaching Myself To See","doi":"https://doi.org/10.21983/P3.0303.1.00","publicationDate":"2021-02-11","place":"Earth, Milky Way","contributions":[{"fullName":"Tito Mukhopadhyay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}]},{"workId":"571255b8-5bf5-4fe1-a201-5bc7aded7f9d","fullTitle":"The Perfect Mango","doi":"https://doi.org/10.21983/P3.0245.1.00","publicationDate":"2019-02-20","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4cfb06e-a5a6-48cc-b7e5-c38228c132a8","fullTitle":"The Unnaming of Aliass","doi":"https://doi.org/10.21983/P3.0299.1.00","publicationDate":"2020-10-01","place":"Earth, Milky Way","contributions":[{"fullName":"Karin Bolender","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"}}} +{"data":{"imprint":{"imprintUrl":"https://punctumbooks.com/imprints/3ecologies-books/","imprintId":"78b0a283-9be3-4fed-a811-a7d4b9df7b25","imprintName":"3Ecologies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9","fullTitle":"A Manga Perfeita","doi":"https://doi.org/10.21983/P3.0270.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Christine Greiner","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Ernesto Filho","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"c3d008a2-b357-4886-acc4-a2c77f1749ee","fullTitle":"Last Year at Betty and Bob's: An Actual Occasion","doi":"https://doi.org/10.53288/0363.1.00","publicationDate":"2021-07-08","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"781b77bd-edf8-4688-937d-cc7cc47de89f","fullTitle":"Last Year at Betty and Bob's: An Adventure","doi":"https://doi.org/10.21983/P3.0234.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ce38f309-4438-479f-bd1c-b3690dbd7d8d","fullTitle":"Last Year at Betty and Bob's: A Novelty","doi":"https://doi.org/10.21983/P3.0233.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"edf31616-ea2a-4c51-b932-f510b9eb8848","fullTitle":"No Archive Will Restore You","doi":"https://doi.org/10.21983/P3.0231.1.00","publicationDate":"2018-11-13","place":"Earth, Milky Way","contributions":[{"fullName":"Julietta Singh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d4a3f6cb-3023-4088-a5f4-147fb4510874","fullTitle":"Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Matthew Goulish","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Will Daddario","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1d9045f8-1d8f-479c-983d-383f3a289bec","fullTitle":"Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art","doi":"https://doi.org/10.21983/P3.0327.1.00","publicationDate":"2021-02-18","place":"Earth, Milky Way","contributions":[{"fullName":"Curt Cloninger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ffa5c5dd-ab4b-4739-8281-275d8c1fb504","fullTitle":"Sweet Spots: Writing the Connective Tissue of Relation","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mattie-Martha Sempert","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"757ff294-0fca-40f5-9f33-39a2d3fd5c8a","fullTitle":"Teaching Myself To See","doi":"https://doi.org/10.21983/P3.0303.1.00","publicationDate":"2021-02-11","place":"Earth, Milky Way","contributions":[{"fullName":"Tito Mukhopadhyay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}]},{"workId":"571255b8-5bf5-4fe1-a201-5bc7aded7f9d","fullTitle":"The Perfect Mango","doi":"https://doi.org/10.21983/P3.0245.1.00","publicationDate":"2019-02-20","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4cfb06e-a5a6-48cc-b7e5-c38228c132a8","fullTitle":"The Unnaming of Aliass","doi":"https://doi.org/10.21983/P3.0299.1.00","publicationDate":"2020-10-01","place":"Earth, Milky Way","contributions":[{"fullName":"Karin Bolender","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle index bcbb6e4..3d331b0 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprint.pickle @@ -1 +1 @@ -{"imprintUrl": "https://punctumbooks.com/imprints/3ecologies-books/", "imprintId": "78b0a283-9be3-4fed-a811-a7d4b9df7b25", "imprintName": "3Ecologies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9", "fullTitle": "A Manga Perfeita", "doi": "https://doi.org/10.21983/P3.0270.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Christine Greiner", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Ernesto Filho", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "c3d008a2-b357-4886-acc4-a2c77f1749ee", "fullTitle": "Last Year at Betty and Bob's: An Actual Occasion", "doi": "https://doi.org/10.53288/0363.1.00", "publicationDate": "2021-07-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "781b77bd-edf8-4688-937d-cc7cc47de89f", "fullTitle": "Last Year at Betty and Bob's: An Adventure", "doi": "https://doi.org/10.21983/P3.0234.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ce38f309-4438-479f-bd1c-b3690dbd7d8d", "fullTitle": "Last Year at Betty and Bob's: A Novelty", "doi": "https://doi.org/10.21983/P3.0233.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "edf31616-ea2a-4c51-b932-f510b9eb8848", "fullTitle": "No Archive Will Restore You", "doi": "https://doi.org/10.21983/P3.0231.1.00", "publicationDate": "2018-11-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Julietta Singh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d4a3f6cb-3023-4088-a5f4-147fb4510874", "fullTitle": "Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew Goulish", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Will Dadario", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d9045f8-1d8f-479c-983d-383f3a289bec", "fullTitle": "Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art", "doi": "https://doi.org/10.21983/P3.0327.1.00", "publicationDate": "2021-02-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Curt Cloninger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ffa5c5dd-ab4b-4739-8281-275d8c1fb504", "fullTitle": "Sweet Spots: Writing the Connective Tissue of Relation", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mattie-Martha Sempert", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "757ff294-0fca-40f5-9f33-39a2d3fd5c8a", "fullTitle": "Teaching Myself To See", "doi": "https://doi.org/10.21983/P3.0303.1.00", "publicationDate": "2021-02-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Tito Mukhopadhyay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "571255b8-5bf5-4fe1-a201-5bc7aded7f9d", "fullTitle": "The Perfect Mango", "doi": "https://doi.org/10.21983/P3.0245.1.00", "publicationDate": "2019-02-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4cfb06e-a5a6-48cc-b7e5-c38228c132a8", "fullTitle": "The Unnaming of Aliass", "doi": "https://doi.org/10.21983/P3.0299.1.00", "publicationDate": "2020-10-01", "place": "Earth, Milky Way", "contributions": [{"fullName": "Karin Bolender", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"} +{"imprintUrl": "https://punctumbooks.com/imprints/3ecologies-books/", "imprintId": "78b0a283-9be3-4fed-a811-a7d4b9df7b25", "imprintName": "3Ecologies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9", "fullTitle": "A Manga Perfeita", "doi": "https://doi.org/10.21983/P3.0270.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Christine Greiner", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Ernesto Filho", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "c3d008a2-b357-4886-acc4-a2c77f1749ee", "fullTitle": "Last Year at Betty and Bob's: An Actual Occasion", "doi": "https://doi.org/10.53288/0363.1.00", "publicationDate": "2021-07-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "781b77bd-edf8-4688-937d-cc7cc47de89f", "fullTitle": "Last Year at Betty and Bob's: An Adventure", "doi": "https://doi.org/10.21983/P3.0234.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ce38f309-4438-479f-bd1c-b3690dbd7d8d", "fullTitle": "Last Year at Betty and Bob's: A Novelty", "doi": "https://doi.org/10.21983/P3.0233.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "edf31616-ea2a-4c51-b932-f510b9eb8848", "fullTitle": "No Archive Will Restore You", "doi": "https://doi.org/10.21983/P3.0231.1.00", "publicationDate": "2018-11-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Julietta Singh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d4a3f6cb-3023-4088-a5f4-147fb4510874", "fullTitle": "Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew Goulish", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Will Daddario", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1d9045f8-1d8f-479c-983d-383f3a289bec", "fullTitle": "Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art", "doi": "https://doi.org/10.21983/P3.0327.1.00", "publicationDate": "2021-02-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Curt Cloninger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ffa5c5dd-ab4b-4739-8281-275d8c1fb504", "fullTitle": "Sweet Spots: Writing the Connective Tissue of Relation", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mattie-Martha Sempert", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "757ff294-0fca-40f5-9f33-39a2d3fd5c8a", "fullTitle": "Teaching Myself To See", "doi": "https://doi.org/10.21983/P3.0303.1.00", "publicationDate": "2021-02-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Tito Mukhopadhyay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "571255b8-5bf5-4fe1-a201-5bc7aded7f9d", "fullTitle": "The Perfect Mango", "doi": "https://doi.org/10.21983/P3.0245.1.00", "publicationDate": "2019-02-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4cfb06e-a5a6-48cc-b7e5-c38228c132a8", "fullTitle": "The Unnaming of Aliass", "doi": "https://doi.org/10.21983/P3.0299.1.00", "publicationDate": "2020-10-01", "place": "Earth, Milky Way", "contributions": [{"fullName": "Karin Bolender", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json index c94561f..8721280 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.json @@ -1 +1 @@ -{"data":{"imprints":[{"imprintUrl":"https://punctumbooks.com/imprints/3ecologies-books/","imprintId":"78b0a283-9be3-4fed-a811-a7d4b9df7b25","imprintName":"3Ecologies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9","fullTitle":"A Manga Perfeita","doi":"https://doi.org/10.21983/P3.0270.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Christine Greiner","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Ernesto Filho","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"c3d008a2-b357-4886-acc4-a2c77f1749ee","fullTitle":"Last Year at Betty and Bob's: An Actual Occasion","doi":"https://doi.org/10.53288/0363.1.00","publicationDate":"2021-07-08","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"781b77bd-edf8-4688-937d-cc7cc47de89f","fullTitle":"Last Year at Betty and Bob's: An Adventure","doi":"https://doi.org/10.21983/P3.0234.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ce38f309-4438-479f-bd1c-b3690dbd7d8d","fullTitle":"Last Year at Betty and Bob's: A Novelty","doi":"https://doi.org/10.21983/P3.0233.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"edf31616-ea2a-4c51-b932-f510b9eb8848","fullTitle":"No Archive Will Restore You","doi":"https://doi.org/10.21983/P3.0231.1.00","publicationDate":"2018-11-13","place":"Earth, Milky Way","contributions":[{"fullName":"Julietta Singh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d4a3f6cb-3023-4088-a5f4-147fb4510874","fullTitle":"Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Matthew Goulish","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Will Dadario","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d9045f8-1d8f-479c-983d-383f3a289bec","fullTitle":"Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art","doi":"https://doi.org/10.21983/P3.0327.1.00","publicationDate":"2021-02-18","place":"Earth, Milky Way","contributions":[{"fullName":"Curt Cloninger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ffa5c5dd-ab4b-4739-8281-275d8c1fb504","fullTitle":"Sweet Spots: Writing the Connective Tissue of Relation","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mattie-Martha Sempert","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"757ff294-0fca-40f5-9f33-39a2d3fd5c8a","fullTitle":"Teaching Myself To See","doi":"https://doi.org/10.21983/P3.0303.1.00","publicationDate":"2021-02-11","place":"Earth, Milky Way","contributions":[{"fullName":"Tito Mukhopadhyay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}]},{"workId":"571255b8-5bf5-4fe1-a201-5bc7aded7f9d","fullTitle":"The Perfect Mango","doi":"https://doi.org/10.21983/P3.0245.1.00","publicationDate":"2019-02-20","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4cfb06e-a5a6-48cc-b7e5-c38228c132a8","fullTitle":"The Unnaming of Aliass","doi":"https://doi.org/10.21983/P3.0299.1.00","publicationDate":"2020-10-01","place":"Earth, Milky Way","contributions":[{"fullName":"Karin Bolender","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/advanced-methods/","imprintId":"ef38d49c-f8cb-4621-9f2f-1637560016e4","imprintName":"Advanced Methods","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"0729b9d1-87d3-4739-8266-4780c3cc93da","fullTitle":"Doing Multispecies Theology","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mathew Arthur","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"af1d6a61-66bd-47fd-a8c5-20e433f7076b","fullTitle":"Inefficient Mapping: A Protocol for Attuning to Phenomena","doi":"https://doi.org/10.53288/0336.1.00","publicationDate":"2021-08-05","place":"Earth, Milky Way","contributions":[{"fullName":"Linda Knight","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aa9059ba-930c-4327-97a1-c8c7877332c1","fullTitle":"Making a Laboratory: Dynamic Configurations with Transversal Video","doi":null,"publicationDate":"2020-08-06","place":"Earth, Milky Way","contributions":[{"fullName":"Ben Spatz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8f256239-8104-4838-9587-ac234aedd822","fullTitle":"Speaking for the Social: A Catalog of Methods","doi":"https://doi.org/10.21983/P3.0378.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Gemma John","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Hannah Knox","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprint/anarchist-developments-in-cultural-studies/","imprintId":"3bdf14c5-7f9f-42d2-8e3b-f78de0475c76","imprintName":"Anarchist Developments in Cultural Studies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1d014946-aa73-4fae-9042-ef8830089f3c","fullTitle":"Blasting the Canon","doi":"https://doi.org/10.21983/P3.0035.1.00","publicationDate":"2013-06-25","place":"Brooklyn, NY","contributions":[{"fullName":"Ruth Kinna","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Süreyyya Evren","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"e1f74d6b-adab-4e56-8bc9-6fbd0eaab89c","fullTitle":"Ontological Anarché: Beyond Materialism and Idealism","doi":"https://doi.org/10.21983/P3.0060.1.00","publicationDate":"2014-01-24","place":"Brooklyn, NY","contributions":[{"fullName":"Jason Adams","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Duane Rousselle","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/brainstorm-books/","imprintId":"1e464718-2055-486b-bcd9-6e21309fcd80","imprintName":"Brainstorm Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"fdd9e45a-08b4-4b98-9c34-bada71a34979","fullTitle":"Animal Emotions: How They Drive Human Behavior","doi":"https://doi.org/10.21983/P3.0305.1.00","publicationDate":"2020-06-18","place":"Earth, Milky Way","contributions":[{"fullName":"Kenneth L. Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Christian Montag","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"811fd271-b1dc-490a-a872-3d6867d59e78","fullTitle":"Aural History","doi":"https://doi.org/10.21983/P3.0282.1.00","publicationDate":"2020-03-12","place":"Earth, Milky Way","contributions":[{"fullName":"Gila Ashtor","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f01cb60b-69bf-4d11-bd3c-fd5b36663029","fullTitle":"Covert Plants: Vegetal Consciousness and Agency in an Anthropocentric World","doi":"https://doi.org/10.21983/P3.0207.1.00","publicationDate":"2018-09-11","place":"Earth, Milky Way","contributions":[{"fullName":"Prudence Gibson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Brits Baylee","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"9bdf38ca-95fd-4cf4-adf6-ed26e97cf213","fullTitle":"Critique of Fantasy, Vol. 1: Between a Crypt and a Datemark","doi":"https://doi.org/10.21983/P3.0277.1.00","publicationDate":"2020-06-25","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"89f9c84b-be5c-4020-8edc-6fbe0b1c25f5","fullTitle":"Critique of Fantasy, Vol. 2: The Contest between B-Genres","doi":"https://doi.org/10.21983/P3.0278.1.00","publicationDate":"2020-11-24","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"79464e83-b688-4b82-84bc-18d105f60f33","fullTitle":"Critique of Fantasy, Vol. 3: The Block of Fame","doi":"https://doi.org/10.21983/P3.0279.1.00","publicationDate":"2021-01-14","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"992c6ff8-e166-4014-85cc-b53af250a4e4","fullTitle":"Hack the Experience: Tools for Artists from Cognitive Science","doi":"https://doi.org/10.21983/P3.0206.1.00","publicationDate":"2018-09-04","place":"Earth, Milky Way","contributions":[{"fullName":"Ryan Dewey","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4a42f23b-5277-49b5-8310-c3c38ded5bf5","fullTitle":"Opioids: Addiction, Narrative, Freedom","doi":"https://doi.org/10.21983/P3.0210.1.00","publicationDate":"2018-10-05","place":"Earth, Milky Way","contributions":[{"fullName":"Maia Dolphin-Krute","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"18d3d876-bcaf-4e1c-a67a-05537f808a99","fullTitle":"The Hegemony of Psychopathy","doi":"https://doi.org/10.21983/P3.0180.1.00","publicationDate":"2017-09-19","place":"Earth, Milky Way","contributions":[{"fullName":"Lajos Brons","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5dca2af4-43f2-4cdb-a7a5-5654a722c4e0","fullTitle":"Visceral: Essays on Illness Not as Metaphor","doi":"https://doi.org/10.21983/P3.0185.1.00","publicationDate":"2017-10-16","place":"Earth, Milky Way","contributions":[{"fullName":"Maia Dolphin-Krute","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/ctm-documents-initiative/","imprintId":"cec45cc6-8cb5-43ed-888f-165f3fa73842","imprintName":"CTM Documents Initiative","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"b950d243-7cfc-4aee-b908-d1776be327df","fullTitle":"Image Photograph","doi":"https://doi.org/10.21983/P3.0106.1.00","publicationDate":"2015-07-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marc Lafia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"14f2b847-faeb-43c9-b116-88a0091b6f1f","fullTitle":"Knowledge, Spirit, Law, Book 2: The Anti-Capitalist Sublime","doi":"https://doi.org/10.21983/P3.0191.1.00","publicationDate":"2017-12-24","place":"Earth, Milky Way","contributions":[{"fullName":"Gavin Keeney","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1e0c7c29-dcd4-470d-b3ee-8c4012ac79dd","fullTitle":"Liquid Life: On Non-Linear Materiality","doi":"https://doi.org/10.21983/P3.0246.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Rachel Armstrong","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"47cd079b-03f3-4a5b-b5e4-36cec4db7fab","fullTitle":"The Digital Dionysus: Nietzsche and the Network-Centric Condition","doi":"https://doi.org/10.21983/P3.0149.1.00","publicationDate":"2016-09-12","place":"Earth, Milky Way","contributions":[{"fullName":"Dan Mellamphy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Nandita Biswas Mellamphy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1950e4ba-651c-4ec9-83f6-df46b777b10f","fullTitle":"The Funambulist Pamphlets 10: Literature","doi":"https://doi.org/10.21983/P3.0075.1.00","publicationDate":"2014-08-14","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"bdfc263a-7ace-43f3-9c80-140c6fb32ec7","fullTitle":"The Funambulist Pamphlets 11: Cinema","doi":"https://doi.org/10.21983/P3.0095.1.00","publicationDate":"2015-02-20","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f5fb8a0e-ea1d-471f-b76a-a000edae5956","fullTitle":"The Funambulist Pamphlets 1: Spinoza","doi":"https://doi.org/10.21983/P3.0033.1.00","publicationDate":"2013-06-13","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"911de470-77e1-4816-b437-545122a7bf26","fullTitle":"The Funambulist Pamphlets 2: Foucault","doi":"https://doi.org/10.21983/P3.0034.1.00","publicationDate":"2013-06-17","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"61da662d-c720-4d22-957c-4d96071ee5f2","fullTitle":"The Funambulist Pamphlets 3: Deleuze","doi":"https://doi.org/10.21983/P3.0038.1.00","publicationDate":"2013-07-04","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"419e17ed-3bcc-430c-a67e-3121537e4702","fullTitle":"The Funambulist Pamphlets 4: Legal Theory","doi":"https://doi.org/10.21983/P3.0042.1.00","publicationDate":"2013-08-15","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fe8ddfb7-0e5b-4604-811c-78cf4db7528b","fullTitle":"The Funambulist Pamphlets 5: Occupy Wall Street","doi":"https://doi.org/10.21983/P3.0046.1.00","publicationDate":"2013-09-08","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13390641-86f6-4351-923d-8c456f175bff","fullTitle":"The Funambulist Pamphlets 6: Palestine","doi":"https://doi.org/10.21983/P3.0054.1.00","publicationDate":"2013-11-13","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"448c3581-9167-491e-86f7-08d5a6c953a9","fullTitle":"The Funambulist Pamphlets 7: Cruel Designs","doi":"https://doi.org/10.21983/P3.0057.1.00","publicationDate":"2013-12-21","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d3cbb60f-537f-4bd7-96cb-d8aba595a947","fullTitle":"The Funambulist Pamphlets 8: Arakawa + Madeline Gins","doi":"https://doi.org/10.21983/P3.0064.1.00","publicationDate":"2014-03-12","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6fab7c76-7567-4b57-8ad7-90a5536d87af","fullTitle":"The Funambulist Pamphlets 9: Science Fiction","doi":"https://doi.org/10.21983/P3.0069.1.00","publicationDate":"2014-05-28","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"84bbf59f-1dbb-445e-8f65-f26574f609b6","fullTitle":"The Funambulist Papers, Volume 1","doi":"https://doi.org/10.21983/P3.0053.1.00","publicationDate":"2013-10-23","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3b41b8de-b9bb-4ebd-a002-52052a9e39a9","fullTitle":"The Funambulist Papers, Volume 2","doi":"https://doi.org/10.21983/P3.0098.1.00","publicationDate":"2015-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/dead-letter-office/","imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","imprintName":"Dead Letter Office","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","fullTitle":"A Bibliography for After Jews and Arabs","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f02786d4-3bcc-473e-8d43-3da66c7e877c","fullTitle":"A Brief Genealogy of Jewish Republicanism: Parting Ways with Judith Butler","doi":"https://doi.org/10.21983/P3.0159.1.00","publicationDate":"2016-12-16","place":"Earth, Milky Way","contributions":[{"fullName":"Irene Tucker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fd67d684-aaff-4260-bb94-9d0373015620","fullTitle":"An Edition of Miles Hogarde's \"A Mirroure of Myserie\"","doi":"https://doi.org/10.21983/P3.0316.1.00","publicationDate":"2021-06-03","place":"Earth, Milky Way","contributions":[{"fullName":"Sebastian Sobecki","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5f441303-4fc6-4a7d-951e-5b966a1cbd91","fullTitle":"An Unspecific Dog: Artifacts of This Late Stage in History","doi":"https://doi.org/10.21983/P3.0163.1.00","publicationDate":"2017-01-18","place":"Earth, Milky Way","contributions":[{"fullName":"Joshua Rothes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7eb6f426-e913-4d69-92c5-15a640f1b4b9","fullTitle":"A Sanctuary of Sounds","doi":"https://doi.org/10.21983/P3.0029.1.00","publicationDate":"2013-05-23","place":"Brooklyn, NY","contributions":[{"fullName":"Andreas Burckhardt","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4fc74913-bde4-426e-b7e5-2f66c60af484","fullTitle":"As If: Essays in As You Like It","doi":"https://doi.org/10.21983/P3.0162.1.00","publicationDate":"2016-12-29","place":"Earth, Milky Way","contributions":[{"fullName":"William N. West","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"06db2bc1-e25a-42c8-8908-fbd774f73204","fullTitle":"Atopological Trilogy: Deleuze and Guattari","doi":"https://doi.org/10.21983/P3.0096.1.00","publicationDate":"2015-03-15","place":"Brooklyn, NY","contributions":[{"fullName":"Zafer Aracagök","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Manola Antonioli","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"a022743e-8b77-4246-a068-e08d57815e27","fullTitle":"CMOK to YOu To: A Correspondence","doi":"https://doi.org/10.21983/P3.0150.1.00","publicationDate":"2016-09-15","place":"Earth, Milky Way","contributions":[{"fullName":"Marc James Léger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Nina Živančević","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f94ded4d-1c87-4503-82f1-a1ca4346e756","fullTitle":"Come As You Are, After Eve Kosofsky Sedgwick","doi":"https://doi.org/10.21983/P3.0342.1.00","publicationDate":"2021-04-06","place":"Earth, Milky Way","contributions":[{"fullName":"Eve Kosofsky Sedgwick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonathan Goldberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"449add5c-b935-47e2-8e46-2545fad86221","fullTitle":"Escargotesque, or, What Is Experience","doi":"https://doi.org/10.21983/P3.0089.1.00","publicationDate":"2015-01-26","place":"Brooklyn, NY","contributions":[{"fullName":"M.H. Bowker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"628bb121-5ba2-4fc1-a741-a8062c45b63b","fullTitle":"Gaffe/Stutter","doi":"https://doi.org/10.21983/P3.0049.1.00","publicationDate":"2013-10-06","place":"Brooklyn, NY","contributions":[{"fullName":"Whitney Anne Trettien","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f131762c-a877-4925-9fa1-50555bc4e2ae","fullTitle":"[Given, If, Then]: A Reading in Three Parts","doi":"https://doi.org/10.21983/P3.0090.1.00","publicationDate":"2015-02-08","place":"Brooklyn, NY","contributions":[{"fullName":"Jennifer Hope Davy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Julia Hölzl","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cb11259b-7b83-498e-bc8a-7c184ee2c279","fullTitle":"Going Postcard: The Letter(s) of Jacques Derrida","doi":"https://doi.org/10.21983/P3.0171.1.00","publicationDate":"2017-05-15","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f8b57164-89e6-48b1-bd70-9d360b53a453","fullTitle":"Helicography","doi":"https://doi.org/10.53288/0352.1.00","publicationDate":"2021-07-22","place":"Earth, Milky Way","contributions":[{"fullName":"Craig Dworkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6689db84-b329-4ca5-b10c-010fd90c7e90","fullTitle":"History of an Abuse","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ceffc30d-1d28-48c3-acee-e6a2dc38ff37","fullTitle":"How We Read","doi":"https://doi.org/10.21983/P3.0259.1.00","publicationDate":"2019-07-18","place":"Earth, Milky Way","contributions":[{"fullName":"Kaitlin Heller","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Suzanne Conklin Akbari","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"63e2f6b6-f324-4bdc-836e-55515ba3cd8f","fullTitle":"How We Write: Thirteen Ways of Looking at a Blank Page","doi":"https://doi.org/10.21983/P3.0110.1.00","publicationDate":"2015-09-11","place":"Brooklyn, NY","contributions":[{"fullName":"Suzanne Conklin Akbari","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f5217945-8c2c-4e65-a5dd-3dbff208dfb7","fullTitle":"In Divisible Cities: A Phanto-Cartographical Missive","doi":"https://doi.org/10.21983/P3.0044.1.00","publicationDate":"2013-08-26","place":"Brooklyn, NY","contributions":[{"fullName":"Dominic Pettman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d5f5978b-32e0-44a1-a72a-c80568c9b93a","fullTitle":"I Open Fire","doi":"https://doi.org/10.21983/P3.0086.1.00","publicationDate":"2014-12-28","place":"Brooklyn, NY","contributions":[{"fullName":"David Pol","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c6125a74-2801-4255-afe9-89cdb8d253f4","fullTitle":"John Gardner: A Tiny Eulogy","doi":"https://doi.org/10.21983/P3.0013.1.00","publicationDate":"2012-11-29","place":"Brooklyn, NY","contributions":[{"fullName":"Phil Jourdan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8377c394-c27a-44cb-98f5-5e5b789ad7b8","fullTitle":"Last Day Every Day: Figural Thinking from Auerbach and Kracauer to Agamben and Brenez","doi":"https://doi.org/10.21983/P3.0012.1.00","publicationDate":"2012-10-23","place":"Brooklyn, NY","contributions":[{"fullName":"Adrian Martin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1809f10a-d0e3-4481-8f96-cca7f240d656","fullTitle":"Letters on the Autonomy Project in Art and Politics","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Janet Sarbanes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5f1db605-88b6-427a-84cb-ce2fcf0f89a3","fullTitle":"Massa por Argamassa: A \"Libraria de Babel\" e o Sonho de Totalidade","doi":"https://doi.org/10.21983/P3.0264.1.00","publicationDate":"2019-09-17","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Basile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Yuri N. Martinez Laskowski","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f20869c5-746f-491b-8c34-f88dc3728e18","fullTitle":"Minóy","doi":"https://doi.org/10.21983/P3.0072.1.00","publicationDate":"2014-06-30","place":"Brooklyn, NY","contributions":[{"fullName":"Joseph Nechvatal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d40aa92-380c-4fae-98d8-c598bb32e7c6","fullTitle":"Misinterest: Essays, Pensées, and Dreams","doi":"https://doi.org/10.21983/P3.0256.1.00","publicationDate":"2019-06-27","place":"Earth, Milky Way","contributions":[{"fullName":"M.H. Bowker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"34682ba4-201f-4122-8e4a-edc3edc57a7b","fullTitle":"Nicholas of Cusa and the Kairos of Modernity: Cassirer, Gadamer, Blumenberg","doi":"https://doi.org/10.21983/P3.0045.1.00","publicationDate":"2013-09-05","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Edward Moore","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1cfca75f-2e57-4f34-85fb-a1585315a2a9","fullTitle":"Noise Thinks the Anthropocene: An Experiment in Noise Poetics","doi":"https://doi.org/10.21983/P3.0244.1.00","publicationDate":"2019-02-13","place":"Earth, Milky Way","contributions":[{"fullName":"Aaron Zwintscher","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"571d5d40-cfd6-4270-9530-88bfcfc5d8b5","fullTitle":"Non-Conceptual Negativity: Damaged Reflections on Turkey","doi":"https://doi.org/10.21983/P3.0247.1.00","publicationDate":"2019-03-27","place":"Earth, Milky Way","contributions":[{"fullName":"Zafer Aracagök","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Fraco \"Bifo\" Berardi","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"3eb0d095-fc27-4add-8202-1dc2333a758c","fullTitle":"Notes on Trumpspace: Politics, Aesthetics, and the Fantasy of Home","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"David Stephenson Markus","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"48e2a673-aec2-4ed6-99d4-46a8de200493","fullTitle":"Nothing in MoMA","doi":"https://doi.org/10.21983/P3.0208.1.00","publicationDate":"2018-09-22","place":"Earth, Milky Way","contributions":[{"fullName":"Abraham Adams","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97019dea-e207-4909-b907-076d0620ff74","fullTitle":"Obiter Dicta","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Erick Verran","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"10a41381-792f-4376-bed1-3781d1b8bae7","fullTitle":"Of Learned Ignorance: Idea of a Treatise in Philosophy","doi":"https://doi.org/10.21983/P3.0031.1.00","publicationDate":"2013-06-04","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b43ec529-2f51-4c59-b3cb-394f3649502c","fullTitle":"Of the Contract","doi":"https://doi.org/10.21983/P3.0174.1.00","publicationDate":"2017-07-11","place":"Earth, Milky Way","contributions":[{"fullName":"Christopher Clifton","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"63b0e966-e81c-4d84-b41d-3445b0d9911f","fullTitle":"Paris Bride: A Modernist Life","doi":"https://doi.org/10.21983/P3.0281.1.00","publicationDate":"2020-02-21","place":"Earth, Milky Way","contributions":[{"fullName":"John Schad","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed1a8fb5-8b71-43ca-9748-ebd43f0d7580","fullTitle":"Philosophy for Militants","doi":"https://doi.org/10.21983/P3.0168.1.00","publicationDate":"2017-03-15","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5b652d05-2b5f-465a-8c66-f4dc01dafd03","fullTitle":"[provisional self-evidence]","doi":"https://doi.org/10.21983/P3.0111.1.00","publicationDate":"2015-09-13","place":"Brooklyn, NY","contributions":[{"fullName":"Rachel Arrighi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cd836291-fb7f-4508-bdff-cd59dca2b447","fullTitle":"Queer Insists (for José Esteban Muñoz)","doi":"https://doi.org/10.21983/P3.0082.1.00","publicationDate":"2014-12-04","place":"Brooklyn, NY","contributions":[{"fullName":"Michael O'Rourke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"46ab709c-3272-4a03-991e-d1b1394b8e2c","fullTitle":"Ravish the Republic: The Archives of the Iron Garters Crime/Art Collective","doi":"https://doi.org/10.21983/P3.0107.1.00","publicationDate":"2015-07-15","place":"Brooklyn, NY","contributions":[{"fullName":"Michael L. Berger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"28a0db09-a149-43fe-ba08-00dde962b4b8","fullTitle":"Reiner Schürmann and Poetics of Politics","doi":"https://doi.org/10.21983/P3.0209.1.00","publicationDate":"2018-09-28","place":"Earth, Milky Way","contributions":[{"fullName":"Christopher Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5dda1ad6-70ac-4a31-baf2-b77f8f5a8190","fullTitle":"Sappho: Fragments","doi":"https://doi.org/10.21983/P3.0238.1.00","publicationDate":"2018-12-31","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Goldberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"L.O. Aranye Fradenburg Joy","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"8cd5ce6c-d604-46ac-b4f7-1f871589d96a","fullTitle":"Still Life: Notes on Barbara Loden's \"Wanda\" (1970)","doi":"https://doi.org/10.53288/0326.1.00","publicationDate":"2021-07-29","place":"Earth, Milky Way","contributions":[{"fullName":"Anna Backman Rogers","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1547aa4b-7629-4a21-8b2b-621223c73ec9","fullTitle":"Still Thriving: On the Importance of Aranye Fradenburg","doi":"https://doi.org/10.21983/P3.0099.1.00","publicationDate":"2015-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"L.O. Aranye Fradenburg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"08543bd7-e603-43ae-bb0f-1d4c1c96030b","fullTitle":"Suite on \"Spiritus Silvestre\": For Symphony","doi":"https://doi.org/10.21983/P3.0020.1.00","publicationDate":"2012-12-25","place":"Brooklyn, NY","contributions":[{"fullName":"Denzil Ford","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9839926e-56ea-4d71-a3de-44cabd1d2893","fullTitle":"Tar for Mortar: \"The Library of Babel\" and the Dream of Totality","doi":"https://doi.org/10.21983/P3.0196.1.00","publicationDate":"2018-03-15","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Basile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"58aadfa5-abc6-4c44-9768-f8ff41502867","fullTitle":"The Afterlife of Genre: Remnants of the Trauerspiel in Buffy the Vampire Slayer","doi":"https://doi.org/10.21983/P3.0061.1.00","publicationDate":"2014-02-21","place":"Brooklyn, NY","contributions":[{"fullName":"Anthony Curtis Adler","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1d30497f-4340-43ab-b328-9fd2fed3106e","fullTitle":"The Anthology of Babel","doi":"https://doi.org/10.21983/P3.0254.1.00","publicationDate":"2020-01-24","place":"Earth, Milky Way","contributions":[{"fullName":"Ed Simon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"26d522d4-fb46-47bf-a344-fe6af86688d3","fullTitle":"The Bodies That Remain","doi":"https://doi.org/10.21983/P3.0212.1.00","publicationDate":"2018-10-16","place":"Earth, Milky Way","contributions":[{"fullName":"Emmy Beber","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a065ad95-716a-4005-b436-a46d9dbd64df","fullTitle":"The Communism of Thought","doi":"https://doi.org/10.21983/P3.0059.1.00","publicationDate":"2014-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c51c8fa-947b-4a12-a2e9-5306ee81d117","fullTitle":"The Death of Conrad Unger: Some Conjectures Regarding Parasitosis and Associated Suicide Behavior","doi":"https://doi.org/10.21983/P3.0008.1.00","publicationDate":"2012-08-13","place":"Brooklyn, NY","contributions":[{"fullName":"Gary L. Shipley","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"33917b8f-775f-4ee2-a43a-6b5285579f84","fullTitle":"The Non-Library","doi":"https://doi.org/10.21983/P3.0065.1.00","publicationDate":"2014-03-13","place":"Brooklyn, NY","contributions":[{"fullName":"Trevor Owen Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"60813d93-663f-4974-8789-1a2ee83cd042","fullTitle":"Theory Is Like a Surging Sea","doi":"https://doi.org/10.21983/P3.0108.1.00","publicationDate":"2015-08-02","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"119e45d6-63ab-4cc4-aabf-06ecba1fb055","fullTitle":"The Witch and the Hysteric: The Monstrous Medieval in Benjamin Christensen's Häxan","doi":"https://doi.org/10.21983/P3.0074.1.00","publicationDate":"2014-08-08","place":"Brooklyn, NY","contributions":[{"fullName":"Patricia Clare Ingham","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alexander Doty","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d6651c3c-c453-42ab-84b3-4e847d3a3324","fullTitle":"Traffic Jams: Analysing Everyday Life through the Immanent Materialism of Deleuze & Guattari","doi":"https://doi.org/10.21983/P3.0023.1.00","publicationDate":"2013-02-13","place":"Brooklyn, NY","contributions":[{"fullName":"David R. Cole","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1399a869-9f56-4980-981d-2cc83f0a6668","fullTitle":"Truth and Fiction: Notes on (Exceptional) Faith in Art","doi":"https://doi.org/10.21983/P3.0007.1.00","publicationDate":"2012-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"Milcho Manchevski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adrian Martin","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"b904a8eb-9c98-4bb1-bf25-3cb9d075b157","fullTitle":"Warez: The Infrastructure and Aesthetics of Piracy","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Martin Eve","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"77e1fa52-1938-47dd-b8a5-2a57bfbc91d1","fullTitle":"What Is Philosophy?","doi":"https://doi.org/10.21983/P3.0011.1.00","publicationDate":"2012-10-09","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"27602ce3-fbd6-4044-8b44-b8421670edae","fullTitle":"Wonder, Horror, and Mystery in Contemporary Cinema: Letters on Malick, Von Trier, and Kieślowski","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Morgan Meis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"J.M. Tyree","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/department-of-eagles/","imprintId":"ef4aece6-6e9c-4f90-b5c3-7e4b78e8942d","imprintName":"Department of Eagles","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"3ccdbbfc-6550-49f4-8ec9-77fc94a7a099","fullTitle":"Broken Narrative: The Politics of Contemporary Art in Albania","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Armando Lulaj","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marco Mazzi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Brenda Porster","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Tomii Keiko","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Osamu Kanemura","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":6},{"fullName":"Jonida Gashi","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":5}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/dotawo/","imprintId":"f891a5f0-2af2-4eda-b686-db9dd74ee73d","imprintName":"Dotawo","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1c39ca0c-0189-44d3-bb2f-9345e2a2b152","fullTitle":"Dotawo: A Journal of Nubian Studies 2","doi":"https://doi.org/10.21983/P3.0104.1.00","publicationDate":"2015-06-01","place":"Brooklyn, NY","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Angelika Jakobi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"861ea7cc-5447-4c60-8657-c50d0a31cd24","fullTitle":"Dotawo: a Journal of Nubian Studies 3: Know-Hows and Techniques in Ancient Sudan","doi":"https://doi.org/10.21983/P3.0148.1.00","publicationDate":"2016-08-11","place":"Earth, Milky Way","contributions":[{"fullName":"Marc Maillot","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"431b58fe-7f59-49d9-bf6f-53eae379ee4d","fullTitle":"Dotawo: A Journal of Nubian Studies 4: Place Names and Place Naming in Nubia","doi":"https://doi.org/10.21983/P3.0184.1.00","publicationDate":"2017-10-12","place":"Earth, Milky Way","contributions":[{"fullName":"Alexandros Tsakos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Robin Seignobos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3c5923bc-e76b-4fbe-8d8c-1a49a49020a8","fullTitle":"Dotawo: A Journal of Nubian Studies 5: Nubian Women","doi":"https://doi.org/10.21983/P3.0242.1.00","publicationDate":"2019-02-05","place":"Earth, Milky Way","contributions":[{"fullName":"Anne Jennings","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"15ab17fe-2486-4ca5-bb47-6b804793f80d","fullTitle":"Dotawo: A Journal of Nubian Studies 6: Miscellanea Nubiana","doi":"https://doi.org/10.21983/P3.0321.1.00","publicationDate":"2019-12-26","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Simmons","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aa431454-40d3-42f5-8069-381a15789257","fullTitle":"Dotawo: A Journal of Nubian Studies 7: Comparative Northern East Sudanic Linguistics","doi":"https://doi.org/10.21983/P3.0350.1.00","publicationDate":"2021-03-23","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7a4506ac-dfdc-4054-b2d1-d8fdf4cea12b","fullTitle":"Nubian Proverbs","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Maher Habbob","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a8e6722a-1858-4f38-995d-bde0b120fe8c","fullTitle":"The Old Nubian Language","doi":"https://doi.org/10.21983/P3.0179.1.00","publicationDate":"2017-09-11","place":"Earth, Milky Way","contributions":[{"fullName":"Eugenia Smagina","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"José Andrés Alonso de la Fuente","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"0cd80cd2-1733-4bde-b48f-a03fc01acfbf","fullTitle":"The Old Nubian Texts from Attiri","doi":"https://doi.org/10.21983/P3.0156.1.00","publicationDate":"2016-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Petra Weschenfelder","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent Pierre-Michel Laisney","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kerstin Weber-Thum","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Alexandros Tsakos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4}]}],"__typename":"Imprint"},{"imprintUrl":null,"imprintId":"47e62ae1-6698-46aa-840c-d4507697459f","imprintName":"eth press","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"5f24bd29-3d48-4a70-8491-6269f7cc6212","fullTitle":"Ballads","doi":"https://doi.org/10.21983/P3.0105.1.00","publicationDate":"2015-06-03","place":"Brooklyn, NY","contributions":[{"fullName":"Richard Owens","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0a8fba81-f1d0-498c-88c4-0b96d3bf2947","fullTitle":"Cotton Nero A.x: The Works of the \"Pearl\" Poet","doi":"https://doi.org/10.21983/P3.0066.1.00","publicationDate":"2014-04-24","place":"Brooklyn, NY","contributions":[{"fullName":"Chris Piuma","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Lisa Ampleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Daniel C. Remein","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"David Hadbawnik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"53cd2c70-eab6-45b7-a147-8ef1c87d9ac0","fullTitle":"dôNrm'-lä-püsl","doi":"https://doi.org/10.21983/P3.0183.1.00","publicationDate":"2017-10-05","place":"Earth, Milky Way","contributions":[{"fullName":"kari edwards","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Tina Žigon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"34584bfe-1cf8-49c5-b8d1-6302ea1cfcfa","fullTitle":"Snowline","doi":"https://doi.org/10.21983/P3.0093.1.00","publicationDate":"2015-02-15","place":"Brooklyn, NY","contributions":[{"fullName":"Donato Mancini","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cc73eed0-a1f9-4ad4-b7d8-2394b92765f0","fullTitle":"Unless As Stone Is","doi":"https://doi.org/10.21983/P3.0058.1.00","publicationDate":"2014-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Sam Lohmann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/gracchi-books/","imprintId":"41193484-91d1-44f3-8d0c-0452a35d17a0","imprintName":"Gracchi Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1603556c-53fc-4d14-b0bf-8c18ad7b24ab","fullTitle":"Social and Intellectual Networking in the Early Middle Ages","doi":null,"publicationDate":null,"place":null,"contributions":[{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"K. Patrick Fazioli","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"6813bf17-373c-49ce-b9e3-1d7ab98f2977","fullTitle":"The Christian Economy of the Early Medieval West: Towards a Temple Society","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Ian Wood","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2f93b300-f147-48f5-95d5-afd0e0161fe6","fullTitle":"Urban Interactions: Communication and Competition in Late Antiquity and the Early Middle Ages","doi":"https://doi.org/10.21983/P3.0300.1.00","publicationDate":"2020-10-15","place":"Earth, Milky Way","contributions":[{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael Burrows","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ian Wood","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"Michael J. Kelly","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"678f4564-d01a-4ffe-8bdb-fead78f87955","fullTitle":"Vera Lex Historiae?: Constructions of Truth in Medieval Historical Narrative","doi":"https://doi.org/10.21983/P3.0369.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Catalin Taranu","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/helvete/","imprintId":"b3dc0be6-6739-4777-ada0-77b1f5074f7d","imprintName":"Helvete","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"417ecc06-51a4-4660-959b-482763864559","fullTitle":"Helvete 1: Incipit","doi":"https://doi.org/10.21983/P3.0027.1.00","publicationDate":"2013-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"Aspasia Stephanou","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Amelia Ishmael","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Zareen Price","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ben Woodard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"3cc0269d-7170-4981-8ac7-5b01e7b9e080","fullTitle":"Helvete 2: With Head Downwards: Inversions in Black Metal","doi":"https://doi.org/10.21983/P3.0102.1.00","publicationDate":"2015-05-19","place":"Brooklyn, NY","contributions":[{"fullName":"Niall Scott","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Steve Shakespeare","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"fa4bc310-b7db-458a-8ba9-13347a91c862","fullTitle":"Helvete 3: Bleeding Black Noise","doi":"https://doi.org/10.21983/P3.0158.1.00","publicationDate":"2016-12-14","place":"Earth, Milky Way","contributions":[{"fullName":"Amelia Ishmael","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/lamma/","imprintId":"f852b678-e8ac-4949-a64d-3891d4855e3d","imprintName":"Lamma","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"ce7ec5ea-88b2-430f-92be-0f2436600a46","fullTitle":"Lamma: A Journal of Libyan Studies 1","doi":"https://doi.org/10.21983/P3.0337.1.00","publicationDate":"2020-07-21","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Benkato","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Leila Tayeb","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Amina Zarrugh","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://www.matteringpress.org","imprintId":"cb483a78-851f-4936-82d2-8dcd555dcda9","imprintName":"Mattering Press","updatedAt":"2021-03-25T16:33:14.299495+00:00","createdAt":"2021-03-25T16:25:02.238699+00:00","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6","publisher":{"publisherName":"Mattering Press","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6"},"works":[{"workId":"95e15115-4009-4cb0-8824-011038e3c116","fullTitle":"Energy Worlds: In Experiment","doi":"https://doi.org/10.28938/9781912729098","publicationDate":"2021-05-01","place":"Manchester","contributions":[{"fullName":"Brit Ross Winthereik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Laura Watts","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"James Maguire","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"091abd14-7bc0-4fe7-8194-552edb02b98b","fullTitle":"Inventing the Social","doi":"https://doi.org/10.28938/9780995527768","publicationDate":"2018-07-11","place":"Manchester","contributions":[{"fullName":"Michael Guggenheim","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alex Wilkie","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Noortje Marres","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c38728e0-9739-4ad3-b0a7-6cda9a9da4b9","fullTitle":"Sensing InSecurity: Sensors as transnational security infrastructures","doi":null,"publicationDate":null,"place":"Manchester","contributions":[]}],"__typename":"Imprint"},{"imprintUrl":"https://www.mediastudies.press/","imprintId":"5078b33c-5b3f-48bf-bf37-ced6b02beb7c","imprintName":"mediastudies.press","updatedAt":"2021-06-15T14:40:51.652638+00:00","createdAt":"2021-06-15T14:40:51.652638+00:00","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5","publisher":{"publisherName":"mediastudies.press","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5"},"works":[{"workId":"6763ec18-b4af-4767-976c-5b808a64e641","fullTitle":"Liberty and the News","doi":"https://doi.org/10.32376/3f8575cb.2e69e142","publicationDate":"2020-11-15","place":"Bethlehem, PA","contributions":[{"fullName":"Walter Lippmann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sue Curry Jansen","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"3162a992-05dd-4b74-9fe0-0f16879ce6de","fullTitle":"Our Master’s Voice: Advertising","doi":"https://doi.org/10.21428/3f8575cb.dbba9917","publicationDate":"2020-10-15","place":"Bethlehem, PA","contributions":[{"fullName":"James Rorty","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jefferson Pooley","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"64891e84-6aac-437a-a380-0481312bd2ef","fullTitle":"Social Media & the Self: An Open Reader","doi":"https://doi.org/10.32376/3f8575cb.1fc3f80a","publicationDate":"2021-07-15","place":"Bethlehem, PA","contributions":[{"fullName":"Jefferson Pooley","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://meson.press","imprintId":"0299480e-869b-486c-8a65-7818598c107b","imprintName":"meson press","updatedAt":"2021-03-25T16:36:00.832381+00:00","createdAt":"2021-03-25T16:36:00.832381+00:00","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b","publisher":{"publisherName":"meson press","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b"},"works":[{"workId":"59ecdda1-efd8-45d2-b6a6-11bc8fe480f5","fullTitle":"Earth and Beyond in Tumultuous Times: A Critical Atlas of the Anthropocene","doi":"https://doi.org/10.14619/1891","publicationDate":"2021-03-15","place":"Lüneburg","contributions":[{"fullName":"Petra Löffler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Réka Patrícia Gál","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"36f7480e-ca45-452c-a5c0-ba1dccf135ec","fullTitle":"Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices","doi":"https://doi.org/10.14619/1860","publicationDate":"2021-05-17","place":"Lueneburg","contributions":[{"fullName":"Wanda Strauven","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"38872158-58b9-4ddf-a90e-f6001ac6c62d","fullTitle":"Trick 17: Mediengeschichten zwischen Zauberkunst und Wissenschaft","doi":"https://doi.org/10.14619/017","publicationDate":"2016-07-14","place":"Lüneburg, Germany","contributions":[{"fullName":"Sebastian Vehlken","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":1},{"fullName":"Jan Müggenburg","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Katja Müller-Helle","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":2},{"fullName":"Florian Sprenger","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":4}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/oe-case-files/","imprintId":"39a17f7f-c3f3-4bfe-8c5e-842d53182aad","imprintName":"Œ Case Files","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"a8bf3374-f153-460d-902a-adea7f41d7c7","fullTitle":"Œ Case Files, Vol. 01","doi":"https://doi.org/10.21983/P3.0354.1.00","publicationDate":"2021-05-13","place":"Earth, Milky Way","contributions":[{"fullName":"Simone Ferracina","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/oliphaunt-books/","imprintId":"353047d8-1ea4-4cc5-bd08-e9cedb4a3e8d","imprintName":"Oliphaunt Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"0090dbfb-bc8f-44aa-9803-08b277861b14","fullTitle":"Animal, Vegetable, Mineral: Ethics and Objects","doi":"https://doi.org/10.21983/P3.0006.1.00","publicationDate":"2012-05-07","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"eb8a2862-e812-4730-ab06-8dff1b6208bf","fullTitle":"Burn after Reading: Vol. 1, Miniature Manifestos for a Post/medieval Studies + Vol. 2, The Future We Want: A Collaboration","doi":"https://doi.org/10.21983/P3.0067.1.00","publicationDate":"2014-04-28","place":"Brooklyn, NY","contributions":[{"fullName":"Myra Seaman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"37cb9bb4-0bb3-4bd3-86ea-d8dfb60c9cd8","fullTitle":"Inhuman Nature","doi":"https://doi.org/10.21983/P3.0078.1.00","publicationDate":"2014-09-23","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"},"works":[{"workId":"fdeb2a1b-af39-4165-889d-cc7a5a31d5fa","fullTitle":"Acoustemologies in Contact: Sounding Subjects and Modes of Listening in Early Modernity","doi":"https://doi.org/10.11647/OBP.0226","publicationDate":"2021-01-19","place":"Cambridge, UK","contributions":[{"fullName":"Emily Wilbourne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Suzanne G. Cusick","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"31aea193-58de-43eb-aadb-23300ba5ee40","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0075","publicationDate":"2016-01-25","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fc088d17-bab2-4bfa-90bc-b320760c6c97","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0181","publicationDate":"2019-10-24","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b59def35-5712-44ed-8490-9073ab1c6cdc","fullTitle":"A European Public Investment Outlook","doi":"https://doi.org/10.11647/OBP.0222","publicationDate":"2020-06-12","place":"Cambridge, UK","contributions":[{"fullName":"Floriana Cerniglia","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Francesco Saraceno","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"528e4526-42e4-4e68-a0d5-f74a285c35a6","fullTitle":"A Fleet Street In Every Town: The Provincial Press in England, 1855-1900","doi":"https://doi.org/10.11647/OBP.0152","publicationDate":"2018-12-13","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Hobbs","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"35941026-43eb-496f-b560-2c21a6dbbbfc","fullTitle":"Agency: Moral Identity and Free Will","doi":"https://doi.org/10.11647/OBP.0197","publicationDate":"2020-04-01","place":"Cambridge, UK","contributions":[{"fullName":"David Weissman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3dbfa65a-ed33-46b5-9105-c5694c9c6bab","fullTitle":"A Handbook and Reader of Ottoman Arabic","doi":"https://doi.org/10.11647/OBP.0208","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Esther-Miriam Wagner","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0229f930-1e01-40b8-b4a8-03ab57624ced","fullTitle":"A Lexicon of Medieval Nordic Law","doi":"https://doi.org/10.11647/OBP.0188","publicationDate":"2020-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Christine Peel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Jeffrey Love","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Erik Simensen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Inger Larsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ulrika Djärv","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"defda2f0-1003-419a-8c3c-ac8d0b1abd17","fullTitle":"A Musicology of Performance: Theory and Method Based on Bach's Solos for Violin","doi":"https://doi.org/10.11647/OBP.0064","publicationDate":"2015-08-17","place":"Cambridge, UK","contributions":[{"fullName":"Dorottya Fabian","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"99af261d-8a31-449e-bf26-20e0178b8ed1","fullTitle":"An Anglo-Norman Reader","doi":"https://doi.org/10.11647/OBP.0110","publicationDate":"2018-02-08","place":"Cambridge, UK","contributions":[{"fullName":"Jane Bliss","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0d45084-d852-470d-b9f7-4719304f8a56","fullTitle":"Animals and Medicine: The Contribution of Animal Experiments to the Control of Disease","doi":"https://doi.org/10.11647/OBP.0055","publicationDate":"2015-05-04","place":"Cambridge, UK","contributions":[{"fullName":"Jack Botting","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Regina Botting","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Adrian R. Morrison","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"5a597468-a3eb-4026-b29e-eb93b8a7b0d6","fullTitle":"Annunciations: Sacred Music for the Twenty-First Century","doi":"https://doi.org/10.11647/OBP.0172","publicationDate":"2019-05-01","place":"Cambridge, UK","contributions":[{"fullName":"George Corbett","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"857a5788-a709-4d56-8607-337c1cabd9a2","fullTitle":"ANZUS and the Early Cold War: Strategy and Diplomacy between Australia, New Zealand and the United States, 1945-1956","doi":"https://doi.org/10.11647/OBP.0141","publicationDate":"2018-09-07","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Kelly","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0263f0c-48cd-4923-aef5-1b204636507c","fullTitle":"A People Passing Rude: British Responses to Russian Culture","doi":"https://doi.org/10.11647/OBP.0022","publicationDate":"2012-11-01","place":"Cambridge, UK","contributions":[{"fullName":"Anthony Cross","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"69c69fef-ab46-45ab-96d5-d7c4e5d4bce4","fullTitle":"Arab Media Systems","doi":"https://doi.org/10.11647/OBP.0238","publicationDate":"2021-03-03","place":"Cambridge, UK","contributions":[{"fullName":"Carola Richter","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Claudia Kozman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1e3ef1d6-a460-4b47-8d14-78c3d18e40c1","fullTitle":"A Time Travel Dialogue","doi":"https://doi.org/10.11647/OBP.0043","publicationDate":"2014-08-01","place":"Cambridge, UK","contributions":[{"fullName":"John W. Carroll","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"664931f6-27ca-4409-bb47-5642ca60117e","fullTitle":"A Victorian Curate: A Study of the Life and Career of the Rev. Dr John Hunt ","doi":"https://doi.org/10.11647/OBP.0248","publicationDate":"2021-05-03","place":"Cambridge, UK","contributions":[{"fullName":"David Yeandle","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"721fc7c9-7531-40cd-9e59-ab1bef5fc261","fullTitle":"Basic Knowledge and Conditions on Knowledge","doi":"https://doi.org/10.11647/OBP.0104","publicationDate":"2017-10-30","place":"Cambridge, UK","contributions":[{"fullName":"Mark McBride","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"39aafd68-dc83-4951-badf-d1f146a38fd4","fullTitle":"B C, Before Computers: On Information Technology from Writing to the Age of Digital Data","doi":"https://doi.org/10.11647/OBP.0225","publicationDate":"2020-10-22","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Robertson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a373ccbd-0665-4faa-bc24-15542e5cb0cf","fullTitle":"Behaviour, Development and Evolution","doi":"https://doi.org/10.11647/OBP.0097","publicationDate":"2017-02-20","place":"Cambridge, UK","contributions":[{"fullName":"Patrick Bateson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"e76e054c-617d-4004-b68d-54739205df8d","fullTitle":"Beyond Holy Russia: The Life and Times of Stephen Graham","doi":"https://doi.org/10.11647/OBP.0040","publicationDate":"2014-02-19","place":"Cambridge, UK","contributions":[{"fullName":"Michael Hughes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fe599a6c-ecd8-4ed3-a39e-5778cb9b77da","fullTitle":"Beyond Price: Essays on Birth and Death","doi":"https://doi.org/10.11647/OBP.0061","publicationDate":"2015-10-08","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c7ded4f3-4850-44eb-bd5b-e196a2254d3f","fullTitle":"Bourdieu and Literature","doi":"https://doi.org/10.11647/OBP.0027","publicationDate":"2011-11-30","place":"Cambridge, UK","contributions":[{"fullName":"John R.W. Speller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"456b46b9-bbec-4832-95ca-b23dcb975df1","fullTitle":"Brownshirt Princess: A Study of the 'Nazi Conscience'","doi":"https://doi.org/10.11647/OBP.0003","publicationDate":"2009-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Lionel Gossman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1","fullTitle":"Chronicles from Kashmir: An Annotated, Multimedia Script","doi":"https://doi.org/10.11647/OBP.0223","publicationDate":"2020-09-14","place":"Cambridge, UK","contributions":[{"fullName":"Nandita Dinesh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c5fe7f09-7dfb-4637-82c8-653a6cb683e7","fullTitle":"Cicero, Against Verres, 2.1.53–86: Latin Text with Introduction, Study Questions, Commentary and English Translation","doi":"https://doi.org/10.11647/OBP.0016","publicationDate":"2011-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a03ba4d1-1576-41d0-9e8b-d74eccb682e2","fullTitle":"Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation","doi":"https://doi.org/10.11647/OBP.0045","publicationDate":"2014-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Louise Hodgson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7e753cbc-c74b-4214-a565-2300f544be77","fullTitle":"Cicero, Philippic 2, 44–50, 78–92, 100–119: Latin Text, Study Aids with Vocabulary, and Commentary","doi":"https://doi.org/10.11647/OBP.0156","publicationDate":"2018-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fd4d3c2a-355f-4bc0-83cb-1cd6764976e7","fullTitle":"Classical Music: Contemporary Perspectives and Challenges","doi":"https://doi.org/10.11647/OBP.0242","publicationDate":"2021-03-30","place":"Cambridge, UK","contributions":[{"fullName":"Beckerman Michael","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Boghossian Paul","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"9ea10b68-b23c-4562-b0ca-03ba548889a3","fullTitle":"Coleridge's Laws: A Study of Coleridge in Malta","doi":"https://doi.org/10.11647/OBP.0005","publicationDate":"2010-01-01","place":"Cambridge, UK","contributions":[{"fullName":"Barry Hough","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Howard Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Lydia Davis","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Micheal John Kooy","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"98776400-e985-488d-a3f1-9d88879db3cf","fullTitle":"Complexity, Security and Civil Society in East Asia: Foreign Policies and the Korean Peninsula","doi":"https://doi.org/10.11647/OBP.0059","publicationDate":"2015-06-22","place":"Cambridge, UK","contributions":[{"fullName":"Kiho Yi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Peter Hayes","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"296c6880-6212-48d2-b327-2c13b6e28d5f","fullTitle":"Conservation Biology in Sub-Saharan Africa","doi":"https://doi.org/10.11647/OBP.0177","publicationDate":"2019-09-08","place":"Cambridge, UK","contributions":[{"fullName":"John W. Wilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Richard B. Primack","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"e5ade02a-2f32-495a-b879-98b54df04c0a","fullTitle":"Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary","doi":"https://doi.org/10.11647/OBP.0068","publicationDate":"2015-10-05","place":"Cambridge, UK","contributions":[{"fullName":"Bret Mulligan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c86acc9-89a0-4b17-bcdd-520d33fc4f54","fullTitle":"Creative Multilingualism: A Manifesto","doi":"https://doi.org/10.11647/OBP.0206","publicationDate":"2020-05-20","place":"Cambridge, UK","contributions":[{"fullName":"Wen-chin Ouyang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Rajinder Dudrah","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Andrew Gosler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Martin Maiden","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Suzanne Graham","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Katrin Kohl","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"10ddfb3d-3434-46f8-a3bb-14dfc0ce9591","fullTitle":"Cultural Heritage Ethics: Between Theory and Practice","doi":"https://doi.org/10.11647/OBP.0047","publicationDate":"2014-10-13","place":"Cambridge, UK","contributions":[{"fullName":"Sandis Constantine","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2b031e1a-678b-4dcb-becb-cbd0f0ce9182","fullTitle":"Deliberation, Representation, Equity: Research Approaches, Tools and Algorithms for Participatory Processes","doi":"https://doi.org/10.11647/OBP.0108","publicationDate":"2017-01-23","place":"Cambridge, UK","contributions":[{"fullName":"Mats Danielson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Love Ekenberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Karin Hansson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Göran Cars","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"bc253bff-cf00-433d-89a2-031500b888ff","fullTitle":"Delivering on the Promise of Democracy: Visual Case Studies in Educational Equity and Transformation","doi":"https://doi.org/10.11647/OBP.0157","publicationDate":"2019-01-16","place":"Cambridge, UK","contributions":[{"fullName":"Sukhwant Jhaj","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"517963d1-a56a-4250-8a07-56743ba60d95","fullTitle":"Democracy and Power: The Delhi Lectures","doi":"https://doi.org/10.11647/OBP.0050","publicationDate":"2014-12-07","place":"Cambridge, UK","contributions":[{"fullName":"Noam Chomsky","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jean Drèze","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"60450f84-3e18-4beb-bafe-87c78b5a0159","fullTitle":"Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition","doi":"https://doi.org/10.11647/OBP.0098","publicationDate":"2016-06-20","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]},{"workId":"b3989be1-9115-4635-b766-92f6ebfabef1","fullTitle":"Denis Diderot's 'Rameau's Nephew': A Multi-media Edition","doi":"https://doi.org/10.11647/OBP.0044","publicationDate":"2014-08-24","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]},{"workId":"594ddcb6-2363-47c8-858e-76af2283e486","fullTitle":"Dickens’s Working Notes for 'Dombey and Son'","doi":"https://doi.org/10.11647/OBP.0092","publicationDate":"2017-09-04","place":"Cambridge, UK","contributions":[{"fullName":"Tony Laing","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d3adf77-c72b-4b69-bf5a-a042a38a837a","fullTitle":"Dictionary of the British English Spelling System","doi":"https://doi.org/10.11647/OBP.0053","publicationDate":"2015-03-30","place":"Cambridge, UK","contributions":[{"fullName":"Greg Brooks","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"364c223d-9c90-4ceb-90e2-51be7d84e923","fullTitle":"Die Europaidee im Zeitalter der Aufklärung","doi":"https://doi.org/10.11647/OBP.0127","publicationDate":"2017-08-21","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d4812e4-c491-4465-8e92-64e4f13662f1","fullTitle":"Digital Humanities Pedagogy: Practices, Principles and Politics","doi":"https://doi.org/10.11647/OBP.0024","publicationDate":"2012-12-20","place":"Cambridge, UK","contributions":[{"fullName":"Brett D. Hirsch","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"43d96298-a683-4098-9492-bba1466cb8e0","fullTitle":"Digital Scholarly Editing: Theories and Practices","doi":"https://doi.org/10.11647/OBP.0095","publicationDate":"2016-08-15","place":"Cambridge, UK","contributions":[{"fullName":"Elena Pierazzo","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Matthew James Driscoll","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"912c2731-3ca1-4ad9-b601-5d968da6b030","fullTitle":"Digital Technology and the Practices of Humanities Research","doi":"https://doi.org/10.11647/OBP.0192","publicationDate":"2020-01-30","place":"Cambridge, UK","contributions":[{"fullName":"Jennifer Edmond","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"78bbcc00-a336-4eb6-b4b5-0c57beec0295","fullTitle":"Discourses We Live By: Narratives of Educational and Social Endeavour","doi":"https://doi.org/10.11647/OBP.0203","publicationDate":"2020-07-03","place":"Cambridge, UK","contributions":[{"fullName":"Hazel R. Wright","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marianne Høyen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1312613f-e01a-499a-b0d0-7289d5b9013d","fullTitle":"Diversity and Rabbinization: Jewish Texts and Societies between 400 and 1000 CE","doi":"https://doi.org/10.11647/OBP.0219","publicationDate":"2021-04-30","place":"Cambridge, UK","contributions":[{"fullName":"Gavin McDowell","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Ron Naiweld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel Stökl Ben Ezra","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"2d74b1a9-c3b0-4278-8cad-856fadc6a19d","fullTitle":"Don Carlos Infante of Spain: A Dramatic Poem","doi":"https://doi.org/10.11647/OBP.0134","publicationDate":"2018-06-04","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"b190b3c5-88c0-4e4a-939a-26995b7ff95c","fullTitle":"Earth 2020: An Insider’s Guide to a Rapidly Changing Planet","doi":"https://doi.org/10.11647/OBP.0193","publicationDate":"2020-04-22","place":"Cambridge, UK","contributions":[{"fullName":"Philippe D. Tortell","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a5e6aa48-02ba-48e4-887f-1c100a532de8","fullTitle":"Economic Fables","doi":"https://doi.org/10.11647/OBP.0020","publicationDate":"2012-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Ariel Rubinstein","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2b63a26d-0db1-4200-983f-8b69d9821d8b","fullTitle":"Engaging Researchers with Data Management: The Cookbook","doi":"https://doi.org/10.11647/OBP.0185","publicationDate":"2019-10-09","place":"Cambridge, UK","contributions":[{"fullName":"Yan Wang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"James Savage","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Connie Clare","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marta Teperek","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Maria Cruz","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Elli Papadopoulou","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"af162e8a-23ab-49e6-896d-e53b9d6c0039","fullTitle":"Essays in Conveyancing and Property Law in Honour of Professor Robert Rennie","doi":"https://doi.org/10.11647/OBP.0056","publicationDate":"2015-05-11","place":"Cambridge, UK","contributions":[{"fullName":"Frankie McCarthy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Stephen Bogle","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"James Chalmers","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"98d053d6-dcc2-409a-8841-9f19920b49ee","fullTitle":"Essays in Honour of Eamonn Cantwell: Yeats Annual No. 20","doi":"https://doi.org/10.11647/OBP.0081","publicationDate":"2016-12-05","place":"Cambridge, UK","contributions":[{"fullName":"Warwick Gould","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"24689aa7-af74-4238-ad75-a9469f094068","fullTitle":"Essays on Paula Rego: Smile When You Think about Hell","doi":"https://doi.org/10.11647/OBP.0178","publicationDate":"2019-09-24","place":"Cambridge, UK","contributions":[{"fullName":"Maria Manuel Lisboa","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f76ab190-35f4-4136-86dd-d7fa02ccaebb","fullTitle":"Ethics for A-Level","doi":"https://doi.org/10.11647/OBP.0125","publicationDate":"2017-07-31","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Fisher","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mark Dimmock","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d90e1915-1d2a-40e6-a94c-79f671031224","fullTitle":"Europa im Geisterkrieg. Studien zu Nietzsche","doi":"https://doi.org/10.11647/OBP.0133","publicationDate":"2018-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Werner Stegmaier","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andrea C. Bertino","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"a0a8d5f1-12d0-4d51-973d-ed1dfa73f01f","fullTitle":"Exploring the Interior: Essays on Literary and Cultural History","doi":"https://doi.org/10.11647/OBP.0126","publicationDate":"2018-05-24","place":"Cambridge, UK","contributions":[{"fullName":"Karl S. Guthke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3795e166-413c-4568-8c19-1117689ef14b","fullTitle":"Feeding the City: Work and Food Culture of the Mumbai Dabbawalas","doi":"https://doi.org/10.11647/OBP.0031","publicationDate":"2013-07-15","place":"Cambridge, UK","contributions":[{"fullName":"Sara Roncaglia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Angela Arnone","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Pier Giorgio Solinas","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"5da7830b-6d55-4eb4-899e-cb2a13b30111","fullTitle":"Fiesco's Conspiracy at Genoa","doi":"https://doi.org/10.11647/OBP.0058","publicationDate":"2015-05-27","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"John Guthrie","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"83b7409e-f076-4598-965e-9e15615be247","fullTitle":"Forests and Food: Addressing Hunger and Nutrition Across Sustainable Landscapes","doi":"https://doi.org/10.11647/OBP.0085","publicationDate":"2015-11-15","place":"Cambridge, UK","contributions":[{"fullName":"Christoph Wildburger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bhaskar Vira","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Stephanie Mansourian","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"1654967f-82f1-4ed0-ae81-7ebbfb9c183d","fullTitle":"Foundations for Moral Relativism","doi":"https://doi.org/10.11647/OBP.0029","publicationDate":"2013-04-17","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"00766beb-0597-48a8-ba70-dd2b8382ec37","fullTitle":"Foundations for Moral Relativism: Second Expanded Edition","doi":"https://doi.org/10.11647/OBP.0086","publicationDate":"2015-11-23","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3083819d-1084-418a-85d4-4f71c2fea139","fullTitle":"From Darkness to Light: Writers in Museums 1798-1898","doi":"https://doi.org/10.11647/OBP.0151","publicationDate":"2019-03-12","place":"Cambridge, UK","contributions":[{"fullName":"Rosella Mamoli Zorzi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Katherine Manthorne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5bf6450f-99a7-4375-ad94-d5bde1b0282c","fullTitle":"From Dust to Digital: Ten Years of the Endangered Archives Programme","doi":"https://doi.org/10.11647/OBP.0052","publicationDate":"2015-02-16","place":"Cambridge, UK","contributions":[{"fullName":"Maja Kominko","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d16896b7-691e-4620-9adb-1d7a42c69bde","fullTitle":"From Goethe to Gundolf: Essays on German Literature and Culture","doi":"https://doi.org/10.11647/OBP.0258","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Roger Paulin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3a167e24-36b5-4d0e-b55f-af6be9a7c827","fullTitle":"Frontier Encounters: Knowledge and Practice at the Russian, Chinese and Mongolian Border","doi":"https://doi.org/10.11647/OBP.0026","publicationDate":"2012-08-01","place":"Cambridge, UK","contributions":[{"fullName":"Grégory Delaplace","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Caroline Humphrey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Franck Billé","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1471f4c3-a88c-4301-b98a-7193be6dde4b","fullTitle":"Gallucci's Commentary on Dürer’s 'Four Books on Human Proportion': Renaissance Proportion Theory","doi":"https://doi.org/10.11647/OBP.0198","publicationDate":"2020-03-25","place":"Cambridge, UK","contributions":[{"fullName":"James Hutson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"101eb7c2-f15f-41f9-b53a-dfccd4b28301","fullTitle":"Global Warming in Local Discourses: How Communities around the World Make Sense of Climate Change","doi":"https://doi.org/10.11647/OBP.0212","publicationDate":"2020-10-14","place":"Cambridge, UK","contributions":[{"fullName":"Michael Brüggemann","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Simone Rödder","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"32e99c61-2352-4a88-bb9a-bd81f113ba1e","fullTitle":"God's Babies: Natalism and Bible Interpretation in Modern America","doi":"https://doi.org/10.11647/OBP.0048","publicationDate":"2014-12-17","place":"Cambridge, UK","contributions":[{"fullName":"John McKeown","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ab3a9d7f-c9b9-42bf-9942-45f68b40bcd6","fullTitle":"Hanging on to the Edges: Essays on Science, Society and the Academic Life","doi":"https://doi.org/10.11647/OBP.0155","publicationDate":"2018-10-15","place":"Cambridge, UK","contributions":[{"fullName":"Daniel Nettle","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9d5ac1c6-a763-49b4-98b2-355d888169be","fullTitle":"Henry James's Europe: Heritage and Transfer","doi":"https://doi.org/10.11647/OBP.0013","publicationDate":"2011-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Adrian Harding","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Annick Duperray","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dennis Tredy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b7790cae-1901-446e-b529-b5fe393d8061","fullTitle":"History of International Relations: A Non-European Perspective","doi":"https://doi.org/10.11647/OBP.0074","publicationDate":"2019-07-31","place":"Cambridge, UK","contributions":[{"fullName":"Erik Ringmar","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7b9b68c6-8bb6-42c5-8b19-bf5e56b7293e","fullTitle":"How to Read a Folktale: The 'Ibonia' Epic from Madagascar","doi":"https://doi.org/10.11647/OBP.0034","publicationDate":"2013-10-08","place":"Cambridge, UK","contributions":[{"fullName":"Lee Haring","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"23651a20-a26e-4253-b0a9-c8b5bf1409c7","fullTitle":"Human and Machine Consciousness","doi":"https://doi.org/10.11647/OBP.0107","publicationDate":"2018-03-07","place":"Cambridge, UK","contributions":[{"fullName":"David Gamez","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"27def25d-48ad-470d-9fbe-1ddc8376e1cb","fullTitle":"Human Cultures through the Scientific Lens: Essays in Evolutionary Cognitive Anthropology","doi":"https://doi.org/10.11647/OBP.0257","publicationDate":"2021-07-09","place":"Cambridge, UK","contributions":[{"fullName":"Pascal Boyer","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"859a1313-7b02-4c66-8010-dbe533c4412a","fullTitle":"Hyperion or the Hermit in Greece","doi":"https://doi.org/10.11647/OBP.0160","publicationDate":"2019-02-25","place":"Cambridge, UK","contributions":[{"fullName":"Howard Gaskill","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1f591391-7497-4447-8c06-d25006a1b922","fullTitle":"Image, Knife, and Gluepot: Early Assemblage in Manuscript and Print","doi":"https://doi.org/10.11647/OBP.0145","publicationDate":"2019-07-16","place":"Cambridge, UK","contributions":[{"fullName":"Kathryn M. Rudy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"50516c2a-154e-4758-9b94-586987af2b7f","fullTitle":"Information and Empire: Mechanisms of Communication in Russia, 1600-1854","doi":"https://doi.org/10.11647/OBP.0122","publicationDate":"2017-11-27","place":"Cambridge, UK","contributions":[{"fullName":"Katherine Bowers","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Simon Franklin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1549f31d-4783-4a63-a050-90ffafd77328","fullTitle":"Infrastructure Investment in Indonesia: A Focus on Ports","doi":"https://doi.org/10.11647/OBP.0189","publicationDate":"2019-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Colin Duffield","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Felix Kin Peng Hui","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Sally Wilson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"1692a92d-f86a-4155-9e6c-16f38586b7fc","fullTitle":"Intellectual Property and Public Health in the Developing World","doi":"https://doi.org/10.11647/OBP.0093","publicationDate":"2016-05-30","place":"Cambridge, UK","contributions":[{"fullName":"Monirul Azam","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d6850e99-33ce-4cae-ac7c-bd82cf23432b","fullTitle":"In the Lands of the Romanovs: An Annotated Bibliography of First-hand English-language Accounts of the Russian Empire (1613-1917)","doi":"https://doi.org/10.11647/OBP.0042","publicationDate":"2014-04-27","place":"Cambridge, UK","contributions":[{"fullName":"Anthony Cross","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4455a769-d374-4eed-8e6a-84c220757c0d","fullTitle":"Introducing Vigilant Audiences","doi":"https://doi.org/10.11647/OBP.0200","publicationDate":"2020-10-14","place":"Cambridge, UK","contributions":[{"fullName":"Rashid Gabdulhakov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel Trottier","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Qian Huang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"e414ca1b-a7f2-48c7-9adb-549a04711241","fullTitle":"Inventory Analytics","doi":"https://doi.org/10.11647/OBP.0252","publicationDate":"2021-05-24","place":"Cambridge, UK","contributions":[{"fullName":"Roberto Rossi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ad55c2c5-9769-4648-9c42-dc4cef1f1c99","fullTitle":"Is Behavioral Economics Doomed? The Ordinary versus the Extraordinary","doi":"https://doi.org/10.11647/OBP.0021","publicationDate":"2012-09-17","place":"Cambridge, UK","contributions":[{"fullName":"David K. Levine","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2ceb72f2-ddde-45a7-84a9-27523849f8f5","fullTitle":"Jane Austen: Reflections of a Reader","doi":"https://doi.org/10.11647/OBP.0216","publicationDate":"2021-02-03","place":"Cambridge, UK","contributions":[{"fullName":"Nora Bartlett","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jane Stabler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5b542db8-c128-48ff-a48c-003c95eaca25","fullTitle":"Jewish-Muslim Intellectual History Entangled: Textual Materials from the Firkovitch Collection, Saint Petersburg","doi":"https://doi.org/10.11647/OBP.0214","publicationDate":"2020-08-03","place":"Cambridge, UK","contributions":[{"fullName":"Jan Thiele","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Wilferd Madelung","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Omar Hamdan","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Adang Camilla","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sabine Schmidtke","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Bruno Chiesa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"df7eb598-914a-49eb-9cbd-9766bd06be84","fullTitle":"Just Managing? What it Means for the Families of Austerity Britain","doi":"https://doi.org/10.11647/OBP.0112","publicationDate":"2017-05-29","place":"Cambridge, UK","contributions":[{"fullName":"Paul Kyprianou","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mark O'Brien","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c5e415c4-1ed1-4c58-abae-b1476689a867","fullTitle":"Knowledge and the Norm of Assertion: An Essay in Philosophical Science","doi":"https://doi.org/10.11647/OBP.0083","publicationDate":"2016-02-26","place":"Cambridge, UK","contributions":[{"fullName":"John Turri","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9fc774fa-3a18-42d8-89e3-b5a23d822dd6","fullTitle":"Labor and Value: Rethinking Marx’s Theory of Exploitation","doi":"https://doi.org/10.11647/OBP.0182","publicationDate":"2019-10-02","place":"Cambridge, UK","contributions":[{"fullName":"Ernesto Screpanti","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"29e28ee7-c52d-43f3-95da-f99f33f0e737","fullTitle":"Les Bienveillantes de Jonathan Littell: Études réunies par Murielle Lucie Clément","doi":"https://doi.org/10.11647/OBP.0006","publicationDate":"2010-04-01","place":"Cambridge, UK","contributions":[{"fullName":"Murielle Lucie Clément","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d9e671dd-ab2a-4fd0-ada3-4925449a63a8","fullTitle":"Letters of Blood and Other Works in English","doi":"https://doi.org/10.11647/OBP.0017","publicationDate":"2011-11-30","place":"Cambridge, UK","contributions":[{"fullName":"Göran Printz-Påhlson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Robert Archambeau","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Elinor Shaffer","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":4},{"fullName":"Lars-Håkan Svensson","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"c699f257-f3e4-4c98-9a3f-741c6a40b62a","fullTitle":"L’idée de l’Europe: au Siècle des Lumières","doi":"https://doi.org/10.11647/OBP.0116","publicationDate":"2017-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"a795aafb-d189-4d15-8e64-b9a3fbfa8e09","fullTitle":"Life Histories of Etnos Theory in Russia and Beyond","doi":"https://doi.org/10.11647/OBP.0150","publicationDate":"2019-02-06","place":"Cambridge, UK","contributions":[{"fullName":"Dmitry V Arzyutov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"David G. Anderson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sergei S. Alymov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"5c55effb-2a3e-4e0d-a46d-edad7830fd8e","fullTitle":"Lifestyle in Siberia and the Russian North","doi":"https://doi.org/10.11647/OBP.0171","publicationDate":"2019-11-22","place":"Cambridge, UK","contributions":[{"fullName":"Joachim Otto Habeck","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6090bfc8-3143-4599-b0dd-17705f754e8c","fullTitle":"Like Nobody's Business: An Insider's Guide to How US University Finances Really Work","doi":"https://doi.org/10.11647/OBP.0240","publicationDate":"2021-02-23","place":"Cambridge, UK","contributions":[{"fullName":"Andrew C. Comrie","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"25a2f70a-832d-4c8d-b28f-75f838b6e171","fullTitle":"Liminal Spaces: Migration and Women of the Guyanese Diaspora","doi":"https://doi.org/10.11647/OBP.0218","publicationDate":"2020-09-29","place":"Cambridge, UK","contributions":[{"fullName":"Grace Aneiza Ali","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9845c8a9-b283-4cb8-8961-d41e5fe795f1","fullTitle":"Literature Against Criticism: University English and Contemporary Fiction in Conflict","doi":"https://doi.org/10.11647/OBP.0102","publicationDate":"2016-10-17","place":"Cambridge, UK","contributions":[{"fullName":"Martin Paul Eve","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f957ab3d-c925-4bf2-82fa-9809007753e7","fullTitle":"Living Earth Community: Multiple Ways of Being and Knowing","doi":"https://doi.org/10.11647/OBP.0186","publicationDate":"2020-05-07","place":"Cambridge, UK","contributions":[{"fullName":"John Grim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Mary Evelyn Tucker","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Sam Mickey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"545f9f42-87c0-415e-9086-eee27925c85b","fullTitle":"Long Narrative Songs from the Mongghul of Northeast Tibet: Texts in Mongghul, Chinese, and English","doi":"https://doi.org/10.11647/OBP.0124","publicationDate":"2017-10-30","place":"Cambridge, UK","contributions":[{"fullName":"Gerald Roche","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Li Dechun","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/peanut-books/","imprintId":"5cc7d3db-f300-4813-9c68-3ccc18a6277b","imprintName":"Peanut Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"14a2356a-4767-4136-b44a-684a28dc87a6","fullTitle":"In a Trance: On Paleo Art","doi":"https://doi.org/10.21983/P3.0081.1.00","publicationDate":"2014-11-13","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Skoblow","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"200b11a8-57d6-4f81-b089-ddd4ee7fe2f2","fullTitle":"The Apartment of Tragic Appliances: Poems","doi":"https://doi.org/10.21983/P3.0030.1.00","publicationDate":"2013-05-26","place":"Brooklyn, NY","contributions":[{"fullName":"Michael D. Snediker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"49ebcb4a-928f-4d83-9596-b296dfce0b20","fullTitle":"The Petroleum Manga: A Project by Marina Zurkow","doi":"https://doi.org/10.21983/P3.0062.1.00","publicationDate":"2014-02-25","place":"Brooklyn, NY","contributions":[{"fullName":"Marina Zurkow","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2a360648-3157-4a1b-9ba7-a61895a8a10c","fullTitle":"Where the Tiny Things Are: Feathered Essays","doi":"https://doi.org/10.21983/P3.0181.1.00","publicationDate":"2017-09-26","place":"Earth, Milky Way","contributions":[{"fullName":"Nicole Walker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/","imprintId":"7522e351-8a91-40fa-bf45-02cb38368b0b","imprintName":"punctum books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"5402ea62-7a1b-48b4-b5fb-7b114c04bc27","fullTitle":"A Boy Asleep under the Sun: Versions of Sandro Penna","doi":"https://doi.org/10.21983/P3.0080.1.00","publicationDate":"2014-11-11","place":"Brooklyn, NY","contributions":[{"fullName":"Sandro Penna","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Peter Valente","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Peter Valente","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"8a27431b-b1f9-4fed-a8e0-0a0aadc9d98c","fullTitle":"A Buddha Land in This World: Philosophy, Utopia, and Radical Buddhism","doi":"https://doi.org/10.53288/0373.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Lajos Brons","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"eeb920c0-6f2e-462c-a315-3687b5ca8da3","fullTitle":"Action [poems]","doi":"https://doi.org/10.21983/P3.0083.1.00","publicationDate":"2014-12-10","place":"Brooklyn, NY","contributions":[{"fullName":"Anthony Opal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"20dab41d-2267-4a68-befa-d787b7c98599","fullTitle":"After the \"Speculative Turn\": Realism, Philosophy, and Feminism","doi":"https://doi.org/10.21983/P3.0152.1.00","publicationDate":"2016-10-26","place":"Earth, Milky Way","contributions":[{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katerina Kolozova","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13a03c11-0f22-4d40-881d-b935452d4bf3","fullTitle":"Air Supplied","doi":"https://doi.org/10.21983/P3.0201.1.00","publicationDate":"2018-05-23","place":"Earth, Milky Way","contributions":[{"fullName":"David Cross","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5147a952-3d44-4beb-8d49-b41c91bce733","fullTitle":"Alternative Historiographies of the Digital Humanities","doi":"https://doi.org/10.53288/0274.1.00","publicationDate":"2021-06-24","place":"Earth, Milky Way","contributions":[{"fullName":"Adeline Koh","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dorothy Kim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f712541c-07b4-477c-8b8c-8c1a307810d0","fullTitle":"And Another Thing: Nonanthropocentrism and Art","doi":"https://doi.org/10.21983/P3.0144.1.00","publicationDate":"2016-06-18","place":"Earth, Milky Way","contributions":[{"fullName":"Katherine Behar","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Emmy Mikelson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"27e17948-02c4-4ba3-8244-5c229cc8e9b8","fullTitle":"Anglo-Saxon(ist) Pasts, postSaxon Futures","doi":"https://doi.org/10.21983/P3.0262.1.00","publicationDate":"2019-12-30","place":"Earth, Milky Way","contributions":[{"fullName":"Donna-Beth Ellard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f3c9e9d8-9a38-4558-be2e-cab9a70d62f0","fullTitle":"Annotations to Geoffrey Hill's Speech! Speech!","doi":"https://doi.org/10.21983/P3.0004.1.00","publicationDate":"2012-01-26","place":"Brooklyn, NY","contributions":[{"fullName":"Ann Hassan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"baf524c6-0a2c-40f2-90a7-e19c6e1b6b97","fullTitle":"Anthropocene Unseen: A Lexicon","doi":"https://doi.org/10.21983/P3.0265.1.00","publicationDate":"2020-02-07","place":"Earth, Milky Way","contributions":[{"fullName":"Cymene Howe","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anand Pandian","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f6afff19-25ae-41f8-8a7a-6c1acffafc39","fullTitle":"Antiracism Inc.: Why the Way We Talk about Racial Justice Matters","doi":"https://doi.org/10.21983/P3.0250.1.00","publicationDate":"2019-04-25","place":"Earth, Milky Way","contributions":[{"fullName":"Paula Ioanide","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alison Reed","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Felice Blake","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"88c47bd3-f8c9-4157-9d1a-770d9be8c173","fullTitle":"A Nuclear Refrain: Emotion, Empire, and the Democratic Potential of Protest","doi":"https://doi.org/10.21983/P3.0271.1.00","publicationDate":"2019-12-19","place":"Earth, Milky Way","contributions":[{"fullName":"Kye Askins","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Phil Johnstone","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kelvin Mason","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"41508a3c-614b-473e-aa74-edcb6b09dc9d","fullTitle":"Ardea: A Philosophical Novella","doi":"https://doi.org/10.21983/P3.0147.1.00","publicationDate":"2016-07-09","place":"Earth, Milky Way","contributions":[{"fullName":"Freya Mathews","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ae9f8357-4b39-4809-a8e9-766e200fb937","fullTitle":"A Rushed Quality","doi":"https://doi.org/10.21983/P3.0103.1.00","publicationDate":"2015-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Odell","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3f78b298-8826-4162-886e-af21a77f2957","fullTitle":"Athens and the War on Public Space: Tracing a City in Crisis","doi":"https://doi.org/10.21983/P3.0199.1.00","publicationDate":"2018-04-20","place":"Earth, Milky Way","contributions":[{"fullName":"Christos Filippidis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Klara Jaya Brekke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Antonis Vradis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"3da27fb9-7a15-446e-ae0f-258c7dd4fd94","fullTitle":"Barton Myers: Works of Architecture and Urbanism","doi":"https://doi.org/10.21983/P3.0249.1.00","publicationDate":"2019-07-05","place":"Earth, Milky Way","contributions":[{"fullName":"Kris Miller-Fisher","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jocelyn Gibbs","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f4d42680-8b02-4e3a-9ec8-44aee852b29f","fullTitle":"Bathroom Songs: Eve Kosofsky Sedgwick as a Poet","doi":"https://doi.org/10.21983/P3.0189.1.00","publicationDate":"2017-11-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jason Edwards","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"637566b3-dca3-4a8b-b5bd-01fcbb77ca09","fullTitle":"Beowulf: A Translation","doi":"https://doi.org/10.21983/P3.0009.1.00","publicationDate":"2012-08-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Hadbawnik","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Thomas Meyer","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel C. Remein","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"David Hadbawnik","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"9bae1a52-f764-417d-9d45-4df12f71cf07","fullTitle":"Beowulf by All","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Elaine Treharne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jean Abbott","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mateusz Fafinski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"a2ce9f9c-f594-4165-83be-e3751d4d17fe","fullTitle":"Beta Exercise: The Theory and Practice of Osamu Kanemura","doi":"https://doi.org/10.21983/P3.0241.1.00","publicationDate":"2019-01-23","place":"Earth, Milky Way","contributions":[{"fullName":"Osamu Kanemura","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Marco Mazzi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Nicholas Marshall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Michiyo Miyake","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"735d8962-5ec7-41ce-a73a-a43c35cc354f","fullTitle":"Between Species/Between Spaces: Art and Science on the Outer Cape","doi":"https://doi.org/10.21983/P3.0325.1.00","publicationDate":"2020-08-13","place":"Earth, Milky Way","contributions":[{"fullName":"Dylan Gauthier","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kendra Sullivan","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a871cb31-e158-401d-a639-3767131c0f34","fullTitle":"Bigger Than You: Big Data and Obesity","doi":"https://doi.org/10.21983/P3.0135.1.00","publicationDate":"2016-03-03","place":"Earth, Milky Way","contributions":[{"fullName":"Katherine Behar","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"940d0880-83b5-499d-9f39-1bf30ccfc4d0","fullTitle":"Book of Anonymity","doi":"https://doi.org/10.21983/P3.0315.1.00","publicationDate":"2021-03-04","place":"Earth, Milky Way","contributions":[{"fullName":"Anon Collective","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"006571ae-ac0e-4cb0-8a3f-71280aa7f23b","fullTitle":"Broken Records","doi":"https://doi.org/10.21983/P3.0137.1.00","publicationDate":"2016-03-21","place":"Earth, Milky Way","contributions":[{"fullName":"Snežana Žabić","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"47c71c05-a4f1-48da-b8d5-9e5ba139a8ea","fullTitle":"Building Black: Towards Antiracist Architecture","doi":"https://doi.org/10.21983/P3.0372.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Elliot C. Mason","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"dd9008ae-0172-4e07-b3cf-50c35c51b606","fullTitle":"Bullied: The Story of an Abuse","doi":"https://doi.org/10.21983/P3.0356.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"46344fe3-1d72-4ddd-a57e-1d3f4377d2a2","fullTitle":"Centaurs, Rioting in Thessaly: Memory and the Classical World","doi":"https://doi.org/10.21983/P3.0192.1.00","publicationDate":"2018-01-09","place":"Earth, Milky Way","contributions":[{"fullName":"Martyn Hudson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7f1d3e2e-c708-4f59-81cf-104c1ca528d0","fullTitle":"Chaste Cinematics","doi":"https://doi.org/10.21983/P3.0117.1.00","publicationDate":"2015-10-31","place":"Brooklyn, NY","contributions":[{"fullName":"Victor J. Vitanza","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b2d1b2e3-226e-43c2-a898-fbad7b410e3f","fullTitle":"Christina McPhee: A Commonplace Book","doi":"https://doi.org/10.21983/P3.0186.1.00","publicationDate":"2017-10-17","place":"Earth, Milky Way","contributions":[{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"45aa16fa-5fd5-4449-a3bd-52d734fcb0a9","fullTitle":"Cinema's Doppelgängers\n","doi":"https://doi.org/10.53288/0320.1.00","publicationDate":"2021-06-17","place":"Earth, Milky Way","contributions":[{"fullName":"Doug Dibbern","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"84447325-88e2-4658-8597-3f2329451156","fullTitle":"Clinical Encounters in Sexuality: Psychoanalytic Practice and Queer Theory","doi":"https://doi.org/10.21983/P3.0167.1.00","publicationDate":"2017-03-07","place":"Earth, Milky Way","contributions":[{"fullName":"Eve Watson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Noreen Giffney","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d0430e3-3640-4d87-8f02-cbb45f6ae83b","fullTitle":"Comic Providence","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Janet Thormann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0ff62120-4478-46dc-8d01-1d7e1dc5b7a6","fullTitle":"Commonist Tendencies: Mutual Aid beyond Communism","doi":"https://doi.org/10.21983/P3.0040.1.00","publicationDate":"2013-07-23","place":"Brooklyn, NY","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea","doi":"https://doi.org/10.21983/P3.0269.1.00","publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"93330f65-a84f-4c5c-aa44-f710c714eca2","fullTitle":"Continent. Year 1: A Selection of Issues 1.1–1.4","doi":"https://doi.org/10.21983/P3.0016.1.00","publicationDate":"2012-12-12","place":"Brooklyn, NY","contributions":[{"fullName":"Nico Jenkins","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Adam Staley Groves","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Paul Boshears","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Jamie Allen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3d78e15e-19cb-464a-a238-b5291dbfd49f","fullTitle":"Creep: A Life, A Theory, An Apology","doi":"https://doi.org/10.21983/P3.0178.1.00","publicationDate":"2017-08-29","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f2a2626b-4029-4e43-bb84-7b3cacf61b23","fullTitle":"Crisis States: Governance, Resistance & Precarious Capitalism","doi":"https://doi.org/10.21983/P3.0146.1.00","publicationDate":"2016-07-05","place":"Earth, Milky Way","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"639a3c5b-82ad-4557-897b-2bfebe3dc53c","fullTitle":"Critique of Sovereignty, Book 1: Contemporary Theories of Sovereignty","doi":"https://doi.org/10.21983/P3.0114.1.00","publicationDate":"2015-09-28","place":"Brooklyn, NY","contributions":[{"fullName":"Marc Lombardo","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f37627c1-d89f-434c-9915-f1f2f33dc037","fullTitle":"Crush","doi":"https://doi.org/10.21983/P3.0063.1.00","publicationDate":"2014-02-27","place":"Brooklyn, NY","contributions":[{"fullName":"Will Stockton","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"D. Gilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"43355368-b29b-4fa1-9ed6-780f4983364a","fullTitle":"Damayanti and Nala's Tale","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Dan Rudmann","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"11749800-364e-4a27-bf79-9f0ceeacb4d6","fullTitle":"Dark Chaucer: An Assortment","doi":"https://doi.org/10.21983/P3.0018.1.00","publicationDate":"2012-12-23","place":"Brooklyn, NY","contributions":[{"fullName":"Nicola Masciandaro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Myra Seaman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"7fe2c6dc-6673-4537-a397-1f0377c2296f","fullTitle":"Dear Professor: A Chronicle of Absences","doi":"https://doi.org/10.21983/P3.0160.1.00","publicationDate":"2016-12-19","place":"Earth, Milky Way","contributions":[{"fullName":"Filip Noterdaeme","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Shuki Cohen","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"0985e294-aa85-40d0-90ce-af53ae37898d","fullTitle":"Deleuze and the Passions","doi":"https://doi.org/10.21983/P3.0161.1.00","publicationDate":"2016-12-21","place":"Earth, Milky Way","contributions":[{"fullName":"Sjoerd van Tuinen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ceciel Meiborg","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9e6bb4d8-4e05-4cd7-abe9-4a795ade0340","fullTitle":"Derrida and Queer Theory","doi":"https://doi.org/10.21983/P3.0172.1.00","publicationDate":"2017-05-26","place":"Earth, Milky Way","contributions":[{"fullName":"Christian Hite","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9e11adff-abed-4b5d-adef-b0c4466231e8","fullTitle":"Desire/Love","doi":"https://doi.org/10.21983/P3.0015.1.00","publicationDate":"2012-12-05","place":"Brooklyn, NY","contributions":[{"fullName":"Lauren Berlant","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6141d35a-a5a6-43ee-b6b6-5caa41bce869","fullTitle":"Desire/Love","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Lauren Berlant","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13c12944-701a-41f4-9d85-c753267d564b","fullTitle":"Destroyer of Naivetés","doi":"https://doi.org/10.21983/P3.0118.1.00","publicationDate":"2015-11-07","place":"Brooklyn, NY","contributions":[{"fullName":"Joseph Nechvatal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"69c890c5-d8c5-4295-b5a7-688560929d8b","fullTitle":"Dialectics Unbound: On the Possibility of Total Writing","doi":"https://doi.org/10.21983/P3.0041.1.00","publicationDate":"2013-07-28","place":"Brooklyn, NY","contributions":[{"fullName":"Maxwell Kennel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"25be3523-34b5-43c9-a3e2-b12ffb859025","fullTitle":"Dire Pessimism: An Essay","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Thomas Carl Wall","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"245c521a-5014-4da0-bf2b-35eff9673367","fullTitle":"dis/cord: Thinking Sound through Agential Realism","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Kevin Toksöz Fairbarn","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"488c640d-e742-465a-98b4-1234bb09d038","fullTitle":"Diseases of the Head: Essays on the Horrors of Speculative Philosophy","doi":"https://doi.org/10.21983/P3.0280.1.00","publicationDate":"2020-09-24","place":"Earth, Milky Way","contributions":[{"fullName":"Matt Rosen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"754c1299-9b8d-41ac-a1d6-534f174fa87b","fullTitle":"Disturbing Times: Medieval Pasts, Reimagined Futures","doi":"https://doi.org/10.21983/P3.0313.1.00","publicationDate":"2020-06-04","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Anna Kłosowska","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Catherine E. Karkov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"438e0846-b4b9-4c84-9545-d7a6fb13e996","fullTitle":"Divine Name Verification: An Essay on Anti-Darwinism, Intelligent Design, and the Computational Nature of Reality","doi":"https://doi.org/10.21983/P3.0043.1.00","publicationDate":"2013-08-23","place":"Brooklyn, NY","contributions":[{"fullName":"Noah Horwitz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9d1f849d-cf0f-4d0c-8dab-8819fad00337","fullTitle":"Dollar Theater Theory","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Trevor Owen Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cd037a39-f6b9-462a-a207-5079a000065b","fullTitle":"Dotawo: A Journal of Nubian Studies 1","doi":"https://doi.org/10.21983/P3.0071.1.00","publicationDate":"2014-06-23","place":"Brooklyn, NY","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Angelika Jakobi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"6092f859-05fe-475d-b914-3c1a6534e6b9","fullTitle":"Down to Earth: A Memoir","doi":"https://doi.org/10.21983/P3.0306.1.00","publicationDate":"2020-10-22","place":"Earth, Milky Way","contributions":[{"fullName":"Gísli Pálsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna Yates","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrina Downs-Rose","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"ac6acc15-6927-4cef-95d3-1c71183ef2a6","fullTitle":"Echoes of No Thing: Thinking between Heidegger and Dōgen","doi":"https://doi.org/10.21983/P3.0239.1.00","publicationDate":"2019-01-04","place":"Earth, Milky Way","contributions":[{"fullName":"Nico Jenkins","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2658fe95-2df3-4e7d-8df6-e86c18359a23","fullTitle":"Ephemeral Coast, S. Wales","doi":"https://doi.org/10.21983/P3.0079.1.00","publicationDate":"2014-11-01","place":"Brooklyn, NY","contributions":[{"fullName":"Celina Jeffery","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"98ce9caa-487e-4391-86c9-e5d8129be5b6","fullTitle":"Essays on the Peripheries","doi":"https://doi.org/10.21983/P3.0291.1.00","publicationDate":"2021-04-22","place":"Earth, Milky Way","contributions":[{"fullName":"Peter Valente","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"19b32470-bf29-48e1-99db-c08ef90516a9","fullTitle":"Everyday Cinema: The Films of Marc Lafia","doi":"https://doi.org/10.21983/P3.0164.1.00","publicationDate":"2017-01-31","place":"Earth, Milky Way","contributions":[{"fullName":"Marc Lafia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"859e72c3-8159-48e4-b2f0-842f3400cb8d","fullTitle":"Extraterritorialities in Occupied Worlds","doi":"https://doi.org/10.21983/P3.0131.1.00","publicationDate":"2016-02-16","place":"Earth, Milky Way","contributions":[{"fullName":"Ruti Sela Maayan Amir","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1b870455-0b99-4d0e-af22-49f4ebbb6493","fullTitle":"Finding Room in Beirut: Places of the Everyday","doi":"https://doi.org/10.21983/P3.0243.1.00","publicationDate":"2019-02-08","place":"Earth, Milky Way","contributions":[{"fullName":"Carole Lévesque","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6ca16a49-7c95-4c81-b8f0-8f3c7e42de7d","fullTitle":"Flash + Cube (1965–1975)","doi":"https://doi.org/10.21983/P3.0036.1.00","publicationDate":"2013-07-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marget Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7fbc96cf-4c88-4e70-b1fe-d4e69324184a","fullTitle":"Flash + Cube (1965–1975)","doi":null,"publicationDate":"2012-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marget Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f4a04558-958a-43da-b009-d5b7580c532f","fullTitle":"Follow for Now, Volume 2: More Interviews with Friends and Heroes","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Roy Christopher","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97a2ac65-5b1b-4ab8-8588-db8340f04d27","fullTitle":"Fuckhead","doi":"https://doi.org/10.21983/P3.0048.1.00","publicationDate":"2013-09-24","place":"Brooklyn, NY","contributions":[{"fullName":"David Rawson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f3294e78-9a12-49ff-983e-ed6154ff621e","fullTitle":"Gender Trouble Couplets, Volume 1","doi":"https://doi.org/10.21983/P3.0266.1.00","publicationDate":"2019-11-15","place":"Earth, Milky Way","contributions":[{"fullName":"A.W. Strouse","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna M. Kłosowska","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"c80467d8-d472-4643-9a50-4ac489da14dd","fullTitle":"Geographies of Identity","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jill Darling","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"bbe77bbb-0242-46d7-92d2-cfd35c17fe8f","fullTitle":"Heathen Earth: Trumpism and Political Ecology","doi":"https://doi.org/10.21983/P3.0170.1.00","publicationDate":"2017-05-09","place":"Earth, Milky Way","contributions":[{"fullName":"Kyle McGee","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"875a78d7-fad2-4c22-bb04-35e0456b6efa","fullTitle":"Heavy Processing (More than a Feeling)","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"T.L. Cowan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jasmine Rault","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7f72c34d-4515-42eb-a32e-38fe74217b70","fullTitle":"Hephaestus Reloaded: Composed for Ten Hands / Efesto Reloaded: Composizioni per 10 mani","doi":"https://doi.org/10.21983/P3.0258.1.00","publicationDate":"2019-12-13","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Berg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Brunella Antomarini","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Miltos Maneta","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Vladimir D’Amora","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pietro Traversa","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":8},{"fullName":"Patrick Camiller","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":7},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":6}]},{"workId":"b63ffeb5-7906-4c74-8ec2-68cbe87f593c","fullTitle":"History According to Cattle","doi":"https://doi.org/10.21983/P3.0116.1.00","publicationDate":"2015-10-01","place":"Brooklyn, NY","contributions":[{"fullName":"Terike Haapoja","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Laura Gustafsson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4f46d026-49c6-4319-b79a-a6f70d412b5c","fullTitle":"Homotopia? Gay Identity, Sameness & the Politics of Desire","doi":"https://doi.org/10.21983/P3.0124.1.00","publicationDate":"2015-12-25","place":"Brooklyn, NY","contributions":[{"fullName":"Jonathan Kemp","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0257269-5ca3-40b3-b4e1-90f66baddb88","fullTitle":"Humid, All Too Humid: Overheated Observations","doi":"https://doi.org/10.21983/P3.0132.1.00","publicationDate":"2016-02-25","place":"Earth, Milky Way","contributions":[{"fullName":"Dominic Pettman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"241f9c62-26be-4d0f-864b-ad4b243a03c3","fullTitle":"Imperial Physique","doi":"https://doi.org/10.21983/P3.0268.1.00","publicationDate":"2019-11-19","place":"Earth, Milky Way","contributions":[{"fullName":"JH Phrydas","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aeed0683-e022-42d0-a954-f9f36afc4bbf","fullTitle":"Incomparable Poetry: An Essay on the Financial Crisis of 2007–2008 and Irish Literature","doi":"https://doi.org/10.21983/P3.0286.1.00","publicationDate":"2020-05-14","place":"Earth, Milky Way","contributions":[{"fullName":"Robert Kiely","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5ec826f5-18ab-498c-8b66-bd288618df15","fullTitle":"Insurrectionary Infrastructures","doi":"https://doi.org/10.21983/P3.0200.1.00","publicationDate":"2018-05-02","place":"Earth, Milky Way","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"89990379-94c2-4590-9037-cbd5052694a4","fullTitle":"Intimate Bureaucracies","doi":"https://doi.org/10.21983/P3.0005.1.00","publicationDate":"2012-03-09","place":"Brooklyn, NY","contributions":[{"fullName":"dj readies","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"85a2a2fe-d515-4784-b451-d26ec4c62a4f","fullTitle":"Iteration:Again: 13 Public Art Projects across Tasmania","doi":"https://doi.org/10.21983/P3.0037.1.00","publicationDate":"2013-07-02","place":"Brooklyn, NY","contributions":[{"fullName":"David Cross","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael Edwards","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"f3db2a03-75db-4837-af31-4bb0cb189fa2","fullTitle":"Itinerant Philosophy: On Alphonso Lingis","doi":"https://doi.org/10.21983/P3.0073.1.00","publicationDate":"2014-08-04","place":"Brooklyn, NY","contributions":[{"fullName":"Tom Sparrow","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bobby George","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1376b0f4-e967-4a6f-8d7d-8ba876bbbdde","fullTitle":"Itinerant Spectator/Itinerant Spectacle","doi":"https://doi.org/10.21983/P3.0056.1.00","publicationDate":"2013-12-20","place":"Brooklyn, NY","contributions":[{"fullName":"P.A. Skantze","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"da814d9f-14ff-4660-acfe-52ac2a2058fa","fullTitle":"Journal of Badiou Studies 3: On Ethics","doi":"https://doi.org/10.21983/P3.0070.1.00","publicationDate":"2014-06-04","place":"Brooklyn, NY","contributions":[{"fullName":"Arthur Rose","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Nicolò Fazioni","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7e2e26fd-4b0b-4c0b-a1fa-278524c43757","fullTitle":"Journal of Badiou Studies 5: Architheater","doi":"https://doi.org/10.21983/P3.0173.1.00","publicationDate":"2017-07-07","place":"Earth, Milky Way","contributions":[{"fullName":"Arthur Rose","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adi Efal-Lautenschläger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"d2e40ec1-5c2a-404d-8e9f-6727c7c178dc","fullTitle":"Kill Boxes: Facing the Legacy of US-Sponsored Torture, Indefinite Detention, and Drone Warfare","doi":"https://doi.org/10.21983/P3.0166.1.00","publicationDate":"2017-03-02","place":"Earth, Milky Way","contributions":[{"fullName":"Elisabeth Weber","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Richard Falk","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"75693fd0-e93a-4fc3-b82e-4c83a11f28b1","fullTitle":"Knocking the Hustle: Against the Neoliberal Turn in Black Politics","doi":"https://doi.org/10.21983/P3.0121.1.00","publicationDate":"2015-12-10","place":"Brooklyn, NY","contributions":[{"fullName":"Lester K. Spence","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed3ea389-5d5c-430c-9453-814ed94e027b","fullTitle":"Knowledge, Spirit, Law, Book 1: Radical Scholarship","doi":"https://doi.org/10.21983/P3.0123.1.00","publicationDate":"2015-12-24","place":"Brooklyn, NY","contributions":[{"fullName":"Gavin Keeney","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d0d59741-4866-42c3-8528-f65c3da3ffdd","fullTitle":"Language Parasites: Of Phorontology","doi":"https://doi.org/10.21983/P3.0169.1.00","publicationDate":"2017-05-04","place":"Earth, Milky Way","contributions":[{"fullName":"Sean Braune","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1a71ecd5-c868-44af-9b53-b45888fb241c","fullTitle":"Lapidari 1: Texts","doi":"https://doi.org/10.21983/P3.0094.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonida Gashi","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"df518095-84ff-4138-b2f9-5d8fe6ddf53a","fullTitle":"Lapidari 2: Images, Part I","doi":"https://doi.org/10.21983/P3.0091.1.00","publicationDate":"2015-02-15","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"a9d68f12-1de4-4c08-84b1-fe9a786ab47f","fullTitle":"Lapidari 3: Images, Part II","doi":"https://doi.org/10.21983/P3.0092.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"08788fe1-c17d-4f6b-aeab-c81aa3036940","fullTitle":"Left Bank Dream","doi":"https://doi.org/10.21983/P3.0084.1.00","publicationDate":"2014-12-26","place":"Brooklyn, NY","contributions":[{"fullName":"Beryl Scholssman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b4d68a6d-01fb-48f1-9f64-1fcdaaf1cdfd","fullTitle":"Leper Creativity: Cyclonopedia Symposium","doi":"https://doi.org/10.21983/P3.0017.1.00","publicationDate":"2012-12-22","place":"Brooklyn, NY","contributions":[{"fullName":"Eugene Thacker","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Nicola Masciandaro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Edward Keller","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"00e012c5-9232-472c-bd8b-8ca4ea6d1275","fullTitle":"Li Bo Unkempt","doi":"https://doi.org/10.21983/P3.0322.1.00","publicationDate":"2021-03-30","place":"Earth, Milky Way","contributions":[{"fullName":"Kidder Smith","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Kidder Smith","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mike Zhai","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Traktung Yeshe Dorje","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":4},{"fullName":"Maria Dolgenas","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":5}]},{"workId":"534c3d13-b18b-4be5-91e6-768c0cf09361","fullTitle":"Living with Monsters","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Ilana Gershon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Yasmine Musharbash","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"636a5aa6-1d37-4cd2-8742-4dcad8c67e0c","fullTitle":"Love Don't Need a Reason: The Life & Music of Michael Callen","doi":"https://doi.org/10.21983/P3.0297.1.00","publicationDate":"2020-11-05","place":"Earth, Milky Way","contributions":[{"fullName":"Matthew J.\n Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6dcf29ea-76c1-4121-ad7f-2341574c45fe","fullTitle":"Luminol Theory","doi":"https://doi.org/10.21983/P3.0177.1.00","publicationDate":"2017-08-24","place":"Earth, Milky Way","contributions":[{"fullName":"Laura E. Joyce","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed96eea8-82c6-46c5-a19b-dad5e45962c6","fullTitle":"Make and Let Die: Untimely Sovereignties","doi":"https://doi.org/10.21983/P3.0136.1.00","publicationDate":"2016-03-10","place":"Earth, Milky Way","contributions":[{"fullName":"Kathleen Biddick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Eileen A. Joy","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"003137ea-4fe6-470d-8bd3-f936ad065f3c","fullTitle":"Making the Geologic Now: Responses to Material Conditions of Contemporary Life","doi":"https://doi.org/10.21983/P3.0014.1.00","publicationDate":"2012-12-04","place":"Brooklyn, NY","contributions":[{"fullName":"Elisabeth Ellsworth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jamie Kruse","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"35ed7096-8218-43d7-a572-6453c9892ed1","fullTitle":"Manifesto for a Post-Critical Pedagogy","doi":"https://doi.org/10.21983/P3.0193.1.00","publicationDate":"2018-01-11","place":"Earth, Milky Way","contributions":[{"fullName":"Piotr Zamojski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Joris Vlieghe","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Naomi Hodgson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":null,"imprintId":"3437ff40-3bff-4cda-9f0b-1003d2980335","imprintName":"Risking Education","updatedAt":"2021-07-06T17:43:41.987789+00:00","createdAt":"2021-07-06T17:43:41.987789+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","fullTitle":"Nothing As We Need It: A Chimera","doi":"https://doi.org/10.53288/0382.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Daniela Cascella","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/speculations/","imprintId":"dcf8d636-38ae-4a63-bae1-40a61b5a3417","imprintName":"Speculations","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"03da5b84-80ba-48bc-89b9-b63fc56b364b","fullTitle":"Speculations","doi":"https://doi.org/10.21983/P3.0343.1.00","publicationDate":"2020-07-30","place":"Earth, Milky Way","contributions":[{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c00d9a0c-320d-4dfb-ba0c-d1adbdb491ef","fullTitle":"Speculations 3","doi":"https://doi.org/10.21983/P3.0010.1.00","publicationDate":"2012-09-03","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"2c71d808-d1a7-4918-afbb-2dfc121e7768","fullTitle":"Speculations II","doi":"https://doi.org/10.21983/P3.0344.1.00","publicationDate":"2020-07-30","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"ee2cb855-4c94-4176-b62c-3114985dd84e","fullTitle":"Speculations IV: Speculative Realism","doi":"https://doi.org/10.21983/P3.0032.1.00","publicationDate":"2013-06-05","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"435a1db3-1bbb-44b2-9368-7b2fd8a4e63e","fullTitle":"Speculations VI","doi":"https://doi.org/10.21983/P3.0122.1.00","publicationDate":"2015-12-12","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/thought-crimes/","imprintId":"f2dc7495-17af-4d8a-9306-168fc6fa1f41","imprintName":"Thought | Crimes","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1bba80bd-2efd-41a2-9b09-4ff8da0efeb9","fullTitle":"New Developments in Anarchist Studies","doi":"https://doi.org/10.21983/P3.0349.1.00","publicationDate":"2015-06-13","place":"Brooklyn, NY","contributions":[{"fullName":"pj lilley","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jeff Shantz","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5a1cd53e-640b-46e7-82a6-d95bc4907e36","fullTitle":"The Spectacle of the False Flag: Parapolitics from JFK to Watergate","doi":"https://doi.org/10.21983/P3.0347.1.00","publicationDate":"2014-03-01","place":"Brooklyn, NY","contributions":[{"fullName":"Eric Wilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Guido Giacomo Preparata","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2},{"fullName":"Jeff Shantz","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"c8245465-2937-40fd-9c3e-7bd33deef477","fullTitle":"Who Killed the Berkeley School? Struggles Over Radical Criminology ","doi":"https://doi.org/10.21983/P3.0348.1.00","publicationDate":"2014-04-21","place":"Brooklyn, NY","contributions":[{"fullName":"Julia Schwendinger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Herman Schwendinger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jeff Shantz","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/tiny-collections/","imprintId":"be4c8448-93c8-4146-8d9c-84d121bc4bec","imprintName":"Tiny Collections","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","fullTitle":"Closer to Dust","doi":"https://doi.org/10.53288/0324.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Sara A. Rich","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"771e1cde-d224-4cb6-bac7-7f5ef4d1a405","fullTitle":"Coconuts: A Tiny History","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Kathleen E. Kennedy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"20d15631-f886-43a0-b00b-b62426710bdf","fullTitle":"Elemental Disappearances","doi":"https://doi.org/10.21983/P3.0157.1.00","publicationDate":"2016-11-28","place":"Earth, Milky Way","contributions":[{"fullName":"Jason Bahbak Mohaghegh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Dejan Lukić","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"177e3717-4c07-4f31-9318-616ad3b71e89","fullTitle":"Sea Monsters: Things from the Sea, Volume 2","doi":"https://doi.org/10.21983/P3.0182.1.00","publicationDate":"2017-09-29","place":"Earth, Milky Way","contributions":[{"fullName":"Asa Simon Mittman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Thea Tomaini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6dd15dd7-ae8c-4438-a597-7c99d5be4138","fullTitle":"Walk on the Beach: Things from the Sea, Volume 1","doi":"https://doi.org/10.21983/P3.0143.1.00","publicationDate":"2016-06-17","place":"Earth, Milky Way","contributions":[{"fullName":"Maggie M. Williams","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Karen Eileen Overbey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/uitgeverij/","imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","imprintName":"Uitgeverij","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"b5c810e1-c847-4553-a24e-9893164d9786","fullTitle":"(((","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}]},{"workId":"df9bf011-efaf-49a7-9497-2a4d4cfde9e8","fullTitle":"An Anthology of Asemic Handwriting","doi":"https://doi.org/10.21983/P3.0220.1.00","publicationDate":"2013-08-26","place":"The Hague/Tirana","contributions":[{"fullName":"Michael Jacobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Tim Gaze","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8b77c06a-3c1c-48ac-a32e-466ef37f293e","fullTitle":"A Neo Tropical Companion","doi":"https://doi.org/10.21983/P3.0217.1.00","publicationDate":"2012-01-26","place":"The Hague/Tirana","contributions":[{"fullName":"Jamie Stewart","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c3c09f99-71f9-431c-b0f4-ff30c3f7fe11","fullTitle":"Continuum: Writings on Poetry as Artistic Practice","doi":"https://doi.org/10.21983/P3.0229.1.00","publicationDate":"2015-11-26","place":"The Hague/Tirana","contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c30545e-539b-419a-8b96-5f6c475bab9e","fullTitle":"Disrupting the Digital Humanities","doi":"https://doi.org/10.21983/P3.0230.1.00","publicationDate":"2018-11-06","place":"Earth, Milky Way","contributions":[{"fullName":"Jesse Stommel","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dorothy Kim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"dfe575e1-2836-43f3-a11b-316af9509612","fullTitle":"Exegesis of a Renunciation – Esegesi di una rinuncia","doi":"https://doi.org/10.21983/P3.0226.1.00","publicationDate":"2014-10-14","place":"The Hague/Tirana","contributions":[{"fullName":"Francesco Aprile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bartolomé Ferrando","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2},{"fullName":"Caggiula Cristiano","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"a9b27739-0d29-4238-8a41-47b3ac2d5bd5","fullTitle":"Filial Arcade & Other Poems","doi":"https://doi.org/10.21983/P3.0223.1.00","publicationDate":"2013-12-21","place":"The Hague/Tirana","contributions":[{"fullName":"Adam Staley Groves","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"c2c22cdf-b9d5-406d-9127-45cea8e741b1","fullTitle":"Hippolytus","doi":"https://doi.org/10.21983/P3.0218.1.00","publicationDate":"2012-08-21","place":"The Hague/Tirana","contributions":[{"fullName":"Euripides","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sean Gurd","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"ebeae9d6-7543-4cd4-9fa9-c39c43ba0d4b","fullTitle":"Men in Aïda","doi":"https://doi.org/10.21983/P3.0224.0.00","publicationDate":"2014-12-31","place":"The Hague/Tirana","contributions":[{"fullName":"David J. Melnick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sean Gurd","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"d24a0567-d430-4768-8c4d-1b9d59394af2","fullTitle":"On Blinking","doi":"https://doi.org/10.21983/P3.0219.1.00","publicationDate":"2012-08-23","place":"The Hague/Tirana","contributions":[{"fullName":"Sarah Brigid Hannis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeremy Fernando","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97d205c8-32f0-4e64-a7df-bf56334be638","fullTitle":"paq'batlh: A Klingon Epic","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Floris Schönfeld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. Van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Kees Ligtelijn","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marc Okrand","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"e81ef154-5bc3-481b-9083-64fd7aeb7575","fullTitle":"paq'batlh: The Klingon Epic","doi":"https://doi.org/10.21983/P3.0215.1.00","publicationDate":"2011-10-10","place":"The Hague/Tirana","contributions":[{"fullName":"Floris Schönfeld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. Van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Kees Ligtelijn","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marc Okrand","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"119f1640-dfb4-488f-a564-ef507d74b72d","fullTitle":"Pen in the Park: A Resistance Fairytale – Pen Parkta: Bir Direniş Masalı","doi":"https://doi.org/10.21983/P3.0225.1.00","publicationDate":"2014-02-12","place":"The Hague/Tirana","contributions":[{"fullName":"Raşel Meseri","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sanne Karssenberg","contributionType":"ILUSTRATOR","mainContribution":false,"contributionOrdinal":2}]},{"workId":"0cb39600-2fd2-4a7a-9d3a-6d92b8e32e9e","fullTitle":"Poetry from Beyond the Grave","doi":"https://doi.org/10.21983/P3.0222.1.00","publicationDate":"2013-05-10","place":"The Hague/Tirana","contributions":[{"fullName":"Francisco Cândido \"Chico\" Xavier","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vitor Peqeuno","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeremy Fernando","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"69365c88-4571-45f3-8770-5a94f7c9badc","fullTitle":"Poetry Vocare","doi":"https://doi.org/10.21983/P3.0213.1.00","publicationDate":"2011-01-23","place":"The Hague/Tirana","contributions":[{"fullName":"Adam Staley Groves","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Judith Balso","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"bc283f71-9f37-47c4-b30b-8ed9f3be9f9c","fullTitle":"The Guerrilla I Like a Poet – Ang Gerilya Ay Tulad ng Makata","doi":"https://doi.org/10.21983/P3.0221.1.00","publicationDate":"2013-09-27","place":"The Hague/Tirana","contributions":[{"fullName":"Jose Maria Sison","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonas Staal","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"7be9aa8c-b8af-4b2f-96ff-16e4532f2b83","fullTitle":"The Miracle of Saint Mina – Gis Miinan Nokkor","doi":"https://doi.org/10.21983/P3.0216.1.00","publicationDate":"2012-01-05","place":"The Hague/Tirana","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"El-Shafie El-Guzuuli","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b55c95a7-ce6e-4cfb-8945-cab4e04001e5","fullTitle":"To Be, or Not to Be: Paraphrased","doi":"https://doi.org/10.21983/P3.0227.1.00","publicationDate":"2016-06-17","place":"The Hague/Tirana","contributions":[{"fullName":"Bardsley Rosenbridge","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"367397db-bcb4-4f0e-9185-4be74c119c19","fullTitle":"Writing Art","doi":"https://doi.org/10.21983/P3.0228.1.00","publicationDate":"2015-11-26","place":"The Hague/Tirana","contributions":[{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Alessandro De Francesco","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"6a109b6a-55e9-4dd5-b670-61926c10e611","fullTitle":"Writing Death","doi":"https://doi.org/10.21983/P3.0214.1.00","publicationDate":"2011-06-06","place":"The Hague/Tirana","contributions":[{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Avital Ronell","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]}],"__typename":"Imprint"}]}} +{"data":{"imprints":[{"imprintUrl":"https://punctumbooks.com/imprints/3ecologies-books/","imprintId":"78b0a283-9be3-4fed-a811-a7d4b9df7b25","imprintName":"3Ecologies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9","fullTitle":"A Manga Perfeita","doi":"https://doi.org/10.21983/P3.0270.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Christine Greiner","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Ernesto Filho","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"c3d008a2-b357-4886-acc4-a2c77f1749ee","fullTitle":"Last Year at Betty and Bob's: An Actual Occasion","doi":"https://doi.org/10.53288/0363.1.00","publicationDate":"2021-07-08","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"781b77bd-edf8-4688-937d-cc7cc47de89f","fullTitle":"Last Year at Betty and Bob's: An Adventure","doi":"https://doi.org/10.21983/P3.0234.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ce38f309-4438-479f-bd1c-b3690dbd7d8d","fullTitle":"Last Year at Betty and Bob's: A Novelty","doi":"https://doi.org/10.21983/P3.0233.1.00","publicationDate":"2018-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Sher Doruff","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"edf31616-ea2a-4c51-b932-f510b9eb8848","fullTitle":"No Archive Will Restore You","doi":"https://doi.org/10.21983/P3.0231.1.00","publicationDate":"2018-11-13","place":"Earth, Milky Way","contributions":[{"fullName":"Julietta Singh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d4a3f6cb-3023-4088-a5f4-147fb4510874","fullTitle":"Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Matthew Goulish","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Will Daddario","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1d9045f8-1d8f-479c-983d-383f3a289bec","fullTitle":"Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art","doi":"https://doi.org/10.21983/P3.0327.1.00","publicationDate":"2021-02-18","place":"Earth, Milky Way","contributions":[{"fullName":"Curt Cloninger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ffa5c5dd-ab4b-4739-8281-275d8c1fb504","fullTitle":"Sweet Spots: Writing the Connective Tissue of Relation","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mattie-Martha Sempert","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"757ff294-0fca-40f5-9f33-39a2d3fd5c8a","fullTitle":"Teaching Myself To See","doi":"https://doi.org/10.21983/P3.0303.1.00","publicationDate":"2021-02-11","place":"Earth, Milky Way","contributions":[{"fullName":"Tito Mukhopadhyay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2beff5ba-a543-407e-ae7a-f0ed1788f297","fullTitle":"Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto","doi":"https://doi.org/10.21983/P3.0307.1.00","publicationDate":"2021-04-15","place":"Earth, Milky Way","contributions":[{"fullName":"Alice Rivières","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrin Solhdju","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Damien Bright","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":4},{"fullName":"Isabelle Stengers","contributionType":"AFTERWORD_BY","mainContribution":true,"contributionOrdinal":3}]},{"workId":"571255b8-5bf5-4fe1-a201-5bc7aded7f9d","fullTitle":"The Perfect Mango","doi":"https://doi.org/10.21983/P3.0245.1.00","publicationDate":"2019-02-20","place":"Earth, Milky Way","contributions":[{"fullName":"Erin Manning","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4cfb06e-a5a6-48cc-b7e5-c38228c132a8","fullTitle":"The Unnaming of Aliass","doi":"https://doi.org/10.21983/P3.0299.1.00","publicationDate":"2020-10-01","place":"Earth, Milky Way","contributions":[{"fullName":"Karin Bolender","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/advanced-methods/","imprintId":"ef38d49c-f8cb-4621-9f2f-1637560016e4","imprintName":"Advanced Methods","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"0729b9d1-87d3-4739-8266-4780c3cc93da","fullTitle":"Doing Multispecies Theology","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Mathew Arthur","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"af1d6a61-66bd-47fd-a8c5-20e433f7076b","fullTitle":"Inefficient Mapping: A Protocol for Attuning to Phenomena","doi":"https://doi.org/10.53288/0336.1.00","publicationDate":"2021-08-05","place":"Earth, Milky Way","contributions":[{"fullName":"Linda Knight","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aa9059ba-930c-4327-97a1-c8c7877332c1","fullTitle":"Making a Laboratory: Dynamic Configurations with Transversal Video","doi":"https://doi.org/10.21983/P3.0295.1.00","publicationDate":"2020-08-06","place":"Earth, Milky Way","contributions":[{"fullName":"Ben Spatz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8f256239-8104-4838-9587-ac234aedd822","fullTitle":"Speaking for the Social: A Catalog of Methods","doi":"https://doi.org/10.21983/P3.0378.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Gemma John","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Hannah Knox","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprint/anarchist-developments-in-cultural-studies/","imprintId":"3bdf14c5-7f9f-42d2-8e3b-f78de0475c76","imprintName":"Anarchist Developments in Cultural Studies","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1d014946-aa73-4fae-9042-ef8830089f3c","fullTitle":"Blasting the Canon","doi":"https://doi.org/10.21983/P3.0035.1.00","publicationDate":"2013-06-25","place":"Brooklyn, NY","contributions":[{"fullName":"Ruth Kinna","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Süreyyya Evren","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"e1f74d6b-adab-4e56-8bc9-6fbd0eaab89c","fullTitle":"Ontological Anarché: Beyond Materialism and Idealism","doi":"https://doi.org/10.21983/P3.0060.1.00","publicationDate":"2014-01-24","place":"Brooklyn, NY","contributions":[{"fullName":"Jason Adams","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Duane Rousselle","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/brainstorm-books/","imprintId":"1e464718-2055-486b-bcd9-6e21309fcd80","imprintName":"Brainstorm Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"fdd9e45a-08b4-4b98-9c34-bada71a34979","fullTitle":"Animal Emotions: How They Drive Human Behavior","doi":"https://doi.org/10.21983/P3.0305.1.00","publicationDate":"2020-06-18","place":"Earth, Milky Way","contributions":[{"fullName":"Kenneth L. Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Christian Montag","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"811fd271-b1dc-490a-a872-3d6867d59e78","fullTitle":"Aural History","doi":"https://doi.org/10.21983/P3.0282.1.00","publicationDate":"2020-03-12","place":"Earth, Milky Way","contributions":[{"fullName":"Gila Ashtor","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f01cb60b-69bf-4d11-bd3c-fd5b36663029","fullTitle":"Covert Plants: Vegetal Consciousness and Agency in an Anthropocentric World","doi":"https://doi.org/10.21983/P3.0207.1.00","publicationDate":"2018-09-11","place":"Earth, Milky Way","contributions":[{"fullName":"Prudence Gibson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Brits Baylee","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"9bdf38ca-95fd-4cf4-adf6-ed26e97cf213","fullTitle":"Critique of Fantasy, Vol. 1: Between a Crypt and a Datemark","doi":"https://doi.org/10.21983/P3.0277.1.00","publicationDate":"2020-06-25","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"89f9c84b-be5c-4020-8edc-6fbe0b1c25f5","fullTitle":"Critique of Fantasy, Vol. 2: The Contest between B-Genres","doi":"https://doi.org/10.21983/P3.0278.1.00","publicationDate":"2020-11-24","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"79464e83-b688-4b82-84bc-18d105f60f33","fullTitle":"Critique of Fantasy, Vol. 3: The Block of Fame","doi":"https://doi.org/10.21983/P3.0279.1.00","publicationDate":"2021-01-14","place":"Earth, Milky Way","contributions":[{"fullName":"Laurence A. Rickels","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"992c6ff8-e166-4014-85cc-b53af250a4e4","fullTitle":"Hack the Experience: Tools for Artists from Cognitive Science","doi":"https://doi.org/10.21983/P3.0206.1.00","publicationDate":"2018-09-04","place":"Earth, Milky Way","contributions":[{"fullName":"Ryan Dewey","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4a42f23b-5277-49b5-8310-c3c38ded5bf5","fullTitle":"Opioids: Addiction, Narrative, Freedom","doi":"https://doi.org/10.21983/P3.0210.1.00","publicationDate":"2018-10-05","place":"Earth, Milky Way","contributions":[{"fullName":"Maia Dolphin-Krute","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"18d3d876-bcaf-4e1c-a67a-05537f808a99","fullTitle":"The Hegemony of Psychopathy","doi":"https://doi.org/10.21983/P3.0180.1.00","publicationDate":"2017-09-19","place":"Earth, Milky Way","contributions":[{"fullName":"Lajos Brons","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5dca2af4-43f2-4cdb-a7a5-5654a722c4e0","fullTitle":"Visceral: Essays on Illness Not as Metaphor","doi":"https://doi.org/10.21983/P3.0185.1.00","publicationDate":"2017-10-16","place":"Earth, Milky Way","contributions":[{"fullName":"Maia Dolphin-Krute","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/ctm-documents-initiative/","imprintId":"cec45cc6-8cb5-43ed-888f-165f3fa73842","imprintName":"CTM Documents Initiative","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"b950d243-7cfc-4aee-b908-d1776be327df","fullTitle":"Image Photograph","doi":"https://doi.org/10.21983/P3.0106.1.00","publicationDate":"2015-07-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marc Lafia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"14f2b847-faeb-43c9-b116-88a0091b6f1f","fullTitle":"Knowledge, Spirit, Law, Book 2: The Anti-Capitalist Sublime","doi":"https://doi.org/10.21983/P3.0191.1.00","publicationDate":"2017-12-24","place":"Earth, Milky Way","contributions":[{"fullName":"Gavin Keeney","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1e0c7c29-dcd4-470d-b3ee-8c4012ac79dd","fullTitle":"Liquid Life: On Non-Linear Materiality","doi":"https://doi.org/10.21983/P3.0246.1.00","publicationDate":"2019-12-18","place":"Earth, Milky Way","contributions":[{"fullName":"Rachel Armstrong","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"47cd079b-03f3-4a5b-b5e4-36cec4db7fab","fullTitle":"The Digital Dionysus: Nietzsche and the Network-Centric Condition","doi":"https://doi.org/10.21983/P3.0149.1.00","publicationDate":"2016-09-12","place":"Earth, Milky Way","contributions":[{"fullName":"Dan Mellamphy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Nandita Biswas Mellamphy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1950e4ba-651c-4ec9-83f6-df46b777b10f","fullTitle":"The Funambulist Pamphlets 10: Literature","doi":"https://doi.org/10.21983/P3.0075.1.00","publicationDate":"2014-08-14","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"bdfc263a-7ace-43f3-9c80-140c6fb32ec7","fullTitle":"The Funambulist Pamphlets 11: Cinema","doi":"https://doi.org/10.21983/P3.0095.1.00","publicationDate":"2015-02-20","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f5fb8a0e-ea1d-471f-b76a-a000edae5956","fullTitle":"The Funambulist Pamphlets 1: Spinoza","doi":"https://doi.org/10.21983/P3.0033.1.00","publicationDate":"2013-06-13","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"911de470-77e1-4816-b437-545122a7bf26","fullTitle":"The Funambulist Pamphlets 2: Foucault","doi":"https://doi.org/10.21983/P3.0034.1.00","publicationDate":"2013-06-17","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"61da662d-c720-4d22-957c-4d96071ee5f2","fullTitle":"The Funambulist Pamphlets 3: Deleuze","doi":"https://doi.org/10.21983/P3.0038.1.00","publicationDate":"2013-07-04","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"419e17ed-3bcc-430c-a67e-3121537e4702","fullTitle":"The Funambulist Pamphlets 4: Legal Theory","doi":"https://doi.org/10.21983/P3.0042.1.00","publicationDate":"2013-08-15","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fe8ddfb7-0e5b-4604-811c-78cf4db7528b","fullTitle":"The Funambulist Pamphlets 5: Occupy Wall Street","doi":"https://doi.org/10.21983/P3.0046.1.00","publicationDate":"2013-09-08","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13390641-86f6-4351-923d-8c456f175bff","fullTitle":"The Funambulist Pamphlets 6: Palestine","doi":"https://doi.org/10.21983/P3.0054.1.00","publicationDate":"2013-11-13","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"448c3581-9167-491e-86f7-08d5a6c953a9","fullTitle":"The Funambulist Pamphlets 7: Cruel Designs","doi":"https://doi.org/10.21983/P3.0057.1.00","publicationDate":"2013-12-21","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d3cbb60f-537f-4bd7-96cb-d8aba595a947","fullTitle":"The Funambulist Pamphlets 8: Arakawa + Madeline Gins","doi":"https://doi.org/10.21983/P3.0064.1.00","publicationDate":"2014-03-12","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6fab7c76-7567-4b57-8ad7-90a5536d87af","fullTitle":"The Funambulist Pamphlets 9: Science Fiction","doi":"https://doi.org/10.21983/P3.0069.1.00","publicationDate":"2014-05-28","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"84bbf59f-1dbb-445e-8f65-f26574f609b6","fullTitle":"The Funambulist Papers, Volume 1","doi":"https://doi.org/10.21983/P3.0053.1.00","publicationDate":"2013-10-23","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3b41b8de-b9bb-4ebd-a002-52052a9e39a9","fullTitle":"The Funambulist Papers, Volume 2","doi":"https://doi.org/10.21983/P3.0098.1.00","publicationDate":"2015-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"Léopold Lambert","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/dead-letter-office/","imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","imprintName":"Dead Letter Office","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","fullTitle":"A Bibliography for After Jews and Arabs","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f02786d4-3bcc-473e-8d43-3da66c7e877c","fullTitle":"A Brief Genealogy of Jewish Republicanism: Parting Ways with Judith Butler","doi":"https://doi.org/10.21983/P3.0159.1.00","publicationDate":"2016-12-16","place":"Earth, Milky Way","contributions":[{"fullName":"Irene Tucker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fd67d684-aaff-4260-bb94-9d0373015620","fullTitle":"An Edition of Miles Hogarde's \"A Mirroure of Myserie\"","doi":"https://doi.org/10.21983/P3.0316.1.00","publicationDate":"2021-06-03","place":"Earth, Milky Way","contributions":[{"fullName":"Sebastian Sobecki","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5f441303-4fc6-4a7d-951e-5b966a1cbd91","fullTitle":"An Unspecific Dog: Artifacts of This Late Stage in History","doi":"https://doi.org/10.21983/P3.0163.1.00","publicationDate":"2017-01-18","place":"Earth, Milky Way","contributions":[{"fullName":"Joshua Rothes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7eb6f426-e913-4d69-92c5-15a640f1b4b9","fullTitle":"A Sanctuary of Sounds","doi":"https://doi.org/10.21983/P3.0029.1.00","publicationDate":"2013-05-23","place":"Brooklyn, NY","contributions":[{"fullName":"Andreas Burckhardt","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4fc74913-bde4-426e-b7e5-2f66c60af484","fullTitle":"As If: Essays in As You Like It","doi":"https://doi.org/10.21983/P3.0162.1.00","publicationDate":"2016-12-29","place":"Earth, Milky Way","contributions":[{"fullName":"William N. West","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"06db2bc1-e25a-42c8-8908-fbd774f73204","fullTitle":"Atopological Trilogy: Deleuze and Guattari","doi":"https://doi.org/10.21983/P3.0096.1.00","publicationDate":"2015-03-15","place":"Brooklyn, NY","contributions":[{"fullName":"Zafer Aracagök","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Manola Antonioli","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"a022743e-8b77-4246-a068-e08d57815e27","fullTitle":"CMOK to YOu To: A Correspondence","doi":"https://doi.org/10.21983/P3.0150.1.00","publicationDate":"2016-09-15","place":"Earth, Milky Way","contributions":[{"fullName":"Marc James Léger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Nina Živančević","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f94ded4d-1c87-4503-82f1-a1ca4346e756","fullTitle":"Come As You Are, After Eve Kosofsky Sedgwick","doi":"https://doi.org/10.21983/P3.0342.1.00","publicationDate":"2021-04-06","place":"Earth, Milky Way","contributions":[{"fullName":"Eve Kosofsky Sedgwick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonathan Goldberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"449add5c-b935-47e2-8e46-2545fad86221","fullTitle":"Escargotesque, or, What Is Experience","doi":"https://doi.org/10.21983/P3.0089.1.00","publicationDate":"2015-01-26","place":"Brooklyn, NY","contributions":[{"fullName":"M.H. Bowker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"628bb121-5ba2-4fc1-a741-a8062c45b63b","fullTitle":"Gaffe/Stutter","doi":"https://doi.org/10.21983/P3.0049.1.00","publicationDate":"2013-10-06","place":"Brooklyn, NY","contributions":[{"fullName":"Whitney Anne Trettien","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f131762c-a877-4925-9fa1-50555bc4e2ae","fullTitle":"[Given, If, Then]: A Reading in Three Parts","doi":"https://doi.org/10.21983/P3.0090.1.00","publicationDate":"2015-02-08","place":"Brooklyn, NY","contributions":[{"fullName":"Jennifer Hope Davy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Julia Hölzl","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cb11259b-7b83-498e-bc8a-7c184ee2c279","fullTitle":"Going Postcard: The Letter(s) of Jacques Derrida","doi":"https://doi.org/10.21983/P3.0171.1.00","publicationDate":"2017-05-15","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f8b57164-89e6-48b1-bd70-9d360b53a453","fullTitle":"Helicography","doi":"https://doi.org/10.53288/0352.1.00","publicationDate":"2021-07-22","place":"Earth, Milky Way","contributions":[{"fullName":"Craig Dworkin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6689db84-b329-4ca5-b10c-010fd90c7e90","fullTitle":"History of an Abuse","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ceffc30d-1d28-48c3-acee-e6a2dc38ff37","fullTitle":"How We Read","doi":"https://doi.org/10.21983/P3.0259.1.00","publicationDate":"2019-07-18","place":"Earth, Milky Way","contributions":[{"fullName":"Kaitlin Heller","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Suzanne Conklin Akbari","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"63e2f6b6-f324-4bdc-836e-55515ba3cd8f","fullTitle":"How We Write: Thirteen Ways of Looking at a Blank Page","doi":"https://doi.org/10.21983/P3.0110.1.00","publicationDate":"2015-09-11","place":"Brooklyn, NY","contributions":[{"fullName":"Suzanne Conklin Akbari","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f5217945-8c2c-4e65-a5dd-3dbff208dfb7","fullTitle":"In Divisible Cities: A Phanto-Cartographical Missive","doi":"https://doi.org/10.21983/P3.0044.1.00","publicationDate":"2013-08-26","place":"Brooklyn, NY","contributions":[{"fullName":"Dominic Pettman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d5f5978b-32e0-44a1-a72a-c80568c9b93a","fullTitle":"I Open Fire","doi":"https://doi.org/10.21983/P3.0086.1.00","publicationDate":"2014-12-28","place":"Brooklyn, NY","contributions":[{"fullName":"David Pol","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c6125a74-2801-4255-afe9-89cdb8d253f4","fullTitle":"John Gardner: A Tiny Eulogy","doi":"https://doi.org/10.21983/P3.0013.1.00","publicationDate":"2012-11-29","place":"Brooklyn, NY","contributions":[{"fullName":"Phil Jourdan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8377c394-c27a-44cb-98f5-5e5b789ad7b8","fullTitle":"Last Day Every Day: Figural Thinking from Auerbach and Kracauer to Agamben and Brenez","doi":"https://doi.org/10.21983/P3.0012.1.00","publicationDate":"2012-10-23","place":"Brooklyn, NY","contributions":[{"fullName":"Adrian Martin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1809f10a-d0e3-4481-8f96-cca7f240d656","fullTitle":"Letters on the Autonomy Project in Art and Politics","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Janet Sarbanes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5f1db605-88b6-427a-84cb-ce2fcf0f89a3","fullTitle":"Massa por Argamassa: A \"Libraria de Babel\" e o Sonho de Totalidade","doi":"https://doi.org/10.21983/P3.0264.1.00","publicationDate":"2019-09-17","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Basile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Yuri N. Martinez Laskowski","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f20869c5-746f-491b-8c34-f88dc3728e18","fullTitle":"Minóy","doi":"https://doi.org/10.21983/P3.0072.1.00","publicationDate":"2014-06-30","place":"Brooklyn, NY","contributions":[{"fullName":"Joseph Nechvatal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d40aa92-380c-4fae-98d8-c598bb32e7c6","fullTitle":"Misinterest: Essays, Pensées, and Dreams","doi":"https://doi.org/10.21983/P3.0256.1.00","publicationDate":"2019-06-27","place":"Earth, Milky Way","contributions":[{"fullName":"M.H. Bowker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"34682ba4-201f-4122-8e4a-edc3edc57a7b","fullTitle":"Nicholas of Cusa and the Kairos of Modernity: Cassirer, Gadamer, Blumenberg","doi":"https://doi.org/10.21983/P3.0045.1.00","publicationDate":"2013-09-05","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Edward Moore","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1cfca75f-2e57-4f34-85fb-a1585315a2a9","fullTitle":"Noise Thinks the Anthropocene: An Experiment in Noise Poetics","doi":"https://doi.org/10.21983/P3.0244.1.00","publicationDate":"2019-02-13","place":"Earth, Milky Way","contributions":[{"fullName":"Aaron Zwintscher","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"571d5d40-cfd6-4270-9530-88bfcfc5d8b5","fullTitle":"Non-Conceptual Negativity: Damaged Reflections on Turkey","doi":"https://doi.org/10.21983/P3.0247.1.00","publicationDate":"2019-03-27","place":"Earth, Milky Way","contributions":[{"fullName":"Zafer Aracagök","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Fraco \"Bifo\" Berardi","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"3eb0d095-fc27-4add-8202-1dc2333a758c","fullTitle":"Notes on Trumpspace: Politics, Aesthetics, and the Fantasy of Home","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"David Stephenson Markus","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"48e2a673-aec2-4ed6-99d4-46a8de200493","fullTitle":"Nothing in MoMA","doi":"https://doi.org/10.21983/P3.0208.1.00","publicationDate":"2018-09-22","place":"Earth, Milky Way","contributions":[{"fullName":"Abraham Adams","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97019dea-e207-4909-b907-076d0620ff74","fullTitle":"Obiter Dicta","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Erick Verran","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"10a41381-792f-4376-bed1-3781d1b8bae7","fullTitle":"Of Learned Ignorance: Idea of a Treatise in Philosophy","doi":"https://doi.org/10.21983/P3.0031.1.00","publicationDate":"2013-06-04","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b43ec529-2f51-4c59-b3cb-394f3649502c","fullTitle":"Of the Contract","doi":"https://doi.org/10.21983/P3.0174.1.00","publicationDate":"2017-07-11","place":"Earth, Milky Way","contributions":[{"fullName":"Christopher Clifton","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"63b0e966-e81c-4d84-b41d-3445b0d9911f","fullTitle":"Paris Bride: A Modernist Life","doi":"https://doi.org/10.21983/P3.0281.1.00","publicationDate":"2020-02-21","place":"Earth, Milky Way","contributions":[{"fullName":"John Schad","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed1a8fb5-8b71-43ca-9748-ebd43f0d7580","fullTitle":"Philosophy for Militants","doi":"https://doi.org/10.21983/P3.0168.1.00","publicationDate":"2017-03-15","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5b652d05-2b5f-465a-8c66-f4dc01dafd03","fullTitle":"[provisional self-evidence]","doi":"https://doi.org/10.21983/P3.0111.1.00","publicationDate":"2015-09-13","place":"Brooklyn, NY","contributions":[{"fullName":"Rachel Arrighi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cd836291-fb7f-4508-bdff-cd59dca2b447","fullTitle":"Queer Insists (for José Esteban Muñoz)","doi":"https://doi.org/10.21983/P3.0082.1.00","publicationDate":"2014-12-04","place":"Brooklyn, NY","contributions":[{"fullName":"Michael O'Rourke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"46ab709c-3272-4a03-991e-d1b1394b8e2c","fullTitle":"Ravish the Republic: The Archives of the Iron Garters Crime/Art Collective","doi":"https://doi.org/10.21983/P3.0107.1.00","publicationDate":"2015-07-15","place":"Brooklyn, NY","contributions":[{"fullName":"Michael L. Berger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"28a0db09-a149-43fe-ba08-00dde962b4b8","fullTitle":"Reiner Schürmann and Poetics of Politics","doi":"https://doi.org/10.21983/P3.0209.1.00","publicationDate":"2018-09-28","place":"Earth, Milky Way","contributions":[{"fullName":"Christopher Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5dda1ad6-70ac-4a31-baf2-b77f8f5a8190","fullTitle":"Sappho: Fragments","doi":"https://doi.org/10.21983/P3.0238.1.00","publicationDate":"2018-12-31","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Goldberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"L.O. Aranye Fradenburg Joy","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"8cd5ce6c-d604-46ac-b4f7-1f871589d96a","fullTitle":"Still Life: Notes on Barbara Loden's \"Wanda\" (1970)","doi":"https://doi.org/10.53288/0326.1.00","publicationDate":"2021-07-29","place":"Earth, Milky Way","contributions":[{"fullName":"Anna Backman Rogers","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1547aa4b-7629-4a21-8b2b-621223c73ec9","fullTitle":"Still Thriving: On the Importance of Aranye Fradenburg","doi":"https://doi.org/10.21983/P3.0099.1.00","publicationDate":"2015-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"L.O. Aranye Fradenburg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"08543bd7-e603-43ae-bb0f-1d4c1c96030b","fullTitle":"Suite on \"Spiritus Silvestre\": For Symphony","doi":"https://doi.org/10.21983/P3.0020.1.00","publicationDate":"2012-12-25","place":"Brooklyn, NY","contributions":[{"fullName":"Denzil Ford","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9839926e-56ea-4d71-a3de-44cabd1d2893","fullTitle":"Tar for Mortar: \"The Library of Babel\" and the Dream of Totality","doi":"https://doi.org/10.21983/P3.0196.1.00","publicationDate":"2018-03-15","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Basile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"58aadfa5-abc6-4c44-9768-f8ff41502867","fullTitle":"The Afterlife of Genre: Remnants of the Trauerspiel in Buffy the Vampire Slayer","doi":"https://doi.org/10.21983/P3.0061.1.00","publicationDate":"2014-02-21","place":"Brooklyn, NY","contributions":[{"fullName":"Anthony Curtis Adler","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1d30497f-4340-43ab-b328-9fd2fed3106e","fullTitle":"The Anthology of Babel","doi":"https://doi.org/10.21983/P3.0254.1.00","publicationDate":"2020-01-24","place":"Earth, Milky Way","contributions":[{"fullName":"Ed Simon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"26d522d4-fb46-47bf-a344-fe6af86688d3","fullTitle":"The Bodies That Remain","doi":"https://doi.org/10.21983/P3.0212.1.00","publicationDate":"2018-10-16","place":"Earth, Milky Way","contributions":[{"fullName":"Emmy Beber","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a065ad95-716a-4005-b436-a46d9dbd64df","fullTitle":"The Communism of Thought","doi":"https://doi.org/10.21983/P3.0059.1.00","publicationDate":"2014-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c51c8fa-947b-4a12-a2e9-5306ee81d117","fullTitle":"The Death of Conrad Unger: Some Conjectures Regarding Parasitosis and Associated Suicide Behavior","doi":"https://doi.org/10.21983/P3.0008.1.00","publicationDate":"2012-08-13","place":"Brooklyn, NY","contributions":[{"fullName":"Gary L. Shipley","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a4ff976a-ac8a-49b8-a89c-f52f3030ccaa","fullTitle":"The Map and the Territory\n","doi":"https://doi.org/10.53288/0319.1.00","publicationDate":"2021-08-12","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"33917b8f-775f-4ee2-a43a-6b5285579f84","fullTitle":"The Non-Library","doi":"https://doi.org/10.21983/P3.0065.1.00","publicationDate":"2014-03-13","place":"Brooklyn, NY","contributions":[{"fullName":"Trevor Owen Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"60813d93-663f-4974-8789-1a2ee83cd042","fullTitle":"Theory Is Like a Surging Sea","doi":"https://doi.org/10.21983/P3.0108.1.00","publicationDate":"2015-08-02","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"119e45d6-63ab-4cc4-aabf-06ecba1fb055","fullTitle":"The Witch and the Hysteric: The Monstrous Medieval in Benjamin Christensen's Häxan","doi":"https://doi.org/10.21983/P3.0074.1.00","publicationDate":"2014-08-08","place":"Brooklyn, NY","contributions":[{"fullName":"Patricia Clare Ingham","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alexander Doty","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d6651c3c-c453-42ab-84b3-4e847d3a3324","fullTitle":"Traffic Jams: Analysing Everyday Life through the Immanent Materialism of Deleuze & Guattari","doi":"https://doi.org/10.21983/P3.0023.1.00","publicationDate":"2013-02-13","place":"Brooklyn, NY","contributions":[{"fullName":"David R. Cole","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1399a869-9f56-4980-981d-2cc83f0a6668","fullTitle":"Truth and Fiction: Notes on (Exceptional) Faith in Art","doi":"https://doi.org/10.21983/P3.0007.1.00","publicationDate":"2012-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"Milcho Manchevski","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adrian Martin","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"b904a8eb-9c98-4bb1-bf25-3cb9d075b157","fullTitle":"Warez: The Infrastructure and Aesthetics of Piracy","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Martin Paul Eve","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"77e1fa52-1938-47dd-b8a5-2a57bfbc91d1","fullTitle":"What Is Philosophy?","doi":"https://doi.org/10.21983/P3.0011.1.00","publicationDate":"2012-10-09","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Munro","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"27602ce3-fbd6-4044-8b44-b8421670edae","fullTitle":"Wonder, Horror, and Mystery in Contemporary Cinema: Letters on Malick, Von Trier, and Kieślowski","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Morgan Meis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"J.M. Tyree","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/department-of-eagles/","imprintId":"ef4aece6-6e9c-4f90-b5c3-7e4b78e8942d","imprintName":"Department of Eagles","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"3ccdbbfc-6550-49f4-8ec9-77fc94a7a099","fullTitle":"Broken Narrative: The Politics of Contemporary Art in Albania","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Armando Lulaj","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marco Mazzi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Brenda Porster","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Tomii Keiko","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Osamu Kanemura","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":6},{"fullName":"Jonida Gashi","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":5}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/dotawo/","imprintId":"f891a5f0-2af2-4eda-b686-db9dd74ee73d","imprintName":"Dotawo","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1c39ca0c-0189-44d3-bb2f-9345e2a2b152","fullTitle":"Dotawo: A Journal of Nubian Studies 2","doi":"https://doi.org/10.21983/P3.0104.1.00","publicationDate":"2015-06-01","place":"Brooklyn, NY","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Angelika Jakobi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"861ea7cc-5447-4c60-8657-c50d0a31cd24","fullTitle":"Dotawo: a Journal of Nubian Studies 3: Know-Hows and Techniques in Ancient Sudan","doi":"https://doi.org/10.21983/P3.0148.1.00","publicationDate":"2016-08-11","place":"Earth, Milky Way","contributions":[{"fullName":"Marc Maillot","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"431b58fe-7f59-49d9-bf6f-53eae379ee4d","fullTitle":"Dotawo: A Journal of Nubian Studies 4: Place Names and Place Naming in Nubia","doi":"https://doi.org/10.21983/P3.0184.1.00","publicationDate":"2017-10-12","place":"Earth, Milky Way","contributions":[{"fullName":"Alexandros Tsakos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Robin Seignobos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3c5923bc-e76b-4fbe-8d8c-1a49a49020a8","fullTitle":"Dotawo: A Journal of Nubian Studies 5: Nubian Women","doi":"https://doi.org/10.21983/P3.0242.1.00","publicationDate":"2019-02-05","place":"Earth, Milky Way","contributions":[{"fullName":"Anne Jennings","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"15ab17fe-2486-4ca5-bb47-6b804793f80d","fullTitle":"Dotawo: A Journal of Nubian Studies 6: Miscellanea Nubiana","doi":"https://doi.org/10.21983/P3.0321.1.00","publicationDate":"2019-12-26","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Simmons","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aa431454-40d3-42f5-8069-381a15789257","fullTitle":"Dotawo: A Journal of Nubian Studies 7: Comparative Northern East Sudanic Linguistics","doi":"https://doi.org/10.21983/P3.0350.1.00","publicationDate":"2021-03-23","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7a4506ac-dfdc-4054-b2d1-d8fdf4cea12b","fullTitle":"Nubian Proverbs","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Maher Habbob","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a8e6722a-1858-4f38-995d-bde0b120fe8c","fullTitle":"The Old Nubian Language","doi":"https://doi.org/10.21983/P3.0179.1.00","publicationDate":"2017-09-11","place":"Earth, Milky Way","contributions":[{"fullName":"Eugenia Smagina","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"José Andrés Alonso de la Fuente","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"0cd80cd2-1733-4bde-b48f-a03fc01acfbf","fullTitle":"The Old Nubian Texts from Attiri","doi":"https://doi.org/10.21983/P3.0156.1.00","publicationDate":"2016-11-22","place":"Earth, Milky Way","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Petra Weschenfelder","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent Pierre-Michel Laisney","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kerstin Weber-Thum","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Alexandros Tsakos","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4}]}],"__typename":"Imprint"},{"imprintUrl":null,"imprintId":"47e62ae1-6698-46aa-840c-d4507697459f","imprintName":"eth press","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"5f24bd29-3d48-4a70-8491-6269f7cc6212","fullTitle":"Ballads","doi":"https://doi.org/10.21983/P3.0105.1.00","publicationDate":"2015-06-03","place":"Brooklyn, NY","contributions":[{"fullName":"Richard Owens","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0a8fba81-f1d0-498c-88c4-0b96d3bf2947","fullTitle":"Cotton Nero A.x: The Works of the \"Pearl\" Poet","doi":"https://doi.org/10.21983/P3.0066.1.00","publicationDate":"2014-04-24","place":"Brooklyn, NY","contributions":[{"fullName":"Chris Piuma","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Lisa Ampleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Daniel C. Remein","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"David Hadbawnik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"53cd2c70-eab6-45b7-a147-8ef1c87d9ac0","fullTitle":"dôNrm'-lä-püsl","doi":"https://doi.org/10.21983/P3.0183.1.00","publicationDate":"2017-10-05","place":"Earth, Milky Way","contributions":[{"fullName":"kari edwards","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Tina Žigon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"34584bfe-1cf8-49c5-b8d1-6302ea1cfcfa","fullTitle":"Snowline","doi":"https://doi.org/10.21983/P3.0093.1.00","publicationDate":"2015-02-15","place":"Brooklyn, NY","contributions":[{"fullName":"Donato Mancini","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cc73eed0-a1f9-4ad4-b7d8-2394b92765f0","fullTitle":"Unless As Stone Is","doi":"https://doi.org/10.21983/P3.0058.1.00","publicationDate":"2014-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Sam Lohmann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/gracchi-books/","imprintId":"41193484-91d1-44f3-8d0c-0452a35d17a0","imprintName":"Gracchi Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1603556c-53fc-4d14-b0bf-8c18ad7b24ab","fullTitle":"Social and Intellectual Networking in the Early Middle Ages","doi":null,"publicationDate":null,"place":null,"contributions":[{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"K. Patrick Fazioli","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"6813bf17-373c-49ce-b9e3-1d7ab98f2977","fullTitle":"The Christian Economy of the Early Medieval West: Towards a Temple Society","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Ian Wood","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2f93b300-f147-48f5-95d5-afd0e0161fe6","fullTitle":"Urban Interactions: Communication and Competition in Late Antiquity and the Early Middle Ages","doi":"https://doi.org/10.21983/P3.0300.1.00","publicationDate":"2020-10-15","place":"Earth, Milky Way","contributions":[{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael Burrows","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ian Wood","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"Michael J. Kelly","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"678f4564-d01a-4ffe-8bdb-fead78f87955","fullTitle":"Vera Lex Historiae?: Constructions of Truth in Medieval Historical Narrative","doi":"https://doi.org/10.21983/P3.0369.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Catalin Taranu","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/helvete/","imprintId":"b3dc0be6-6739-4777-ada0-77b1f5074f7d","imprintName":"Helvete","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"417ecc06-51a4-4660-959b-482763864559","fullTitle":"Helvete 1: Incipit","doi":"https://doi.org/10.21983/P3.0027.1.00","publicationDate":"2013-04-09","place":"Brooklyn, NY","contributions":[{"fullName":"Aspasia Stephanou","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Amelia Ishmael","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Zareen Price","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ben Woodard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"3cc0269d-7170-4981-8ac7-5b01e7b9e080","fullTitle":"Helvete 2: With Head Downwards: Inversions in Black Metal","doi":"https://doi.org/10.21983/P3.0102.1.00","publicationDate":"2015-05-19","place":"Brooklyn, NY","contributions":[{"fullName":"Niall Scott","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Steve Shakespeare","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"fa4bc310-b7db-458a-8ba9-13347a91c862","fullTitle":"Helvete 3: Bleeding Black Noise","doi":"https://doi.org/10.21983/P3.0158.1.00","publicationDate":"2016-12-14","place":"Earth, Milky Way","contributions":[{"fullName":"Amelia Ishmael","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/lamma/","imprintId":"f852b678-e8ac-4949-a64d-3891d4855e3d","imprintName":"Lamma","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"ce7ec5ea-88b2-430f-92be-0f2436600a46","fullTitle":"Lamma: A Journal of Libyan Studies 1","doi":"https://doi.org/10.21983/P3.0337.1.00","publicationDate":"2020-07-21","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Benkato","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Leila Tayeb","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Amina Zarrugh","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://www.matteringpress.org","imprintId":"cb483a78-851f-4936-82d2-8dcd555dcda9","imprintName":"Mattering Press","updatedAt":"2021-03-25T16:33:14.299495+00:00","createdAt":"2021-03-25T16:25:02.238699+00:00","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6","publisher":{"publisherName":"Mattering Press","publisherId":"17d701c1-307e-4228-83ca-d8e90d7b87a6"},"works":[{"workId":"95e15115-4009-4cb0-8824-011038e3c116","fullTitle":"Energy Worlds: In Experiment","doi":"https://doi.org/10.28938/9781912729098","publicationDate":"2021-05-01","place":"Manchester","contributions":[{"fullName":"Brit Ross Winthereik","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Laura Watts","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"James Maguire","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"091abd14-7bc0-4fe7-8194-552edb02b98b","fullTitle":"Inventing the Social","doi":"https://doi.org/10.28938/9780995527768","publicationDate":"2018-07-11","place":"Manchester","contributions":[{"fullName":"Michael Guggenheim","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alex Wilkie","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Noortje Marres","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c38728e0-9739-4ad3-b0a7-6cda9a9da4b9","fullTitle":"Sensing InSecurity: Sensors as transnational security infrastructures","doi":null,"publicationDate":null,"place":"Manchester","contributions":[]}],"__typename":"Imprint"},{"imprintUrl":"https://www.mediastudies.press/","imprintId":"5078b33c-5b3f-48bf-bf37-ced6b02beb7c","imprintName":"mediastudies.press","updatedAt":"2021-06-15T14:40:51.652638+00:00","createdAt":"2021-06-15T14:40:51.652638+00:00","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5","publisher":{"publisherName":"mediastudies.press","publisherId":"4ab3bec2-c491-46d4-8731-47a5d9b33cc5"},"works":[{"workId":"6763ec18-b4af-4767-976c-5b808a64e641","fullTitle":"Liberty and the News","doi":"https://doi.org/10.32376/3f8575cb.2e69e142","publicationDate":"2020-11-15","place":"Bethlehem, PA","contributions":[{"fullName":"Walter Lippmann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sue Curry Jansen","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"3162a992-05dd-4b74-9fe0-0f16879ce6de","fullTitle":"Our Master’s Voice: Advertising","doi":"https://doi.org/10.21428/3f8575cb.dbba9917","publicationDate":"2020-10-15","place":"Bethlehem, PA","contributions":[{"fullName":"James Rorty","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jefferson Pooley","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"64891e84-6aac-437a-a380-0481312bd2ef","fullTitle":"Social Media & the Self: An Open Reader","doi":"https://doi.org/10.32376/3f8575cb.1fc3f80a","publicationDate":"2021-07-15","place":"Bethlehem, PA","contributions":[{"fullName":"Jefferson Pooley","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://meson.press","imprintId":"0299480e-869b-486c-8a65-7818598c107b","imprintName":"meson press","updatedAt":"2021-03-25T16:36:00.832381+00:00","createdAt":"2021-03-25T16:36:00.832381+00:00","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b","publisher":{"publisherName":"meson press","publisherId":"f0ae98da-c433-45b8-af3f-5c709ad0221b"},"works":[{"workId":"59ecdda1-efd8-45d2-b6a6-11bc8fe480f5","fullTitle":"Earth and Beyond in Tumultuous Times: A Critical Atlas of the Anthropocene","doi":"https://doi.org/10.14619/1891","publicationDate":"2021-03-15","place":"Lüneburg","contributions":[{"fullName":"Petra Löffler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Réka Patrícia Gál","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"36f7480e-ca45-452c-a5c0-ba1dccf135ec","fullTitle":"Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices","doi":"https://doi.org/10.14619/1860","publicationDate":"2021-05-17","place":"Lueneburg","contributions":[{"fullName":"Wanda Strauven","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"38872158-58b9-4ddf-a90e-f6001ac6c62d","fullTitle":"Trick 17: Mediengeschichten zwischen Zauberkunst und Wissenschaft","doi":"https://doi.org/10.14619/017","publicationDate":"2016-07-14","place":"Lüneburg, Germany","contributions":[{"fullName":"Sebastian Vehlken","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":1},{"fullName":"Jan Müggenburg","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Katja Müller-Helle","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":2},{"fullName":"Florian Sprenger","contributionType":"AUTHOR","mainContribution":false,"contributionOrdinal":4}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/oe-case-files/","imprintId":"39a17f7f-c3f3-4bfe-8c5e-842d53182aad","imprintName":"Œ Case Files","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"a8bf3374-f153-460d-902a-adea7f41d7c7","fullTitle":"Œ Case Files, Vol. 01","doi":"https://doi.org/10.21983/P3.0354.1.00","publicationDate":"2021-05-13","place":"Earth, Milky Way","contributions":[{"fullName":"Simone Ferracina","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/oliphaunt-books/","imprintId":"353047d8-1ea4-4cc5-bd08-e9cedb4a3e8d","imprintName":"Oliphaunt Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"0090dbfb-bc8f-44aa-9803-08b277861b14","fullTitle":"Animal, Vegetable, Mineral: Ethics and Objects","doi":"https://doi.org/10.21983/P3.0006.1.00","publicationDate":"2012-05-07","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"eb8a2862-e812-4730-ab06-8dff1b6208bf","fullTitle":"Burn after Reading: Vol. 1, Miniature Manifestos for a Post/medieval Studies + Vol. 2, The Future We Want: A Collaboration","doi":"https://doi.org/10.21983/P3.0067.1.00","publicationDate":"2014-04-28","place":"Brooklyn, NY","contributions":[{"fullName":"Myra Seaman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"37cb9bb4-0bb3-4bd3-86ea-d8dfb60c9cd8","fullTitle":"Inhuman Nature","doi":"https://doi.org/10.21983/P3.0078.1.00","publicationDate":"2014-09-23","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Jerome Cohen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://www.openbookpublishers.com/","imprintId":"145369a6-916a-4107-ba0f-ce28137659c2","imprintName":"Open Book Publishers","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b","publisher":{"publisherName":"Open Book Publishers","publisherId":"85fd969a-a16c-480b-b641-cb9adf979c3b"},"works":[{"workId":"fdeb2a1b-af39-4165-889d-cc7a5a31d5fa","fullTitle":"Acoustemologies in Contact: Sounding Subjects and Modes of Listening in Early Modernity","doi":"https://doi.org/10.11647/OBP.0226","publicationDate":"2021-01-19","place":"Cambridge, UK","contributions":[{"fullName":"Emily Wilbourne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Suzanne G. Cusick","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"31aea193-58de-43eb-aadb-23300ba5ee40","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0075","publicationDate":"2016-01-25","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fc088d17-bab2-4bfa-90bc-b320760c6c97","fullTitle":"Advanced Problems in Mathematics: Preparing for University","doi":"https://doi.org/10.11647/OBP.0181","publicationDate":"2019-10-24","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Siklos","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b59def35-5712-44ed-8490-9073ab1c6cdc","fullTitle":"A European Public Investment Outlook","doi":"https://doi.org/10.11647/OBP.0222","publicationDate":"2020-06-12","place":"Cambridge, UK","contributions":[{"fullName":"Floriana Cerniglia","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Francesco Saraceno","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"528e4526-42e4-4e68-a0d5-f74a285c35a6","fullTitle":"A Fleet Street In Every Town: The Provincial Press in England, 1855-1900","doi":"https://doi.org/10.11647/OBP.0152","publicationDate":"2018-12-13","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Hobbs","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"35941026-43eb-496f-b560-2c21a6dbbbfc","fullTitle":"Agency: Moral Identity and Free Will","doi":"https://doi.org/10.11647/OBP.0197","publicationDate":"2020-04-01","place":"Cambridge, UK","contributions":[{"fullName":"David Weissman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3dbfa65a-ed33-46b5-9105-c5694c9c6bab","fullTitle":"A Handbook and Reader of Ottoman Arabic","doi":"https://doi.org/10.11647/OBP.0208","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Esther-Miriam Wagner","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0229f930-1e01-40b8-b4a8-03ab57624ced","fullTitle":"A Lexicon of Medieval Nordic Law","doi":"https://doi.org/10.11647/OBP.0188","publicationDate":"2020-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Christine Peel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Jeffrey Love","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Erik Simensen","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Inger Larsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ulrika Djärv","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"defda2f0-1003-419a-8c3c-ac8d0b1abd17","fullTitle":"A Musicology of Performance: Theory and Method Based on Bach's Solos for Violin","doi":"https://doi.org/10.11647/OBP.0064","publicationDate":"2015-08-17","place":"Cambridge, UK","contributions":[{"fullName":"Dorottya Fabian","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"99af261d-8a31-449e-bf26-20e0178b8ed1","fullTitle":"An Anglo-Norman Reader","doi":"https://doi.org/10.11647/OBP.0110","publicationDate":"2018-02-08","place":"Cambridge, UK","contributions":[{"fullName":"Jane Bliss","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0d45084-d852-470d-b9f7-4719304f8a56","fullTitle":"Animals and Medicine: The Contribution of Animal Experiments to the Control of Disease","doi":"https://doi.org/10.11647/OBP.0055","publicationDate":"2015-05-04","place":"Cambridge, UK","contributions":[{"fullName":"Jack Botting","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Regina Botting","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Adrian R. Morrison","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"5a597468-a3eb-4026-b29e-eb93b8a7b0d6","fullTitle":"Annunciations: Sacred Music for the Twenty-First Century","doi":"https://doi.org/10.11647/OBP.0172","publicationDate":"2019-05-01","place":"Cambridge, UK","contributions":[{"fullName":"George Corbett","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"857a5788-a709-4d56-8607-337c1cabd9a2","fullTitle":"ANZUS and the Early Cold War: Strategy and Diplomacy between Australia, New Zealand and the United States, 1945-1956","doi":"https://doi.org/10.11647/OBP.0141","publicationDate":"2018-09-07","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Kelly","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0263f0c-48cd-4923-aef5-1b204636507c","fullTitle":"A People Passing Rude: British Responses to Russian Culture","doi":"https://doi.org/10.11647/OBP.0022","publicationDate":"2012-11-01","place":"Cambridge, UK","contributions":[{"fullName":"Anthony Cross","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"69c69fef-ab46-45ab-96d5-d7c4e5d4bce4","fullTitle":"Arab Media Systems","doi":"https://doi.org/10.11647/OBP.0238","publicationDate":"2021-03-03","place":"Cambridge, UK","contributions":[{"fullName":"Carola Richter","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Claudia Kozman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1e3ef1d6-a460-4b47-8d14-78c3d18e40c1","fullTitle":"A Time Travel Dialogue","doi":"https://doi.org/10.11647/OBP.0043","publicationDate":"2014-08-01","place":"Cambridge, UK","contributions":[{"fullName":"John W. Carroll","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"664931f6-27ca-4409-bb47-5642ca60117e","fullTitle":"A Victorian Curate: A Study of the Life and Career of the Rev. Dr John Hunt ","doi":"https://doi.org/10.11647/OBP.0248","publicationDate":"2021-05-03","place":"Cambridge, UK","contributions":[{"fullName":"David Yeandle","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"721fc7c9-7531-40cd-9e59-ab1bef5fc261","fullTitle":"Basic Knowledge and Conditions on Knowledge","doi":"https://doi.org/10.11647/OBP.0104","publicationDate":"2017-10-30","place":"Cambridge, UK","contributions":[{"fullName":"Mark McBride","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"39aafd68-dc83-4951-badf-d1f146a38fd4","fullTitle":"B C, Before Computers: On Information Technology from Writing to the Age of Digital Data","doi":"https://doi.org/10.11647/OBP.0225","publicationDate":"2020-10-22","place":"Cambridge, UK","contributions":[{"fullName":"Stephen Robertson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a373ccbd-0665-4faa-bc24-15542e5cb0cf","fullTitle":"Behaviour, Development and Evolution","doi":"https://doi.org/10.11647/OBP.0097","publicationDate":"2017-02-20","place":"Cambridge, UK","contributions":[{"fullName":"Patrick Bateson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"e76e054c-617d-4004-b68d-54739205df8d","fullTitle":"Beyond Holy Russia: The Life and Times of Stephen Graham","doi":"https://doi.org/10.11647/OBP.0040","publicationDate":"2014-02-19","place":"Cambridge, UK","contributions":[{"fullName":"Michael Hughes","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fe599a6c-ecd8-4ed3-a39e-5778cb9b77da","fullTitle":"Beyond Price: Essays on Birth and Death","doi":"https://doi.org/10.11647/OBP.0061","publicationDate":"2015-10-08","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c7ded4f3-4850-44eb-bd5b-e196a2254d3f","fullTitle":"Bourdieu and Literature","doi":"https://doi.org/10.11647/OBP.0027","publicationDate":"2011-11-30","place":"Cambridge, UK","contributions":[{"fullName":"John R.W. Speller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"456b46b9-bbec-4832-95ca-b23dcb975df1","fullTitle":"Brownshirt Princess: A Study of the 'Nazi Conscience'","doi":"https://doi.org/10.11647/OBP.0003","publicationDate":"2009-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Lionel Gossman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1","fullTitle":"Chronicles from Kashmir: An Annotated, Multimedia Script","doi":"https://doi.org/10.11647/OBP.0223","publicationDate":"2020-09-14","place":"Cambridge, UK","contributions":[{"fullName":"Nandita Dinesh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c5fe7f09-7dfb-4637-82c8-653a6cb683e7","fullTitle":"Cicero, Against Verres, 2.1.53–86: Latin Text with Introduction, Study Questions, Commentary and English Translation","doi":"https://doi.org/10.11647/OBP.0016","publicationDate":"2011-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a03ba4d1-1576-41d0-9e8b-d74eccb682e2","fullTitle":"Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation","doi":"https://doi.org/10.11647/OBP.0045","publicationDate":"2014-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Louise Hodgson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7e753cbc-c74b-4214-a565-2300f544be77","fullTitle":"Cicero, Philippic 2, 44–50, 78–92, 100–119: Latin Text, Study Aids with Vocabulary, and Commentary","doi":"https://doi.org/10.11647/OBP.0156","publicationDate":"2018-09-03","place":"Cambridge, UK","contributions":[{"fullName":"Ingo Gildenhard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"fd4d3c2a-355f-4bc0-83cb-1cd6764976e7","fullTitle":"Classical Music: Contemporary Perspectives and Challenges","doi":"https://doi.org/10.11647/OBP.0242","publicationDate":"2021-03-30","place":"Cambridge, UK","contributions":[{"fullName":"Beckerman Michael","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Boghossian Paul","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"9ea10b68-b23c-4562-b0ca-03ba548889a3","fullTitle":"Coleridge's Laws: A Study of Coleridge in Malta","doi":"https://doi.org/10.11647/OBP.0005","publicationDate":"2010-01-01","place":"Cambridge, UK","contributions":[{"fullName":"Barry Hough","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Howard Davis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Lydia Davis","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Micheal John Kooy","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"98776400-e985-488d-a3f1-9d88879db3cf","fullTitle":"Complexity, Security and Civil Society in East Asia: Foreign Policies and the Korean Peninsula","doi":"https://doi.org/10.11647/OBP.0059","publicationDate":"2015-06-22","place":"Cambridge, UK","contributions":[{"fullName":"Kiho Yi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Peter Hayes","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"296c6880-6212-48d2-b327-2c13b6e28d5f","fullTitle":"Conservation Biology in Sub-Saharan Africa","doi":"https://doi.org/10.11647/OBP.0177","publicationDate":"2019-09-08","place":"Cambridge, UK","contributions":[{"fullName":"John W. Wilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Richard B. Primack","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"e5ade02a-2f32-495a-b879-98b54df04c0a","fullTitle":"Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary","doi":"https://doi.org/10.11647/OBP.0068","publicationDate":"2015-10-05","place":"Cambridge, UK","contributions":[{"fullName":"Bret Mulligan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c86acc9-89a0-4b17-bcdd-520d33fc4f54","fullTitle":"Creative Multilingualism: A Manifesto","doi":"https://doi.org/10.11647/OBP.0206","publicationDate":"2020-05-20","place":"Cambridge, UK","contributions":[{"fullName":"Wen-chin Ouyang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Rajinder Dudrah","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Andrew Gosler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Martin Maiden","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Suzanne Graham","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Katrin Kohl","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"10ddfb3d-3434-46f8-a3bb-14dfc0ce9591","fullTitle":"Cultural Heritage Ethics: Between Theory and Practice","doi":"https://doi.org/10.11647/OBP.0047","publicationDate":"2014-10-13","place":"Cambridge, UK","contributions":[{"fullName":"Sandis Constantine","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2b031e1a-678b-4dcb-becb-cbd0f0ce9182","fullTitle":"Deliberation, Representation, Equity: Research Approaches, Tools and Algorithms for Participatory Processes","doi":"https://doi.org/10.11647/OBP.0108","publicationDate":"2017-01-23","place":"Cambridge, UK","contributions":[{"fullName":"Mats Danielson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Love Ekenberg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Karin Hansson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Göran Cars","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"bc253bff-cf00-433d-89a2-031500b888ff","fullTitle":"Delivering on the Promise of Democracy: Visual Case Studies in Educational Equity and Transformation","doi":"https://doi.org/10.11647/OBP.0157","publicationDate":"2019-01-16","place":"Cambridge, UK","contributions":[{"fullName":"Sukhwant Jhaj","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"517963d1-a56a-4250-8a07-56743ba60d95","fullTitle":"Democracy and Power: The Delhi Lectures","doi":"https://doi.org/10.11647/OBP.0050","publicationDate":"2014-12-07","place":"Cambridge, UK","contributions":[{"fullName":"Noam Chomsky","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jean Drèze","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"60450f84-3e18-4beb-bafe-87c78b5a0159","fullTitle":"Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition","doi":"https://doi.org/10.11647/OBP.0098","publicationDate":"2016-06-20","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]},{"workId":"b3989be1-9115-4635-b766-92f6ebfabef1","fullTitle":"Denis Diderot's 'Rameau's Nephew': A Multi-media Edition","doi":"https://doi.org/10.11647/OBP.0044","publicationDate":"2014-08-24","place":"Cambridge, UK","contributions":[{"fullName":"Denis Diderot","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marian Hobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kate E. Tunstall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Caroline Warman","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pascal Duc","contributionType":"MUSIC_EDITOR","mainContribution":false,"contributionOrdinal":5}]},{"workId":"594ddcb6-2363-47c8-858e-76af2283e486","fullTitle":"Dickens’s Working Notes for 'Dombey and Son'","doi":"https://doi.org/10.11647/OBP.0092","publicationDate":"2017-09-04","place":"Cambridge, UK","contributions":[{"fullName":"Tony Laing","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d3adf77-c72b-4b69-bf5a-a042a38a837a","fullTitle":"Dictionary of the British English Spelling System","doi":"https://doi.org/10.11647/OBP.0053","publicationDate":"2015-03-30","place":"Cambridge, UK","contributions":[{"fullName":"Greg Brooks","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"364c223d-9c90-4ceb-90e2-51be7d84e923","fullTitle":"Die Europaidee im Zeitalter der Aufklärung","doi":"https://doi.org/10.11647/OBP.0127","publicationDate":"2017-08-21","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1d4812e4-c491-4465-8e92-64e4f13662f1","fullTitle":"Digital Humanities Pedagogy: Practices, Principles and Politics","doi":"https://doi.org/10.11647/OBP.0024","publicationDate":"2012-12-20","place":"Cambridge, UK","contributions":[{"fullName":"Brett D. Hirsch","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"43d96298-a683-4098-9492-bba1466cb8e0","fullTitle":"Digital Scholarly Editing: Theories and Practices","doi":"https://doi.org/10.11647/OBP.0095","publicationDate":"2016-08-15","place":"Cambridge, UK","contributions":[{"fullName":"Elena Pierazzo","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Matthew James Driscoll","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"912c2731-3ca1-4ad9-b601-5d968da6b030","fullTitle":"Digital Technology and the Practices of Humanities Research","doi":"https://doi.org/10.11647/OBP.0192","publicationDate":"2020-01-30","place":"Cambridge, UK","contributions":[{"fullName":"Jennifer Edmond","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"78bbcc00-a336-4eb6-b4b5-0c57beec0295","fullTitle":"Discourses We Live By: Narratives of Educational and Social Endeavour","doi":"https://doi.org/10.11647/OBP.0203","publicationDate":"2020-07-03","place":"Cambridge, UK","contributions":[{"fullName":"Hazel R. Wright","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marianne Høyen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"1312613f-e01a-499a-b0d0-7289d5b9013d","fullTitle":"Diversity and Rabbinization: Jewish Texts and Societies between 400 and 1000 CE","doi":"https://doi.org/10.11647/OBP.0219","publicationDate":"2021-04-30","place":"Cambridge, UK","contributions":[{"fullName":"Gavin McDowell","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Ron Naiweld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel Stökl Ben Ezra","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"2d74b1a9-c3b0-4278-8cad-856fadc6a19d","fullTitle":"Don Carlos Infante of Spain: A Dramatic Poem","doi":"https://doi.org/10.11647/OBP.0134","publicationDate":"2018-06-04","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"b190b3c5-88c0-4e4a-939a-26995b7ff95c","fullTitle":"Earth 2020: An Insider’s Guide to a Rapidly Changing Planet","doi":"https://doi.org/10.11647/OBP.0193","publicationDate":"2020-04-22","place":"Cambridge, UK","contributions":[{"fullName":"Philippe D. Tortell","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a5e6aa48-02ba-48e4-887f-1c100a532de8","fullTitle":"Economic Fables","doi":"https://doi.org/10.11647/OBP.0020","publicationDate":"2012-04-20","place":"Cambridge, UK","contributions":[{"fullName":"Ariel Rubinstein","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2b63a26d-0db1-4200-983f-8b69d9821d8b","fullTitle":"Engaging Researchers with Data Management: The Cookbook","doi":"https://doi.org/10.11647/OBP.0185","publicationDate":"2019-10-09","place":"Cambridge, UK","contributions":[{"fullName":"Yan Wang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"James Savage","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Connie Clare","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marta Teperek","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Maria Cruz","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Elli Papadopoulou","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"af162e8a-23ab-49e6-896d-e53b9d6c0039","fullTitle":"Essays in Conveyancing and Property Law in Honour of Professor Robert Rennie","doi":"https://doi.org/10.11647/OBP.0056","publicationDate":"2015-05-11","place":"Cambridge, UK","contributions":[{"fullName":"Frankie McCarthy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Stephen Bogle","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"James Chalmers","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"98d053d6-dcc2-409a-8841-9f19920b49ee","fullTitle":"Essays in Honour of Eamonn Cantwell: Yeats Annual No. 20","doi":"https://doi.org/10.11647/OBP.0081","publicationDate":"2016-12-05","place":"Cambridge, UK","contributions":[{"fullName":"Warwick Gould","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"24689aa7-af74-4238-ad75-a9469f094068","fullTitle":"Essays on Paula Rego: Smile When You Think about Hell","doi":"https://doi.org/10.11647/OBP.0178","publicationDate":"2019-09-24","place":"Cambridge, UK","contributions":[{"fullName":"Maria Manuel Lisboa","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f76ab190-35f4-4136-86dd-d7fa02ccaebb","fullTitle":"Ethics for A-Level","doi":"https://doi.org/10.11647/OBP.0125","publicationDate":"2017-07-31","place":"Cambridge, UK","contributions":[{"fullName":"Andrew Fisher","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mark Dimmock","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d90e1915-1d2a-40e6-a94c-79f671031224","fullTitle":"Europa im Geisterkrieg. Studien zu Nietzsche","doi":"https://doi.org/10.11647/OBP.0133","publicationDate":"2018-06-19","place":"Cambridge, UK","contributions":[{"fullName":"Werner Stegmaier","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andrea C. Bertino","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"a0a8d5f1-12d0-4d51-973d-ed1dfa73f01f","fullTitle":"Exploring the Interior: Essays on Literary and Cultural History","doi":"https://doi.org/10.11647/OBP.0126","publicationDate":"2018-05-24","place":"Cambridge, UK","contributions":[{"fullName":"Karl S. Guthke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3795e166-413c-4568-8c19-1117689ef14b","fullTitle":"Feeding the City: Work and Food Culture of the Mumbai Dabbawalas","doi":"https://doi.org/10.11647/OBP.0031","publicationDate":"2013-07-15","place":"Cambridge, UK","contributions":[{"fullName":"Sara Roncaglia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Angela Arnone","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Pier Giorgio Solinas","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"5da7830b-6d55-4eb4-899e-cb2a13b30111","fullTitle":"Fiesco's Conspiracy at Genoa","doi":"https://doi.org/10.11647/OBP.0058","publicationDate":"2015-05-27","place":"Cambridge, UK","contributions":[{"fullName":"Friedrich Schiller","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Flora Kimmich","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"John Guthrie","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"83b7409e-f076-4598-965e-9e15615be247","fullTitle":"Forests and Food: Addressing Hunger and Nutrition Across Sustainable Landscapes","doi":"https://doi.org/10.11647/OBP.0085","publicationDate":"2015-11-15","place":"Cambridge, UK","contributions":[{"fullName":"Christoph Wildburger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bhaskar Vira","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Stephanie Mansourian","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"1654967f-82f1-4ed0-ae81-7ebbfb9c183d","fullTitle":"Foundations for Moral Relativism","doi":"https://doi.org/10.11647/OBP.0029","publicationDate":"2013-04-17","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"00766beb-0597-48a8-ba70-dd2b8382ec37","fullTitle":"Foundations for Moral Relativism: Second Expanded Edition","doi":"https://doi.org/10.11647/OBP.0086","publicationDate":"2015-11-23","place":"Cambridge, UK","contributions":[{"fullName":"J. David Velleman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3083819d-1084-418a-85d4-4f71c2fea139","fullTitle":"From Darkness to Light: Writers in Museums 1798-1898","doi":"https://doi.org/10.11647/OBP.0151","publicationDate":"2019-03-12","place":"Cambridge, UK","contributions":[{"fullName":"Rosella Mamoli Zorzi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Katherine Manthorne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5bf6450f-99a7-4375-ad94-d5bde1b0282c","fullTitle":"From Dust to Digital: Ten Years of the Endangered Archives Programme","doi":"https://doi.org/10.11647/OBP.0052","publicationDate":"2015-02-16","place":"Cambridge, UK","contributions":[{"fullName":"Maja Kominko","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d16896b7-691e-4620-9adb-1d7a42c69bde","fullTitle":"From Goethe to Gundolf: Essays on German Literature and Culture","doi":"https://doi.org/10.11647/OBP.0258","publicationDate":null,"place":"Cambridge, UK","contributions":[{"fullName":"Roger Paulin","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3a167e24-36b5-4d0e-b55f-af6be9a7c827","fullTitle":"Frontier Encounters: Knowledge and Practice at the Russian, Chinese and Mongolian Border","doi":"https://doi.org/10.11647/OBP.0026","publicationDate":"2012-08-01","place":"Cambridge, UK","contributions":[{"fullName":"Grégory Delaplace","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Caroline Humphrey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Franck Billé","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1471f4c3-a88c-4301-b98a-7193be6dde4b","fullTitle":"Gallucci's Commentary on Dürer’s 'Four Books on Human Proportion': Renaissance Proportion Theory","doi":"https://doi.org/10.11647/OBP.0198","publicationDate":"2020-03-25","place":"Cambridge, UK","contributions":[{"fullName":"James Hutson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"101eb7c2-f15f-41f9-b53a-dfccd4b28301","fullTitle":"Global Warming in Local Discourses: How Communities around the World Make Sense of Climate Change","doi":"https://doi.org/10.11647/OBP.0212","publicationDate":"2020-10-14","place":"Cambridge, UK","contributions":[{"fullName":"Michael Brüggemann","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Simone Rödder","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"32e99c61-2352-4a88-bb9a-bd81f113ba1e","fullTitle":"God's Babies: Natalism and Bible Interpretation in Modern America","doi":"https://doi.org/10.11647/OBP.0048","publicationDate":"2014-12-17","place":"Cambridge, UK","contributions":[{"fullName":"John McKeown","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ab3a9d7f-c9b9-42bf-9942-45f68b40bcd6","fullTitle":"Hanging on to the Edges: Essays on Science, Society and the Academic Life","doi":"https://doi.org/10.11647/OBP.0155","publicationDate":"2018-10-15","place":"Cambridge, UK","contributions":[{"fullName":"Daniel Nettle","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9d5ac1c6-a763-49b4-98b2-355d888169be","fullTitle":"Henry James's Europe: Heritage and Transfer","doi":"https://doi.org/10.11647/OBP.0013","publicationDate":"2011-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Adrian Harding","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Annick Duperray","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dennis Tredy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b7790cae-1901-446e-b529-b5fe393d8061","fullTitle":"History of International Relations: A Non-European Perspective","doi":"https://doi.org/10.11647/OBP.0074","publicationDate":"2019-07-31","place":"Cambridge, UK","contributions":[{"fullName":"Erik Ringmar","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7b9b68c6-8bb6-42c5-8b19-bf5e56b7293e","fullTitle":"How to Read a Folktale: The 'Ibonia' Epic from Madagascar","doi":"https://doi.org/10.11647/OBP.0034","publicationDate":"2013-10-08","place":"Cambridge, UK","contributions":[{"fullName":"Lee Haring","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"23651a20-a26e-4253-b0a9-c8b5bf1409c7","fullTitle":"Human and Machine Consciousness","doi":"https://doi.org/10.11647/OBP.0107","publicationDate":"2018-03-07","place":"Cambridge, UK","contributions":[{"fullName":"David Gamez","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"27def25d-48ad-470d-9fbe-1ddc8376e1cb","fullTitle":"Human Cultures through the Scientific Lens: Essays in Evolutionary Cognitive Anthropology","doi":"https://doi.org/10.11647/OBP.0257","publicationDate":"2021-07-09","place":"Cambridge, UK","contributions":[{"fullName":"Pascal Boyer","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"859a1313-7b02-4c66-8010-dbe533c4412a","fullTitle":"Hyperion or the Hermit in Greece","doi":"https://doi.org/10.11647/OBP.0160","publicationDate":"2019-02-25","place":"Cambridge, UK","contributions":[{"fullName":"Howard Gaskill","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1f591391-7497-4447-8c06-d25006a1b922","fullTitle":"Image, Knife, and Gluepot: Early Assemblage in Manuscript and Print","doi":"https://doi.org/10.11647/OBP.0145","publicationDate":"2019-07-16","place":"Cambridge, UK","contributions":[{"fullName":"Kathryn M. Rudy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"50516c2a-154e-4758-9b94-586987af2b7f","fullTitle":"Information and Empire: Mechanisms of Communication in Russia, 1600-1854","doi":"https://doi.org/10.11647/OBP.0122","publicationDate":"2017-11-27","place":"Cambridge, UK","contributions":[{"fullName":"Katherine Bowers","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Simon Franklin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1549f31d-4783-4a63-a050-90ffafd77328","fullTitle":"Infrastructure Investment in Indonesia: A Focus on Ports","doi":"https://doi.org/10.11647/OBP.0189","publicationDate":"2019-11-18","place":"Cambridge, UK","contributions":[{"fullName":"Colin Duffield","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Felix Kin Peng Hui","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Sally Wilson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"1692a92d-f86a-4155-9e6c-16f38586b7fc","fullTitle":"Intellectual Property and Public Health in the Developing World","doi":"https://doi.org/10.11647/OBP.0093","publicationDate":"2016-05-30","place":"Cambridge, UK","contributions":[{"fullName":"Monirul Azam","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d6850e99-33ce-4cae-ac7c-bd82cf23432b","fullTitle":"In the Lands of the Romanovs: An Annotated Bibliography of First-hand English-language Accounts of the Russian Empire (1613-1917)","doi":"https://doi.org/10.11647/OBP.0042","publicationDate":"2014-04-27","place":"Cambridge, UK","contributions":[{"fullName":"Anthony Cross","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4455a769-d374-4eed-8e6a-84c220757c0d","fullTitle":"Introducing Vigilant Audiences","doi":"https://doi.org/10.11647/OBP.0200","publicationDate":"2020-10-14","place":"Cambridge, UK","contributions":[{"fullName":"Rashid Gabdulhakov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel Trottier","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Qian Huang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"e414ca1b-a7f2-48c7-9adb-549a04711241","fullTitle":"Inventory Analytics","doi":"https://doi.org/10.11647/OBP.0252","publicationDate":"2021-05-24","place":"Cambridge, UK","contributions":[{"fullName":"Roberto Rossi","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ad55c2c5-9769-4648-9c42-dc4cef1f1c99","fullTitle":"Is Behavioral Economics Doomed? The Ordinary versus the Extraordinary","doi":"https://doi.org/10.11647/OBP.0021","publicationDate":"2012-09-17","place":"Cambridge, UK","contributions":[{"fullName":"David K. Levine","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2ceb72f2-ddde-45a7-84a9-27523849f8f5","fullTitle":"Jane Austen: Reflections of a Reader","doi":"https://doi.org/10.11647/OBP.0216","publicationDate":"2021-02-03","place":"Cambridge, UK","contributions":[{"fullName":"Nora Bartlett","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jane Stabler","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5b542db8-c128-48ff-a48c-003c95eaca25","fullTitle":"Jewish-Muslim Intellectual History Entangled: Textual Materials from the Firkovitch Collection, Saint Petersburg","doi":"https://doi.org/10.11647/OBP.0214","publicationDate":"2020-08-03","place":"Cambridge, UK","contributions":[{"fullName":"Jan Thiele","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":6},{"fullName":"Wilferd Madelung","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Omar Hamdan","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Adang Camilla","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sabine Schmidtke","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Bruno Chiesa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"df7eb598-914a-49eb-9cbd-9766bd06be84","fullTitle":"Just Managing? What it Means for the Families of Austerity Britain","doi":"https://doi.org/10.11647/OBP.0112","publicationDate":"2017-05-29","place":"Cambridge, UK","contributions":[{"fullName":"Paul Kyprianou","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mark O'Brien","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c5e415c4-1ed1-4c58-abae-b1476689a867","fullTitle":"Knowledge and the Norm of Assertion: An Essay in Philosophical Science","doi":"https://doi.org/10.11647/OBP.0083","publicationDate":"2016-02-26","place":"Cambridge, UK","contributions":[{"fullName":"John Turri","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9fc774fa-3a18-42d8-89e3-b5a23d822dd6","fullTitle":"Labor and Value: Rethinking Marx’s Theory of Exploitation","doi":"https://doi.org/10.11647/OBP.0182","publicationDate":"2019-10-02","place":"Cambridge, UK","contributions":[{"fullName":"Ernesto Screpanti","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"29e28ee7-c52d-43f3-95da-f99f33f0e737","fullTitle":"Les Bienveillantes de Jonathan Littell: Études réunies par Murielle Lucie Clément","doi":"https://doi.org/10.11647/OBP.0006","publicationDate":"2010-04-01","place":"Cambridge, UK","contributions":[{"fullName":"Murielle Lucie Clément","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d9e671dd-ab2a-4fd0-ada3-4925449a63a8","fullTitle":"Letters of Blood and Other Works in English","doi":"https://doi.org/10.11647/OBP.0017","publicationDate":"2011-11-30","place":"Cambridge, UK","contributions":[{"fullName":"Göran Printz-Påhlson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Robert Archambeau","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Elinor Shaffer","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":4},{"fullName":"Lars-Håkan Svensson","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"c699f257-f3e4-4c98-9a3f-741c6a40b62a","fullTitle":"L’idée de l’Europe: au Siècle des Lumières","doi":"https://doi.org/10.11647/OBP.0116","publicationDate":"2017-05-01","place":"Cambridge, UK","contributions":[{"fullName":"Rotraud von Kulessa","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Catriona Seth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"a795aafb-d189-4d15-8e64-b9a3fbfa8e09","fullTitle":"Life Histories of Etnos Theory in Russia and Beyond","doi":"https://doi.org/10.11647/OBP.0150","publicationDate":"2019-02-06","place":"Cambridge, UK","contributions":[{"fullName":"Dmitry V Arzyutov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"David G. Anderson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sergei S. Alymov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"5c55effb-2a3e-4e0d-a46d-edad7830fd8e","fullTitle":"Lifestyle in Siberia and the Russian North","doi":"https://doi.org/10.11647/OBP.0171","publicationDate":"2019-11-22","place":"Cambridge, UK","contributions":[{"fullName":"Joachim Otto Habeck","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6090bfc8-3143-4599-b0dd-17705f754e8c","fullTitle":"Like Nobody's Business: An Insider's Guide to How US University Finances Really Work","doi":"https://doi.org/10.11647/OBP.0240","publicationDate":"2021-02-23","place":"Cambridge, UK","contributions":[{"fullName":"Andrew C. Comrie","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"25a2f70a-832d-4c8d-b28f-75f838b6e171","fullTitle":"Liminal Spaces: Migration and Women of the Guyanese Diaspora","doi":"https://doi.org/10.11647/OBP.0218","publicationDate":"2020-09-29","place":"Cambridge, UK","contributions":[{"fullName":"Grace Aneiza Ali","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9845c8a9-b283-4cb8-8961-d41e5fe795f1","fullTitle":"Literature Against Criticism: University English and Contemporary Fiction in Conflict","doi":"https://doi.org/10.11647/OBP.0102","publicationDate":"2016-10-17","place":"Cambridge, UK","contributions":[{"fullName":"Martin Paul Eve","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f957ab3d-c925-4bf2-82fa-9809007753e7","fullTitle":"Living Earth Community: Multiple Ways of Being and Knowing","doi":"https://doi.org/10.11647/OBP.0186","publicationDate":"2020-05-07","place":"Cambridge, UK","contributions":[{"fullName":"John Grim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Mary Evelyn Tucker","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Sam Mickey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"545f9f42-87c0-415e-9086-eee27925c85b","fullTitle":"Long Narrative Songs from the Mongghul of Northeast Tibet: Texts in Mongghul, Chinese, and English","doi":"https://doi.org/10.11647/OBP.0124","publicationDate":"2017-10-30","place":"Cambridge, UK","contributions":[{"fullName":"Gerald Roche","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Li Dechun","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mark Turin","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/peanut-books/","imprintId":"5cc7d3db-f300-4813-9c68-3ccc18a6277b","imprintName":"Peanut Books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"14a2356a-4767-4136-b44a-684a28dc87a6","fullTitle":"In a Trance: On Paleo Art","doi":"https://doi.org/10.21983/P3.0081.1.00","publicationDate":"2014-11-13","place":"Brooklyn, NY","contributions":[{"fullName":"Jeffrey Skoblow","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"200b11a8-57d6-4f81-b089-ddd4ee7fe2f2","fullTitle":"The Apartment of Tragic Appliances: Poems","doi":"https://doi.org/10.21983/P3.0030.1.00","publicationDate":"2013-05-26","place":"Brooklyn, NY","contributions":[{"fullName":"Michael D. Snediker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"49ebcb4a-928f-4d83-9596-b296dfce0b20","fullTitle":"The Petroleum Manga: A Project by Marina Zurkow","doi":"https://doi.org/10.21983/P3.0062.1.00","publicationDate":"2014-02-25","place":"Brooklyn, NY","contributions":[{"fullName":"Marina Zurkow","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2a360648-3157-4a1b-9ba7-a61895a8a10c","fullTitle":"Where the Tiny Things Are: Feathered Essays","doi":"https://doi.org/10.21983/P3.0181.1.00","publicationDate":"2017-09-26","place":"Earth, Milky Way","contributions":[{"fullName":"Nicole Walker","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/","imprintId":"7522e351-8a91-40fa-bf45-02cb38368b0b","imprintName":"punctum books","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"5402ea62-7a1b-48b4-b5fb-7b114c04bc27","fullTitle":"A Boy Asleep under the Sun: Versions of Sandro Penna","doi":"https://doi.org/10.21983/P3.0080.1.00","publicationDate":"2014-11-11","place":"Brooklyn, NY","contributions":[{"fullName":"Sandro Penna","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Peter Valente","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Peter Valente","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"8a27431b-b1f9-4fed-a8e0-0a0aadc9d98c","fullTitle":"A Buddha Land in This World: Philosophy, Utopia, and Radical Buddhism","doi":"https://doi.org/10.53288/0373.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Lajos Brons","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"eeb920c0-6f2e-462c-a315-3687b5ca8da3","fullTitle":"Action [poems]","doi":"https://doi.org/10.21983/P3.0083.1.00","publicationDate":"2014-12-10","place":"Brooklyn, NY","contributions":[{"fullName":"Anthony Opal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"20dab41d-2267-4a68-befa-d787b7c98599","fullTitle":"After the \"Speculative Turn\": Realism, Philosophy, and Feminism","doi":"https://doi.org/10.21983/P3.0152.1.00","publicationDate":"2016-10-26","place":"Earth, Milky Way","contributions":[{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katerina Kolozova","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13a03c11-0f22-4d40-881d-b935452d4bf3","fullTitle":"Air Supplied","doi":"https://doi.org/10.21983/P3.0201.1.00","publicationDate":"2018-05-23","place":"Earth, Milky Way","contributions":[{"fullName":"David Cross","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5147a952-3d44-4beb-8d49-b41c91bce733","fullTitle":"Alternative Historiographies of the Digital Humanities","doi":"https://doi.org/10.53288/0274.1.00","publicationDate":"2021-06-24","place":"Earth, Milky Way","contributions":[{"fullName":"Adeline Koh","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dorothy Kim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f712541c-07b4-477c-8b8c-8c1a307810d0","fullTitle":"And Another Thing: Nonanthropocentrism and Art","doi":"https://doi.org/10.21983/P3.0144.1.00","publicationDate":"2016-06-18","place":"Earth, Milky Way","contributions":[{"fullName":"Katherine Behar","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Emmy Mikelson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"27e17948-02c4-4ba3-8244-5c229cc8e9b8","fullTitle":"Anglo-Saxon(ist) Pasts, postSaxon Futures","doi":"https://doi.org/10.21983/P3.0262.1.00","publicationDate":"2019-12-30","place":"Earth, Milky Way","contributions":[{"fullName":"Donna-Beth Ellard","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f3c9e9d8-9a38-4558-be2e-cab9a70d62f0","fullTitle":"Annotations to Geoffrey Hill's Speech! Speech!","doi":"https://doi.org/10.21983/P3.0004.1.00","publicationDate":"2012-01-26","place":"Brooklyn, NY","contributions":[{"fullName":"Ann Hassan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"baf524c6-0a2c-40f2-90a7-e19c6e1b6b97","fullTitle":"Anthropocene Unseen: A Lexicon","doi":"https://doi.org/10.21983/P3.0265.1.00","publicationDate":"2020-02-07","place":"Earth, Milky Way","contributions":[{"fullName":"Cymene Howe","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anand Pandian","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f6afff19-25ae-41f8-8a7a-6c1acffafc39","fullTitle":"Antiracism Inc.: Why the Way We Talk about Racial Justice Matters","doi":"https://doi.org/10.21983/P3.0250.1.00","publicationDate":"2019-04-25","place":"Earth, Milky Way","contributions":[{"fullName":"Paula Ioanide","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Alison Reed","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Felice Blake","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"88c47bd3-f8c9-4157-9d1a-770d9be8c173","fullTitle":"A Nuclear Refrain: Emotion, Empire, and the Democratic Potential of Protest","doi":"https://doi.org/10.21983/P3.0271.1.00","publicationDate":"2019-12-19","place":"Earth, Milky Way","contributions":[{"fullName":"Kye Askins","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Phil Johnstone","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kelvin Mason","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"41508a3c-614b-473e-aa74-edcb6b09dc9d","fullTitle":"Ardea: A Philosophical Novella","doi":"https://doi.org/10.21983/P3.0147.1.00","publicationDate":"2016-07-09","place":"Earth, Milky Way","contributions":[{"fullName":"Freya Mathews","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ae9f8357-4b39-4809-a8e9-766e200fb937","fullTitle":"A Rushed Quality","doi":"https://doi.org/10.21983/P3.0103.1.00","publicationDate":"2015-05-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Odell","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3f78b298-8826-4162-886e-af21a77f2957","fullTitle":"Athens and the War on Public Space: Tracing a City in Crisis","doi":"https://doi.org/10.21983/P3.0199.1.00","publicationDate":"2018-04-20","place":"Earth, Milky Way","contributions":[{"fullName":"Christos Filippidis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Klara Jaya Brekke","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Antonis Vradis","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"3da27fb9-7a15-446e-ae0f-258c7dd4fd94","fullTitle":"Barton Myers: Works of Architecture and Urbanism","doi":"https://doi.org/10.21983/P3.0249.1.00","publicationDate":"2019-07-05","place":"Earth, Milky Way","contributions":[{"fullName":"Kris Miller-Fisher","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jocelyn Gibbs","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"f4d42680-8b02-4e3a-9ec8-44aee852b29f","fullTitle":"Bathroom Songs: Eve Kosofsky Sedgwick as a Poet","doi":"https://doi.org/10.21983/P3.0189.1.00","publicationDate":"2017-11-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jason Edwards","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"637566b3-dca3-4a8b-b5bd-01fcbb77ca09","fullTitle":"Beowulf: A Translation","doi":"https://doi.org/10.21983/P3.0009.1.00","publicationDate":"2012-08-25","place":"Brooklyn, NY","contributions":[{"fullName":"David Hadbawnik","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Thomas Meyer","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Daniel C. Remein","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":3},{"fullName":"David Hadbawnik","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":4}]},{"workId":"9bae1a52-f764-417d-9d45-4df12f71cf07","fullTitle":"Beowulf by All","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Elaine Treharne","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jean Abbott","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Mateusz Fafinski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"a2ce9f9c-f594-4165-83be-e3751d4d17fe","fullTitle":"Beta Exercise: The Theory and Practice of Osamu Kanemura","doi":"https://doi.org/10.21983/P3.0241.1.00","publicationDate":"2019-01-23","place":"Earth, Milky Way","contributions":[{"fullName":"Osamu Kanemura","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Marco Mazzi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Nicholas Marshall","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Michiyo Miyake","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"735d8962-5ec7-41ce-a73a-a43c35cc354f","fullTitle":"Between Species/Between Spaces: Art and Science on the Outer Cape","doi":"https://doi.org/10.21983/P3.0325.1.00","publicationDate":"2020-08-13","place":"Earth, Milky Way","contributions":[{"fullName":"Dylan Gauthier","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Kendra Sullivan","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a871cb31-e158-401d-a639-3767131c0f34","fullTitle":"Bigger Than You: Big Data and Obesity","doi":"https://doi.org/10.21983/P3.0135.1.00","publicationDate":"2016-03-03","place":"Earth, Milky Way","contributions":[{"fullName":"Katherine Behar","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"940d0880-83b5-499d-9f39-1bf30ccfc4d0","fullTitle":"Book of Anonymity","doi":"https://doi.org/10.21983/P3.0315.1.00","publicationDate":"2021-03-04","place":"Earth, Milky Way","contributions":[{"fullName":"Anon Collective","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"006571ae-ac0e-4cb0-8a3f-71280aa7f23b","fullTitle":"Broken Records","doi":"https://doi.org/10.21983/P3.0137.1.00","publicationDate":"2016-03-21","place":"Earth, Milky Way","contributions":[{"fullName":"Snežana Žabić","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"47c71c05-a4f1-48da-b8d5-9e5ba139a8ea","fullTitle":"Building Black: Towards Antiracist Architecture","doi":"https://doi.org/10.21983/P3.0372.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Elliot C. Mason","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"dd9008ae-0172-4e07-b3cf-50c35c51b606","fullTitle":"Bullied: The Story of an Abuse","doi":"https://doi.org/10.21983/P3.0356.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"46344fe3-1d72-4ddd-a57e-1d3f4377d2a2","fullTitle":"Centaurs, Rioting in Thessaly: Memory and the Classical World","doi":"https://doi.org/10.21983/P3.0192.1.00","publicationDate":"2018-01-09","place":"Earth, Milky Way","contributions":[{"fullName":"Martyn Hudson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7f1d3e2e-c708-4f59-81cf-104c1ca528d0","fullTitle":"Chaste Cinematics","doi":"https://doi.org/10.21983/P3.0117.1.00","publicationDate":"2015-10-31","place":"Brooklyn, NY","contributions":[{"fullName":"Victor J. Vitanza","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b2d1b2e3-226e-43c2-a898-fbad7b410e3f","fullTitle":"Christina McPhee: A Commonplace Book","doi":"https://doi.org/10.21983/P3.0186.1.00","publicationDate":"2017-10-17","place":"Earth, Milky Way","contributions":[{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"45aa16fa-5fd5-4449-a3bd-52d734fcb0a9","fullTitle":"Cinema's Doppelgängers\n","doi":"https://doi.org/10.53288/0320.1.00","publicationDate":"2021-06-17","place":"Earth, Milky Way","contributions":[{"fullName":"Doug Dibbern","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"84447325-88e2-4658-8597-3f2329451156","fullTitle":"Clinical Encounters in Sexuality: Psychoanalytic Practice and Queer Theory","doi":"https://doi.org/10.21983/P3.0167.1.00","publicationDate":"2017-03-07","place":"Earth, Milky Way","contributions":[{"fullName":"Eve Watson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Noreen Giffney","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4d0430e3-3640-4d87-8f02-cbb45f6ae83b","fullTitle":"Comic Providence","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Janet Thormann","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"0ff62120-4478-46dc-8d01-1d7e1dc5b7a6","fullTitle":"Commonist Tendencies: Mutual Aid beyond Communism","doi":"https://doi.org/10.21983/P3.0040.1.00","publicationDate":"2013-07-23","place":"Brooklyn, NY","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d890e88f-16d7-4b75-bef1-5e4d09c8daa0","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea","doi":"https://doi.org/10.21983/P3.0269.1.00","publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"a603437d-578e-4577-9800-645614b28b4b","fullTitle":"Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]","doi":null,"publicationDate":"2020-09-10","place":"Earth, Milky Way","contributions":[{"fullName":"Jian Zhang","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bruce Robertson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"93330f65-a84f-4c5c-aa44-f710c714eca2","fullTitle":"Continent. Year 1: A Selection of Issues 1.1–1.4","doi":"https://doi.org/10.21983/P3.0016.1.00","publicationDate":"2012-12-12","place":"Brooklyn, NY","contributions":[{"fullName":"Nico Jenkins","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Adam Staley Groves","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Paul Boshears","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Jamie Allen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"3d78e15e-19cb-464a-a238-b5291dbfd49f","fullTitle":"Creep: A Life, A Theory, An Apology","doi":"https://doi.org/10.21983/P3.0178.1.00","publicationDate":"2017-08-29","place":"Earth, Milky Way","contributions":[{"fullName":"Jonathan Alexander","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f2a2626b-4029-4e43-bb84-7b3cacf61b23","fullTitle":"Crisis States: Governance, Resistance & Precarious Capitalism","doi":"https://doi.org/10.21983/P3.0146.1.00","publicationDate":"2016-07-05","place":"Earth, Milky Way","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"639a3c5b-82ad-4557-897b-2bfebe3dc53c","fullTitle":"Critique of Sovereignty, Book 1: Contemporary Theories of Sovereignty","doi":"https://doi.org/10.21983/P3.0114.1.00","publicationDate":"2015-09-28","place":"Brooklyn, NY","contributions":[{"fullName":"Marc Lombardo","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f37627c1-d89f-434c-9915-f1f2f33dc037","fullTitle":"Crush","doi":"https://doi.org/10.21983/P3.0063.1.00","publicationDate":"2014-02-27","place":"Brooklyn, NY","contributions":[{"fullName":"Will Stockton","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"D. Gilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"43355368-b29b-4fa1-9ed6-780f4983364a","fullTitle":"Damayanti and Nala's Tale","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Dan Rudmann","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"11749800-364e-4a27-bf79-9f0ceeacb4d6","fullTitle":"Dark Chaucer: An Assortment","doi":"https://doi.org/10.21983/P3.0018.1.00","publicationDate":"2012-12-23","place":"Brooklyn, NY","contributions":[{"fullName":"Nicola Masciandaro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Myra Seaman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Eileen A. Joy","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"7fe2c6dc-6673-4537-a397-1f0377c2296f","fullTitle":"Dear Professor: A Chronicle of Absences","doi":"https://doi.org/10.21983/P3.0160.1.00","publicationDate":"2016-12-19","place":"Earth, Milky Way","contributions":[{"fullName":"Filip Noterdaeme","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Shuki Cohen","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"0985e294-aa85-40d0-90ce-af53ae37898d","fullTitle":"Deleuze and the Passions","doi":"https://doi.org/10.21983/P3.0161.1.00","publicationDate":"2016-12-21","place":"Earth, Milky Way","contributions":[{"fullName":"Sjoerd van Tuinen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Ceciel Meiborg","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9e6bb4d8-4e05-4cd7-abe9-4a795ade0340","fullTitle":"Derrida and Queer Theory","doi":"https://doi.org/10.21983/P3.0172.1.00","publicationDate":"2017-05-26","place":"Earth, Milky Way","contributions":[{"fullName":"Christian Hite","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9e11adff-abed-4b5d-adef-b0c4466231e8","fullTitle":"Desire/Love","doi":"https://doi.org/10.21983/P3.0015.1.00","publicationDate":"2012-12-05","place":"Brooklyn, NY","contributions":[{"fullName":"Lauren Berlant","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6141d35a-a5a6-43ee-b6b6-5caa41bce869","fullTitle":"Desire/Love","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Lauren Berlant","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"13c12944-701a-41f4-9d85-c753267d564b","fullTitle":"Destroyer of Naivetés","doi":"https://doi.org/10.21983/P3.0118.1.00","publicationDate":"2015-11-07","place":"Brooklyn, NY","contributions":[{"fullName":"Joseph Nechvatal","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"69c890c5-d8c5-4295-b5a7-688560929d8b","fullTitle":"Dialectics Unbound: On the Possibility of Total Writing","doi":"https://doi.org/10.21983/P3.0041.1.00","publicationDate":"2013-07-28","place":"Brooklyn, NY","contributions":[{"fullName":"Maxwell Kennel","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"25be3523-34b5-43c9-a3e2-b12ffb859025","fullTitle":"Dire Pessimism: An Essay","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Thomas Carl Wall","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"245c521a-5014-4da0-bf2b-35eff9673367","fullTitle":"dis/cord: Thinking Sound through Agential Realism","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Kevin Toksöz Fairbarn","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"488c640d-e742-465a-98b4-1234bb09d038","fullTitle":"Diseases of the Head: Essays on the Horrors of Speculative Philosophy","doi":"https://doi.org/10.21983/P3.0280.1.00","publicationDate":"2020-09-24","place":"Earth, Milky Way","contributions":[{"fullName":"Matt Rosen","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"754c1299-9b8d-41ac-a1d6-534f174fa87b","fullTitle":"Disturbing Times: Medieval Pasts, Reimagined Futures","doi":"https://doi.org/10.21983/P3.0313.1.00","publicationDate":"2020-06-04","place":"Earth, Milky Way","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Anna Kłosowska","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Catherine E. Karkov","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"438e0846-b4b9-4c84-9545-d7a6fb13e996","fullTitle":"Divine Name Verification: An Essay on Anti-Darwinism, Intelligent Design, and the Computational Nature of Reality","doi":"https://doi.org/10.21983/P3.0043.1.00","publicationDate":"2013-08-23","place":"Brooklyn, NY","contributions":[{"fullName":"Noah Horwitz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"9d1f849d-cf0f-4d0c-8dab-8819fad00337","fullTitle":"Dollar Theater Theory","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Trevor Owen Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"cd037a39-f6b9-462a-a207-5079a000065b","fullTitle":"Dotawo: A Journal of Nubian Studies 1","doi":"https://doi.org/10.21983/P3.0071.1.00","publicationDate":"2014-06-23","place":"Brooklyn, NY","contributions":[{"fullName":"Giovanni Ruffini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Angelika Jakobi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"6092f859-05fe-475d-b914-3c1a6534e6b9","fullTitle":"Down to Earth: A Memoir","doi":"https://doi.org/10.21983/P3.0306.1.00","publicationDate":"2020-10-22","place":"Earth, Milky Way","contributions":[{"fullName":"Gísli Pálsson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna Yates","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Katrina Downs-Rose","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"ac6acc15-6927-4cef-95d3-1c71183ef2a6","fullTitle":"Echoes of No Thing: Thinking between Heidegger and Dōgen","doi":"https://doi.org/10.21983/P3.0239.1.00","publicationDate":"2019-01-04","place":"Earth, Milky Way","contributions":[{"fullName":"Nico Jenkins","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"2658fe95-2df3-4e7d-8df6-e86c18359a23","fullTitle":"Ephemeral Coast, S. Wales","doi":"https://doi.org/10.21983/P3.0079.1.00","publicationDate":"2014-11-01","place":"Brooklyn, NY","contributions":[{"fullName":"Celina Jeffery","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"98ce9caa-487e-4391-86c9-e5d8129be5b6","fullTitle":"Essays on the Peripheries","doi":"https://doi.org/10.21983/P3.0291.1.00","publicationDate":"2021-04-22","place":"Earth, Milky Way","contributions":[{"fullName":"Peter Valente","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"19b32470-bf29-48e1-99db-c08ef90516a9","fullTitle":"Everyday Cinema: The Films of Marc Lafia","doi":"https://doi.org/10.21983/P3.0164.1.00","publicationDate":"2017-01-31","place":"Earth, Milky Way","contributions":[{"fullName":"Marc Lafia","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"859e72c3-8159-48e4-b2f0-842f3400cb8d","fullTitle":"Extraterritorialities in Occupied Worlds","doi":"https://doi.org/10.21983/P3.0131.1.00","publicationDate":"2016-02-16","place":"Earth, Milky Way","contributions":[{"fullName":"Ruti Sela Maayan Amir","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1b870455-0b99-4d0e-af22-49f4ebbb6493","fullTitle":"Finding Room in Beirut: Places of the Everyday","doi":"https://doi.org/10.21983/P3.0243.1.00","publicationDate":"2019-02-08","place":"Earth, Milky Way","contributions":[{"fullName":"Carole Lévesque","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6ca16a49-7c95-4c81-b8f0-8f3c7e42de7d","fullTitle":"Flash + Cube (1965–1975)","doi":"https://doi.org/10.21983/P3.0036.1.00","publicationDate":"2013-07-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marget Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"7fbc96cf-4c88-4e70-b1fe-d4e69324184a","fullTitle":"Flash + Cube (1965–1975)","doi":null,"publicationDate":"2012-01-01","place":"Brooklyn, NY","contributions":[{"fullName":"Marget Long","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f4a04558-958a-43da-b009-d5b7580c532f","fullTitle":"Follow for Now, Volume 2: More Interviews with Friends and Heroes","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Roy Christopher","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97a2ac65-5b1b-4ab8-8588-db8340f04d27","fullTitle":"Fuckhead","doi":"https://doi.org/10.21983/P3.0048.1.00","publicationDate":"2013-09-24","place":"Brooklyn, NY","contributions":[{"fullName":"David Rawson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"f3294e78-9a12-49ff-983e-ed6154ff621e","fullTitle":"Gender Trouble Couplets, Volume 1","doi":"https://doi.org/10.21983/P3.0266.1.00","publicationDate":"2019-11-15","place":"Earth, Milky Way","contributions":[{"fullName":"A.W. Strouse","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Anna M. Kłosowska","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"c80467d8-d472-4643-9a50-4ac489da14dd","fullTitle":"Geographies of Identity","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Jill Darling","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"bbe77bbb-0242-46d7-92d2-cfd35c17fe8f","fullTitle":"Heathen Earth: Trumpism and Political Ecology","doi":"https://doi.org/10.21983/P3.0170.1.00","publicationDate":"2017-05-09","place":"Earth, Milky Way","contributions":[{"fullName":"Kyle McGee","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"875a78d7-fad2-4c22-bb04-35e0456b6efa","fullTitle":"Heavy Processing (More than a Feeling)","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"T.L. Cowan","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jasmine Rault","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7f72c34d-4515-42eb-a32e-38fe74217b70","fullTitle":"Hephaestus Reloaded: Composed for Ten Hands / Efesto Reloaded: Composizioni per 10 mani","doi":"https://doi.org/10.21983/P3.0258.1.00","publicationDate":"2019-12-13","place":"Earth, Milky Way","contributions":[{"fullName":"Adam Berg","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Brunella Antomarini","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Miltos Maneta","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Vladimir D’Amora","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Pietro Traversa","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":8},{"fullName":"Patrick Camiller","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":7},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":6}]},{"workId":"b63ffeb5-7906-4c74-8ec2-68cbe87f593c","fullTitle":"History According to Cattle","doi":"https://doi.org/10.21983/P3.0116.1.00","publicationDate":"2015-10-01","place":"Brooklyn, NY","contributions":[{"fullName":"Terike Haapoja","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Laura Gustafsson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"4f46d026-49c6-4319-b79a-a6f70d412b5c","fullTitle":"Homotopia? Gay Identity, Sameness & the Politics of Desire","doi":"https://doi.org/10.21983/P3.0124.1.00","publicationDate":"2015-12-25","place":"Brooklyn, NY","contributions":[{"fullName":"Jonathan Kemp","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b0257269-5ca3-40b3-b4e1-90f66baddb88","fullTitle":"Humid, All Too Humid: Overheated Observations","doi":"https://doi.org/10.21983/P3.0132.1.00","publicationDate":"2016-02-25","place":"Earth, Milky Way","contributions":[{"fullName":"Dominic Pettman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"241f9c62-26be-4d0f-864b-ad4b243a03c3","fullTitle":"Imperial Physique","doi":"https://doi.org/10.21983/P3.0268.1.00","publicationDate":"2019-11-19","place":"Earth, Milky Way","contributions":[{"fullName":"JH Phrydas","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"aeed0683-e022-42d0-a954-f9f36afc4bbf","fullTitle":"Incomparable Poetry: An Essay on the Financial Crisis of 2007–2008 and Irish Literature","doi":"https://doi.org/10.21983/P3.0286.1.00","publicationDate":"2020-05-14","place":"Earth, Milky Way","contributions":[{"fullName":"Robert Kiely","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"5ec826f5-18ab-498c-8b66-bd288618df15","fullTitle":"Insurrectionary Infrastructures","doi":"https://doi.org/10.21983/P3.0200.1.00","publicationDate":"2018-05-02","place":"Earth, Milky Way","contributions":[{"fullName":"Jeff Shantz","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"89990379-94c2-4590-9037-cbd5052694a4","fullTitle":"Intimate Bureaucracies","doi":"https://doi.org/10.21983/P3.0005.1.00","publicationDate":"2012-03-09","place":"Brooklyn, NY","contributions":[{"fullName":"dj readies","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"85a2a2fe-d515-4784-b451-d26ec4c62a4f","fullTitle":"Iteration:Again: 13 Public Art Projects across Tasmania","doi":"https://doi.org/10.21983/P3.0037.1.00","publicationDate":"2013-07-02","place":"Brooklyn, NY","contributions":[{"fullName":"David Cross","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael Edwards","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"f3db2a03-75db-4837-af31-4bb0cb189fa2","fullTitle":"Itinerant Philosophy: On Alphonso Lingis","doi":"https://doi.org/10.21983/P3.0073.1.00","publicationDate":"2014-08-04","place":"Brooklyn, NY","contributions":[{"fullName":"Tom Sparrow","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Bobby George","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1376b0f4-e967-4a6f-8d7d-8ba876bbbdde","fullTitle":"Itinerant Spectator/Itinerant Spectacle","doi":"https://doi.org/10.21983/P3.0056.1.00","publicationDate":"2013-12-20","place":"Brooklyn, NY","contributions":[{"fullName":"P.A. Skantze","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"da814d9f-14ff-4660-acfe-52ac2a2058fa","fullTitle":"Journal of Badiou Studies 3: On Ethics","doi":"https://doi.org/10.21983/P3.0070.1.00","publicationDate":"2014-06-04","place":"Brooklyn, NY","contributions":[{"fullName":"Arthur Rose","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Nicolò Fazioni","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"7e2e26fd-4b0b-4c0b-a1fa-278524c43757","fullTitle":"Journal of Badiou Studies 5: Architheater","doi":"https://doi.org/10.21983/P3.0173.1.00","publicationDate":"2017-07-07","place":"Earth, Milky Way","contributions":[{"fullName":"Arthur Rose","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Michael J. Kelly","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Adi Efal-Lautenschläger","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"d2e40ec1-5c2a-404d-8e9f-6727c7c178dc","fullTitle":"Kill Boxes: Facing the Legacy of US-Sponsored Torture, Indefinite Detention, and Drone Warfare","doi":"https://doi.org/10.21983/P3.0166.1.00","publicationDate":"2017-03-02","place":"Earth, Milky Way","contributions":[{"fullName":"Elisabeth Weber","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Richard Falk","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"75693fd0-e93a-4fc3-b82e-4c83a11f28b1","fullTitle":"Knocking the Hustle: Against the Neoliberal Turn in Black Politics","doi":"https://doi.org/10.21983/P3.0121.1.00","publicationDate":"2015-12-10","place":"Brooklyn, NY","contributions":[{"fullName":"Lester K. Spence","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed3ea389-5d5c-430c-9453-814ed94e027b","fullTitle":"Knowledge, Spirit, Law, Book 1: Radical Scholarship","doi":"https://doi.org/10.21983/P3.0123.1.00","publicationDate":"2015-12-24","place":"Brooklyn, NY","contributions":[{"fullName":"Gavin Keeney","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"d0d59741-4866-42c3-8528-f65c3da3ffdd","fullTitle":"Language Parasites: Of Phorontology","doi":"https://doi.org/10.21983/P3.0169.1.00","publicationDate":"2017-05-04","place":"Earth, Milky Way","contributions":[{"fullName":"Sean Braune","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"1a71ecd5-c868-44af-9b53-b45888fb241c","fullTitle":"Lapidari 1: Texts","doi":"https://doi.org/10.21983/P3.0094.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonida Gashi","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"df518095-84ff-4138-b2f9-5d8fe6ddf53a","fullTitle":"Lapidari 2: Images, Part I","doi":"https://doi.org/10.21983/P3.0091.1.00","publicationDate":"2015-02-15","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"a9d68f12-1de4-4c08-84b1-fe9a786ab47f","fullTitle":"Lapidari 3: Images, Part II","doi":"https://doi.org/10.21983/P3.0092.1.00","publicationDate":"2015-02-16","place":"Brooklyn, NY","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"08788fe1-c17d-4f6b-aeab-c81aa3036940","fullTitle":"Left Bank Dream","doi":"https://doi.org/10.21983/P3.0084.1.00","publicationDate":"2014-12-26","place":"Brooklyn, NY","contributions":[{"fullName":"Beryl Scholssman","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b4d68a6d-01fb-48f1-9f64-1fcdaaf1cdfd","fullTitle":"Leper Creativity: Cyclonopedia Symposium","doi":"https://doi.org/10.21983/P3.0017.1.00","publicationDate":"2012-12-22","place":"Brooklyn, NY","contributions":[{"fullName":"Eugene Thacker","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Nicola Masciandaro","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Edward Keller","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"00e012c5-9232-472c-bd8b-8ca4ea6d1275","fullTitle":"Li Bo Unkempt","doi":"https://doi.org/10.21983/P3.0322.1.00","publicationDate":"2021-03-30","place":"Earth, Milky Way","contributions":[{"fullName":"Kidder Smith","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Kidder Smith","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Mike Zhai","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Traktung Yeshe Dorje","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":4},{"fullName":"Maria Dolgenas","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":5}]},{"workId":"534c3d13-b18b-4be5-91e6-768c0cf09361","fullTitle":"Living with Monsters","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Ilana Gershon","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Yasmine Musharbash","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"636a5aa6-1d37-4cd2-8742-4dcad8c67e0c","fullTitle":"Love Don't Need a Reason: The Life & Music of Michael Callen","doi":"https://doi.org/10.21983/P3.0297.1.00","publicationDate":"2020-11-05","place":"Earth, Milky Way","contributions":[{"fullName":"Matthew J.\n Jones","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6dcf29ea-76c1-4121-ad7f-2341574c45fe","fullTitle":"Luminol Theory","doi":"https://doi.org/10.21983/P3.0177.1.00","publicationDate":"2017-08-24","place":"Earth, Milky Way","contributions":[{"fullName":"Laura E. Joyce","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"ed96eea8-82c6-46c5-a19b-dad5e45962c6","fullTitle":"Make and Let Die: Untimely Sovereignties","doi":"https://doi.org/10.21983/P3.0136.1.00","publicationDate":"2016-03-10","place":"Earth, Milky Way","contributions":[{"fullName":"Kathleen Biddick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Eileen A. Joy","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"003137ea-4fe6-470d-8bd3-f936ad065f3c","fullTitle":"Making the Geologic Now: Responses to Material Conditions of Contemporary Life","doi":"https://doi.org/10.21983/P3.0014.1.00","publicationDate":"2012-12-04","place":"Brooklyn, NY","contributions":[{"fullName":"Elisabeth Ellsworth","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jamie Kruse","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"35ed7096-8218-43d7-a572-6453c9892ed1","fullTitle":"Manifesto for a Post-Critical Pedagogy","doi":"https://doi.org/10.21983/P3.0193.1.00","publicationDate":"2018-01-11","place":"Earth, Milky Way","contributions":[{"fullName":"Piotr Zamojski","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Joris Vlieghe","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Naomi Hodgson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":null,"imprintId":"3437ff40-3bff-4cda-9f0b-1003d2980335","imprintName":"Risking Education","updatedAt":"2021-07-06T17:43:41.987789+00:00","createdAt":"2021-07-06T17:43:41.987789+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"a01f41d6-1da8-4b0b-87b4-82ecc41c6d55","fullTitle":"Nothing As We Need It: A Chimera","doi":"https://doi.org/10.53288/0382.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Daniela Cascella","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/speculations/","imprintId":"dcf8d636-38ae-4a63-bae1-40a61b5a3417","imprintName":"Speculations","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"03da5b84-80ba-48bc-89b9-b63fc56b364b","fullTitle":"Speculations","doi":"https://doi.org/10.21983/P3.0343.1.00","publicationDate":"2020-07-30","place":"Earth, Milky Way","contributions":[{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c00d9a0c-320d-4dfb-ba0c-d1adbdb491ef","fullTitle":"Speculations 3","doi":"https://doi.org/10.21983/P3.0010.1.00","publicationDate":"2012-09-03","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"2c71d808-d1a7-4918-afbb-2dfc121e7768","fullTitle":"Speculations II","doi":"https://doi.org/10.21983/P3.0344.1.00","publicationDate":"2020-07-30","place":"Earth, Milky Way","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3}]},{"workId":"ee2cb855-4c94-4176-b62c-3114985dd84e","fullTitle":"Speculations IV: Speculative Realism","doi":"https://doi.org/10.21983/P3.0032.1.00","publicationDate":"2013-06-05","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Paul J. Ennis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":4},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Thomas Gokey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":5},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"435a1db3-1bbb-44b2-9368-7b2fd8a4e63e","fullTitle":"Speculations VI","doi":"https://doi.org/10.21983/P3.0122.1.00","publicationDate":"2015-12-12","place":"Brooklyn, NY","contributions":[{"fullName":"Michael Austin","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Robert Jackson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Fabio Gironi","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/thought-crimes/","imprintId":"f2dc7495-17af-4d8a-9306-168fc6fa1f41","imprintName":"Thought | Crimes","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"1bba80bd-2efd-41a2-9b09-4ff8da0efeb9","fullTitle":"New Developments in Anarchist Studies","doi":"https://doi.org/10.21983/P3.0349.1.00","publicationDate":"2015-06-13","place":"Brooklyn, NY","contributions":[{"fullName":"pj lilley","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jeff Shantz","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"5a1cd53e-640b-46e7-82a6-d95bc4907e36","fullTitle":"The Spectacle of the False Flag: Parapolitics from JFK to Watergate","doi":"https://doi.org/10.21983/P3.0347.1.00","publicationDate":"2014-03-01","place":"Brooklyn, NY","contributions":[{"fullName":"Eric Wilson","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Guido Giacomo Preparata","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2},{"fullName":"Jeff Shantz","contributionType":"PREFACE_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"c8245465-2937-40fd-9c3e-7bd33deef477","fullTitle":"Who Killed the Berkeley School? Struggles Over Radical Criminology ","doi":"https://doi.org/10.21983/P3.0348.1.00","publicationDate":"2014-04-21","place":"Brooklyn, NY","contributions":[{"fullName":"Julia Schwendinger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Herman Schwendinger","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jeff Shantz","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/tiny-collections/","imprintId":"be4c8448-93c8-4146-8d9c-84d121bc4bec","imprintName":"Tiny Collections","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"501a8862-dc30-4d1e-ab47-deb9f5579678","fullTitle":"Closer to Dust","doi":"https://doi.org/10.53288/0324.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Sara A. Rich","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"771e1cde-d224-4cb6-bac7-7f5ef4d1a405","fullTitle":"Coconuts: A Tiny History","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Kathleen E. Kennedy","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"20d15631-f886-43a0-b00b-b62426710bdf","fullTitle":"Elemental Disappearances","doi":"https://doi.org/10.21983/P3.0157.1.00","publicationDate":"2016-11-28","place":"Earth, Milky Way","contributions":[{"fullName":"Jason Bahbak Mohaghegh","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Dejan Lukić","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"177e3717-4c07-4f31-9318-616ad3b71e89","fullTitle":"Sea Monsters: Things from the Sea, Volume 2","doi":"https://doi.org/10.21983/P3.0182.1.00","publicationDate":"2017-09-29","place":"Earth, Milky Way","contributions":[{"fullName":"Asa Simon Mittman","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Thea Tomaini","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6dd15dd7-ae8c-4438-a597-7c99d5be4138","fullTitle":"Walk on the Beach: Things from the Sea, Volume 1","doi":"https://doi.org/10.21983/P3.0143.1.00","publicationDate":"2016-06-17","place":"Earth, Milky Way","contributions":[{"fullName":"Maggie M. Williams","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Karen Eileen Overbey","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]}],"__typename":"Imprint"},{"imprintUrl":"https://punctumbooks.com/imprints/uitgeverij/","imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","imprintName":"Uitgeverij","updatedAt":"2021-01-07T16:32:40.853895+00:00","createdAt":"2021-01-07T16:32:40.853895+00:00","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5"},"works":[{"workId":"b5c810e1-c847-4553-a24e-9893164d9786","fullTitle":"(((","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2}]},{"workId":"df9bf011-efaf-49a7-9497-2a4d4cfde9e8","fullTitle":"An Anthology of Asemic Handwriting","doi":"https://doi.org/10.21983/P3.0220.1.00","publicationDate":"2013-08-26","place":"The Hague/Tirana","contributions":[{"fullName":"Michael Jacobson","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Tim Gaze","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"8b77c06a-3c1c-48ac-a32e-466ef37f293e","fullTitle":"A Neo Tropical Companion","doi":"https://doi.org/10.21983/P3.0217.1.00","publicationDate":"2012-01-26","place":"The Hague/Tirana","contributions":[{"fullName":"Jamie Stewart","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"c3c09f99-71f9-431c-b0f4-ff30c3f7fe11","fullTitle":"Continuum: Writings on Poetry as Artistic Practice","doi":"https://doi.org/10.21983/P3.0229.1.00","publicationDate":"2015-11-26","place":"The Hague/Tirana","contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"6c30545e-539b-419a-8b96-5f6c475bab9e","fullTitle":"Disrupting the Digital Humanities","doi":"https://doi.org/10.21983/P3.0230.1.00","publicationDate":"2018-11-06","place":"Earth, Milky Way","contributions":[{"fullName":"Jesse Stommel","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Dorothy Kim","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"dfe575e1-2836-43f3-a11b-316af9509612","fullTitle":"Exegesis of a Renunciation – Esegesi di una rinuncia","doi":"https://doi.org/10.21983/P3.0226.1.00","publicationDate":"2014-10-14","place":"The Hague/Tirana","contributions":[{"fullName":"Francesco Aprile","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Bartolomé Ferrando","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":2},{"fullName":"Caggiula Cristiano","contributionType":"AFTERWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"a9b27739-0d29-4238-8a41-47b3ac2d5bd5","fullTitle":"Filial Arcade & Other Poems","doi":"https://doi.org/10.21983/P3.0223.1.00","publicationDate":"2013-12-21","place":"The Hague/Tirana","contributions":[{"fullName":"Adam Staley Groves","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Marco Mazzi","contributionType":"PHOTOGRAPHER","mainContribution":false,"contributionOrdinal":2}]},{"workId":"c2c22cdf-b9d5-406d-9127-45cea8e741b1","fullTitle":"Hippolytus","doi":"https://doi.org/10.21983/P3.0218.1.00","publicationDate":"2012-08-21","place":"The Hague/Tirana","contributions":[{"fullName":"Euripides","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sean Gurd","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"ebeae9d6-7543-4cd4-9fa9-c39c43ba0d4b","fullTitle":"Men in Aïda","doi":"https://doi.org/10.21983/P3.0224.0.00","publicationDate":"2014-12-31","place":"The Hague/Tirana","contributions":[{"fullName":"David J. Melnick","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sean Gurd","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2}]},{"workId":"d24a0567-d430-4768-8c4d-1b9d59394af2","fullTitle":"On Blinking","doi":"https://doi.org/10.21983/P3.0219.1.00","publicationDate":"2012-08-23","place":"The Hague/Tirana","contributions":[{"fullName":"Sarah Brigid Hannis","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeremy Fernando","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"97d205c8-32f0-4e64-a7df-bf56334be638","fullTitle":"paq'batlh: A Klingon Epic","doi":null,"publicationDate":null,"place":"Earth, Milky Way","contributions":[{"fullName":"Floris Schönfeld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. Van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Kees Ligtelijn","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marc Okrand","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"e81ef154-5bc3-481b-9083-64fd7aeb7575","fullTitle":"paq'batlh: The Klingon Epic","doi":"https://doi.org/10.21983/P3.0215.1.00","publicationDate":"2011-10-10","place":"The Hague/Tirana","contributions":[{"fullName":"Floris Schönfeld","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vincent W.J. Van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":3},{"fullName":"Kees Ligtelijn","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Marc Okrand","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":4}]},{"workId":"119f1640-dfb4-488f-a564-ef507d74b72d","fullTitle":"Pen in the Park: A Resistance Fairytale – Pen Parkta: Bir Direniş Masalı","doi":"https://doi.org/10.21983/P3.0225.1.00","publicationDate":"2014-02-12","place":"The Hague/Tirana","contributions":[{"fullName":"Raşel Meseri","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Sanne Karssenberg","contributionType":"ILUSTRATOR","mainContribution":false,"contributionOrdinal":2}]},{"workId":"0cb39600-2fd2-4a7a-9d3a-6d92b8e32e9e","fullTitle":"Poetry from Beyond the Grave","doi":"https://doi.org/10.21983/P3.0222.1.00","publicationDate":"2013-05-10","place":"The Hague/Tirana","contributions":[{"fullName":"Francisco Cândido \"Chico\" Xavier","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Vitor Peqeuno","contributionType":"TRANSLATOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"Jeremy Fernando","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":3}]},{"workId":"69365c88-4571-45f3-8770-5a94f7c9badc","fullTitle":"Poetry Vocare","doi":"https://doi.org/10.21983/P3.0213.1.00","publicationDate":"2011-01-23","place":"The Hague/Tirana","contributions":[{"fullName":"Adam Staley Groves","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Judith Balso","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"bc283f71-9f37-47c4-b30b-8ed9f3be9f9c","fullTitle":"The Guerrilla I Like a Poet – Ang Gerilya Ay Tulad ng Makata","doi":"https://doi.org/10.21983/P3.0221.1.00","publicationDate":"2013-09-27","place":"The Hague/Tirana","contributions":[{"fullName":"Jose Maria Sison","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Jonas Staal","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"7be9aa8c-b8af-4b2f-96ff-16e4532f2b83","fullTitle":"The Miracle of Saint Mina – Gis Miinan Nokkor","doi":"https://doi.org/10.21983/P3.0216.1.00","publicationDate":"2012-01-05","place":"The Hague/Tirana","contributions":[{"fullName":"Vincent W.J. van Gerven Oei","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":2},{"fullName":"El-Shafie El-Guzuuli","contributionType":"EDITOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"b55c95a7-ce6e-4cfb-8945-cab4e04001e5","fullTitle":"To Be, or Not to Be: Paraphrased","doi":"https://doi.org/10.21983/P3.0227.1.00","publicationDate":"2016-06-17","place":"The Hague/Tirana","contributions":[{"fullName":"Bardsley Rosenbridge","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1}]},{"workId":"367397db-bcb4-4f0e-9185-4be74c119c19","fullTitle":"Writing Art","doi":"https://doi.org/10.21983/P3.0228.1.00","publicationDate":"2015-11-26","place":"The Hague/Tirana","contributions":[{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Alessandro De Francesco","contributionType":"INTRODUCTION_BY","mainContribution":false,"contributionOrdinal":2}]},{"workId":"6a109b6a-55e9-4dd5-b670-61926c10e611","fullTitle":"Writing Death","doi":"https://doi.org/10.21983/P3.0214.1.00","publicationDate":"2011-06-06","place":"The Hague/Tirana","contributions":[{"fullName":"Jeremy Fernando","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1},{"fullName":"Avital Ronell","contributionType":"FOREWORD_BY","mainContribution":false,"contributionOrdinal":2}]}],"__typename":"Imprint"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle index 1e592a8..d24d334 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/imprints.pickle @@ -1 +1 @@ -[{"imprintUrl": "https://punctumbooks.com/imprints/3ecologies-books/", "imprintId": "78b0a283-9be3-4fed-a811-a7d4b9df7b25", "imprintName": "3Ecologies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9", "fullTitle": "A Manga Perfeita", "doi": "https://doi.org/10.21983/P3.0270.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Christine Greiner", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Ernesto Filho", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "c3d008a2-b357-4886-acc4-a2c77f1749ee", "fullTitle": "Last Year at Betty and Bob's: An Actual Occasion", "doi": "https://doi.org/10.53288/0363.1.00", "publicationDate": "2021-07-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "781b77bd-edf8-4688-937d-cc7cc47de89f", "fullTitle": "Last Year at Betty and Bob's: An Adventure", "doi": "https://doi.org/10.21983/P3.0234.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ce38f309-4438-479f-bd1c-b3690dbd7d8d", "fullTitle": "Last Year at Betty and Bob's: A Novelty", "doi": "https://doi.org/10.21983/P3.0233.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "edf31616-ea2a-4c51-b932-f510b9eb8848", "fullTitle": "No Archive Will Restore You", "doi": "https://doi.org/10.21983/P3.0231.1.00", "publicationDate": "2018-11-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Julietta Singh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d4a3f6cb-3023-4088-a5f4-147fb4510874", "fullTitle": "Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew Goulish", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Will Dadario", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d9045f8-1d8f-479c-983d-383f3a289bec", "fullTitle": "Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art", "doi": "https://doi.org/10.21983/P3.0327.1.00", "publicationDate": "2021-02-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Curt Cloninger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ffa5c5dd-ab4b-4739-8281-275d8c1fb504", "fullTitle": "Sweet Spots: Writing the Connective Tissue of Relation", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mattie-Martha Sempert", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "757ff294-0fca-40f5-9f33-39a2d3fd5c8a", "fullTitle": "Teaching Myself To See", "doi": "https://doi.org/10.21983/P3.0303.1.00", "publicationDate": "2021-02-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Tito Mukhopadhyay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "571255b8-5bf5-4fe1-a201-5bc7aded7f9d", "fullTitle": "The Perfect Mango", "doi": "https://doi.org/10.21983/P3.0245.1.00", "publicationDate": "2019-02-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4cfb06e-a5a6-48cc-b7e5-c38228c132a8", "fullTitle": "The Unnaming of Aliass", "doi": "https://doi.org/10.21983/P3.0299.1.00", "publicationDate": "2020-10-01", "place": "Earth, Milky Way", "contributions": [{"fullName": "Karin Bolender", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/advanced-methods/", "imprintId": "ef38d49c-f8cb-4621-9f2f-1637560016e4", "imprintName": "Advanced Methods", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "0729b9d1-87d3-4739-8266-4780c3cc93da", "fullTitle": "Doing Multispecies Theology", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mathew Arthur", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "af1d6a61-66bd-47fd-a8c5-20e433f7076b", "fullTitle": "Inefficient Mapping: A Protocol for Attuning to Phenomena", "doi": "https://doi.org/10.53288/0336.1.00", "publicationDate": "2021-08-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Linda Knight", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aa9059ba-930c-4327-97a1-c8c7877332c1", "fullTitle": "Making a Laboratory: Dynamic Configurations with Transversal Video", "doi": null, "publicationDate": "2020-08-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ben Spatz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8f256239-8104-4838-9587-ac234aedd822", "fullTitle": "Speaking for the Social: A Catalog of Methods", "doi": "https://doi.org/10.21983/P3.0378.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Gemma John", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Hannah Knox", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprint/anarchist-developments-in-cultural-studies/", "imprintId": "3bdf14c5-7f9f-42d2-8e3b-f78de0475c76", "imprintName": "Anarchist Developments in Cultural Studies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1d014946-aa73-4fae-9042-ef8830089f3c", "fullTitle": "Blasting the Canon", "doi": "https://doi.org/10.21983/P3.0035.1.00", "publicationDate": "2013-06-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Ruth Kinna", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "S\u00fcreyyya Evren", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "e1f74d6b-adab-4e56-8bc9-6fbd0eaab89c", "fullTitle": "Ontological Anarch\u00e9: Beyond Materialism and Idealism", "doi": "https://doi.org/10.21983/P3.0060.1.00", "publicationDate": "2014-01-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jason Adams", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Duane Rousselle", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/brainstorm-books/", "imprintId": "1e464718-2055-486b-bcd9-6e21309fcd80", "imprintName": "Brainstorm Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "fdd9e45a-08b4-4b98-9c34-bada71a34979", "fullTitle": "Animal Emotions: How They Drive Human Behavior", "doi": "https://doi.org/10.21983/P3.0305.1.00", "publicationDate": "2020-06-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kenneth L. Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Christian Montag", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "811fd271-b1dc-490a-a872-3d6867d59e78", "fullTitle": "Aural History", "doi": "https://doi.org/10.21983/P3.0282.1.00", "publicationDate": "2020-03-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Gila Ashtor", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f01cb60b-69bf-4d11-bd3c-fd5b36663029", "fullTitle": "Covert Plants: Vegetal Consciousness and Agency in an Anthropocentric World", "doi": "https://doi.org/10.21983/P3.0207.1.00", "publicationDate": "2018-09-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Prudence Gibson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Brits Baylee", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "9bdf38ca-95fd-4cf4-adf6-ed26e97cf213", "fullTitle": "Critique of Fantasy, Vol. 1: Between a Crypt and a Datemark", "doi": "https://doi.org/10.21983/P3.0277.1.00", "publicationDate": "2020-06-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "89f9c84b-be5c-4020-8edc-6fbe0b1c25f5", "fullTitle": "Critique of Fantasy, Vol. 2: The Contest between B-Genres", "doi": "https://doi.org/10.21983/P3.0278.1.00", "publicationDate": "2020-11-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "79464e83-b688-4b82-84bc-18d105f60f33", "fullTitle": "Critique of Fantasy, Vol. 3: The Block of Fame", "doi": "https://doi.org/10.21983/P3.0279.1.00", "publicationDate": "2021-01-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "992c6ff8-e166-4014-85cc-b53af250a4e4", "fullTitle": "Hack the Experience: Tools for Artists from Cognitive Science", "doi": "https://doi.org/10.21983/P3.0206.1.00", "publicationDate": "2018-09-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ryan Dewey", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4a42f23b-5277-49b5-8310-c3c38ded5bf5", "fullTitle": "Opioids: Addiction, Narrative, Freedom", "doi": "https://doi.org/10.21983/P3.0210.1.00", "publicationDate": "2018-10-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maia Dolphin-Krute", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "18d3d876-bcaf-4e1c-a67a-05537f808a99", "fullTitle": "The Hegemony of Psychopathy", "doi": "https://doi.org/10.21983/P3.0180.1.00", "publicationDate": "2017-09-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Lajos Brons", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5dca2af4-43f2-4cdb-a7a5-5654a722c4e0", "fullTitle": "Visceral: Essays on Illness Not as Metaphor", "doi": "https://doi.org/10.21983/P3.0185.1.00", "publicationDate": "2017-10-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maia Dolphin-Krute", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/ctm-documents-initiative/", "imprintId": "cec45cc6-8cb5-43ed-888f-165f3fa73842", "imprintName": "CTM Documents Initiative", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "b950d243-7cfc-4aee-b908-d1776be327df", "fullTitle": "Image Photograph", "doi": "https://doi.org/10.21983/P3.0106.1.00", "publicationDate": "2015-07-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marc Lafia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "14f2b847-faeb-43c9-b116-88a0091b6f1f", "fullTitle": "Knowledge, Spirit, Law, Book 2: The Anti-Capitalist Sublime", "doi": "https://doi.org/10.21983/P3.0191.1.00", "publicationDate": "2017-12-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Gavin Keeney", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1e0c7c29-dcd4-470d-b3ee-8c4012ac79dd", "fullTitle": "Liquid Life: On Non-Linear Materiality", "doi": "https://doi.org/10.21983/P3.0246.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Rachel Armstrong", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "47cd079b-03f3-4a5b-b5e4-36cec4db7fab", "fullTitle": "The Digital Dionysus: Nietzsche and the Network-Centric Condition", "doi": "https://doi.org/10.21983/P3.0149.1.00", "publicationDate": "2016-09-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dan Mellamphy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Nandita Biswas Mellamphy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1950e4ba-651c-4ec9-83f6-df46b777b10f", "fullTitle": "The Funambulist Pamphlets 10: Literature", "doi": "https://doi.org/10.21983/P3.0075.1.00", "publicationDate": "2014-08-14", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "bdfc263a-7ace-43f3-9c80-140c6fb32ec7", "fullTitle": "The Funambulist Pamphlets 11: Cinema", "doi": "https://doi.org/10.21983/P3.0095.1.00", "publicationDate": "2015-02-20", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f5fb8a0e-ea1d-471f-b76a-a000edae5956", "fullTitle": "The Funambulist Pamphlets 1: Spinoza", "doi": "https://doi.org/10.21983/P3.0033.1.00", "publicationDate": "2013-06-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "911de470-77e1-4816-b437-545122a7bf26", "fullTitle": "The Funambulist Pamphlets 2: Foucault", "doi": "https://doi.org/10.21983/P3.0034.1.00", "publicationDate": "2013-06-17", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "61da662d-c720-4d22-957c-4d96071ee5f2", "fullTitle": "The Funambulist Pamphlets 3: Deleuze", "doi": "https://doi.org/10.21983/P3.0038.1.00", "publicationDate": "2013-07-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "419e17ed-3bcc-430c-a67e-3121537e4702", "fullTitle": "The Funambulist Pamphlets 4: Legal Theory", "doi": "https://doi.org/10.21983/P3.0042.1.00", "publicationDate": "2013-08-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fe8ddfb7-0e5b-4604-811c-78cf4db7528b", "fullTitle": "The Funambulist Pamphlets 5: Occupy Wall Street", "doi": "https://doi.org/10.21983/P3.0046.1.00", "publicationDate": "2013-09-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13390641-86f6-4351-923d-8c456f175bff", "fullTitle": "The Funambulist Pamphlets 6: Palestine", "doi": "https://doi.org/10.21983/P3.0054.1.00", "publicationDate": "2013-11-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "448c3581-9167-491e-86f7-08d5a6c953a9", "fullTitle": "The Funambulist Pamphlets 7: Cruel Designs", "doi": "https://doi.org/10.21983/P3.0057.1.00", "publicationDate": "2013-12-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d3cbb60f-537f-4bd7-96cb-d8aba595a947", "fullTitle": "The Funambulist Pamphlets 8: Arakawa + Madeline Gins", "doi": "https://doi.org/10.21983/P3.0064.1.00", "publicationDate": "2014-03-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6fab7c76-7567-4b57-8ad7-90a5536d87af", "fullTitle": "The Funambulist Pamphlets 9: Science Fiction", "doi": "https://doi.org/10.21983/P3.0069.1.00", "publicationDate": "2014-05-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "84bbf59f-1dbb-445e-8f65-f26574f609b6", "fullTitle": "The Funambulist Papers, Volume 1", "doi": "https://doi.org/10.21983/P3.0053.1.00", "publicationDate": "2013-10-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3b41b8de-b9bb-4ebd-a002-52052a9e39a9", "fullTitle": "The Funambulist Papers, Volume 2", "doi": "https://doi.org/10.21983/P3.0098.1.00", "publicationDate": "2015-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/dead-letter-office/", "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "imprintName": "Dead Letter Office", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "fullTitle": "A Bibliography for After Jews and Arabs", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f02786d4-3bcc-473e-8d43-3da66c7e877c", "fullTitle": "A Brief Genealogy of Jewish Republicanism: Parting Ways with Judith Butler", "doi": "https://doi.org/10.21983/P3.0159.1.00", "publicationDate": "2016-12-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Irene Tucker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fd67d684-aaff-4260-bb94-9d0373015620", "fullTitle": "An Edition of Miles Hogarde's \"A Mirroure of Myserie\"", "doi": "https://doi.org/10.21983/P3.0316.1.00", "publicationDate": "2021-06-03", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sebastian Sobecki", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5f441303-4fc6-4a7d-951e-5b966a1cbd91", "fullTitle": "An Unspecific Dog: Artifacts of This Late Stage in History", "doi": "https://doi.org/10.21983/P3.0163.1.00", "publicationDate": "2017-01-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Joshua Rothes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7eb6f426-e913-4d69-92c5-15a640f1b4b9", "fullTitle": "A Sanctuary of Sounds", "doi": "https://doi.org/10.21983/P3.0029.1.00", "publicationDate": "2013-05-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Andreas Burckhardt", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4fc74913-bde4-426e-b7e5-2f66c60af484", "fullTitle": "As If: Essays in As You Like It", "doi": "https://doi.org/10.21983/P3.0162.1.00", "publicationDate": "2016-12-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "William N. West", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "06db2bc1-e25a-42c8-8908-fbd774f73204", "fullTitle": "Atopological Trilogy: Deleuze and Guattari", "doi": "https://doi.org/10.21983/P3.0096.1.00", "publicationDate": "2015-03-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Zafer Aracag\u00f6k", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Manola Antonioli", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "a022743e-8b77-4246-a068-e08d57815e27", "fullTitle": "CMOK to YOu To: A Correspondence", "doi": "https://doi.org/10.21983/P3.0150.1.00", "publicationDate": "2016-09-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc James L\u00e9ger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Nina \u017divan\u010devi\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f94ded4d-1c87-4503-82f1-a1ca4346e756", "fullTitle": "Come As You Are, After Eve Kosofsky Sedgwick", "doi": "https://doi.org/10.21983/P3.0342.1.00", "publicationDate": "2021-04-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eve Kosofsky Sedgwick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonathan Goldberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "449add5c-b935-47e2-8e46-2545fad86221", "fullTitle": "Escargotesque, or, What Is Experience", "doi": "https://doi.org/10.21983/P3.0089.1.00", "publicationDate": "2015-01-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "M.H. Bowker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "628bb121-5ba2-4fc1-a741-a8062c45b63b", "fullTitle": "Gaffe/Stutter", "doi": "https://doi.org/10.21983/P3.0049.1.00", "publicationDate": "2013-10-06", "place": "Brooklyn, NY", "contributions": [{"fullName": "Whitney Anne Trettien", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f131762c-a877-4925-9fa1-50555bc4e2ae", "fullTitle": "[Given, If, Then]: A Reading in Three Parts", "doi": "https://doi.org/10.21983/P3.0090.1.00", "publicationDate": "2015-02-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jennifer Hope Davy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Julia H\u00f6lzl", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cb11259b-7b83-498e-bc8a-7c184ee2c279", "fullTitle": "Going Postcard: The Letter(s) of Jacques Derrida", "doi": "https://doi.org/10.21983/P3.0171.1.00", "publicationDate": "2017-05-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f8b57164-89e6-48b1-bd70-9d360b53a453", "fullTitle": "Helicography", "doi": "https://doi.org/10.53288/0352.1.00", "publicationDate": "2021-07-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Craig Dworkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6689db84-b329-4ca5-b10c-010fd90c7e90", "fullTitle": "History of an Abuse", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ceffc30d-1d28-48c3-acee-e6a2dc38ff37", "fullTitle": "How We Read", "doi": "https://doi.org/10.21983/P3.0259.1.00", "publicationDate": "2019-07-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kaitlin Heller", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Suzanne Conklin Akbari", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "63e2f6b6-f324-4bdc-836e-55515ba3cd8f", "fullTitle": "How We Write: Thirteen Ways of Looking at a Blank Page", "doi": "https://doi.org/10.21983/P3.0110.1.00", "publicationDate": "2015-09-11", "place": "Brooklyn, NY", "contributions": [{"fullName": "Suzanne Conklin Akbari", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f5217945-8c2c-4e65-a5dd-3dbff208dfb7", "fullTitle": "In Divisible Cities: A Phanto-Cartographical Missive", "doi": "https://doi.org/10.21983/P3.0044.1.00", "publicationDate": "2013-08-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Dominic Pettman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d5f5978b-32e0-44a1-a72a-c80568c9b93a", "fullTitle": "I Open Fire", "doi": "https://doi.org/10.21983/P3.0086.1.00", "publicationDate": "2014-12-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Pol", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c6125a74-2801-4255-afe9-89cdb8d253f4", "fullTitle": "John Gardner: A Tiny Eulogy", "doi": "https://doi.org/10.21983/P3.0013.1.00", "publicationDate": "2012-11-29", "place": "Brooklyn, NY", "contributions": [{"fullName": "Phil Jourdan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8377c394-c27a-44cb-98f5-5e5b789ad7b8", "fullTitle": "Last Day Every Day: Figural Thinking from Auerbach and Kracauer to Agamben and Brenez", "doi": "https://doi.org/10.21983/P3.0012.1.00", "publicationDate": "2012-10-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Adrian Martin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1809f10a-d0e3-4481-8f96-cca7f240d656", "fullTitle": "Letters on the Autonomy Project in Art and Politics", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Janet Sarbanes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5f1db605-88b6-427a-84cb-ce2fcf0f89a3", "fullTitle": "Massa por Argamassa: A \"Libraria de Babel\" e o Sonho de Totalidade", "doi": "https://doi.org/10.21983/P3.0264.1.00", "publicationDate": "2019-09-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Basile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Yuri N. Martinez Laskowski", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f20869c5-746f-491b-8c34-f88dc3728e18", "fullTitle": "Min\u00f3y", "doi": "https://doi.org/10.21983/P3.0072.1.00", "publicationDate": "2014-06-30", "place": "Brooklyn, NY", "contributions": [{"fullName": "Joseph Nechvatal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d40aa92-380c-4fae-98d8-c598bb32e7c6", "fullTitle": "Misinterest: Essays, Pens\u00e9es, and Dreams", "doi": "https://doi.org/10.21983/P3.0256.1.00", "publicationDate": "2019-06-27", "place": "Earth, Milky Way", "contributions": [{"fullName": "M.H. Bowker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "34682ba4-201f-4122-8e4a-edc3edc57a7b", "fullTitle": "Nicholas of Cusa and the Kairos of Modernity: Cassirer, Gadamer, Blumenberg", "doi": "https://doi.org/10.21983/P3.0045.1.00", "publicationDate": "2013-09-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Edward Moore", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1cfca75f-2e57-4f34-85fb-a1585315a2a9", "fullTitle": "Noise Thinks the Anthropocene: An Experiment in Noise Poetics", "doi": "https://doi.org/10.21983/P3.0244.1.00", "publicationDate": "2019-02-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Aaron Zwintscher", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "571d5d40-cfd6-4270-9530-88bfcfc5d8b5", "fullTitle": "Non-Conceptual Negativity: Damaged Reflections on Turkey", "doi": "https://doi.org/10.21983/P3.0247.1.00", "publicationDate": "2019-03-27", "place": "Earth, Milky Way", "contributions": [{"fullName": "Zafer Aracag\u00f6k", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Fraco \"Bifo\" Berardi", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "3eb0d095-fc27-4add-8202-1dc2333a758c", "fullTitle": "Notes on Trumpspace: Politics, Aesthetics, and the Fantasy of Home", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "David Stephenson Markus", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "48e2a673-aec2-4ed6-99d4-46a8de200493", "fullTitle": "Nothing in MoMA", "doi": "https://doi.org/10.21983/P3.0208.1.00", "publicationDate": "2018-09-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Abraham Adams", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97019dea-e207-4909-b907-076d0620ff74", "fullTitle": "Obiter Dicta", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Erick Verran", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "10a41381-792f-4376-bed1-3781d1b8bae7", "fullTitle": "Of Learned Ignorance: Idea of a Treatise in Philosophy", "doi": "https://doi.org/10.21983/P3.0031.1.00", "publicationDate": "2013-06-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b43ec529-2f51-4c59-b3cb-394f3649502c", "fullTitle": "Of the Contract", "doi": "https://doi.org/10.21983/P3.0174.1.00", "publicationDate": "2017-07-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christopher Clifton", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "63b0e966-e81c-4d84-b41d-3445b0d9911f", "fullTitle": "Paris Bride: A Modernist Life", "doi": "https://doi.org/10.21983/P3.0281.1.00", "publicationDate": "2020-02-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "John Schad", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed1a8fb5-8b71-43ca-9748-ebd43f0d7580", "fullTitle": "Philosophy for Militants", "doi": "https://doi.org/10.21983/P3.0168.1.00", "publicationDate": "2017-03-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5b652d05-2b5f-465a-8c66-f4dc01dafd03", "fullTitle": "[provisional self-evidence]", "doi": "https://doi.org/10.21983/P3.0111.1.00", "publicationDate": "2015-09-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Rachel Arrighi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cd836291-fb7f-4508-bdff-cd59dca2b447", "fullTitle": "Queer Insists (for Jos\u00e9 Esteban Mu\u00f1oz)", "doi": "https://doi.org/10.21983/P3.0082.1.00", "publicationDate": "2014-12-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael O'Rourke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "46ab709c-3272-4a03-991e-d1b1394b8e2c", "fullTitle": "Ravish the Republic: The Archives of the Iron Garters Crime/Art Collective", "doi": "https://doi.org/10.21983/P3.0107.1.00", "publicationDate": "2015-07-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael L. Berger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "28a0db09-a149-43fe-ba08-00dde962b4b8", "fullTitle": "Reiner Sch\u00fcrmann and Poetics of Politics", "doi": "https://doi.org/10.21983/P3.0209.1.00", "publicationDate": "2018-09-28", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christopher Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5dda1ad6-70ac-4a31-baf2-b77f8f5a8190", "fullTitle": "Sappho: Fragments", "doi": "https://doi.org/10.21983/P3.0238.1.00", "publicationDate": "2018-12-31", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Goldberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "L.O. Aranye Fradenburg Joy", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "8cd5ce6c-d604-46ac-b4f7-1f871589d96a", "fullTitle": "Still Life: Notes on Barbara Loden's \"Wanda\" (1970)", "doi": "https://doi.org/10.53288/0326.1.00", "publicationDate": "2021-07-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anna Backman Rogers", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1547aa4b-7629-4a21-8b2b-621223c73ec9", "fullTitle": "Still Thriving: On the Importance of Aranye Fradenburg", "doi": "https://doi.org/10.21983/P3.0099.1.00", "publicationDate": "2015-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "L.O. Aranye Fradenburg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "08543bd7-e603-43ae-bb0f-1d4c1c96030b", "fullTitle": "Suite on \"Spiritus Silvestre\": For Symphony", "doi": "https://doi.org/10.21983/P3.0020.1.00", "publicationDate": "2012-12-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Denzil Ford", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9839926e-56ea-4d71-a3de-44cabd1d2893", "fullTitle": "Tar for Mortar: \"The Library of Babel\" and the Dream of Totality", "doi": "https://doi.org/10.21983/P3.0196.1.00", "publicationDate": "2018-03-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Basile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "58aadfa5-abc6-4c44-9768-f8ff41502867", "fullTitle": "The Afterlife of Genre: Remnants of the Trauerspiel in Buffy the Vampire Slayer", "doi": "https://doi.org/10.21983/P3.0061.1.00", "publicationDate": "2014-02-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "Anthony Curtis Adler", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1d30497f-4340-43ab-b328-9fd2fed3106e", "fullTitle": "The Anthology of Babel", "doi": "https://doi.org/10.21983/P3.0254.1.00", "publicationDate": "2020-01-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ed Simon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "26d522d4-fb46-47bf-a344-fe6af86688d3", "fullTitle": "The Bodies That Remain", "doi": "https://doi.org/10.21983/P3.0212.1.00", "publicationDate": "2018-10-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Emmy Beber", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a065ad95-716a-4005-b436-a46d9dbd64df", "fullTitle": "The Communism of Thought", "doi": "https://doi.org/10.21983/P3.0059.1.00", "publicationDate": "2014-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c51c8fa-947b-4a12-a2e9-5306ee81d117", "fullTitle": "The Death of Conrad Unger: Some Conjectures Regarding Parasitosis and Associated Suicide Behavior", "doi": "https://doi.org/10.21983/P3.0008.1.00", "publicationDate": "2012-08-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Gary L. Shipley", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "33917b8f-775f-4ee2-a43a-6b5285579f84", "fullTitle": "The Non-Library", "doi": "https://doi.org/10.21983/P3.0065.1.00", "publicationDate": "2014-03-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Trevor Owen Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "60813d93-663f-4974-8789-1a2ee83cd042", "fullTitle": "Theory Is Like a Surging Sea", "doi": "https://doi.org/10.21983/P3.0108.1.00", "publicationDate": "2015-08-02", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "119e45d6-63ab-4cc4-aabf-06ecba1fb055", "fullTitle": "The Witch and the Hysteric: The Monstrous Medieval in Benjamin Christensen's H\u00e4xan", "doi": "https://doi.org/10.21983/P3.0074.1.00", "publicationDate": "2014-08-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "Patricia Clare Ingham", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alexander Doty", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d6651c3c-c453-42ab-84b3-4e847d3a3324", "fullTitle": "Traffic Jams: Analysing Everyday Life through the Immanent Materialism of Deleuze & Guattari", "doi": "https://doi.org/10.21983/P3.0023.1.00", "publicationDate": "2013-02-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "David R. Cole", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "fullTitle": "Truth and Fiction: Notes on (Exceptional) Faith in Art", "doi": "https://doi.org/10.21983/P3.0007.1.00", "publicationDate": "2012-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Milcho Manchevski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adrian Martin", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "b904a8eb-9c98-4bb1-bf25-3cb9d075b157", "fullTitle": "Warez: The Infrastructure and Aesthetics of Piracy", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Martin Eve", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "77e1fa52-1938-47dd-b8a5-2a57bfbc91d1", "fullTitle": "What Is Philosophy?", "doi": "https://doi.org/10.21983/P3.0011.1.00", "publicationDate": "2012-10-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "27602ce3-fbd6-4044-8b44-b8421670edae", "fullTitle": "Wonder, Horror, and Mystery in Contemporary Cinema: Letters on Malick, Von Trier, and Kie\u015blowski", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Morgan Meis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "J.M. Tyree", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/department-of-eagles/", "imprintId": "ef4aece6-6e9c-4f90-b5c3-7e4b78e8942d", "imprintName": "Department of Eagles", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "3ccdbbfc-6550-49f4-8ec9-77fc94a7a099", "fullTitle": "Broken Narrative: The Politics of Contemporary Art in Albania", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Armando Lulaj", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marco Mazzi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Brenda Porster", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Tomii Keiko", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Osamu Kanemura", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 6}, {"fullName": "Jonida Gashi", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 5}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/dotawo/", "imprintId": "f891a5f0-2af2-4eda-b686-db9dd74ee73d", "imprintName": "Dotawo", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1c39ca0c-0189-44d3-bb2f-9345e2a2b152", "fullTitle": "Dotawo: A Journal of Nubian Studies 2", "doi": "https://doi.org/10.21983/P3.0104.1.00", "publicationDate": "2015-06-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Angelika Jakobi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "861ea7cc-5447-4c60-8657-c50d0a31cd24", "fullTitle": "Dotawo: a Journal of Nubian Studies 3: Know-Hows and Techniques in Ancient Sudan", "doi": "https://doi.org/10.21983/P3.0148.1.00", "publicationDate": "2016-08-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc Maillot", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "431b58fe-7f59-49d9-bf6f-53eae379ee4d", "fullTitle": "Dotawo: A Journal of Nubian Studies 4: Place Names and Place Naming in Nubia", "doi": "https://doi.org/10.21983/P3.0184.1.00", "publicationDate": "2017-10-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alexandros Tsakos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Robin Seignobos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3c5923bc-e76b-4fbe-8d8c-1a49a49020a8", "fullTitle": "Dotawo: A Journal of Nubian Studies 5: Nubian Women", "doi": "https://doi.org/10.21983/P3.0242.1.00", "publicationDate": "2019-02-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anne Jennings", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "15ab17fe-2486-4ca5-bb47-6b804793f80d", "fullTitle": "Dotawo: A Journal of Nubian Studies 6: Miscellanea Nubiana", "doi": "https://doi.org/10.21983/P3.0321.1.00", "publicationDate": "2019-12-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Simmons", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aa431454-40d3-42f5-8069-381a15789257", "fullTitle": "Dotawo: A Journal of Nubian Studies 7: Comparative Northern East Sudanic Linguistics", "doi": "https://doi.org/10.21983/P3.0350.1.00", "publicationDate": "2021-03-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7a4506ac-dfdc-4054-b2d1-d8fdf4cea12b", "fullTitle": "Nubian Proverbs", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Maher Habbob", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a8e6722a-1858-4f38-995d-bde0b120fe8c", "fullTitle": "The Old Nubian Language", "doi": "https://doi.org/10.21983/P3.0179.1.00", "publicationDate": "2017-09-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eugenia Smagina", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jos\u00e9 Andr\u00e9s Alonso de la Fuente", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "0cd80cd2-1733-4bde-b48f-a03fc01acfbf", "fullTitle": "The Old Nubian Texts from Attiri", "doi": "https://doi.org/10.21983/P3.0156.1.00", "publicationDate": "2016-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Petra Weschenfelder", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent Pierre-Michel Laisney", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kerstin Weber-Thum", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Alexandros Tsakos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}]}], "__typename": "Imprint"}, {"imprintUrl": null, "imprintId": "47e62ae1-6698-46aa-840c-d4507697459f", "imprintName": "eth press", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "5f24bd29-3d48-4a70-8491-6269f7cc6212", "fullTitle": "Ballads", "doi": "https://doi.org/10.21983/P3.0105.1.00", "publicationDate": "2015-06-03", "place": "Brooklyn, NY", "contributions": [{"fullName": "Richard Owens", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0a8fba81-f1d0-498c-88c4-0b96d3bf2947", "fullTitle": "Cotton Nero A.x: The Works of the \"Pearl\" Poet", "doi": "https://doi.org/10.21983/P3.0066.1.00", "publicationDate": "2014-04-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Chris Piuma", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Lisa Ampleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Daniel C. Remein", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "David Hadbawnik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "53cd2c70-eab6-45b7-a147-8ef1c87d9ac0", "fullTitle": "d\u00f4Nrm'-l\u00e4-p\u00fcsl", "doi": "https://doi.org/10.21983/P3.0183.1.00", "publicationDate": "2017-10-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "kari edwards", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Tina \u017digon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "34584bfe-1cf8-49c5-b8d1-6302ea1cfcfa", "fullTitle": "Snowline", "doi": "https://doi.org/10.21983/P3.0093.1.00", "publicationDate": "2015-02-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Donato Mancini", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cc73eed0-a1f9-4ad4-b7d8-2394b92765f0", "fullTitle": "Unless As Stone Is", "doi": "https://doi.org/10.21983/P3.0058.1.00", "publicationDate": "2014-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Sam Lohmann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/gracchi-books/", "imprintId": "41193484-91d1-44f3-8d0c-0452a35d17a0", "imprintName": "Gracchi Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1603556c-53fc-4d14-b0bf-8c18ad7b24ab", "fullTitle": "Social and Intellectual Networking in the Early Middle Ages", "doi": null, "publicationDate": null, "place": null, "contributions": [{"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "K. Patrick Fazioli", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "6813bf17-373c-49ce-b9e3-1d7ab98f2977", "fullTitle": "The Christian Economy of the Early Medieval West: Towards a Temple Society", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Ian Wood", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2f93b300-f147-48f5-95d5-afd0e0161fe6", "fullTitle": "Urban Interactions: Communication and Competition in Late Antiquity and the Early Middle Ages", "doi": "https://doi.org/10.21983/P3.0300.1.00", "publicationDate": "2020-10-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael Burrows", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ian Wood", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Michael J. Kelly", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "678f4564-d01a-4ffe-8bdb-fead78f87955", "fullTitle": "Vera Lex Historiae?: Constructions of Truth in Medieval Historical Narrative", "doi": "https://doi.org/10.21983/P3.0369.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Catalin Taranu", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/helvete/", "imprintId": "b3dc0be6-6739-4777-ada0-77b1f5074f7d", "imprintName": "Helvete", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "417ecc06-51a4-4660-959b-482763864559", "fullTitle": "Helvete 1: Incipit", "doi": "https://doi.org/10.21983/P3.0027.1.00", "publicationDate": "2013-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Aspasia Stephanou", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Amelia Ishmael", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Zareen Price", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ben Woodard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "3cc0269d-7170-4981-8ac7-5b01e7b9e080", "fullTitle": "Helvete 2: With Head Downwards: Inversions in Black Metal", "doi": "https://doi.org/10.21983/P3.0102.1.00", "publicationDate": "2015-05-19", "place": "Brooklyn, NY", "contributions": [{"fullName": "Niall Scott", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Steve Shakespeare", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "fa4bc310-b7db-458a-8ba9-13347a91c862", "fullTitle": "Helvete 3: Bleeding Black Noise", "doi": "https://doi.org/10.21983/P3.0158.1.00", "publicationDate": "2016-12-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Amelia Ishmael", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/lamma/", "imprintId": "f852b678-e8ac-4949-a64d-3891d4855e3d", "imprintName": "Lamma", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "ce7ec5ea-88b2-430f-92be-0f2436600a46", "fullTitle": "Lamma: A Journal of Libyan Studies 1", "doi": "https://doi.org/10.21983/P3.0337.1.00", "publicationDate": "2020-07-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Benkato", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Leila Tayeb", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Amina Zarrugh", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://www.matteringpress.org", "imprintId": "cb483a78-851f-4936-82d2-8dcd555dcda9", "imprintName": "Mattering Press", "updatedAt": "2021-03-25T16:33:14.299495+00:00", "createdAt": "2021-03-25T16:25:02.238699+00:00", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6", "publisher": {"publisherName": "Mattering Press", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6"}, "works": [{"workId": "95e15115-4009-4cb0-8824-011038e3c116", "fullTitle": "Energy Worlds: In Experiment", "doi": "https://doi.org/10.28938/9781912729098", "publicationDate": "2021-05-01", "place": "Manchester", "contributions": [{"fullName": "Brit Ross Winthereik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Laura Watts", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "James Maguire", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "091abd14-7bc0-4fe7-8194-552edb02b98b", "fullTitle": "Inventing the Social", "doi": "https://doi.org/10.28938/9780995527768", "publicationDate": "2018-07-11", "place": "Manchester", "contributions": [{"fullName": "Michael Guggenheim", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alex Wilkie", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Noortje Marres", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c38728e0-9739-4ad3-b0a7-6cda9a9da4b9", "fullTitle": "Sensing InSecurity: Sensors as transnational security infrastructures", "doi": null, "publicationDate": null, "place": "Manchester", "contributions": []}], "__typename": "Imprint"}, {"imprintUrl": "https://www.mediastudies.press/", "imprintId": "5078b33c-5b3f-48bf-bf37-ced6b02beb7c", "imprintName": "mediastudies.press", "updatedAt": "2021-06-15T14:40:51.652638+00:00", "createdAt": "2021-06-15T14:40:51.652638+00:00", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5", "publisher": {"publisherName": "mediastudies.press", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5"}, "works": [{"workId": "6763ec18-b4af-4767-976c-5b808a64e641", "fullTitle": "Liberty and the News", "doi": "https://doi.org/10.32376/3f8575cb.2e69e142", "publicationDate": "2020-11-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "Walter Lippmann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sue Curry Jansen", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "3162a992-05dd-4b74-9fe0-0f16879ce6de", "fullTitle": "Our Master\u2019s Voice: Advertising", "doi": "https://doi.org/10.21428/3f8575cb.dbba9917", "publicationDate": "2020-10-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "James Rorty", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jefferson Pooley", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "64891e84-6aac-437a-a380-0481312bd2ef", "fullTitle": "Social Media & the Self: An Open Reader", "doi": "https://doi.org/10.32376/3f8575cb.1fc3f80a", "publicationDate": "2021-07-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "Jefferson Pooley", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://meson.press", "imprintId": "0299480e-869b-486c-8a65-7818598c107b", "imprintName": "meson press", "updatedAt": "2021-03-25T16:36:00.832381+00:00", "createdAt": "2021-03-25T16:36:00.832381+00:00", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b", "publisher": {"publisherName": "meson press", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b"}, "works": [{"workId": "59ecdda1-efd8-45d2-b6a6-11bc8fe480f5", "fullTitle": "Earth and Beyond in Tumultuous Times: A Critical Atlas of the Anthropocene", "doi": "https://doi.org/10.14619/1891", "publicationDate": "2021-03-15", "place": "L\u00fcneburg", "contributions": [{"fullName": "Petra L\u00f6ffler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "R\u00e9ka Patr\u00edcia G\u00e1l", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "36f7480e-ca45-452c-a5c0-ba1dccf135ec", "fullTitle": "Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices", "doi": "https://doi.org/10.14619/1860", "publicationDate": "2021-05-17", "place": "Lueneburg", "contributions": [{"fullName": "Wanda Strauven", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "38872158-58b9-4ddf-a90e-f6001ac6c62d", "fullTitle": "Trick 17: Mediengeschichten zwischen Zauberkunst und Wissenschaft", "doi": "https://doi.org/10.14619/017", "publicationDate": "2016-07-14", "place": "L\u00fcneburg, Germany", "contributions": [{"fullName": "Sebastian Vehlken", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 1}, {"fullName": "Jan M\u00fcggenburg", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Katja M\u00fcller-Helle", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Florian Sprenger", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 4}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/oe-case-files/", "imprintId": "39a17f7f-c3f3-4bfe-8c5e-842d53182aad", "imprintName": "\u0152 Case Files", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "a8bf3374-f153-460d-902a-adea7f41d7c7", "fullTitle": "\u0152 Case Files, Vol. 01", "doi": "https://doi.org/10.21983/P3.0354.1.00", "publicationDate": "2021-05-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Simone Ferracina", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/oliphaunt-books/", "imprintId": "353047d8-1ea4-4cc5-bd08-e9cedb4a3e8d", "imprintName": "Oliphaunt Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "0090dbfb-bc8f-44aa-9803-08b277861b14", "fullTitle": "Animal, Vegetable, Mineral: Ethics and Objects", "doi": "https://doi.org/10.21983/P3.0006.1.00", "publicationDate": "2012-05-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "eb8a2862-e812-4730-ab06-8dff1b6208bf", "fullTitle": "Burn after Reading: Vol. 1, Miniature Manifestos for a Post/medieval Studies + Vol. 2, The Future We Want: A Collaboration", "doi": "https://doi.org/10.21983/P3.0067.1.00", "publicationDate": "2014-04-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Myra Seaman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "37cb9bb4-0bb3-4bd3-86ea-d8dfb60c9cd8", "fullTitle": "Inhuman Nature", "doi": "https://doi.org/10.21983/P3.0078.1.00", "publicationDate": "2014-09-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://www.openbookpublishers.com/", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprintName": "Open Book Publishers", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}, "works": [{"workId": "fdeb2a1b-af39-4165-889d-cc7a5a31d5fa", "fullTitle": "Acoustemologies in Contact: Sounding Subjects and Modes of Listening in Early Modernity", "doi": "https://doi.org/10.11647/OBP.0226", "publicationDate": "2021-01-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Emily Wilbourne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Suzanne G. Cusick", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "31aea193-58de-43eb-aadb-23300ba5ee40", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0075", "publicationDate": "2016-01-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fc088d17-bab2-4bfa-90bc-b320760c6c97", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0181", "publicationDate": "2019-10-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b59def35-5712-44ed-8490-9073ab1c6cdc", "fullTitle": "A European Public Investment Outlook", "doi": "https://doi.org/10.11647/OBP.0222", "publicationDate": "2020-06-12", "place": "Cambridge, UK", "contributions": [{"fullName": "Floriana Cerniglia", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Francesco Saraceno", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "528e4526-42e4-4e68-a0d5-f74a285c35a6", "fullTitle": "A Fleet Street In Every Town: The Provincial Press in England, 1855-1900", "doi": "https://doi.org/10.11647/OBP.0152", "publicationDate": "2018-12-13", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Hobbs", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "35941026-43eb-496f-b560-2c21a6dbbbfc", "fullTitle": "Agency: Moral Identity and Free Will", "doi": "https://doi.org/10.11647/OBP.0197", "publicationDate": "2020-04-01", "place": "Cambridge, UK", "contributions": [{"fullName": "David Weissman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3dbfa65a-ed33-46b5-9105-c5694c9c6bab", "fullTitle": "A Handbook and Reader of Ottoman Arabic", "doi": "https://doi.org/10.11647/OBP.0208", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Esther-Miriam Wagner", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0229f930-1e01-40b8-b4a8-03ab57624ced", "fullTitle": "A Lexicon of Medieval Nordic Law", "doi": "https://doi.org/10.11647/OBP.0188", "publicationDate": "2020-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Christine Peel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Jeffrey Love", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Erik Simensen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Inger Larsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ulrika Dj\u00e4rv", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "defda2f0-1003-419a-8c3c-ac8d0b1abd17", "fullTitle": "A Musicology of Performance: Theory and Method Based on Bach's Solos for Violin", "doi": "https://doi.org/10.11647/OBP.0064", "publicationDate": "2015-08-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Dorottya Fabian", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "99af261d-8a31-449e-bf26-20e0178b8ed1", "fullTitle": "An Anglo-Norman Reader", "doi": "https://doi.org/10.11647/OBP.0110", "publicationDate": "2018-02-08", "place": "Cambridge, UK", "contributions": [{"fullName": "Jane Bliss", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0d45084-d852-470d-b9f7-4719304f8a56", "fullTitle": "Animals and Medicine: The Contribution of Animal Experiments to the Control of Disease", "doi": "https://doi.org/10.11647/OBP.0055", "publicationDate": "2015-05-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Jack Botting", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Regina Botting", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Adrian R. Morrison", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "5a597468-a3eb-4026-b29e-eb93b8a7b0d6", "fullTitle": "Annunciations: Sacred Music for the Twenty-First Century", "doi": "https://doi.org/10.11647/OBP.0172", "publicationDate": "2019-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "George Corbett", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "857a5788-a709-4d56-8607-337c1cabd9a2", "fullTitle": "ANZUS and the Early Cold War: Strategy and Diplomacy between Australia, New Zealand and the United States, 1945-1956", "doi": "https://doi.org/10.11647/OBP.0141", "publicationDate": "2018-09-07", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Kelly", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0263f0c-48cd-4923-aef5-1b204636507c", "fullTitle": "A People Passing Rude: British Responses to Russian Culture", "doi": "https://doi.org/10.11647/OBP.0022", "publicationDate": "2012-11-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Anthony Cross", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "69c69fef-ab46-45ab-96d5-d7c4e5d4bce4", "fullTitle": "Arab Media Systems", "doi": "https://doi.org/10.11647/OBP.0238", "publicationDate": "2021-03-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Carola Richter", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Claudia Kozman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1e3ef1d6-a460-4b47-8d14-78c3d18e40c1", "fullTitle": "A Time Travel Dialogue", "doi": "https://doi.org/10.11647/OBP.0043", "publicationDate": "2014-08-01", "place": "Cambridge, UK", "contributions": [{"fullName": "John W. Carroll", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "664931f6-27ca-4409-bb47-5642ca60117e", "fullTitle": "A Victorian Curate: A Study of the Life and Career of the Rev. Dr John Hunt ", "doi": "https://doi.org/10.11647/OBP.0248", "publicationDate": "2021-05-03", "place": "Cambridge, UK", "contributions": [{"fullName": "David Yeandle", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "721fc7c9-7531-40cd-9e59-ab1bef5fc261", "fullTitle": "Basic Knowledge and Conditions on Knowledge", "doi": "https://doi.org/10.11647/OBP.0104", "publicationDate": "2017-10-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Mark McBride", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "39aafd68-dc83-4951-badf-d1f146a38fd4", "fullTitle": "B C, Before Computers: On Information Technology from Writing to the Age of Digital Data", "doi": "https://doi.org/10.11647/OBP.0225", "publicationDate": "2020-10-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Robertson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a373ccbd-0665-4faa-bc24-15542e5cb0cf", "fullTitle": "Behaviour, Development and Evolution", "doi": "https://doi.org/10.11647/OBP.0097", "publicationDate": "2017-02-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Patrick Bateson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "e76e054c-617d-4004-b68d-54739205df8d", "fullTitle": "Beyond Holy Russia: The Life and Times of Stephen Graham", "doi": "https://doi.org/10.11647/OBP.0040", "publicationDate": "2014-02-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Michael Hughes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fe599a6c-ecd8-4ed3-a39e-5778cb9b77da", "fullTitle": "Beyond Price: Essays on Birth and Death", "doi": "https://doi.org/10.11647/OBP.0061", "publicationDate": "2015-10-08", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c7ded4f3-4850-44eb-bd5b-e196a2254d3f", "fullTitle": "Bourdieu and Literature", "doi": "https://doi.org/10.11647/OBP.0027", "publicationDate": "2011-11-30", "place": "Cambridge, UK", "contributions": [{"fullName": "John R.W. Speller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "456b46b9-bbec-4832-95ca-b23dcb975df1", "fullTitle": "Brownshirt Princess: A Study of the 'Nazi Conscience'", "doi": "https://doi.org/10.11647/OBP.0003", "publicationDate": "2009-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Lionel Gossman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1", "fullTitle": "Chronicles from Kashmir: An Annotated, Multimedia Script", "doi": "https://doi.org/10.11647/OBP.0223", "publicationDate": "2020-09-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Nandita Dinesh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c5fe7f09-7dfb-4637-82c8-653a6cb683e7", "fullTitle": "Cicero, Against Verres, 2.1.53\u201386: Latin Text with Introduction, Study Questions, Commentary and English Translation", "doi": "https://doi.org/10.11647/OBP.0016", "publicationDate": "2011-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a03ba4d1-1576-41d0-9e8b-d74eccb682e2", "fullTitle": "Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation", "doi": "https://doi.org/10.11647/OBP.0045", "publicationDate": "2014-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Louise Hodgson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7e753cbc-c74b-4214-a565-2300f544be77", "fullTitle": "Cicero, Philippic 2, 44\u201350, 78\u201392, 100\u2013119: Latin Text, Study Aids with Vocabulary, and Commentary", "doi": "https://doi.org/10.11647/OBP.0156", "publicationDate": "2018-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fd4d3c2a-355f-4bc0-83cb-1cd6764976e7", "fullTitle": "Classical Music: Contemporary Perspectives and Challenges", "doi": "https://doi.org/10.11647/OBP.0242", "publicationDate": "2021-03-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Beckerman Michael", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Boghossian Paul", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "9ea10b68-b23c-4562-b0ca-03ba548889a3", "fullTitle": "Coleridge's Laws: A Study of Coleridge in Malta", "doi": "https://doi.org/10.11647/OBP.0005", "publicationDate": "2010-01-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Barry Hough", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Howard Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Lydia Davis", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Micheal John Kooy", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "98776400-e985-488d-a3f1-9d88879db3cf", "fullTitle": "Complexity, Security and Civil Society in East Asia: Foreign Policies and the Korean Peninsula", "doi": "https://doi.org/10.11647/OBP.0059", "publicationDate": "2015-06-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Kiho Yi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Peter Hayes", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "296c6880-6212-48d2-b327-2c13b6e28d5f", "fullTitle": "Conservation Biology in Sub-Saharan Africa", "doi": "https://doi.org/10.11647/OBP.0177", "publicationDate": "2019-09-08", "place": "Cambridge, UK", "contributions": [{"fullName": "John W. Wilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Richard B. Primack", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "e5ade02a-2f32-495a-b879-98b54df04c0a", "fullTitle": "Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary", "doi": "https://doi.org/10.11647/OBP.0068", "publicationDate": "2015-10-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Bret Mulligan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c86acc9-89a0-4b17-bcdd-520d33fc4f54", "fullTitle": "Creative Multilingualism: A Manifesto", "doi": "https://doi.org/10.11647/OBP.0206", "publicationDate": "2020-05-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Wen-chin Ouyang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Rajinder Dudrah", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Andrew Gosler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Martin Maiden", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Suzanne Graham", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Katrin Kohl", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "10ddfb3d-3434-46f8-a3bb-14dfc0ce9591", "fullTitle": "Cultural Heritage Ethics: Between Theory and Practice", "doi": "https://doi.org/10.11647/OBP.0047", "publicationDate": "2014-10-13", "place": "Cambridge, UK", "contributions": [{"fullName": "Sandis Constantine", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2b031e1a-678b-4dcb-becb-cbd0f0ce9182", "fullTitle": "Deliberation, Representation, Equity: Research Approaches, Tools and Algorithms for Participatory Processes", "doi": "https://doi.org/10.11647/OBP.0108", "publicationDate": "2017-01-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Mats Danielson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Love Ekenberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Karin Hansson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "G\u00f6ran Cars", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "bc253bff-cf00-433d-89a2-031500b888ff", "fullTitle": "Delivering on the Promise of Democracy: Visual Case Studies in Educational Equity and Transformation", "doi": "https://doi.org/10.11647/OBP.0157", "publicationDate": "2019-01-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Sukhwant Jhaj", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "517963d1-a56a-4250-8a07-56743ba60d95", "fullTitle": "Democracy and Power: The Delhi Lectures", "doi": "https://doi.org/10.11647/OBP.0050", "publicationDate": "2014-12-07", "place": "Cambridge, UK", "contributions": [{"fullName": "Noam Chomsky", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jean Dr\u00e8ze", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "60450f84-3e18-4beb-bafe-87c78b5a0159", "fullTitle": "Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition", "doi": "https://doi.org/10.11647/OBP.0098", "publicationDate": "2016-06-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "b3989be1-9115-4635-b766-92f6ebfabef1", "fullTitle": "Denis Diderot's 'Rameau's Nephew': A Multi-media Edition", "doi": "https://doi.org/10.11647/OBP.0044", "publicationDate": "2014-08-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "594ddcb6-2363-47c8-858e-76af2283e486", "fullTitle": "Dickens\u2019s Working Notes for 'Dombey and Son'", "doi": "https://doi.org/10.11647/OBP.0092", "publicationDate": "2017-09-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Tony Laing", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d3adf77-c72b-4b69-bf5a-a042a38a837a", "fullTitle": "Dictionary of the British English Spelling System", "doi": "https://doi.org/10.11647/OBP.0053", "publicationDate": "2015-03-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Greg Brooks", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "364c223d-9c90-4ceb-90e2-51be7d84e923", "fullTitle": "Die Europaidee im Zeitalter der Aufkl\u00e4rung", "doi": "https://doi.org/10.11647/OBP.0127", "publicationDate": "2017-08-21", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d4812e4-c491-4465-8e92-64e4f13662f1", "fullTitle": "Digital Humanities Pedagogy: Practices, Principles and Politics", "doi": "https://doi.org/10.11647/OBP.0024", "publicationDate": "2012-12-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Brett D. Hirsch", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "43d96298-a683-4098-9492-bba1466cb8e0", "fullTitle": "Digital Scholarly Editing: Theories and Practices", "doi": "https://doi.org/10.11647/OBP.0095", "publicationDate": "2016-08-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Elena Pierazzo", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Matthew James Driscoll", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "912c2731-3ca1-4ad9-b601-5d968da6b030", "fullTitle": "Digital Technology and the Practices of Humanities Research", "doi": "https://doi.org/10.11647/OBP.0192", "publicationDate": "2020-01-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Jennifer Edmond", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "78bbcc00-a336-4eb6-b4b5-0c57beec0295", "fullTitle": "Discourses We Live By: Narratives of Educational and Social Endeavour", "doi": "https://doi.org/10.11647/OBP.0203", "publicationDate": "2020-07-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Hazel R. Wright", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marianne H\u00f8yen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1312613f-e01a-499a-b0d0-7289d5b9013d", "fullTitle": "Diversity and Rabbinization: Jewish Texts and Societies between 400 and 1000 CE", "doi": "https://doi.org/10.11647/OBP.0219", "publicationDate": "2021-04-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Gavin McDowell", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Ron Naiweld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel St\u00f6kl Ben Ezra", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "2d74b1a9-c3b0-4278-8cad-856fadc6a19d", "fullTitle": "Don Carlos Infante of Spain: A Dramatic Poem", "doi": "https://doi.org/10.11647/OBP.0134", "publicationDate": "2018-06-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "b190b3c5-88c0-4e4a-939a-26995b7ff95c", "fullTitle": "Earth 2020: An Insider\u2019s Guide to a Rapidly Changing Planet", "doi": "https://doi.org/10.11647/OBP.0193", "publicationDate": "2020-04-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Philippe D. Tortell", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a5e6aa48-02ba-48e4-887f-1c100a532de8", "fullTitle": "Economic Fables", "doi": "https://doi.org/10.11647/OBP.0020", "publicationDate": "2012-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Ariel Rubinstein", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2b63a26d-0db1-4200-983f-8b69d9821d8b", "fullTitle": "Engaging Researchers with Data Management: The Cookbook", "doi": "https://doi.org/10.11647/OBP.0185", "publicationDate": "2019-10-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Yan Wang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "James Savage", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Connie Clare", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marta Teperek", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Maria Cruz", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Elli Papadopoulou", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "af162e8a-23ab-49e6-896d-e53b9d6c0039", "fullTitle": "Essays in Conveyancing and Property Law in Honour of Professor Robert Rennie", "doi": "https://doi.org/10.11647/OBP.0056", "publicationDate": "2015-05-11", "place": "Cambridge, UK", "contributions": [{"fullName": "Frankie McCarthy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Stephen Bogle", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "James Chalmers", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "98d053d6-dcc2-409a-8841-9f19920b49ee", "fullTitle": "Essays in Honour of Eamonn Cantwell: Yeats Annual No. 20", "doi": "https://doi.org/10.11647/OBP.0081", "publicationDate": "2016-12-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Warwick Gould", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "24689aa7-af74-4238-ad75-a9469f094068", "fullTitle": "Essays on Paula Rego: Smile When You Think about Hell", "doi": "https://doi.org/10.11647/OBP.0178", "publicationDate": "2019-09-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Maria Manuel Lisboa", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f76ab190-35f4-4136-86dd-d7fa02ccaebb", "fullTitle": "Ethics for A-Level", "doi": "https://doi.org/10.11647/OBP.0125", "publicationDate": "2017-07-31", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Fisher", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mark Dimmock", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d90e1915-1d2a-40e6-a94c-79f671031224", "fullTitle": "Europa im Geisterkrieg. Studien zu Nietzsche", "doi": "https://doi.org/10.11647/OBP.0133", "publicationDate": "2018-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Werner Stegmaier", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andrea C. Bertino", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "a0a8d5f1-12d0-4d51-973d-ed1dfa73f01f", "fullTitle": "Exploring the Interior: Essays on Literary and Cultural History", "doi": "https://doi.org/10.11647/OBP.0126", "publicationDate": "2018-05-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Karl S. Guthke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3795e166-413c-4568-8c19-1117689ef14b", "fullTitle": "Feeding the City: Work and Food Culture of the Mumbai Dabbawalas", "doi": "https://doi.org/10.11647/OBP.0031", "publicationDate": "2013-07-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Sara Roncaglia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Angela Arnone", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Pier Giorgio Solinas", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "5da7830b-6d55-4eb4-899e-cb2a13b30111", "fullTitle": "Fiesco's Conspiracy at Genoa", "doi": "https://doi.org/10.11647/OBP.0058", "publicationDate": "2015-05-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "John Guthrie", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "83b7409e-f076-4598-965e-9e15615be247", "fullTitle": "Forests and Food: Addressing Hunger and Nutrition Across Sustainable Landscapes", "doi": "https://doi.org/10.11647/OBP.0085", "publicationDate": "2015-11-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Christoph Wildburger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bhaskar Vira", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Stephanie Mansourian", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "1654967f-82f1-4ed0-ae81-7ebbfb9c183d", "fullTitle": "Foundations for Moral Relativism", "doi": "https://doi.org/10.11647/OBP.0029", "publicationDate": "2013-04-17", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "00766beb-0597-48a8-ba70-dd2b8382ec37", "fullTitle": "Foundations for Moral Relativism: Second Expanded Edition", "doi": "https://doi.org/10.11647/OBP.0086", "publicationDate": "2015-11-23", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3083819d-1084-418a-85d4-4f71c2fea139", "fullTitle": "From Darkness to Light: Writers in Museums 1798-1898", "doi": "https://doi.org/10.11647/OBP.0151", "publicationDate": "2019-03-12", "place": "Cambridge, UK", "contributions": [{"fullName": "Rosella Mamoli Zorzi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Katherine Manthorne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5bf6450f-99a7-4375-ad94-d5bde1b0282c", "fullTitle": "From Dust to Digital: Ten Years of the Endangered Archives Programme", "doi": "https://doi.org/10.11647/OBP.0052", "publicationDate": "2015-02-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Maja Kominko", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d16896b7-691e-4620-9adb-1d7a42c69bde", "fullTitle": "From Goethe to Gundolf: Essays on German Literature and Culture", "doi": "https://doi.org/10.11647/OBP.0258", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Roger Paulin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3a167e24-36b5-4d0e-b55f-af6be9a7c827", "fullTitle": "Frontier Encounters: Knowledge and Practice at the Russian, Chinese and Mongolian Border", "doi": "https://doi.org/10.11647/OBP.0026", "publicationDate": "2012-08-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Gr\u00e9gory Delaplace", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Caroline Humphrey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Franck Bill\u00e9", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1471f4c3-a88c-4301-b98a-7193be6dde4b", "fullTitle": "Gallucci's Commentary on D\u00fcrer\u2019s 'Four Books on Human Proportion': Renaissance Proportion Theory", "doi": "https://doi.org/10.11647/OBP.0198", "publicationDate": "2020-03-25", "place": "Cambridge, UK", "contributions": [{"fullName": "James Hutson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "101eb7c2-f15f-41f9-b53a-dfccd4b28301", "fullTitle": "Global Warming in Local Discourses: How Communities around the World Make Sense of Climate Change", "doi": "https://doi.org/10.11647/OBP.0212", "publicationDate": "2020-10-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Michael Br\u00fcggemann", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Simone R\u00f6dder", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "32e99c61-2352-4a88-bb9a-bd81f113ba1e", "fullTitle": "God's Babies: Natalism and Bible Interpretation in Modern America", "doi": "https://doi.org/10.11647/OBP.0048", "publicationDate": "2014-12-17", "place": "Cambridge, UK", "contributions": [{"fullName": "John McKeown", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ab3a9d7f-c9b9-42bf-9942-45f68b40bcd6", "fullTitle": "Hanging on to the Edges: Essays on Science, Society and the Academic Life", "doi": "https://doi.org/10.11647/OBP.0155", "publicationDate": "2018-10-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Daniel Nettle", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9d5ac1c6-a763-49b4-98b2-355d888169be", "fullTitle": "Henry James's Europe: Heritage and Transfer", "doi": "https://doi.org/10.11647/OBP.0013", "publicationDate": "2011-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Adrian Harding", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Annick Duperray", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dennis Tredy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b7790cae-1901-446e-b529-b5fe393d8061", "fullTitle": "History of International Relations: A Non-European Perspective", "doi": "https://doi.org/10.11647/OBP.0074", "publicationDate": "2019-07-31", "place": "Cambridge, UK", "contributions": [{"fullName": "Erik Ringmar", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7b9b68c6-8bb6-42c5-8b19-bf5e56b7293e", "fullTitle": "How to Read a Folktale: The 'Ibonia' Epic from Madagascar", "doi": "https://doi.org/10.11647/OBP.0034", "publicationDate": "2013-10-08", "place": "Cambridge, UK", "contributions": [{"fullName": "Lee Haring", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "23651a20-a26e-4253-b0a9-c8b5bf1409c7", "fullTitle": "Human and Machine Consciousness", "doi": "https://doi.org/10.11647/OBP.0107", "publicationDate": "2018-03-07", "place": "Cambridge, UK", "contributions": [{"fullName": "David Gamez", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "27def25d-48ad-470d-9fbe-1ddc8376e1cb", "fullTitle": "Human Cultures through the Scientific Lens: Essays in Evolutionary Cognitive Anthropology", "doi": "https://doi.org/10.11647/OBP.0257", "publicationDate": "2021-07-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Pascal Boyer", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "859a1313-7b02-4c66-8010-dbe533c4412a", "fullTitle": "Hyperion or the Hermit in Greece", "doi": "https://doi.org/10.11647/OBP.0160", "publicationDate": "2019-02-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Howard Gaskill", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1f591391-7497-4447-8c06-d25006a1b922", "fullTitle": "Image, Knife, and Gluepot: Early Assemblage in Manuscript and Print", "doi": "https://doi.org/10.11647/OBP.0145", "publicationDate": "2019-07-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Kathryn M. Rudy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "50516c2a-154e-4758-9b94-586987af2b7f", "fullTitle": "Information and Empire: Mechanisms of Communication in Russia, 1600-1854", "doi": "https://doi.org/10.11647/OBP.0122", "publicationDate": "2017-11-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Katherine Bowers", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Simon Franklin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1549f31d-4783-4a63-a050-90ffafd77328", "fullTitle": "Infrastructure Investment in Indonesia: A Focus on Ports", "doi": "https://doi.org/10.11647/OBP.0189", "publicationDate": "2019-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Colin Duffield", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Felix Kin Peng Hui", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Sally Wilson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "1692a92d-f86a-4155-9e6c-16f38586b7fc", "fullTitle": "Intellectual Property and Public Health in the Developing World", "doi": "https://doi.org/10.11647/OBP.0093", "publicationDate": "2016-05-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Monirul Azam", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d6850e99-33ce-4cae-ac7c-bd82cf23432b", "fullTitle": "In the Lands of the Romanovs: An Annotated Bibliography of First-hand English-language Accounts of the Russian Empire (1613-1917)", "doi": "https://doi.org/10.11647/OBP.0042", "publicationDate": "2014-04-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Anthony Cross", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4455a769-d374-4eed-8e6a-84c220757c0d", "fullTitle": "Introducing Vigilant Audiences", "doi": "https://doi.org/10.11647/OBP.0200", "publicationDate": "2020-10-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Rashid Gabdulhakov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel Trottier", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Qian Huang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "e414ca1b-a7f2-48c7-9adb-549a04711241", "fullTitle": "Inventory Analytics", "doi": "https://doi.org/10.11647/OBP.0252", "publicationDate": "2021-05-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Roberto Rossi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ad55c2c5-9769-4648-9c42-dc4cef1f1c99", "fullTitle": "Is Behavioral Economics Doomed? The Ordinary versus the Extraordinary", "doi": "https://doi.org/10.11647/OBP.0021", "publicationDate": "2012-09-17", "place": "Cambridge, UK", "contributions": [{"fullName": "David K. Levine", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2ceb72f2-ddde-45a7-84a9-27523849f8f5", "fullTitle": "Jane Austen: Reflections of a Reader", "doi": "https://doi.org/10.11647/OBP.0216", "publicationDate": "2021-02-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Nora Bartlett", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jane Stabler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5b542db8-c128-48ff-a48c-003c95eaca25", "fullTitle": "Jewish-Muslim Intellectual History Entangled: Textual Materials from the Firkovitch Collection, Saint Petersburg", "doi": "https://doi.org/10.11647/OBP.0214", "publicationDate": "2020-08-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Jan Thiele", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Wilferd Madelung", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Omar Hamdan", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Adang Camilla", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sabine Schmidtke", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Bruno Chiesa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "df7eb598-914a-49eb-9cbd-9766bd06be84", "fullTitle": "Just Managing? What it Means for the Families of Austerity Britain", "doi": "https://doi.org/10.11647/OBP.0112", "publicationDate": "2017-05-29", "place": "Cambridge, UK", "contributions": [{"fullName": "Paul Kyprianou", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mark O'Brien", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c5e415c4-1ed1-4c58-abae-b1476689a867", "fullTitle": "Knowledge and the Norm of Assertion: An Essay in Philosophical Science", "doi": "https://doi.org/10.11647/OBP.0083", "publicationDate": "2016-02-26", "place": "Cambridge, UK", "contributions": [{"fullName": "John Turri", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9fc774fa-3a18-42d8-89e3-b5a23d822dd6", "fullTitle": "Labor and Value: Rethinking Marx\u2019s Theory of Exploitation", "doi": "https://doi.org/10.11647/OBP.0182", "publicationDate": "2019-10-02", "place": "Cambridge, UK", "contributions": [{"fullName": "Ernesto Screpanti", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "29e28ee7-c52d-43f3-95da-f99f33f0e737", "fullTitle": "Les Bienveillantes de Jonathan Littell: \u00c9tudes r\u00e9unies par Murielle Lucie Cl\u00e9ment", "doi": "https://doi.org/10.11647/OBP.0006", "publicationDate": "2010-04-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Murielle Lucie Cl\u00e9ment", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d9e671dd-ab2a-4fd0-ada3-4925449a63a8", "fullTitle": "Letters of Blood and Other Works in English", "doi": "https://doi.org/10.11647/OBP.0017", "publicationDate": "2011-11-30", "place": "Cambridge, UK", "contributions": [{"fullName": "G\u00f6ran Printz-P\u00e5hlson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Robert Archambeau", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Elinor Shaffer", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Lars-H\u00e5kan Svensson", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "c699f257-f3e4-4c98-9a3f-741c6a40b62a", "fullTitle": "L\u2019id\u00e9e de l\u2019Europe: au Si\u00e8cle des Lumi\u00e8res", "doi": "https://doi.org/10.11647/OBP.0116", "publicationDate": "2017-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "a795aafb-d189-4d15-8e64-b9a3fbfa8e09", "fullTitle": "Life Histories of Etnos Theory in Russia and Beyond", "doi": "https://doi.org/10.11647/OBP.0150", "publicationDate": "2019-02-06", "place": "Cambridge, UK", "contributions": [{"fullName": "Dmitry V Arzyutov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "David G. Anderson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sergei S. Alymov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "5c55effb-2a3e-4e0d-a46d-edad7830fd8e", "fullTitle": "Lifestyle in Siberia and the Russian North", "doi": "https://doi.org/10.11647/OBP.0171", "publicationDate": "2019-11-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Joachim Otto Habeck", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6090bfc8-3143-4599-b0dd-17705f754e8c", "fullTitle": "Like Nobody's Business: An Insider's Guide to How US University Finances Really Work", "doi": "https://doi.org/10.11647/OBP.0240", "publicationDate": "2021-02-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew C. Comrie", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "25a2f70a-832d-4c8d-b28f-75f838b6e171", "fullTitle": "Liminal Spaces: Migration and Women of the Guyanese Diaspora", "doi": "https://doi.org/10.11647/OBP.0218", "publicationDate": "2020-09-29", "place": "Cambridge, UK", "contributions": [{"fullName": "Grace Aneiza Ali", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9845c8a9-b283-4cb8-8961-d41e5fe795f1", "fullTitle": "Literature Against Criticism: University English and Contemporary Fiction in Conflict", "doi": "https://doi.org/10.11647/OBP.0102", "publicationDate": "2016-10-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Martin Paul Eve", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f957ab3d-c925-4bf2-82fa-9809007753e7", "fullTitle": "Living Earth Community: Multiple Ways of Being and Knowing", "doi": "https://doi.org/10.11647/OBP.0186", "publicationDate": "2020-05-07", "place": "Cambridge, UK", "contributions": [{"fullName": "John Grim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Mary Evelyn Tucker", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Sam Mickey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "545f9f42-87c0-415e-9086-eee27925c85b", "fullTitle": "Long Narrative Songs from the Mongghul of Northeast Tibet: Texts in Mongghul, Chinese, and English", "doi": "https://doi.org/10.11647/OBP.0124", "publicationDate": "2017-10-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Gerald Roche", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Li Dechun", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/peanut-books/", "imprintId": "5cc7d3db-f300-4813-9c68-3ccc18a6277b", "imprintName": "Peanut Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "14a2356a-4767-4136-b44a-684a28dc87a6", "fullTitle": "In a Trance: On Paleo Art", "doi": "https://doi.org/10.21983/P3.0081.1.00", "publicationDate": "2014-11-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Skoblow", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "200b11a8-57d6-4f81-b089-ddd4ee7fe2f2", "fullTitle": "The Apartment of Tragic Appliances: Poems", "doi": "https://doi.org/10.21983/P3.0030.1.00", "publicationDate": "2013-05-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael D. Snediker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "49ebcb4a-928f-4d83-9596-b296dfce0b20", "fullTitle": "The Petroleum Manga: A Project by Marina Zurkow", "doi": "https://doi.org/10.21983/P3.0062.1.00", "publicationDate": "2014-02-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marina Zurkow", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2a360648-3157-4a1b-9ba7-a61895a8a10c", "fullTitle": "Where the Tiny Things Are: Feathered Essays", "doi": "https://doi.org/10.21983/P3.0181.1.00", "publicationDate": "2017-09-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nicole Walker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/", "imprintId": "7522e351-8a91-40fa-bf45-02cb38368b0b", "imprintName": "punctum books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "5402ea62-7a1b-48b4-b5fb-7b114c04bc27", "fullTitle": "A Boy Asleep under the Sun: Versions of Sandro Penna", "doi": "https://doi.org/10.21983/P3.0080.1.00", "publicationDate": "2014-11-11", "place": "Brooklyn, NY", "contributions": [{"fullName": "Sandro Penna", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Peter Valente", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Peter Valente", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "8a27431b-b1f9-4fed-a8e0-0a0aadc9d98c", "fullTitle": "A Buddha Land in This World: Philosophy, Utopia, and Radical Buddhism", "doi": "https://doi.org/10.53288/0373.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Lajos Brons", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "eeb920c0-6f2e-462c-a315-3687b5ca8da3", "fullTitle": "Action [poems]", "doi": "https://doi.org/10.21983/P3.0083.1.00", "publicationDate": "2014-12-10", "place": "Brooklyn, NY", "contributions": [{"fullName": "Anthony Opal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "20dab41d-2267-4a68-befa-d787b7c98599", "fullTitle": "After the \"Speculative Turn\": Realism, Philosophy, and Feminism", "doi": "https://doi.org/10.21983/P3.0152.1.00", "publicationDate": "2016-10-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katerina Kolozova", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13a03c11-0f22-4d40-881d-b935452d4bf3", "fullTitle": "Air Supplied", "doi": "https://doi.org/10.21983/P3.0201.1.00", "publicationDate": "2018-05-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "David Cross", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5147a952-3d44-4beb-8d49-b41c91bce733", "fullTitle": "Alternative Historiographies of the Digital Humanities", "doi": "https://doi.org/10.53288/0274.1.00", "publicationDate": "2021-06-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adeline Koh", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dorothy Kim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f712541c-07b4-477c-8b8c-8c1a307810d0", "fullTitle": "And Another Thing: Nonanthropocentrism and Art", "doi": "https://doi.org/10.21983/P3.0144.1.00", "publicationDate": "2016-06-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Katherine Behar", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Emmy Mikelson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "27e17948-02c4-4ba3-8244-5c229cc8e9b8", "fullTitle": "Anglo-Saxon(ist) Pasts, postSaxon Futures", "doi": "https://doi.org/10.21983/P3.0262.1.00", "publicationDate": "2019-12-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Donna-Beth Ellard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f3c9e9d8-9a38-4558-be2e-cab9a70d62f0", "fullTitle": "Annotations to Geoffrey Hill's Speech! Speech!", "doi": "https://doi.org/10.21983/P3.0004.1.00", "publicationDate": "2012-01-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Ann Hassan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "baf524c6-0a2c-40f2-90a7-e19c6e1b6b97", "fullTitle": "Anthropocene Unseen: A Lexicon", "doi": "https://doi.org/10.21983/P3.0265.1.00", "publicationDate": "2020-02-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Cymene Howe", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anand Pandian", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f6afff19-25ae-41f8-8a7a-6c1acffafc39", "fullTitle": "Antiracism Inc.: Why the Way We Talk about Racial Justice Matters", "doi": "https://doi.org/10.21983/P3.0250.1.00", "publicationDate": "2019-04-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Paula Ioanide", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alison Reed", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Felice Blake", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "88c47bd3-f8c9-4157-9d1a-770d9be8c173", "fullTitle": "A Nuclear Refrain: Emotion, Empire, and the Democratic Potential of Protest", "doi": "https://doi.org/10.21983/P3.0271.1.00", "publicationDate": "2019-12-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kye Askins", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Phil Johnstone", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kelvin Mason", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "41508a3c-614b-473e-aa74-edcb6b09dc9d", "fullTitle": "Ardea: A Philosophical Novella", "doi": "https://doi.org/10.21983/P3.0147.1.00", "publicationDate": "2016-07-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Freya Mathews", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ae9f8357-4b39-4809-a8e9-766e200fb937", "fullTitle": "A Rushed Quality", "doi": "https://doi.org/10.21983/P3.0103.1.00", "publicationDate": "2015-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Odell", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3f78b298-8826-4162-886e-af21a77f2957", "fullTitle": "Athens and the War on Public Space: Tracing a City in Crisis", "doi": "https://doi.org/10.21983/P3.0199.1.00", "publicationDate": "2018-04-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christos Filippidis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Klara Jaya Brekke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Antonis Vradis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "3da27fb9-7a15-446e-ae0f-258c7dd4fd94", "fullTitle": "Barton Myers: Works of Architecture and Urbanism", "doi": "https://doi.org/10.21983/P3.0249.1.00", "publicationDate": "2019-07-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kris Miller-Fisher", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jocelyn Gibbs", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f4d42680-8b02-4e3a-9ec8-44aee852b29f", "fullTitle": "Bathroom Songs: Eve Kosofsky Sedgwick as a Poet", "doi": "https://doi.org/10.21983/P3.0189.1.00", "publicationDate": "2017-11-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jason Edwards", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "637566b3-dca3-4a8b-b5bd-01fcbb77ca09", "fullTitle": "Beowulf: A Translation", "doi": "https://doi.org/10.21983/P3.0009.1.00", "publicationDate": "2012-08-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Hadbawnik", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Thomas Meyer", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel C. Remein", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "David Hadbawnik", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "9bae1a52-f764-417d-9d45-4df12f71cf07", "fullTitle": "Beowulf by All", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Elaine Treharne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jean Abbott", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mateusz Fafinski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "a2ce9f9c-f594-4165-83be-e3751d4d17fe", "fullTitle": "Beta Exercise: The Theory and Practice of Osamu Kanemura", "doi": "https://doi.org/10.21983/P3.0241.1.00", "publicationDate": "2019-01-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "Osamu Kanemura", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Marco Mazzi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Nicholas Marshall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Michiyo Miyake", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "735d8962-5ec7-41ce-a73a-a43c35cc354f", "fullTitle": "Between Species/Between Spaces: Art and Science on the Outer Cape", "doi": "https://doi.org/10.21983/P3.0325.1.00", "publicationDate": "2020-08-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dylan Gauthier", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kendra Sullivan", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a871cb31-e158-401d-a639-3767131c0f34", "fullTitle": "Bigger Than You: Big Data and Obesity", "doi": "https://doi.org/10.21983/P3.0135.1.00", "publicationDate": "2016-03-03", "place": "Earth, Milky Way", "contributions": [{"fullName": "Katherine Behar", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "940d0880-83b5-499d-9f39-1bf30ccfc4d0", "fullTitle": "Book of Anonymity", "doi": "https://doi.org/10.21983/P3.0315.1.00", "publicationDate": "2021-03-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anon Collective", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "006571ae-ac0e-4cb0-8a3f-71280aa7f23b", "fullTitle": "Broken Records", "doi": "https://doi.org/10.21983/P3.0137.1.00", "publicationDate": "2016-03-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sne\u017eana \u017dabi\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "47c71c05-a4f1-48da-b8d5-9e5ba139a8ea", "fullTitle": "Building Black: Towards Antiracist Architecture", "doi": "https://doi.org/10.21983/P3.0372.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Elliot C. Mason", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "dd9008ae-0172-4e07-b3cf-50c35c51b606", "fullTitle": "Bullied: The Story of an Abuse", "doi": "https://doi.org/10.21983/P3.0356.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "46344fe3-1d72-4ddd-a57e-1d3f4377d2a2", "fullTitle": "Centaurs, Rioting in Thessaly: Memory and the Classical World", "doi": "https://doi.org/10.21983/P3.0192.1.00", "publicationDate": "2018-01-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Martyn Hudson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7f1d3e2e-c708-4f59-81cf-104c1ca528d0", "fullTitle": "Chaste Cinematics", "doi": "https://doi.org/10.21983/P3.0117.1.00", "publicationDate": "2015-10-31", "place": "Brooklyn, NY", "contributions": [{"fullName": "Victor J. Vitanza", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b2d1b2e3-226e-43c2-a898-fbad7b410e3f", "fullTitle": "Christina McPhee: A Commonplace Book", "doi": "https://doi.org/10.21983/P3.0186.1.00", "publicationDate": "2017-10-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "45aa16fa-5fd5-4449-a3bd-52d734fcb0a9", "fullTitle": "Cinema's Doppelg\u00e4ngers\n", "doi": "https://doi.org/10.53288/0320.1.00", "publicationDate": "2021-06-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Doug Dibbern", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "84447325-88e2-4658-8597-3f2329451156", "fullTitle": "Clinical Encounters in Sexuality: Psychoanalytic Practice and Queer Theory", "doi": "https://doi.org/10.21983/P3.0167.1.00", "publicationDate": "2017-03-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eve Watson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Noreen Giffney", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d0430e3-3640-4d87-8f02-cbb45f6ae83b", "fullTitle": "Comic Providence", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Janet Thormann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0ff62120-4478-46dc-8d01-1d7e1dc5b7a6", "fullTitle": "Commonist Tendencies: Mutual Aid beyond Communism", "doi": "https://doi.org/10.21983/P3.0040.1.00", "publicationDate": "2013-07-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea", "doi": "https://doi.org/10.21983/P3.0269.1.00", "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "93330f65-a84f-4c5c-aa44-f710c714eca2", "fullTitle": "Continent. Year 1: A Selection of Issues 1.1\u20131.4", "doi": "https://doi.org/10.21983/P3.0016.1.00", "publicationDate": "2012-12-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Adam Staley Groves", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Paul Boshears", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Jamie Allen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3d78e15e-19cb-464a-a238-b5291dbfd49f", "fullTitle": "Creep: A Life, A Theory, An Apology", "doi": "https://doi.org/10.21983/P3.0178.1.00", "publicationDate": "2017-08-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f2a2626b-4029-4e43-bb84-7b3cacf61b23", "fullTitle": "Crisis States: Governance, Resistance & Precarious Capitalism", "doi": "https://doi.org/10.21983/P3.0146.1.00", "publicationDate": "2016-07-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "639a3c5b-82ad-4557-897b-2bfebe3dc53c", "fullTitle": "Critique of Sovereignty, Book 1: Contemporary Theories of Sovereignty", "doi": "https://doi.org/10.21983/P3.0114.1.00", "publicationDate": "2015-09-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marc Lombardo", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f37627c1-d89f-434c-9915-f1f2f33dc037", "fullTitle": "Crush", "doi": "https://doi.org/10.21983/P3.0063.1.00", "publicationDate": "2014-02-27", "place": "Brooklyn, NY", "contributions": [{"fullName": "Will Stockton", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "D. Gilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "43355368-b29b-4fa1-9ed6-780f4983364a", "fullTitle": "Damayanti and Nala's Tale", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Dan Rudmann", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "11749800-364e-4a27-bf79-9f0ceeacb4d6", "fullTitle": "Dark Chaucer: An Assortment", "doi": "https://doi.org/10.21983/P3.0018.1.00", "publicationDate": "2012-12-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nicola Masciandaro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Myra Seaman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "7fe2c6dc-6673-4537-a397-1f0377c2296f", "fullTitle": "Dear Professor: A Chronicle of Absences", "doi": "https://doi.org/10.21983/P3.0160.1.00", "publicationDate": "2016-12-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Filip Noterdaeme", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Shuki Cohen", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "0985e294-aa85-40d0-90ce-af53ae37898d", "fullTitle": "Deleuze and the Passions", "doi": "https://doi.org/10.21983/P3.0161.1.00", "publicationDate": "2016-12-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sjoerd van Tuinen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ceciel Meiborg", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9e6bb4d8-4e05-4cd7-abe9-4a795ade0340", "fullTitle": "Derrida and Queer Theory", "doi": "https://doi.org/10.21983/P3.0172.1.00", "publicationDate": "2017-05-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christian Hite", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9e11adff-abed-4b5d-adef-b0c4466231e8", "fullTitle": "Desire/Love", "doi": "https://doi.org/10.21983/P3.0015.1.00", "publicationDate": "2012-12-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Lauren Berlant", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6141d35a-a5a6-43ee-b6b6-5caa41bce869", "fullTitle": "Desire/Love", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Lauren Berlant", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13c12944-701a-41f4-9d85-c753267d564b", "fullTitle": "Destroyer of Naivet\u00e9s", "doi": "https://doi.org/10.21983/P3.0118.1.00", "publicationDate": "2015-11-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Joseph Nechvatal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "69c890c5-d8c5-4295-b5a7-688560929d8b", "fullTitle": "Dialectics Unbound: On the Possibility of Total Writing", "doi": "https://doi.org/10.21983/P3.0041.1.00", "publicationDate": "2013-07-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Maxwell Kennel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "25be3523-34b5-43c9-a3e2-b12ffb859025", "fullTitle": "Dire Pessimism: An Essay", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Thomas Carl Wall", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "245c521a-5014-4da0-bf2b-35eff9673367", "fullTitle": "dis/cord: Thinking Sound through Agential Realism", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Kevin Toks\u00f6z Fairbarn", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "488c640d-e742-465a-98b4-1234bb09d038", "fullTitle": "Diseases of the Head: Essays on the Horrors of Speculative Philosophy", "doi": "https://doi.org/10.21983/P3.0280.1.00", "publicationDate": "2020-09-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Matt Rosen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "754c1299-9b8d-41ac-a1d6-534f174fa87b", "fullTitle": "Disturbing Times: Medieval Pasts, Reimagined Futures", "doi": "https://doi.org/10.21983/P3.0313.1.00", "publicationDate": "2020-06-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Anna K\u0142osowska", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Catherine E. Karkov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "438e0846-b4b9-4c84-9545-d7a6fb13e996", "fullTitle": "Divine Name Verification: An Essay on Anti-Darwinism, Intelligent Design, and the Computational Nature of Reality", "doi": "https://doi.org/10.21983/P3.0043.1.00", "publicationDate": "2013-08-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Noah Horwitz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9d1f849d-cf0f-4d0c-8dab-8819fad00337", "fullTitle": "Dollar Theater Theory", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Trevor Owen Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cd037a39-f6b9-462a-a207-5079a000065b", "fullTitle": "Dotawo: A Journal of Nubian Studies 1", "doi": "https://doi.org/10.21983/P3.0071.1.00", "publicationDate": "2014-06-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Angelika Jakobi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "6092f859-05fe-475d-b914-3c1a6534e6b9", "fullTitle": "Down to Earth: A Memoir", "doi": "https://doi.org/10.21983/P3.0306.1.00", "publicationDate": "2020-10-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "G\u00edsli P\u00e1lsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna Yates", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrina Downs-Rose", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "ac6acc15-6927-4cef-95d3-1c71183ef2a6", "fullTitle": "Echoes of No Thing: Thinking between Heidegger and D\u014dgen", "doi": "https://doi.org/10.21983/P3.0239.1.00", "publicationDate": "2019-01-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2658fe95-2df3-4e7d-8df6-e86c18359a23", "fullTitle": "Ephemeral Coast, S. Wales", "doi": "https://doi.org/10.21983/P3.0079.1.00", "publicationDate": "2014-11-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Celina Jeffery", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "98ce9caa-487e-4391-86c9-e5d8129be5b6", "fullTitle": "Essays on the Peripheries", "doi": "https://doi.org/10.21983/P3.0291.1.00", "publicationDate": "2021-04-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Peter Valente", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "19b32470-bf29-48e1-99db-c08ef90516a9", "fullTitle": "Everyday Cinema: The Films of Marc Lafia", "doi": "https://doi.org/10.21983/P3.0164.1.00", "publicationDate": "2017-01-31", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc Lafia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "859e72c3-8159-48e4-b2f0-842f3400cb8d", "fullTitle": "Extraterritorialities in Occupied Worlds", "doi": "https://doi.org/10.21983/P3.0131.1.00", "publicationDate": "2016-02-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ruti Sela Maayan Amir", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1b870455-0b99-4d0e-af22-49f4ebbb6493", "fullTitle": "Finding Room in Beirut: Places of the Everyday", "doi": "https://doi.org/10.21983/P3.0243.1.00", "publicationDate": "2019-02-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Carole L\u00e9vesque", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6ca16a49-7c95-4c81-b8f0-8f3c7e42de7d", "fullTitle": "Flash + Cube (1965\u20131975)", "doi": "https://doi.org/10.21983/P3.0036.1.00", "publicationDate": "2013-07-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marget Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7fbc96cf-4c88-4e70-b1fe-d4e69324184a", "fullTitle": "Flash + Cube (1965\u20131975)", "doi": null, "publicationDate": "2012-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marget Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f4a04558-958a-43da-b009-d5b7580c532f", "fullTitle": "Follow for Now, Volume 2: More Interviews with Friends and Heroes", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Roy Christopher", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97a2ac65-5b1b-4ab8-8588-db8340f04d27", "fullTitle": "Fuckhead", "doi": "https://doi.org/10.21983/P3.0048.1.00", "publicationDate": "2013-09-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Rawson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f3294e78-9a12-49ff-983e-ed6154ff621e", "fullTitle": "Gender Trouble Couplets, Volume 1", "doi": "https://doi.org/10.21983/P3.0266.1.00", "publicationDate": "2019-11-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "A.W. Strouse", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna M. K\u0142osowska", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "c80467d8-d472-4643-9a50-4ac489da14dd", "fullTitle": "Geographies of Identity", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jill Darling", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "bbe77bbb-0242-46d7-92d2-cfd35c17fe8f", "fullTitle": "Heathen Earth: Trumpism and Political Ecology", "doi": "https://doi.org/10.21983/P3.0170.1.00", "publicationDate": "2017-05-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kyle McGee", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "875a78d7-fad2-4c22-bb04-35e0456b6efa", "fullTitle": "Heavy Processing (More than a Feeling)", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "T.L. Cowan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jasmine Rault", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7f72c34d-4515-42eb-a32e-38fe74217b70", "fullTitle": "Hephaestus Reloaded: Composed for Ten Hands / Efesto Reloaded: Composizioni per 10 mani", "doi": "https://doi.org/10.21983/P3.0258.1.00", "publicationDate": "2019-12-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Berg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Brunella Antomarini", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Miltos Maneta", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Vladimir D\u2019Amora", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pietro Traversa", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 8}, {"fullName": "Patrick Camiller", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 7}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 6}]}, {"workId": "b63ffeb5-7906-4c74-8ec2-68cbe87f593c", "fullTitle": "History According to Cattle", "doi": "https://doi.org/10.21983/P3.0116.1.00", "publicationDate": "2015-10-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Terike Haapoja", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Laura Gustafsson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4f46d026-49c6-4319-b79a-a6f70d412b5c", "fullTitle": "Homotopia? Gay Identity, Sameness & the Politics of Desire", "doi": "https://doi.org/10.21983/P3.0124.1.00", "publicationDate": "2015-12-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jonathan Kemp", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0257269-5ca3-40b3-b4e1-90f66baddb88", "fullTitle": "Humid, All Too Humid: Overheated Observations", "doi": "https://doi.org/10.21983/P3.0132.1.00", "publicationDate": "2016-02-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dominic Pettman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "241f9c62-26be-4d0f-864b-ad4b243a03c3", "fullTitle": "Imperial Physique", "doi": "https://doi.org/10.21983/P3.0268.1.00", "publicationDate": "2019-11-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "JH Phrydas", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aeed0683-e022-42d0-a954-f9f36afc4bbf", "fullTitle": "Incomparable Poetry: An Essay on the Financial Crisis of 2007\u20132008 and Irish Literature", "doi": "https://doi.org/10.21983/P3.0286.1.00", "publicationDate": "2020-05-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Robert Kiely", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5ec826f5-18ab-498c-8b66-bd288618df15", "fullTitle": "Insurrectionary Infrastructures", "doi": "https://doi.org/10.21983/P3.0200.1.00", "publicationDate": "2018-05-02", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "89990379-94c2-4590-9037-cbd5052694a4", "fullTitle": "Intimate Bureaucracies", "doi": "https://doi.org/10.21983/P3.0005.1.00", "publicationDate": "2012-03-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "dj readies", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "85a2a2fe-d515-4784-b451-d26ec4c62a4f", "fullTitle": "Iteration:Again: 13 Public Art Projects across Tasmania", "doi": "https://doi.org/10.21983/P3.0037.1.00", "publicationDate": "2013-07-02", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Cross", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael Edwards", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "f3db2a03-75db-4837-af31-4bb0cb189fa2", "fullTitle": "Itinerant Philosophy: On Alphonso Lingis", "doi": "https://doi.org/10.21983/P3.0073.1.00", "publicationDate": "2014-08-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Tom Sparrow", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bobby George", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1376b0f4-e967-4a6f-8d7d-8ba876bbbdde", "fullTitle": "Itinerant Spectator/Itinerant Spectacle", "doi": "https://doi.org/10.21983/P3.0056.1.00", "publicationDate": "2013-12-20", "place": "Brooklyn, NY", "contributions": [{"fullName": "P.A. Skantze", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "da814d9f-14ff-4660-acfe-52ac2a2058fa", "fullTitle": "Journal of Badiou Studies 3: On Ethics", "doi": "https://doi.org/10.21983/P3.0070.1.00", "publicationDate": "2014-06-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Arthur Rose", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Nicol\u00f2 Fazioni", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7e2e26fd-4b0b-4c0b-a1fa-278524c43757", "fullTitle": "Journal of Badiou Studies 5: Architheater", "doi": "https://doi.org/10.21983/P3.0173.1.00", "publicationDate": "2017-07-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Arthur Rose", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adi Efal-Lautenschl\u00e4ger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "d2e40ec1-5c2a-404d-8e9f-6727c7c178dc", "fullTitle": "Kill Boxes: Facing the Legacy of US-Sponsored Torture, Indefinite Detention, and Drone Warfare", "doi": "https://doi.org/10.21983/P3.0166.1.00", "publicationDate": "2017-03-02", "place": "Earth, Milky Way", "contributions": [{"fullName": "Elisabeth Weber", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Richard Falk", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "75693fd0-e93a-4fc3-b82e-4c83a11f28b1", "fullTitle": "Knocking the Hustle: Against the Neoliberal Turn in Black Politics", "doi": "https://doi.org/10.21983/P3.0121.1.00", "publicationDate": "2015-12-10", "place": "Brooklyn, NY", "contributions": [{"fullName": "Lester K. Spence", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed3ea389-5d5c-430c-9453-814ed94e027b", "fullTitle": "Knowledge, Spirit, Law, Book 1: Radical Scholarship", "doi": "https://doi.org/10.21983/P3.0123.1.00", "publicationDate": "2015-12-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Gavin Keeney", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d0d59741-4866-42c3-8528-f65c3da3ffdd", "fullTitle": "Language Parasites: Of Phorontology", "doi": "https://doi.org/10.21983/P3.0169.1.00", "publicationDate": "2017-05-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sean Braune", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1a71ecd5-c868-44af-9b53-b45888fb241c", "fullTitle": "Lapidari 1: Texts", "doi": "https://doi.org/10.21983/P3.0094.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonida Gashi", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "df518095-84ff-4138-b2f9-5d8fe6ddf53a", "fullTitle": "Lapidari 2: Images, Part I", "doi": "https://doi.org/10.21983/P3.0091.1.00", "publicationDate": "2015-02-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "a9d68f12-1de4-4c08-84b1-fe9a786ab47f", "fullTitle": "Lapidari 3: Images, Part II", "doi": "https://doi.org/10.21983/P3.0092.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "08788fe1-c17d-4f6b-aeab-c81aa3036940", "fullTitle": "Left Bank Dream", "doi": "https://doi.org/10.21983/P3.0084.1.00", "publicationDate": "2014-12-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Beryl Scholssman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b4d68a6d-01fb-48f1-9f64-1fcdaaf1cdfd", "fullTitle": "Leper Creativity: Cyclonopedia Symposium", "doi": "https://doi.org/10.21983/P3.0017.1.00", "publicationDate": "2012-12-22", "place": "Brooklyn, NY", "contributions": [{"fullName": "Eugene Thacker", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Nicola Masciandaro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Edward Keller", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "00e012c5-9232-472c-bd8b-8ca4ea6d1275", "fullTitle": "Li Bo Unkempt", "doi": "https://doi.org/10.21983/P3.0322.1.00", "publicationDate": "2021-03-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kidder Smith", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Kidder Smith", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mike Zhai", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Traktung Yeshe Dorje", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Maria Dolgenas", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "534c3d13-b18b-4be5-91e6-768c0cf09361", "fullTitle": "Living with Monsters", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Ilana Gershon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Yasmine Musharbash", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "636a5aa6-1d37-4cd2-8742-4dcad8c67e0c", "fullTitle": "Love Don't Need a Reason: The Life & Music of Michael Callen", "doi": "https://doi.org/10.21983/P3.0297.1.00", "publicationDate": "2020-11-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew J.\n Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6dcf29ea-76c1-4121-ad7f-2341574c45fe", "fullTitle": "Luminol Theory", "doi": "https://doi.org/10.21983/P3.0177.1.00", "publicationDate": "2017-08-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laura E. Joyce", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed96eea8-82c6-46c5-a19b-dad5e45962c6", "fullTitle": "Make and Let Die: Untimely Sovereignties", "doi": "https://doi.org/10.21983/P3.0136.1.00", "publicationDate": "2016-03-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kathleen Biddick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Eileen A. Joy", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "003137ea-4fe6-470d-8bd3-f936ad065f3c", "fullTitle": "Making the Geologic Now: Responses to Material Conditions of Contemporary Life", "doi": "https://doi.org/10.21983/P3.0014.1.00", "publicationDate": "2012-12-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Elisabeth Ellsworth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jamie Kruse", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "35ed7096-8218-43d7-a572-6453c9892ed1", "fullTitle": "Manifesto for a Post-Critical Pedagogy", "doi": "https://doi.org/10.21983/P3.0193.1.00", "publicationDate": "2018-01-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Piotr Zamojski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Joris Vlieghe", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Naomi Hodgson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": null, "imprintId": "3437ff40-3bff-4cda-9f0b-1003d2980335", "imprintName": "Risking Education", "updatedAt": "2021-07-06T17:43:41.987789+00:00", "createdAt": "2021-07-06T17:43:41.987789+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "a01f41d6-1da8-4b0b-87b4-82ecc41c6d55", "fullTitle": "Nothing As We Need It: A Chimera", "doi": "https://doi.org/10.53288/0382.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Daniela Cascella", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/speculations/", "imprintId": "dcf8d636-38ae-4a63-bae1-40a61b5a3417", "imprintName": "Speculations", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "03da5b84-80ba-48bc-89b9-b63fc56b364b", "fullTitle": "Speculations", "doi": "https://doi.org/10.21983/P3.0343.1.00", "publicationDate": "2020-07-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c00d9a0c-320d-4dfb-ba0c-d1adbdb491ef", "fullTitle": "Speculations 3", "doi": "https://doi.org/10.21983/P3.0010.1.00", "publicationDate": "2012-09-03", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "2c71d808-d1a7-4918-afbb-2dfc121e7768", "fullTitle": "Speculations II", "doi": "https://doi.org/10.21983/P3.0344.1.00", "publicationDate": "2020-07-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "ee2cb855-4c94-4176-b62c-3114985dd84e", "fullTitle": "Speculations IV: Speculative Realism", "doi": "https://doi.org/10.21983/P3.0032.1.00", "publicationDate": "2013-06-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "435a1db3-1bbb-44b2-9368-7b2fd8a4e63e", "fullTitle": "Speculations VI", "doi": "https://doi.org/10.21983/P3.0122.1.00", "publicationDate": "2015-12-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/thought-crimes/", "imprintId": "f2dc7495-17af-4d8a-9306-168fc6fa1f41", "imprintName": "Thought | Crimes", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1bba80bd-2efd-41a2-9b09-4ff8da0efeb9", "fullTitle": "New Developments in Anarchist Studies", "doi": "https://doi.org/10.21983/P3.0349.1.00", "publicationDate": "2015-06-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "pj lilley", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jeff Shantz", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5a1cd53e-640b-46e7-82a6-d95bc4907e36", "fullTitle": "The Spectacle of the False Flag: Parapolitics from JFK to Watergate", "doi": "https://doi.org/10.21983/P3.0347.1.00", "publicationDate": "2014-03-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Eric Wilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Guido Giacomo Preparata", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Jeff Shantz", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "c8245465-2937-40fd-9c3e-7bd33deef477", "fullTitle": "Who Killed the Berkeley School? Struggles Over Radical Criminology ", "doi": "https://doi.org/10.21983/P3.0348.1.00", "publicationDate": "2014-04-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "Julia Schwendinger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Herman Schwendinger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jeff Shantz", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/tiny-collections/", "imprintId": "be4c8448-93c8-4146-8d9c-84d121bc4bec", "imprintName": "Tiny Collections", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "fullTitle": "Closer to Dust", "doi": "https://doi.org/10.53288/0324.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Sara A. Rich", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "771e1cde-d224-4cb6-bac7-7f5ef4d1a405", "fullTitle": "Coconuts: A Tiny History", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Kathleen E. Kennedy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "20d15631-f886-43a0-b00b-b62426710bdf", "fullTitle": "Elemental Disappearances", "doi": "https://doi.org/10.21983/P3.0157.1.00", "publicationDate": "2016-11-28", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jason Bahbak Mohaghegh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Dejan Luki\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "177e3717-4c07-4f31-9318-616ad3b71e89", "fullTitle": "Sea Monsters: Things from the Sea, Volume 2", "doi": "https://doi.org/10.21983/P3.0182.1.00", "publicationDate": "2017-09-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Asa Simon Mittman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Thea Tomaini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6dd15dd7-ae8c-4438-a597-7c99d5be4138", "fullTitle": "Walk on the Beach: Things from the Sea, Volume 1", "doi": "https://doi.org/10.21983/P3.0143.1.00", "publicationDate": "2016-06-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maggie M. Williams", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Karen Eileen Overbey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/uitgeverij/", "imprintId": "e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1", "imprintName": "Uitgeverij", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "b5c810e1-c847-4553-a24e-9893164d9786", "fullTitle": "(((", "doi": "https://doi.org/10.53288/0370.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Gen Ueda", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "df9bf011-efaf-49a7-9497-2a4d4cfde9e8", "fullTitle": "An Anthology of Asemic Handwriting", "doi": "https://doi.org/10.21983/P3.0220.1.00", "publicationDate": "2013-08-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Michael Jacobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Tim Gaze", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8b77c06a-3c1c-48ac-a32e-466ef37f293e", "fullTitle": "A Neo Tropical Companion", "doi": "https://doi.org/10.21983/P3.0217.1.00", "publicationDate": "2012-01-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jamie Stewart", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c3c09f99-71f9-431c-b0f4-ff30c3f7fe11", "fullTitle": "Continuum: Writings on Poetry as Artistic Practice", "doi": "https://doi.org/10.21983/P3.0229.1.00", "publicationDate": "2015-11-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c30545e-539b-419a-8b96-5f6c475bab9e", "fullTitle": "Disrupting the Digital Humanities", "doi": "https://doi.org/10.21983/P3.0230.1.00", "publicationDate": "2018-11-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jesse Stommel", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dorothy Kim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "dfe575e1-2836-43f3-a11b-316af9509612", "fullTitle": "Exegesis of a Renunciation \u2013 Esegesi di una rinuncia", "doi": "https://doi.org/10.21983/P3.0226.1.00", "publicationDate": "2014-10-14", "place": "The Hague/Tirana", "contributions": [{"fullName": "Francesco Aprile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bartolom\u00e9 Ferrando", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Caggiula Cristiano", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "a9b27739-0d29-4238-8a41-47b3ac2d5bd5", "fullTitle": "Filial Arcade & Other Poems", "doi": "https://doi.org/10.21983/P3.0223.1.00", "publicationDate": "2013-12-21", "place": "The Hague/Tirana", "contributions": [{"fullName": "Adam Staley Groves", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "c2c22cdf-b9d5-406d-9127-45cea8e741b1", "fullTitle": "Hippolytus", "doi": "https://doi.org/10.21983/P3.0218.1.00", "publicationDate": "2012-08-21", "place": "The Hague/Tirana", "contributions": [{"fullName": "Euripides", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sean Gurd", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "ebeae9d6-7543-4cd4-9fa9-c39c43ba0d4b", "fullTitle": "Men in A\u00efda", "doi": "https://doi.org/10.21983/P3.0224.0.00", "publicationDate": "2014-12-31", "place": "The Hague/Tirana", "contributions": [{"fullName": "David J. Melnick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sean Gurd", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "d24a0567-d430-4768-8c4d-1b9d59394af2", "fullTitle": "On Blinking", "doi": "https://doi.org/10.21983/P3.0219.1.00", "publicationDate": "2012-08-23", "place": "The Hague/Tirana", "contributions": [{"fullName": "Sarah Brigid Hannis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeremy Fernando", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97d205c8-32f0-4e64-a7df-bf56334be638", "fullTitle": "paq'batlh: A Klingon Epic", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Floris Sch\u00f6nfeld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. Van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Kees Ligtelijn", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marc Okrand", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "e81ef154-5bc3-481b-9083-64fd7aeb7575", "fullTitle": "paq'batlh: The Klingon Epic", "doi": "https://doi.org/10.21983/P3.0215.1.00", "publicationDate": "2011-10-10", "place": "The Hague/Tirana", "contributions": [{"fullName": "Floris Sch\u00f6nfeld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. Van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Kees Ligtelijn", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marc Okrand", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "119f1640-dfb4-488f-a564-ef507d74b72d", "fullTitle": "Pen in the Park: A Resistance Fairytale \u2013 Pen Parkta: Bir Direni\u015f Masal\u0131", "doi": "https://doi.org/10.21983/P3.0225.1.00", "publicationDate": "2014-02-12", "place": "The Hague/Tirana", "contributions": [{"fullName": "Ra\u015fel Meseri", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sanne Karssenberg", "contributionType": "ILUSTRATOR", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "0cb39600-2fd2-4a7a-9d3a-6d92b8e32e9e", "fullTitle": "Poetry from Beyond the Grave", "doi": "https://doi.org/10.21983/P3.0222.1.00", "publicationDate": "2013-05-10", "place": "The Hague/Tirana", "contributions": [{"fullName": "Francisco C\u00e2ndido \"Chico\" Xavier", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vitor Peqeuno", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeremy Fernando", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "69365c88-4571-45f3-8770-5a94f7c9badc", "fullTitle": "Poetry Vocare", "doi": "https://doi.org/10.21983/P3.0213.1.00", "publicationDate": "2011-01-23", "place": "The Hague/Tirana", "contributions": [{"fullName": "Adam Staley Groves", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Judith Balso", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "bc283f71-9f37-47c4-b30b-8ed9f3be9f9c", "fullTitle": "The Guerrilla I Like a Poet \u2013 Ang Gerilya Ay Tulad ng Makata", "doi": "https://doi.org/10.21983/P3.0221.1.00", "publicationDate": "2013-09-27", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jose Maria Sison", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonas Staal", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "7be9aa8c-b8af-4b2f-96ff-16e4532f2b83", "fullTitle": "The Miracle of Saint Mina \u2013 Gis Miinan Nokkor", "doi": "https://doi.org/10.21983/P3.0216.1.00", "publicationDate": "2012-01-05", "place": "The Hague/Tirana", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "El-Shafie El-Guzuuli", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b55c95a7-ce6e-4cfb-8945-cab4e04001e5", "fullTitle": "To Be, or Not to Be: Paraphrased", "doi": "https://doi.org/10.21983/P3.0227.1.00", "publicationDate": "2016-06-17", "place": "The Hague/Tirana", "contributions": [{"fullName": "Bardsley Rosenbridge", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "367397db-bcb4-4f0e-9185-4be74c119c19", "fullTitle": "Writing Art", "doi": "https://doi.org/10.21983/P3.0228.1.00", "publicationDate": "2015-11-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Alessandro De Francesco", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "6a109b6a-55e9-4dd5-b670-61926c10e611", "fullTitle": "Writing Death", "doi": "https://doi.org/10.21983/P3.0214.1.00", "publicationDate": "2011-06-06", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Avital Ronell", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}], "__typename": "Imprint"}] +[{"imprintUrl": "https://punctumbooks.com/imprints/3ecologies-books/", "imprintId": "78b0a283-9be3-4fed-a811-a7d4b9df7b25", "imprintName": "3Ecologies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "aa2b4fca-a055-4ce9-ac77-1c8ff8b320b9", "fullTitle": "A Manga Perfeita", "doi": "https://doi.org/10.21983/P3.0270.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Christine Greiner", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Ernesto Filho", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "c3d008a2-b357-4886-acc4-a2c77f1749ee", "fullTitle": "Last Year at Betty and Bob's: An Actual Occasion", "doi": "https://doi.org/10.53288/0363.1.00", "publicationDate": "2021-07-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "781b77bd-edf8-4688-937d-cc7cc47de89f", "fullTitle": "Last Year at Betty and Bob's: An Adventure", "doi": "https://doi.org/10.21983/P3.0234.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ce38f309-4438-479f-bd1c-b3690dbd7d8d", "fullTitle": "Last Year at Betty and Bob's: A Novelty", "doi": "https://doi.org/10.21983/P3.0233.1.00", "publicationDate": "2018-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sher Doruff", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "edf31616-ea2a-4c51-b932-f510b9eb8848", "fullTitle": "No Archive Will Restore You", "doi": "https://doi.org/10.21983/P3.0231.1.00", "publicationDate": "2018-11-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Julietta Singh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d4a3f6cb-3023-4088-a5f4-147fb4510874", "fullTitle": "Pitch and Revelation: Reconfigurations of Reading, Poetry, and Philosophy through the Work of Jay Wright", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew Goulish", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Will Daddario", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1d9045f8-1d8f-479c-983d-383f3a289bec", "fullTitle": "Some Ways of Making Nothing: Apophatic Apparatuses in Contemporary Art", "doi": "https://doi.org/10.21983/P3.0327.1.00", "publicationDate": "2021-02-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Curt Cloninger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ffa5c5dd-ab4b-4739-8281-275d8c1fb504", "fullTitle": "Sweet Spots: Writing the Connective Tissue of Relation", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mattie-Martha Sempert", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "757ff294-0fca-40f5-9f33-39a2d3fd5c8a", "fullTitle": "Teaching Myself To See", "doi": "https://doi.org/10.21983/P3.0303.1.00", "publicationDate": "2021-02-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Tito Mukhopadhyay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2beff5ba-a543-407e-ae7a-f0ed1788f297", "fullTitle": "Testing Knowledge: Toward an Ecology of Diagnosis, Preceded by the Dingdingdong Manifesto", "doi": "https://doi.org/10.21983/P3.0307.1.00", "publicationDate": "2021-04-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alice Rivi\u00e8res", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrin Solhdju", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Damien Bright", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Isabelle Stengers", "contributionType": "AFTERWORD_BY", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "571255b8-5bf5-4fe1-a201-5bc7aded7f9d", "fullTitle": "The Perfect Mango", "doi": "https://doi.org/10.21983/P3.0245.1.00", "publicationDate": "2019-02-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Erin Manning", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4cfb06e-a5a6-48cc-b7e5-c38228c132a8", "fullTitle": "The Unnaming of Aliass", "doi": "https://doi.org/10.21983/P3.0299.1.00", "publicationDate": "2020-10-01", "place": "Earth, Milky Way", "contributions": [{"fullName": "Karin Bolender", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/advanced-methods/", "imprintId": "ef38d49c-f8cb-4621-9f2f-1637560016e4", "imprintName": "Advanced Methods", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "0729b9d1-87d3-4739-8266-4780c3cc93da", "fullTitle": "Doing Multispecies Theology", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Mathew Arthur", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "af1d6a61-66bd-47fd-a8c5-20e433f7076b", "fullTitle": "Inefficient Mapping: A Protocol for Attuning to Phenomena", "doi": "https://doi.org/10.53288/0336.1.00", "publicationDate": "2021-08-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Linda Knight", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aa9059ba-930c-4327-97a1-c8c7877332c1", "fullTitle": "Making a Laboratory: Dynamic Configurations with Transversal Video", "doi": "https://doi.org/10.21983/P3.0295.1.00", "publicationDate": "2020-08-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ben Spatz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8f256239-8104-4838-9587-ac234aedd822", "fullTitle": "Speaking for the Social: A Catalog of Methods", "doi": "https://doi.org/10.21983/P3.0378.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Gemma John", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Hannah Knox", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprint/anarchist-developments-in-cultural-studies/", "imprintId": "3bdf14c5-7f9f-42d2-8e3b-f78de0475c76", "imprintName": "Anarchist Developments in Cultural Studies", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1d014946-aa73-4fae-9042-ef8830089f3c", "fullTitle": "Blasting the Canon", "doi": "https://doi.org/10.21983/P3.0035.1.00", "publicationDate": "2013-06-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Ruth Kinna", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "S\u00fcreyyya Evren", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "e1f74d6b-adab-4e56-8bc9-6fbd0eaab89c", "fullTitle": "Ontological Anarch\u00e9: Beyond Materialism and Idealism", "doi": "https://doi.org/10.21983/P3.0060.1.00", "publicationDate": "2014-01-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jason Adams", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Duane Rousselle", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/brainstorm-books/", "imprintId": "1e464718-2055-486b-bcd9-6e21309fcd80", "imprintName": "Brainstorm Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "fdd9e45a-08b4-4b98-9c34-bada71a34979", "fullTitle": "Animal Emotions: How They Drive Human Behavior", "doi": "https://doi.org/10.21983/P3.0305.1.00", "publicationDate": "2020-06-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kenneth L. Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Christian Montag", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "811fd271-b1dc-490a-a872-3d6867d59e78", "fullTitle": "Aural History", "doi": "https://doi.org/10.21983/P3.0282.1.00", "publicationDate": "2020-03-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Gila Ashtor", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f01cb60b-69bf-4d11-bd3c-fd5b36663029", "fullTitle": "Covert Plants: Vegetal Consciousness and Agency in an Anthropocentric World", "doi": "https://doi.org/10.21983/P3.0207.1.00", "publicationDate": "2018-09-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Prudence Gibson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Brits Baylee", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "9bdf38ca-95fd-4cf4-adf6-ed26e97cf213", "fullTitle": "Critique of Fantasy, Vol. 1: Between a Crypt and a Datemark", "doi": "https://doi.org/10.21983/P3.0277.1.00", "publicationDate": "2020-06-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "89f9c84b-be5c-4020-8edc-6fbe0b1c25f5", "fullTitle": "Critique of Fantasy, Vol. 2: The Contest between B-Genres", "doi": "https://doi.org/10.21983/P3.0278.1.00", "publicationDate": "2020-11-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "79464e83-b688-4b82-84bc-18d105f60f33", "fullTitle": "Critique of Fantasy, Vol. 3: The Block of Fame", "doi": "https://doi.org/10.21983/P3.0279.1.00", "publicationDate": "2021-01-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laurence A. Rickels", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "992c6ff8-e166-4014-85cc-b53af250a4e4", "fullTitle": "Hack the Experience: Tools for Artists from Cognitive Science", "doi": "https://doi.org/10.21983/P3.0206.1.00", "publicationDate": "2018-09-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ryan Dewey", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4a42f23b-5277-49b5-8310-c3c38ded5bf5", "fullTitle": "Opioids: Addiction, Narrative, Freedom", "doi": "https://doi.org/10.21983/P3.0210.1.00", "publicationDate": "2018-10-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maia Dolphin-Krute", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "18d3d876-bcaf-4e1c-a67a-05537f808a99", "fullTitle": "The Hegemony of Psychopathy", "doi": "https://doi.org/10.21983/P3.0180.1.00", "publicationDate": "2017-09-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Lajos Brons", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5dca2af4-43f2-4cdb-a7a5-5654a722c4e0", "fullTitle": "Visceral: Essays on Illness Not as Metaphor", "doi": "https://doi.org/10.21983/P3.0185.1.00", "publicationDate": "2017-10-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maia Dolphin-Krute", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/ctm-documents-initiative/", "imprintId": "cec45cc6-8cb5-43ed-888f-165f3fa73842", "imprintName": "CTM Documents Initiative", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "b950d243-7cfc-4aee-b908-d1776be327df", "fullTitle": "Image Photograph", "doi": "https://doi.org/10.21983/P3.0106.1.00", "publicationDate": "2015-07-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marc Lafia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "14f2b847-faeb-43c9-b116-88a0091b6f1f", "fullTitle": "Knowledge, Spirit, Law, Book 2: The Anti-Capitalist Sublime", "doi": "https://doi.org/10.21983/P3.0191.1.00", "publicationDate": "2017-12-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Gavin Keeney", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1e0c7c29-dcd4-470d-b3ee-8c4012ac79dd", "fullTitle": "Liquid Life: On Non-Linear Materiality", "doi": "https://doi.org/10.21983/P3.0246.1.00", "publicationDate": "2019-12-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Rachel Armstrong", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "47cd079b-03f3-4a5b-b5e4-36cec4db7fab", "fullTitle": "The Digital Dionysus: Nietzsche and the Network-Centric Condition", "doi": "https://doi.org/10.21983/P3.0149.1.00", "publicationDate": "2016-09-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dan Mellamphy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Nandita Biswas Mellamphy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1950e4ba-651c-4ec9-83f6-df46b777b10f", "fullTitle": "The Funambulist Pamphlets 10: Literature", "doi": "https://doi.org/10.21983/P3.0075.1.00", "publicationDate": "2014-08-14", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "bdfc263a-7ace-43f3-9c80-140c6fb32ec7", "fullTitle": "The Funambulist Pamphlets 11: Cinema", "doi": "https://doi.org/10.21983/P3.0095.1.00", "publicationDate": "2015-02-20", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f5fb8a0e-ea1d-471f-b76a-a000edae5956", "fullTitle": "The Funambulist Pamphlets 1: Spinoza", "doi": "https://doi.org/10.21983/P3.0033.1.00", "publicationDate": "2013-06-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "911de470-77e1-4816-b437-545122a7bf26", "fullTitle": "The Funambulist Pamphlets 2: Foucault", "doi": "https://doi.org/10.21983/P3.0034.1.00", "publicationDate": "2013-06-17", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "61da662d-c720-4d22-957c-4d96071ee5f2", "fullTitle": "The Funambulist Pamphlets 3: Deleuze", "doi": "https://doi.org/10.21983/P3.0038.1.00", "publicationDate": "2013-07-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "419e17ed-3bcc-430c-a67e-3121537e4702", "fullTitle": "The Funambulist Pamphlets 4: Legal Theory", "doi": "https://doi.org/10.21983/P3.0042.1.00", "publicationDate": "2013-08-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fe8ddfb7-0e5b-4604-811c-78cf4db7528b", "fullTitle": "The Funambulist Pamphlets 5: Occupy Wall Street", "doi": "https://doi.org/10.21983/P3.0046.1.00", "publicationDate": "2013-09-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13390641-86f6-4351-923d-8c456f175bff", "fullTitle": "The Funambulist Pamphlets 6: Palestine", "doi": "https://doi.org/10.21983/P3.0054.1.00", "publicationDate": "2013-11-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "448c3581-9167-491e-86f7-08d5a6c953a9", "fullTitle": "The Funambulist Pamphlets 7: Cruel Designs", "doi": "https://doi.org/10.21983/P3.0057.1.00", "publicationDate": "2013-12-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d3cbb60f-537f-4bd7-96cb-d8aba595a947", "fullTitle": "The Funambulist Pamphlets 8: Arakawa + Madeline Gins", "doi": "https://doi.org/10.21983/P3.0064.1.00", "publicationDate": "2014-03-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6fab7c76-7567-4b57-8ad7-90a5536d87af", "fullTitle": "The Funambulist Pamphlets 9: Science Fiction", "doi": "https://doi.org/10.21983/P3.0069.1.00", "publicationDate": "2014-05-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "84bbf59f-1dbb-445e-8f65-f26574f609b6", "fullTitle": "The Funambulist Papers, Volume 1", "doi": "https://doi.org/10.21983/P3.0053.1.00", "publicationDate": "2013-10-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3b41b8de-b9bb-4ebd-a002-52052a9e39a9", "fullTitle": "The Funambulist Papers, Volume 2", "doi": "https://doi.org/10.21983/P3.0098.1.00", "publicationDate": "2015-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "L\u00e9opold Lambert", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/dead-letter-office/", "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "imprintName": "Dead Letter Office", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "fullTitle": "A Bibliography for After Jews and Arabs", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f02786d4-3bcc-473e-8d43-3da66c7e877c", "fullTitle": "A Brief Genealogy of Jewish Republicanism: Parting Ways with Judith Butler", "doi": "https://doi.org/10.21983/P3.0159.1.00", "publicationDate": "2016-12-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Irene Tucker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fd67d684-aaff-4260-bb94-9d0373015620", "fullTitle": "An Edition of Miles Hogarde's \"A Mirroure of Myserie\"", "doi": "https://doi.org/10.21983/P3.0316.1.00", "publicationDate": "2021-06-03", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sebastian Sobecki", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5f441303-4fc6-4a7d-951e-5b966a1cbd91", "fullTitle": "An Unspecific Dog: Artifacts of This Late Stage in History", "doi": "https://doi.org/10.21983/P3.0163.1.00", "publicationDate": "2017-01-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Joshua Rothes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7eb6f426-e913-4d69-92c5-15a640f1b4b9", "fullTitle": "A Sanctuary of Sounds", "doi": "https://doi.org/10.21983/P3.0029.1.00", "publicationDate": "2013-05-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Andreas Burckhardt", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4fc74913-bde4-426e-b7e5-2f66c60af484", "fullTitle": "As If: Essays in As You Like It", "doi": "https://doi.org/10.21983/P3.0162.1.00", "publicationDate": "2016-12-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "William N. West", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "06db2bc1-e25a-42c8-8908-fbd774f73204", "fullTitle": "Atopological Trilogy: Deleuze and Guattari", "doi": "https://doi.org/10.21983/P3.0096.1.00", "publicationDate": "2015-03-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Zafer Aracag\u00f6k", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Manola Antonioli", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "a022743e-8b77-4246-a068-e08d57815e27", "fullTitle": "CMOK to YOu To: A Correspondence", "doi": "https://doi.org/10.21983/P3.0150.1.00", "publicationDate": "2016-09-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc James L\u00e9ger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Nina \u017divan\u010devi\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f94ded4d-1c87-4503-82f1-a1ca4346e756", "fullTitle": "Come As You Are, After Eve Kosofsky Sedgwick", "doi": "https://doi.org/10.21983/P3.0342.1.00", "publicationDate": "2021-04-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eve Kosofsky Sedgwick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonathan Goldberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "449add5c-b935-47e2-8e46-2545fad86221", "fullTitle": "Escargotesque, or, What Is Experience", "doi": "https://doi.org/10.21983/P3.0089.1.00", "publicationDate": "2015-01-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "M.H. Bowker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "628bb121-5ba2-4fc1-a741-a8062c45b63b", "fullTitle": "Gaffe/Stutter", "doi": "https://doi.org/10.21983/P3.0049.1.00", "publicationDate": "2013-10-06", "place": "Brooklyn, NY", "contributions": [{"fullName": "Whitney Anne Trettien", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f131762c-a877-4925-9fa1-50555bc4e2ae", "fullTitle": "[Given, If, Then]: A Reading in Three Parts", "doi": "https://doi.org/10.21983/P3.0090.1.00", "publicationDate": "2015-02-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jennifer Hope Davy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Julia H\u00f6lzl", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cb11259b-7b83-498e-bc8a-7c184ee2c279", "fullTitle": "Going Postcard: The Letter(s) of Jacques Derrida", "doi": "https://doi.org/10.21983/P3.0171.1.00", "publicationDate": "2017-05-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f8b57164-89e6-48b1-bd70-9d360b53a453", "fullTitle": "Helicography", "doi": "https://doi.org/10.53288/0352.1.00", "publicationDate": "2021-07-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Craig Dworkin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6689db84-b329-4ca5-b10c-010fd90c7e90", "fullTitle": "History of an Abuse", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ceffc30d-1d28-48c3-acee-e6a2dc38ff37", "fullTitle": "How We Read", "doi": "https://doi.org/10.21983/P3.0259.1.00", "publicationDate": "2019-07-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kaitlin Heller", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Suzanne Conklin Akbari", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "63e2f6b6-f324-4bdc-836e-55515ba3cd8f", "fullTitle": "How We Write: Thirteen Ways of Looking at a Blank Page", "doi": "https://doi.org/10.21983/P3.0110.1.00", "publicationDate": "2015-09-11", "place": "Brooklyn, NY", "contributions": [{"fullName": "Suzanne Conklin Akbari", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f5217945-8c2c-4e65-a5dd-3dbff208dfb7", "fullTitle": "In Divisible Cities: A Phanto-Cartographical Missive", "doi": "https://doi.org/10.21983/P3.0044.1.00", "publicationDate": "2013-08-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Dominic Pettman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d5f5978b-32e0-44a1-a72a-c80568c9b93a", "fullTitle": "I Open Fire", "doi": "https://doi.org/10.21983/P3.0086.1.00", "publicationDate": "2014-12-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Pol", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c6125a74-2801-4255-afe9-89cdb8d253f4", "fullTitle": "John Gardner: A Tiny Eulogy", "doi": "https://doi.org/10.21983/P3.0013.1.00", "publicationDate": "2012-11-29", "place": "Brooklyn, NY", "contributions": [{"fullName": "Phil Jourdan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8377c394-c27a-44cb-98f5-5e5b789ad7b8", "fullTitle": "Last Day Every Day: Figural Thinking from Auerbach and Kracauer to Agamben and Brenez", "doi": "https://doi.org/10.21983/P3.0012.1.00", "publicationDate": "2012-10-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Adrian Martin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1809f10a-d0e3-4481-8f96-cca7f240d656", "fullTitle": "Letters on the Autonomy Project in Art and Politics", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Janet Sarbanes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5f1db605-88b6-427a-84cb-ce2fcf0f89a3", "fullTitle": "Massa por Argamassa: A \"Libraria de Babel\" e o Sonho de Totalidade", "doi": "https://doi.org/10.21983/P3.0264.1.00", "publicationDate": "2019-09-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Basile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Yuri N. Martinez Laskowski", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f20869c5-746f-491b-8c34-f88dc3728e18", "fullTitle": "Min\u00f3y", "doi": "https://doi.org/10.21983/P3.0072.1.00", "publicationDate": "2014-06-30", "place": "Brooklyn, NY", "contributions": [{"fullName": "Joseph Nechvatal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d40aa92-380c-4fae-98d8-c598bb32e7c6", "fullTitle": "Misinterest: Essays, Pens\u00e9es, and Dreams", "doi": "https://doi.org/10.21983/P3.0256.1.00", "publicationDate": "2019-06-27", "place": "Earth, Milky Way", "contributions": [{"fullName": "M.H. Bowker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "34682ba4-201f-4122-8e4a-edc3edc57a7b", "fullTitle": "Nicholas of Cusa and the Kairos of Modernity: Cassirer, Gadamer, Blumenberg", "doi": "https://doi.org/10.21983/P3.0045.1.00", "publicationDate": "2013-09-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Edward Moore", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1cfca75f-2e57-4f34-85fb-a1585315a2a9", "fullTitle": "Noise Thinks the Anthropocene: An Experiment in Noise Poetics", "doi": "https://doi.org/10.21983/P3.0244.1.00", "publicationDate": "2019-02-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Aaron Zwintscher", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "571d5d40-cfd6-4270-9530-88bfcfc5d8b5", "fullTitle": "Non-Conceptual Negativity: Damaged Reflections on Turkey", "doi": "https://doi.org/10.21983/P3.0247.1.00", "publicationDate": "2019-03-27", "place": "Earth, Milky Way", "contributions": [{"fullName": "Zafer Aracag\u00f6k", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Fraco \"Bifo\" Berardi", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "3eb0d095-fc27-4add-8202-1dc2333a758c", "fullTitle": "Notes on Trumpspace: Politics, Aesthetics, and the Fantasy of Home", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "David Stephenson Markus", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "48e2a673-aec2-4ed6-99d4-46a8de200493", "fullTitle": "Nothing in MoMA", "doi": "https://doi.org/10.21983/P3.0208.1.00", "publicationDate": "2018-09-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Abraham Adams", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97019dea-e207-4909-b907-076d0620ff74", "fullTitle": "Obiter Dicta", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Erick Verran", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "10a41381-792f-4376-bed1-3781d1b8bae7", "fullTitle": "Of Learned Ignorance: Idea of a Treatise in Philosophy", "doi": "https://doi.org/10.21983/P3.0031.1.00", "publicationDate": "2013-06-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b43ec529-2f51-4c59-b3cb-394f3649502c", "fullTitle": "Of the Contract", "doi": "https://doi.org/10.21983/P3.0174.1.00", "publicationDate": "2017-07-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christopher Clifton", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "63b0e966-e81c-4d84-b41d-3445b0d9911f", "fullTitle": "Paris Bride: A Modernist Life", "doi": "https://doi.org/10.21983/P3.0281.1.00", "publicationDate": "2020-02-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "John Schad", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed1a8fb5-8b71-43ca-9748-ebd43f0d7580", "fullTitle": "Philosophy for Militants", "doi": "https://doi.org/10.21983/P3.0168.1.00", "publicationDate": "2017-03-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5b652d05-2b5f-465a-8c66-f4dc01dafd03", "fullTitle": "[provisional self-evidence]", "doi": "https://doi.org/10.21983/P3.0111.1.00", "publicationDate": "2015-09-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Rachel Arrighi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cd836291-fb7f-4508-bdff-cd59dca2b447", "fullTitle": "Queer Insists (for Jos\u00e9 Esteban Mu\u00f1oz)", "doi": "https://doi.org/10.21983/P3.0082.1.00", "publicationDate": "2014-12-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael O'Rourke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "46ab709c-3272-4a03-991e-d1b1394b8e2c", "fullTitle": "Ravish the Republic: The Archives of the Iron Garters Crime/Art Collective", "doi": "https://doi.org/10.21983/P3.0107.1.00", "publicationDate": "2015-07-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael L. Berger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "28a0db09-a149-43fe-ba08-00dde962b4b8", "fullTitle": "Reiner Sch\u00fcrmann and Poetics of Politics", "doi": "https://doi.org/10.21983/P3.0209.1.00", "publicationDate": "2018-09-28", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christopher Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5dda1ad6-70ac-4a31-baf2-b77f8f5a8190", "fullTitle": "Sappho: Fragments", "doi": "https://doi.org/10.21983/P3.0238.1.00", "publicationDate": "2018-12-31", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Goldberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "L.O. Aranye Fradenburg Joy", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "8cd5ce6c-d604-46ac-b4f7-1f871589d96a", "fullTitle": "Still Life: Notes on Barbara Loden's \"Wanda\" (1970)", "doi": "https://doi.org/10.53288/0326.1.00", "publicationDate": "2021-07-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anna Backman Rogers", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1547aa4b-7629-4a21-8b2b-621223c73ec9", "fullTitle": "Still Thriving: On the Importance of Aranye Fradenburg", "doi": "https://doi.org/10.21983/P3.0099.1.00", "publicationDate": "2015-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "L.O. Aranye Fradenburg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "08543bd7-e603-43ae-bb0f-1d4c1c96030b", "fullTitle": "Suite on \"Spiritus Silvestre\": For Symphony", "doi": "https://doi.org/10.21983/P3.0020.1.00", "publicationDate": "2012-12-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Denzil Ford", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9839926e-56ea-4d71-a3de-44cabd1d2893", "fullTitle": "Tar for Mortar: \"The Library of Babel\" and the Dream of Totality", "doi": "https://doi.org/10.21983/P3.0196.1.00", "publicationDate": "2018-03-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Basile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "58aadfa5-abc6-4c44-9768-f8ff41502867", "fullTitle": "The Afterlife of Genre: Remnants of the Trauerspiel in Buffy the Vampire Slayer", "doi": "https://doi.org/10.21983/P3.0061.1.00", "publicationDate": "2014-02-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "Anthony Curtis Adler", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1d30497f-4340-43ab-b328-9fd2fed3106e", "fullTitle": "The Anthology of Babel", "doi": "https://doi.org/10.21983/P3.0254.1.00", "publicationDate": "2020-01-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ed Simon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "26d522d4-fb46-47bf-a344-fe6af86688d3", "fullTitle": "The Bodies That Remain", "doi": "https://doi.org/10.21983/P3.0212.1.00", "publicationDate": "2018-10-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Emmy Beber", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a065ad95-716a-4005-b436-a46d9dbd64df", "fullTitle": "The Communism of Thought", "doi": "https://doi.org/10.21983/P3.0059.1.00", "publicationDate": "2014-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c51c8fa-947b-4a12-a2e9-5306ee81d117", "fullTitle": "The Death of Conrad Unger: Some Conjectures Regarding Parasitosis and Associated Suicide Behavior", "doi": "https://doi.org/10.21983/P3.0008.1.00", "publicationDate": "2012-08-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Gary L. Shipley", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a4ff976a-ac8a-49b8-a89c-f52f3030ccaa", "fullTitle": "The Map and the Territory\n", "doi": "https://doi.org/10.53288/0319.1.00", "publicationDate": "2021-08-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "33917b8f-775f-4ee2-a43a-6b5285579f84", "fullTitle": "The Non-Library", "doi": "https://doi.org/10.21983/P3.0065.1.00", "publicationDate": "2014-03-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Trevor Owen Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "60813d93-663f-4974-8789-1a2ee83cd042", "fullTitle": "Theory Is Like a Surging Sea", "doi": "https://doi.org/10.21983/P3.0108.1.00", "publicationDate": "2015-08-02", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "119e45d6-63ab-4cc4-aabf-06ecba1fb055", "fullTitle": "The Witch and the Hysteric: The Monstrous Medieval in Benjamin Christensen's H\u00e4xan", "doi": "https://doi.org/10.21983/P3.0074.1.00", "publicationDate": "2014-08-08", "place": "Brooklyn, NY", "contributions": [{"fullName": "Patricia Clare Ingham", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alexander Doty", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d6651c3c-c453-42ab-84b3-4e847d3a3324", "fullTitle": "Traffic Jams: Analysing Everyday Life through the Immanent Materialism of Deleuze & Guattari", "doi": "https://doi.org/10.21983/P3.0023.1.00", "publicationDate": "2013-02-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "David R. Cole", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1399a869-9f56-4980-981d-2cc83f0a6668", "fullTitle": "Truth and Fiction: Notes on (Exceptional) Faith in Art", "doi": "https://doi.org/10.21983/P3.0007.1.00", "publicationDate": "2012-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Milcho Manchevski", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adrian Martin", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "b904a8eb-9c98-4bb1-bf25-3cb9d075b157", "fullTitle": "Warez: The Infrastructure and Aesthetics of Piracy", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Martin Paul Eve", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "77e1fa52-1938-47dd-b8a5-2a57bfbc91d1", "fullTitle": "What Is Philosophy?", "doi": "https://doi.org/10.21983/P3.0011.1.00", "publicationDate": "2012-10-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Munro", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "27602ce3-fbd6-4044-8b44-b8421670edae", "fullTitle": "Wonder, Horror, and Mystery in Contemporary Cinema: Letters on Malick, Von Trier, and Kie\u015blowski", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Morgan Meis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "J.M. Tyree", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/department-of-eagles/", "imprintId": "ef4aece6-6e9c-4f90-b5c3-7e4b78e8942d", "imprintName": "Department of Eagles", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "3ccdbbfc-6550-49f4-8ec9-77fc94a7a099", "fullTitle": "Broken Narrative: The Politics of Contemporary Art in Albania", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Armando Lulaj", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marco Mazzi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Brenda Porster", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Tomii Keiko", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Osamu Kanemura", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 6}, {"fullName": "Jonida Gashi", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 5}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/dotawo/", "imprintId": "f891a5f0-2af2-4eda-b686-db9dd74ee73d", "imprintName": "Dotawo", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1c39ca0c-0189-44d3-bb2f-9345e2a2b152", "fullTitle": "Dotawo: A Journal of Nubian Studies 2", "doi": "https://doi.org/10.21983/P3.0104.1.00", "publicationDate": "2015-06-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Angelika Jakobi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "861ea7cc-5447-4c60-8657-c50d0a31cd24", "fullTitle": "Dotawo: a Journal of Nubian Studies 3: Know-Hows and Techniques in Ancient Sudan", "doi": "https://doi.org/10.21983/P3.0148.1.00", "publicationDate": "2016-08-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc Maillot", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "431b58fe-7f59-49d9-bf6f-53eae379ee4d", "fullTitle": "Dotawo: A Journal of Nubian Studies 4: Place Names and Place Naming in Nubia", "doi": "https://doi.org/10.21983/P3.0184.1.00", "publicationDate": "2017-10-12", "place": "Earth, Milky Way", "contributions": [{"fullName": "Alexandros Tsakos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Robin Seignobos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3c5923bc-e76b-4fbe-8d8c-1a49a49020a8", "fullTitle": "Dotawo: A Journal of Nubian Studies 5: Nubian Women", "doi": "https://doi.org/10.21983/P3.0242.1.00", "publicationDate": "2019-02-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anne Jennings", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "15ab17fe-2486-4ca5-bb47-6b804793f80d", "fullTitle": "Dotawo: A Journal of Nubian Studies 6: Miscellanea Nubiana", "doi": "https://doi.org/10.21983/P3.0321.1.00", "publicationDate": "2019-12-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Simmons", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aa431454-40d3-42f5-8069-381a15789257", "fullTitle": "Dotawo: A Journal of Nubian Studies 7: Comparative Northern East Sudanic Linguistics", "doi": "https://doi.org/10.21983/P3.0350.1.00", "publicationDate": "2021-03-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7a4506ac-dfdc-4054-b2d1-d8fdf4cea12b", "fullTitle": "Nubian Proverbs", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Maher Habbob", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a8e6722a-1858-4f38-995d-bde0b120fe8c", "fullTitle": "The Old Nubian Language", "doi": "https://doi.org/10.21983/P3.0179.1.00", "publicationDate": "2017-09-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eugenia Smagina", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jos\u00e9 Andr\u00e9s Alonso de la Fuente", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "0cd80cd2-1733-4bde-b48f-a03fc01acfbf", "fullTitle": "The Old Nubian Texts from Attiri", "doi": "https://doi.org/10.21983/P3.0156.1.00", "publicationDate": "2016-11-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Petra Weschenfelder", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent Pierre-Michel Laisney", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kerstin Weber-Thum", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Alexandros Tsakos", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}]}], "__typename": "Imprint"}, {"imprintUrl": null, "imprintId": "47e62ae1-6698-46aa-840c-d4507697459f", "imprintName": "eth press", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "5f24bd29-3d48-4a70-8491-6269f7cc6212", "fullTitle": "Ballads", "doi": "https://doi.org/10.21983/P3.0105.1.00", "publicationDate": "2015-06-03", "place": "Brooklyn, NY", "contributions": [{"fullName": "Richard Owens", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0a8fba81-f1d0-498c-88c4-0b96d3bf2947", "fullTitle": "Cotton Nero A.x: The Works of the \"Pearl\" Poet", "doi": "https://doi.org/10.21983/P3.0066.1.00", "publicationDate": "2014-04-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Chris Piuma", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Lisa Ampleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Daniel C. Remein", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "David Hadbawnik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "53cd2c70-eab6-45b7-a147-8ef1c87d9ac0", "fullTitle": "d\u00f4Nrm'-l\u00e4-p\u00fcsl", "doi": "https://doi.org/10.21983/P3.0183.1.00", "publicationDate": "2017-10-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "kari edwards", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Tina \u017digon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "34584bfe-1cf8-49c5-b8d1-6302ea1cfcfa", "fullTitle": "Snowline", "doi": "https://doi.org/10.21983/P3.0093.1.00", "publicationDate": "2015-02-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Donato Mancini", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cc73eed0-a1f9-4ad4-b7d8-2394b92765f0", "fullTitle": "Unless As Stone Is", "doi": "https://doi.org/10.21983/P3.0058.1.00", "publicationDate": "2014-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Sam Lohmann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/gracchi-books/", "imprintId": "41193484-91d1-44f3-8d0c-0452a35d17a0", "imprintName": "Gracchi Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1603556c-53fc-4d14-b0bf-8c18ad7b24ab", "fullTitle": "Social and Intellectual Networking in the Early Middle Ages", "doi": null, "publicationDate": null, "place": null, "contributions": [{"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "K. Patrick Fazioli", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "6813bf17-373c-49ce-b9e3-1d7ab98f2977", "fullTitle": "The Christian Economy of the Early Medieval West: Towards a Temple Society", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Ian Wood", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2f93b300-f147-48f5-95d5-afd0e0161fe6", "fullTitle": "Urban Interactions: Communication and Competition in Late Antiquity and the Early Middle Ages", "doi": "https://doi.org/10.21983/P3.0300.1.00", "publicationDate": "2020-10-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael Burrows", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ian Wood", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Michael J. Kelly", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "678f4564-d01a-4ffe-8bdb-fead78f87955", "fullTitle": "Vera Lex Historiae?: Constructions of Truth in Medieval Historical Narrative", "doi": "https://doi.org/10.21983/P3.0369.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Catalin Taranu", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/helvete/", "imprintId": "b3dc0be6-6739-4777-ada0-77b1f5074f7d", "imprintName": "Helvete", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "417ecc06-51a4-4660-959b-482763864559", "fullTitle": "Helvete 1: Incipit", "doi": "https://doi.org/10.21983/P3.0027.1.00", "publicationDate": "2013-04-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "Aspasia Stephanou", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Amelia Ishmael", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Zareen Price", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ben Woodard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "3cc0269d-7170-4981-8ac7-5b01e7b9e080", "fullTitle": "Helvete 2: With Head Downwards: Inversions in Black Metal", "doi": "https://doi.org/10.21983/P3.0102.1.00", "publicationDate": "2015-05-19", "place": "Brooklyn, NY", "contributions": [{"fullName": "Niall Scott", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Steve Shakespeare", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "fa4bc310-b7db-458a-8ba9-13347a91c862", "fullTitle": "Helvete 3: Bleeding Black Noise", "doi": "https://doi.org/10.21983/P3.0158.1.00", "publicationDate": "2016-12-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Amelia Ishmael", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/lamma/", "imprintId": "f852b678-e8ac-4949-a64d-3891d4855e3d", "imprintName": "Lamma", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "ce7ec5ea-88b2-430f-92be-0f2436600a46", "fullTitle": "Lamma: A Journal of Libyan Studies 1", "doi": "https://doi.org/10.21983/P3.0337.1.00", "publicationDate": "2020-07-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Benkato", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Leila Tayeb", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Amina Zarrugh", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://www.matteringpress.org", "imprintId": "cb483a78-851f-4936-82d2-8dcd555dcda9", "imprintName": "Mattering Press", "updatedAt": "2021-03-25T16:33:14.299495+00:00", "createdAt": "2021-03-25T16:25:02.238699+00:00", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6", "publisher": {"publisherName": "Mattering Press", "publisherId": "17d701c1-307e-4228-83ca-d8e90d7b87a6"}, "works": [{"workId": "95e15115-4009-4cb0-8824-011038e3c116", "fullTitle": "Energy Worlds: In Experiment", "doi": "https://doi.org/10.28938/9781912729098", "publicationDate": "2021-05-01", "place": "Manchester", "contributions": [{"fullName": "Brit Ross Winthereik", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Laura Watts", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "James Maguire", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "091abd14-7bc0-4fe7-8194-552edb02b98b", "fullTitle": "Inventing the Social", "doi": "https://doi.org/10.28938/9780995527768", "publicationDate": "2018-07-11", "place": "Manchester", "contributions": [{"fullName": "Michael Guggenheim", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alex Wilkie", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Noortje Marres", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c38728e0-9739-4ad3-b0a7-6cda9a9da4b9", "fullTitle": "Sensing InSecurity: Sensors as transnational security infrastructures", "doi": null, "publicationDate": null, "place": "Manchester", "contributions": []}], "__typename": "Imprint"}, {"imprintUrl": "https://www.mediastudies.press/", "imprintId": "5078b33c-5b3f-48bf-bf37-ced6b02beb7c", "imprintName": "mediastudies.press", "updatedAt": "2021-06-15T14:40:51.652638+00:00", "createdAt": "2021-06-15T14:40:51.652638+00:00", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5", "publisher": {"publisherName": "mediastudies.press", "publisherId": "4ab3bec2-c491-46d4-8731-47a5d9b33cc5"}, "works": [{"workId": "6763ec18-b4af-4767-976c-5b808a64e641", "fullTitle": "Liberty and the News", "doi": "https://doi.org/10.32376/3f8575cb.2e69e142", "publicationDate": "2020-11-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "Walter Lippmann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sue Curry Jansen", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "3162a992-05dd-4b74-9fe0-0f16879ce6de", "fullTitle": "Our Master\u2019s Voice: Advertising", "doi": "https://doi.org/10.21428/3f8575cb.dbba9917", "publicationDate": "2020-10-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "James Rorty", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jefferson Pooley", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "64891e84-6aac-437a-a380-0481312bd2ef", "fullTitle": "Social Media & the Self: An Open Reader", "doi": "https://doi.org/10.32376/3f8575cb.1fc3f80a", "publicationDate": "2021-07-15", "place": "Bethlehem, PA", "contributions": [{"fullName": "Jefferson Pooley", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://meson.press", "imprintId": "0299480e-869b-486c-8a65-7818598c107b", "imprintName": "meson press", "updatedAt": "2021-03-25T16:36:00.832381+00:00", "createdAt": "2021-03-25T16:36:00.832381+00:00", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b", "publisher": {"publisherName": "meson press", "publisherId": "f0ae98da-c433-45b8-af3f-5c709ad0221b"}, "works": [{"workId": "59ecdda1-efd8-45d2-b6a6-11bc8fe480f5", "fullTitle": "Earth and Beyond in Tumultuous Times: A Critical Atlas of the Anthropocene", "doi": "https://doi.org/10.14619/1891", "publicationDate": "2021-03-15", "place": "L\u00fcneburg", "contributions": [{"fullName": "Petra L\u00f6ffler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "R\u00e9ka Patr\u00edcia G\u00e1l", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "36f7480e-ca45-452c-a5c0-ba1dccf135ec", "fullTitle": "Touchscreen Archaeology: Tracing Histories of Hands-On Media Practices", "doi": "https://doi.org/10.14619/1860", "publicationDate": "2021-05-17", "place": "Lueneburg", "contributions": [{"fullName": "Wanda Strauven", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "38872158-58b9-4ddf-a90e-f6001ac6c62d", "fullTitle": "Trick 17: Mediengeschichten zwischen Zauberkunst und Wissenschaft", "doi": "https://doi.org/10.14619/017", "publicationDate": "2016-07-14", "place": "L\u00fcneburg, Germany", "contributions": [{"fullName": "Sebastian Vehlken", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 1}, {"fullName": "Jan M\u00fcggenburg", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Katja M\u00fcller-Helle", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Florian Sprenger", "contributionType": "AUTHOR", "mainContribution": false, "contributionOrdinal": 4}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/oe-case-files/", "imprintId": "39a17f7f-c3f3-4bfe-8c5e-842d53182aad", "imprintName": "\u0152 Case Files", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "a8bf3374-f153-460d-902a-adea7f41d7c7", "fullTitle": "\u0152 Case Files, Vol. 01", "doi": "https://doi.org/10.21983/P3.0354.1.00", "publicationDate": "2021-05-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Simone Ferracina", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/oliphaunt-books/", "imprintId": "353047d8-1ea4-4cc5-bd08-e9cedb4a3e8d", "imprintName": "Oliphaunt Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "0090dbfb-bc8f-44aa-9803-08b277861b14", "fullTitle": "Animal, Vegetable, Mineral: Ethics and Objects", "doi": "https://doi.org/10.21983/P3.0006.1.00", "publicationDate": "2012-05-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "eb8a2862-e812-4730-ab06-8dff1b6208bf", "fullTitle": "Burn after Reading: Vol. 1, Miniature Manifestos for a Post/medieval Studies + Vol. 2, The Future We Want: A Collaboration", "doi": "https://doi.org/10.21983/P3.0067.1.00", "publicationDate": "2014-04-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Myra Seaman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "37cb9bb4-0bb3-4bd3-86ea-d8dfb60c9cd8", "fullTitle": "Inhuman Nature", "doi": "https://doi.org/10.21983/P3.0078.1.00", "publicationDate": "2014-09-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Jerome Cohen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://www.openbookpublishers.com/", "imprintId": "145369a6-916a-4107-ba0f-ce28137659c2", "imprintName": "Open Book Publishers", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b", "publisher": {"publisherName": "Open Book Publishers", "publisherId": "85fd969a-a16c-480b-b641-cb9adf979c3b"}, "works": [{"workId": "fdeb2a1b-af39-4165-889d-cc7a5a31d5fa", "fullTitle": "Acoustemologies in Contact: Sounding Subjects and Modes of Listening in Early Modernity", "doi": "https://doi.org/10.11647/OBP.0226", "publicationDate": "2021-01-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Emily Wilbourne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Suzanne G. Cusick", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "31aea193-58de-43eb-aadb-23300ba5ee40", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0075", "publicationDate": "2016-01-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fc088d17-bab2-4bfa-90bc-b320760c6c97", "fullTitle": "Advanced Problems in Mathematics: Preparing for University", "doi": "https://doi.org/10.11647/OBP.0181", "publicationDate": "2019-10-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Siklos", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b59def35-5712-44ed-8490-9073ab1c6cdc", "fullTitle": "A European Public Investment Outlook", "doi": "https://doi.org/10.11647/OBP.0222", "publicationDate": "2020-06-12", "place": "Cambridge, UK", "contributions": [{"fullName": "Floriana Cerniglia", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Francesco Saraceno", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "528e4526-42e4-4e68-a0d5-f74a285c35a6", "fullTitle": "A Fleet Street In Every Town: The Provincial Press in England, 1855-1900", "doi": "https://doi.org/10.11647/OBP.0152", "publicationDate": "2018-12-13", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Hobbs", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "35941026-43eb-496f-b560-2c21a6dbbbfc", "fullTitle": "Agency: Moral Identity and Free Will", "doi": "https://doi.org/10.11647/OBP.0197", "publicationDate": "2020-04-01", "place": "Cambridge, UK", "contributions": [{"fullName": "David Weissman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3dbfa65a-ed33-46b5-9105-c5694c9c6bab", "fullTitle": "A Handbook and Reader of Ottoman Arabic", "doi": "https://doi.org/10.11647/OBP.0208", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Esther-Miriam Wagner", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0229f930-1e01-40b8-b4a8-03ab57624ced", "fullTitle": "A Lexicon of Medieval Nordic Law", "doi": "https://doi.org/10.11647/OBP.0188", "publicationDate": "2020-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Christine Peel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Jeffrey Love", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Erik Simensen", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Inger Larsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ulrika Dj\u00e4rv", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "defda2f0-1003-419a-8c3c-ac8d0b1abd17", "fullTitle": "A Musicology of Performance: Theory and Method Based on Bach's Solos for Violin", "doi": "https://doi.org/10.11647/OBP.0064", "publicationDate": "2015-08-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Dorottya Fabian", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "99af261d-8a31-449e-bf26-20e0178b8ed1", "fullTitle": "An Anglo-Norman Reader", "doi": "https://doi.org/10.11647/OBP.0110", "publicationDate": "2018-02-08", "place": "Cambridge, UK", "contributions": [{"fullName": "Jane Bliss", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0d45084-d852-470d-b9f7-4719304f8a56", "fullTitle": "Animals and Medicine: The Contribution of Animal Experiments to the Control of Disease", "doi": "https://doi.org/10.11647/OBP.0055", "publicationDate": "2015-05-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Jack Botting", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Regina Botting", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Adrian R. Morrison", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "5a597468-a3eb-4026-b29e-eb93b8a7b0d6", "fullTitle": "Annunciations: Sacred Music for the Twenty-First Century", "doi": "https://doi.org/10.11647/OBP.0172", "publicationDate": "2019-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "George Corbett", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "857a5788-a709-4d56-8607-337c1cabd9a2", "fullTitle": "ANZUS and the Early Cold War: Strategy and Diplomacy between Australia, New Zealand and the United States, 1945-1956", "doi": "https://doi.org/10.11647/OBP.0141", "publicationDate": "2018-09-07", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Kelly", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0263f0c-48cd-4923-aef5-1b204636507c", "fullTitle": "A People Passing Rude: British Responses to Russian Culture", "doi": "https://doi.org/10.11647/OBP.0022", "publicationDate": "2012-11-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Anthony Cross", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "69c69fef-ab46-45ab-96d5-d7c4e5d4bce4", "fullTitle": "Arab Media Systems", "doi": "https://doi.org/10.11647/OBP.0238", "publicationDate": "2021-03-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Carola Richter", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Claudia Kozman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1e3ef1d6-a460-4b47-8d14-78c3d18e40c1", "fullTitle": "A Time Travel Dialogue", "doi": "https://doi.org/10.11647/OBP.0043", "publicationDate": "2014-08-01", "place": "Cambridge, UK", "contributions": [{"fullName": "John W. Carroll", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "664931f6-27ca-4409-bb47-5642ca60117e", "fullTitle": "A Victorian Curate: A Study of the Life and Career of the Rev. Dr John Hunt ", "doi": "https://doi.org/10.11647/OBP.0248", "publicationDate": "2021-05-03", "place": "Cambridge, UK", "contributions": [{"fullName": "David Yeandle", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "721fc7c9-7531-40cd-9e59-ab1bef5fc261", "fullTitle": "Basic Knowledge and Conditions on Knowledge", "doi": "https://doi.org/10.11647/OBP.0104", "publicationDate": "2017-10-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Mark McBride", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "39aafd68-dc83-4951-badf-d1f146a38fd4", "fullTitle": "B C, Before Computers: On Information Technology from Writing to the Age of Digital Data", "doi": "https://doi.org/10.11647/OBP.0225", "publicationDate": "2020-10-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Stephen Robertson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a373ccbd-0665-4faa-bc24-15542e5cb0cf", "fullTitle": "Behaviour, Development and Evolution", "doi": "https://doi.org/10.11647/OBP.0097", "publicationDate": "2017-02-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Patrick Bateson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "e76e054c-617d-4004-b68d-54739205df8d", "fullTitle": "Beyond Holy Russia: The Life and Times of Stephen Graham", "doi": "https://doi.org/10.11647/OBP.0040", "publicationDate": "2014-02-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Michael Hughes", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fe599a6c-ecd8-4ed3-a39e-5778cb9b77da", "fullTitle": "Beyond Price: Essays on Birth and Death", "doi": "https://doi.org/10.11647/OBP.0061", "publicationDate": "2015-10-08", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c7ded4f3-4850-44eb-bd5b-e196a2254d3f", "fullTitle": "Bourdieu and Literature", "doi": "https://doi.org/10.11647/OBP.0027", "publicationDate": "2011-11-30", "place": "Cambridge, UK", "contributions": [{"fullName": "John R.W. Speller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "456b46b9-bbec-4832-95ca-b23dcb975df1", "fullTitle": "Brownshirt Princess: A Study of the 'Nazi Conscience'", "doi": "https://doi.org/10.11647/OBP.0003", "publicationDate": "2009-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Lionel Gossman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7fe53b7d-a76c-4257-ad4f-e9cc0f7297c1", "fullTitle": "Chronicles from Kashmir: An Annotated, Multimedia Script", "doi": "https://doi.org/10.11647/OBP.0223", "publicationDate": "2020-09-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Nandita Dinesh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c5fe7f09-7dfb-4637-82c8-653a6cb683e7", "fullTitle": "Cicero, Against Verres, 2.1.53\u201386: Latin Text with Introduction, Study Questions, Commentary and English Translation", "doi": "https://doi.org/10.11647/OBP.0016", "publicationDate": "2011-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a03ba4d1-1576-41d0-9e8b-d74eccb682e2", "fullTitle": "Cicero, On Pompey's Command (De Imperio), 27-49: Latin Text, Study Aids with Vocabulary, Commentary, and Translation", "doi": "https://doi.org/10.11647/OBP.0045", "publicationDate": "2014-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Louise Hodgson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7e753cbc-c74b-4214-a565-2300f544be77", "fullTitle": "Cicero, Philippic 2, 44\u201350, 78\u201392, 100\u2013119: Latin Text, Study Aids with Vocabulary, and Commentary", "doi": "https://doi.org/10.11647/OBP.0156", "publicationDate": "2018-09-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Ingo Gildenhard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "fd4d3c2a-355f-4bc0-83cb-1cd6764976e7", "fullTitle": "Classical Music: Contemporary Perspectives and Challenges", "doi": "https://doi.org/10.11647/OBP.0242", "publicationDate": "2021-03-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Beckerman Michael", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Boghossian Paul", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "9ea10b68-b23c-4562-b0ca-03ba548889a3", "fullTitle": "Coleridge's Laws: A Study of Coleridge in Malta", "doi": "https://doi.org/10.11647/OBP.0005", "publicationDate": "2010-01-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Barry Hough", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Howard Davis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Lydia Davis", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Micheal John Kooy", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "98776400-e985-488d-a3f1-9d88879db3cf", "fullTitle": "Complexity, Security and Civil Society in East Asia: Foreign Policies and the Korean Peninsula", "doi": "https://doi.org/10.11647/OBP.0059", "publicationDate": "2015-06-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Kiho Yi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Peter Hayes", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "296c6880-6212-48d2-b327-2c13b6e28d5f", "fullTitle": "Conservation Biology in Sub-Saharan Africa", "doi": "https://doi.org/10.11647/OBP.0177", "publicationDate": "2019-09-08", "place": "Cambridge, UK", "contributions": [{"fullName": "John W. Wilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Richard B. Primack", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "e5ade02a-2f32-495a-b879-98b54df04c0a", "fullTitle": "Cornelius Nepos, Life of Hannibal: Latin Text, Notes, Maps, Illustrations and Vocabulary", "doi": "https://doi.org/10.11647/OBP.0068", "publicationDate": "2015-10-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Bret Mulligan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c86acc9-89a0-4b17-bcdd-520d33fc4f54", "fullTitle": "Creative Multilingualism: A Manifesto", "doi": "https://doi.org/10.11647/OBP.0206", "publicationDate": "2020-05-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Wen-chin Ouyang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Rajinder Dudrah", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Andrew Gosler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Martin Maiden", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Suzanne Graham", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Katrin Kohl", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "10ddfb3d-3434-46f8-a3bb-14dfc0ce9591", "fullTitle": "Cultural Heritage Ethics: Between Theory and Practice", "doi": "https://doi.org/10.11647/OBP.0047", "publicationDate": "2014-10-13", "place": "Cambridge, UK", "contributions": [{"fullName": "Sandis Constantine", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2b031e1a-678b-4dcb-becb-cbd0f0ce9182", "fullTitle": "Deliberation, Representation, Equity: Research Approaches, Tools and Algorithms for Participatory Processes", "doi": "https://doi.org/10.11647/OBP.0108", "publicationDate": "2017-01-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Mats Danielson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Love Ekenberg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Karin Hansson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "G\u00f6ran Cars", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "bc253bff-cf00-433d-89a2-031500b888ff", "fullTitle": "Delivering on the Promise of Democracy: Visual Case Studies in Educational Equity and Transformation", "doi": "https://doi.org/10.11647/OBP.0157", "publicationDate": "2019-01-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Sukhwant Jhaj", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "517963d1-a56a-4250-8a07-56743ba60d95", "fullTitle": "Democracy and Power: The Delhi Lectures", "doi": "https://doi.org/10.11647/OBP.0050", "publicationDate": "2014-12-07", "place": "Cambridge, UK", "contributions": [{"fullName": "Noam Chomsky", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jean Dr\u00e8ze", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "60450f84-3e18-4beb-bafe-87c78b5a0159", "fullTitle": "Denis Diderot 'Rameau's Nephew' - 'Le Neveu de Rameau': A Multi-Media Bilingual Edition", "doi": "https://doi.org/10.11647/OBP.0098", "publicationDate": "2016-06-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "b3989be1-9115-4635-b766-92f6ebfabef1", "fullTitle": "Denis Diderot's 'Rameau's Nephew': A Multi-media Edition", "doi": "https://doi.org/10.11647/OBP.0044", "publicationDate": "2014-08-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Denis Diderot", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marian Hobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kate E. Tunstall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Caroline Warman", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pascal Duc", "contributionType": "MUSIC_EDITOR", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "594ddcb6-2363-47c8-858e-76af2283e486", "fullTitle": "Dickens\u2019s Working Notes for 'Dombey and Son'", "doi": "https://doi.org/10.11647/OBP.0092", "publicationDate": "2017-09-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Tony Laing", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d3adf77-c72b-4b69-bf5a-a042a38a837a", "fullTitle": "Dictionary of the British English Spelling System", "doi": "https://doi.org/10.11647/OBP.0053", "publicationDate": "2015-03-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Greg Brooks", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "364c223d-9c90-4ceb-90e2-51be7d84e923", "fullTitle": "Die Europaidee im Zeitalter der Aufkl\u00e4rung", "doi": "https://doi.org/10.11647/OBP.0127", "publicationDate": "2017-08-21", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1d4812e4-c491-4465-8e92-64e4f13662f1", "fullTitle": "Digital Humanities Pedagogy: Practices, Principles and Politics", "doi": "https://doi.org/10.11647/OBP.0024", "publicationDate": "2012-12-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Brett D. Hirsch", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "43d96298-a683-4098-9492-bba1466cb8e0", "fullTitle": "Digital Scholarly Editing: Theories and Practices", "doi": "https://doi.org/10.11647/OBP.0095", "publicationDate": "2016-08-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Elena Pierazzo", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Matthew James Driscoll", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "912c2731-3ca1-4ad9-b601-5d968da6b030", "fullTitle": "Digital Technology and the Practices of Humanities Research", "doi": "https://doi.org/10.11647/OBP.0192", "publicationDate": "2020-01-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Jennifer Edmond", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "78bbcc00-a336-4eb6-b4b5-0c57beec0295", "fullTitle": "Discourses We Live By: Narratives of Educational and Social Endeavour", "doi": "https://doi.org/10.11647/OBP.0203", "publicationDate": "2020-07-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Hazel R. Wright", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marianne H\u00f8yen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "1312613f-e01a-499a-b0d0-7289d5b9013d", "fullTitle": "Diversity and Rabbinization: Jewish Texts and Societies between 400 and 1000 CE", "doi": "https://doi.org/10.11647/OBP.0219", "publicationDate": "2021-04-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Gavin McDowell", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Ron Naiweld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel St\u00f6kl Ben Ezra", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "2d74b1a9-c3b0-4278-8cad-856fadc6a19d", "fullTitle": "Don Carlos Infante of Spain: A Dramatic Poem", "doi": "https://doi.org/10.11647/OBP.0134", "publicationDate": "2018-06-04", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "b190b3c5-88c0-4e4a-939a-26995b7ff95c", "fullTitle": "Earth 2020: An Insider\u2019s Guide to a Rapidly Changing Planet", "doi": "https://doi.org/10.11647/OBP.0193", "publicationDate": "2020-04-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Philippe D. Tortell", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a5e6aa48-02ba-48e4-887f-1c100a532de8", "fullTitle": "Economic Fables", "doi": "https://doi.org/10.11647/OBP.0020", "publicationDate": "2012-04-20", "place": "Cambridge, UK", "contributions": [{"fullName": "Ariel Rubinstein", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2b63a26d-0db1-4200-983f-8b69d9821d8b", "fullTitle": "Engaging Researchers with Data Management: The Cookbook", "doi": "https://doi.org/10.11647/OBP.0185", "publicationDate": "2019-10-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Yan Wang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "James Savage", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Connie Clare", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marta Teperek", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Maria Cruz", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Elli Papadopoulou", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "af162e8a-23ab-49e6-896d-e53b9d6c0039", "fullTitle": "Essays in Conveyancing and Property Law in Honour of Professor Robert Rennie", "doi": "https://doi.org/10.11647/OBP.0056", "publicationDate": "2015-05-11", "place": "Cambridge, UK", "contributions": [{"fullName": "Frankie McCarthy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Stephen Bogle", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "James Chalmers", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "98d053d6-dcc2-409a-8841-9f19920b49ee", "fullTitle": "Essays in Honour of Eamonn Cantwell: Yeats Annual No. 20", "doi": "https://doi.org/10.11647/OBP.0081", "publicationDate": "2016-12-05", "place": "Cambridge, UK", "contributions": [{"fullName": "Warwick Gould", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "24689aa7-af74-4238-ad75-a9469f094068", "fullTitle": "Essays on Paula Rego: Smile When You Think about Hell", "doi": "https://doi.org/10.11647/OBP.0178", "publicationDate": "2019-09-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Maria Manuel Lisboa", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f76ab190-35f4-4136-86dd-d7fa02ccaebb", "fullTitle": "Ethics for A-Level", "doi": "https://doi.org/10.11647/OBP.0125", "publicationDate": "2017-07-31", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew Fisher", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mark Dimmock", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d90e1915-1d2a-40e6-a94c-79f671031224", "fullTitle": "Europa im Geisterkrieg. Studien zu Nietzsche", "doi": "https://doi.org/10.11647/OBP.0133", "publicationDate": "2018-06-19", "place": "Cambridge, UK", "contributions": [{"fullName": "Werner Stegmaier", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andrea C. Bertino", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "a0a8d5f1-12d0-4d51-973d-ed1dfa73f01f", "fullTitle": "Exploring the Interior: Essays on Literary and Cultural History", "doi": "https://doi.org/10.11647/OBP.0126", "publicationDate": "2018-05-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Karl S. Guthke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3795e166-413c-4568-8c19-1117689ef14b", "fullTitle": "Feeding the City: Work and Food Culture of the Mumbai Dabbawalas", "doi": "https://doi.org/10.11647/OBP.0031", "publicationDate": "2013-07-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Sara Roncaglia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Angela Arnone", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Pier Giorgio Solinas", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "5da7830b-6d55-4eb4-899e-cb2a13b30111", "fullTitle": "Fiesco's Conspiracy at Genoa", "doi": "https://doi.org/10.11647/OBP.0058", "publicationDate": "2015-05-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Friedrich Schiller", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Flora Kimmich", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "John Guthrie", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "83b7409e-f076-4598-965e-9e15615be247", "fullTitle": "Forests and Food: Addressing Hunger and Nutrition Across Sustainable Landscapes", "doi": "https://doi.org/10.11647/OBP.0085", "publicationDate": "2015-11-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Christoph Wildburger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bhaskar Vira", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Stephanie Mansourian", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "1654967f-82f1-4ed0-ae81-7ebbfb9c183d", "fullTitle": "Foundations for Moral Relativism", "doi": "https://doi.org/10.11647/OBP.0029", "publicationDate": "2013-04-17", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "00766beb-0597-48a8-ba70-dd2b8382ec37", "fullTitle": "Foundations for Moral Relativism: Second Expanded Edition", "doi": "https://doi.org/10.11647/OBP.0086", "publicationDate": "2015-11-23", "place": "Cambridge, UK", "contributions": [{"fullName": "J. David Velleman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3083819d-1084-418a-85d4-4f71c2fea139", "fullTitle": "From Darkness to Light: Writers in Museums 1798-1898", "doi": "https://doi.org/10.11647/OBP.0151", "publicationDate": "2019-03-12", "place": "Cambridge, UK", "contributions": [{"fullName": "Rosella Mamoli Zorzi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Katherine Manthorne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5bf6450f-99a7-4375-ad94-d5bde1b0282c", "fullTitle": "From Dust to Digital: Ten Years of the Endangered Archives Programme", "doi": "https://doi.org/10.11647/OBP.0052", "publicationDate": "2015-02-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Maja Kominko", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d16896b7-691e-4620-9adb-1d7a42c69bde", "fullTitle": "From Goethe to Gundolf: Essays on German Literature and Culture", "doi": "https://doi.org/10.11647/OBP.0258", "publicationDate": null, "place": "Cambridge, UK", "contributions": [{"fullName": "Roger Paulin", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3a167e24-36b5-4d0e-b55f-af6be9a7c827", "fullTitle": "Frontier Encounters: Knowledge and Practice at the Russian, Chinese and Mongolian Border", "doi": "https://doi.org/10.11647/OBP.0026", "publicationDate": "2012-08-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Gr\u00e9gory Delaplace", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Caroline Humphrey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Franck Bill\u00e9", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1471f4c3-a88c-4301-b98a-7193be6dde4b", "fullTitle": "Gallucci's Commentary on D\u00fcrer\u2019s 'Four Books on Human Proportion': Renaissance Proportion Theory", "doi": "https://doi.org/10.11647/OBP.0198", "publicationDate": "2020-03-25", "place": "Cambridge, UK", "contributions": [{"fullName": "James Hutson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "101eb7c2-f15f-41f9-b53a-dfccd4b28301", "fullTitle": "Global Warming in Local Discourses: How Communities around the World Make Sense of Climate Change", "doi": "https://doi.org/10.11647/OBP.0212", "publicationDate": "2020-10-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Michael Br\u00fcggemann", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Simone R\u00f6dder", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "32e99c61-2352-4a88-bb9a-bd81f113ba1e", "fullTitle": "God's Babies: Natalism and Bible Interpretation in Modern America", "doi": "https://doi.org/10.11647/OBP.0048", "publicationDate": "2014-12-17", "place": "Cambridge, UK", "contributions": [{"fullName": "John McKeown", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ab3a9d7f-c9b9-42bf-9942-45f68b40bcd6", "fullTitle": "Hanging on to the Edges: Essays on Science, Society and the Academic Life", "doi": "https://doi.org/10.11647/OBP.0155", "publicationDate": "2018-10-15", "place": "Cambridge, UK", "contributions": [{"fullName": "Daniel Nettle", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9d5ac1c6-a763-49b4-98b2-355d888169be", "fullTitle": "Henry James's Europe: Heritage and Transfer", "doi": "https://doi.org/10.11647/OBP.0013", "publicationDate": "2011-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Adrian Harding", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Annick Duperray", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dennis Tredy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b7790cae-1901-446e-b529-b5fe393d8061", "fullTitle": "History of International Relations: A Non-European Perspective", "doi": "https://doi.org/10.11647/OBP.0074", "publicationDate": "2019-07-31", "place": "Cambridge, UK", "contributions": [{"fullName": "Erik Ringmar", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7b9b68c6-8bb6-42c5-8b19-bf5e56b7293e", "fullTitle": "How to Read a Folktale: The 'Ibonia' Epic from Madagascar", "doi": "https://doi.org/10.11647/OBP.0034", "publicationDate": "2013-10-08", "place": "Cambridge, UK", "contributions": [{"fullName": "Lee Haring", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "23651a20-a26e-4253-b0a9-c8b5bf1409c7", "fullTitle": "Human and Machine Consciousness", "doi": "https://doi.org/10.11647/OBP.0107", "publicationDate": "2018-03-07", "place": "Cambridge, UK", "contributions": [{"fullName": "David Gamez", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "27def25d-48ad-470d-9fbe-1ddc8376e1cb", "fullTitle": "Human Cultures through the Scientific Lens: Essays in Evolutionary Cognitive Anthropology", "doi": "https://doi.org/10.11647/OBP.0257", "publicationDate": "2021-07-09", "place": "Cambridge, UK", "contributions": [{"fullName": "Pascal Boyer", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "859a1313-7b02-4c66-8010-dbe533c4412a", "fullTitle": "Hyperion or the Hermit in Greece", "doi": "https://doi.org/10.11647/OBP.0160", "publicationDate": "2019-02-25", "place": "Cambridge, UK", "contributions": [{"fullName": "Howard Gaskill", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1f591391-7497-4447-8c06-d25006a1b922", "fullTitle": "Image, Knife, and Gluepot: Early Assemblage in Manuscript and Print", "doi": "https://doi.org/10.11647/OBP.0145", "publicationDate": "2019-07-16", "place": "Cambridge, UK", "contributions": [{"fullName": "Kathryn M. Rudy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "50516c2a-154e-4758-9b94-586987af2b7f", "fullTitle": "Information and Empire: Mechanisms of Communication in Russia, 1600-1854", "doi": "https://doi.org/10.11647/OBP.0122", "publicationDate": "2017-11-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Katherine Bowers", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Simon Franklin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1549f31d-4783-4a63-a050-90ffafd77328", "fullTitle": "Infrastructure Investment in Indonesia: A Focus on Ports", "doi": "https://doi.org/10.11647/OBP.0189", "publicationDate": "2019-11-18", "place": "Cambridge, UK", "contributions": [{"fullName": "Colin Duffield", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Felix Kin Peng Hui", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Sally Wilson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "1692a92d-f86a-4155-9e6c-16f38586b7fc", "fullTitle": "Intellectual Property and Public Health in the Developing World", "doi": "https://doi.org/10.11647/OBP.0093", "publicationDate": "2016-05-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Monirul Azam", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d6850e99-33ce-4cae-ac7c-bd82cf23432b", "fullTitle": "In the Lands of the Romanovs: An Annotated Bibliography of First-hand English-language Accounts of the Russian Empire (1613-1917)", "doi": "https://doi.org/10.11647/OBP.0042", "publicationDate": "2014-04-27", "place": "Cambridge, UK", "contributions": [{"fullName": "Anthony Cross", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4455a769-d374-4eed-8e6a-84c220757c0d", "fullTitle": "Introducing Vigilant Audiences", "doi": "https://doi.org/10.11647/OBP.0200", "publicationDate": "2020-10-14", "place": "Cambridge, UK", "contributions": [{"fullName": "Rashid Gabdulhakov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel Trottier", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Qian Huang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "e414ca1b-a7f2-48c7-9adb-549a04711241", "fullTitle": "Inventory Analytics", "doi": "https://doi.org/10.11647/OBP.0252", "publicationDate": "2021-05-24", "place": "Cambridge, UK", "contributions": [{"fullName": "Roberto Rossi", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ad55c2c5-9769-4648-9c42-dc4cef1f1c99", "fullTitle": "Is Behavioral Economics Doomed? The Ordinary versus the Extraordinary", "doi": "https://doi.org/10.11647/OBP.0021", "publicationDate": "2012-09-17", "place": "Cambridge, UK", "contributions": [{"fullName": "David K. Levine", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2ceb72f2-ddde-45a7-84a9-27523849f8f5", "fullTitle": "Jane Austen: Reflections of a Reader", "doi": "https://doi.org/10.11647/OBP.0216", "publicationDate": "2021-02-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Nora Bartlett", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jane Stabler", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5b542db8-c128-48ff-a48c-003c95eaca25", "fullTitle": "Jewish-Muslim Intellectual History Entangled: Textual Materials from the Firkovitch Collection, Saint Petersburg", "doi": "https://doi.org/10.11647/OBP.0214", "publicationDate": "2020-08-03", "place": "Cambridge, UK", "contributions": [{"fullName": "Jan Thiele", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 6}, {"fullName": "Wilferd Madelung", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Omar Hamdan", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Adang Camilla", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sabine Schmidtke", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Bruno Chiesa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "df7eb598-914a-49eb-9cbd-9766bd06be84", "fullTitle": "Just Managing? What it Means for the Families of Austerity Britain", "doi": "https://doi.org/10.11647/OBP.0112", "publicationDate": "2017-05-29", "place": "Cambridge, UK", "contributions": [{"fullName": "Paul Kyprianou", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mark O'Brien", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c5e415c4-1ed1-4c58-abae-b1476689a867", "fullTitle": "Knowledge and the Norm of Assertion: An Essay in Philosophical Science", "doi": "https://doi.org/10.11647/OBP.0083", "publicationDate": "2016-02-26", "place": "Cambridge, UK", "contributions": [{"fullName": "John Turri", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9fc774fa-3a18-42d8-89e3-b5a23d822dd6", "fullTitle": "Labor and Value: Rethinking Marx\u2019s Theory of Exploitation", "doi": "https://doi.org/10.11647/OBP.0182", "publicationDate": "2019-10-02", "place": "Cambridge, UK", "contributions": [{"fullName": "Ernesto Screpanti", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "29e28ee7-c52d-43f3-95da-f99f33f0e737", "fullTitle": "Les Bienveillantes de Jonathan Littell: \u00c9tudes r\u00e9unies par Murielle Lucie Cl\u00e9ment", "doi": "https://doi.org/10.11647/OBP.0006", "publicationDate": "2010-04-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Murielle Lucie Cl\u00e9ment", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d9e671dd-ab2a-4fd0-ada3-4925449a63a8", "fullTitle": "Letters of Blood and Other Works in English", "doi": "https://doi.org/10.11647/OBP.0017", "publicationDate": "2011-11-30", "place": "Cambridge, UK", "contributions": [{"fullName": "G\u00f6ran Printz-P\u00e5hlson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Robert Archambeau", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Elinor Shaffer", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Lars-H\u00e5kan Svensson", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "c699f257-f3e4-4c98-9a3f-741c6a40b62a", "fullTitle": "L\u2019id\u00e9e de l\u2019Europe: au Si\u00e8cle des Lumi\u00e8res", "doi": "https://doi.org/10.11647/OBP.0116", "publicationDate": "2017-05-01", "place": "Cambridge, UK", "contributions": [{"fullName": "Rotraud von Kulessa", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Catriona Seth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "a795aafb-d189-4d15-8e64-b9a3fbfa8e09", "fullTitle": "Life Histories of Etnos Theory in Russia and Beyond", "doi": "https://doi.org/10.11647/OBP.0150", "publicationDate": "2019-02-06", "place": "Cambridge, UK", "contributions": [{"fullName": "Dmitry V Arzyutov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "David G. Anderson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sergei S. Alymov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "5c55effb-2a3e-4e0d-a46d-edad7830fd8e", "fullTitle": "Lifestyle in Siberia and the Russian North", "doi": "https://doi.org/10.11647/OBP.0171", "publicationDate": "2019-11-22", "place": "Cambridge, UK", "contributions": [{"fullName": "Joachim Otto Habeck", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6090bfc8-3143-4599-b0dd-17705f754e8c", "fullTitle": "Like Nobody's Business: An Insider's Guide to How US University Finances Really Work", "doi": "https://doi.org/10.11647/OBP.0240", "publicationDate": "2021-02-23", "place": "Cambridge, UK", "contributions": [{"fullName": "Andrew C. Comrie", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "25a2f70a-832d-4c8d-b28f-75f838b6e171", "fullTitle": "Liminal Spaces: Migration and Women of the Guyanese Diaspora", "doi": "https://doi.org/10.11647/OBP.0218", "publicationDate": "2020-09-29", "place": "Cambridge, UK", "contributions": [{"fullName": "Grace Aneiza Ali", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9845c8a9-b283-4cb8-8961-d41e5fe795f1", "fullTitle": "Literature Against Criticism: University English and Contemporary Fiction in Conflict", "doi": "https://doi.org/10.11647/OBP.0102", "publicationDate": "2016-10-17", "place": "Cambridge, UK", "contributions": [{"fullName": "Martin Paul Eve", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f957ab3d-c925-4bf2-82fa-9809007753e7", "fullTitle": "Living Earth Community: Multiple Ways of Being and Knowing", "doi": "https://doi.org/10.11647/OBP.0186", "publicationDate": "2020-05-07", "place": "Cambridge, UK", "contributions": [{"fullName": "John Grim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Mary Evelyn Tucker", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Sam Mickey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "545f9f42-87c0-415e-9086-eee27925c85b", "fullTitle": "Long Narrative Songs from the Mongghul of Northeast Tibet: Texts in Mongghul, Chinese, and English", "doi": "https://doi.org/10.11647/OBP.0124", "publicationDate": "2017-10-30", "place": "Cambridge, UK", "contributions": [{"fullName": "Gerald Roche", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Li Dechun", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mark Turin", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/peanut-books/", "imprintId": "5cc7d3db-f300-4813-9c68-3ccc18a6277b", "imprintName": "Peanut Books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "14a2356a-4767-4136-b44a-684a28dc87a6", "fullTitle": "In a Trance: On Paleo Art", "doi": "https://doi.org/10.21983/P3.0081.1.00", "publicationDate": "2014-11-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeffrey Skoblow", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "200b11a8-57d6-4f81-b089-ddd4ee7fe2f2", "fullTitle": "The Apartment of Tragic Appliances: Poems", "doi": "https://doi.org/10.21983/P3.0030.1.00", "publicationDate": "2013-05-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael D. Snediker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "49ebcb4a-928f-4d83-9596-b296dfce0b20", "fullTitle": "The Petroleum Manga: A Project by Marina Zurkow", "doi": "https://doi.org/10.21983/P3.0062.1.00", "publicationDate": "2014-02-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marina Zurkow", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2a360648-3157-4a1b-9ba7-a61895a8a10c", "fullTitle": "Where the Tiny Things Are: Feathered Essays", "doi": "https://doi.org/10.21983/P3.0181.1.00", "publicationDate": "2017-09-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nicole Walker", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/", "imprintId": "7522e351-8a91-40fa-bf45-02cb38368b0b", "imprintName": "punctum books", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "5402ea62-7a1b-48b4-b5fb-7b114c04bc27", "fullTitle": "A Boy Asleep under the Sun: Versions of Sandro Penna", "doi": "https://doi.org/10.21983/P3.0080.1.00", "publicationDate": "2014-11-11", "place": "Brooklyn, NY", "contributions": [{"fullName": "Sandro Penna", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Peter Valente", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Peter Valente", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "8a27431b-b1f9-4fed-a8e0-0a0aadc9d98c", "fullTitle": "A Buddha Land in This World: Philosophy, Utopia, and Radical Buddhism", "doi": "https://doi.org/10.53288/0373.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Lajos Brons", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "eeb920c0-6f2e-462c-a315-3687b5ca8da3", "fullTitle": "Action [poems]", "doi": "https://doi.org/10.21983/P3.0083.1.00", "publicationDate": "2014-12-10", "place": "Brooklyn, NY", "contributions": [{"fullName": "Anthony Opal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "20dab41d-2267-4a68-befa-d787b7c98599", "fullTitle": "After the \"Speculative Turn\": Realism, Philosophy, and Feminism", "doi": "https://doi.org/10.21983/P3.0152.1.00", "publicationDate": "2016-10-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katerina Kolozova", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13a03c11-0f22-4d40-881d-b935452d4bf3", "fullTitle": "Air Supplied", "doi": "https://doi.org/10.21983/P3.0201.1.00", "publicationDate": "2018-05-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "David Cross", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5147a952-3d44-4beb-8d49-b41c91bce733", "fullTitle": "Alternative Historiographies of the Digital Humanities", "doi": "https://doi.org/10.53288/0274.1.00", "publicationDate": "2021-06-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adeline Koh", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dorothy Kim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f712541c-07b4-477c-8b8c-8c1a307810d0", "fullTitle": "And Another Thing: Nonanthropocentrism and Art", "doi": "https://doi.org/10.21983/P3.0144.1.00", "publicationDate": "2016-06-18", "place": "Earth, Milky Way", "contributions": [{"fullName": "Katherine Behar", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Emmy Mikelson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "27e17948-02c4-4ba3-8244-5c229cc8e9b8", "fullTitle": "Anglo-Saxon(ist) Pasts, postSaxon Futures", "doi": "https://doi.org/10.21983/P3.0262.1.00", "publicationDate": "2019-12-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Donna-Beth Ellard", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f3c9e9d8-9a38-4558-be2e-cab9a70d62f0", "fullTitle": "Annotations to Geoffrey Hill's Speech! Speech!", "doi": "https://doi.org/10.21983/P3.0004.1.00", "publicationDate": "2012-01-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Ann Hassan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "baf524c6-0a2c-40f2-90a7-e19c6e1b6b97", "fullTitle": "Anthropocene Unseen: A Lexicon", "doi": "https://doi.org/10.21983/P3.0265.1.00", "publicationDate": "2020-02-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Cymene Howe", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anand Pandian", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f6afff19-25ae-41f8-8a7a-6c1acffafc39", "fullTitle": "Antiracism Inc.: Why the Way We Talk about Racial Justice Matters", "doi": "https://doi.org/10.21983/P3.0250.1.00", "publicationDate": "2019-04-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Paula Ioanide", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Alison Reed", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Felice Blake", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "88c47bd3-f8c9-4157-9d1a-770d9be8c173", "fullTitle": "A Nuclear Refrain: Emotion, Empire, and the Democratic Potential of Protest", "doi": "https://doi.org/10.21983/P3.0271.1.00", "publicationDate": "2019-12-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kye Askins", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Phil Johnstone", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kelvin Mason", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "41508a3c-614b-473e-aa74-edcb6b09dc9d", "fullTitle": "Ardea: A Philosophical Novella", "doi": "https://doi.org/10.21983/P3.0147.1.00", "publicationDate": "2016-07-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Freya Mathews", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ae9f8357-4b39-4809-a8e9-766e200fb937", "fullTitle": "A Rushed Quality", "doi": "https://doi.org/10.21983/P3.0103.1.00", "publicationDate": "2015-05-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Odell", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3f78b298-8826-4162-886e-af21a77f2957", "fullTitle": "Athens and the War on Public Space: Tracing a City in Crisis", "doi": "https://doi.org/10.21983/P3.0199.1.00", "publicationDate": "2018-04-20", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christos Filippidis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Klara Jaya Brekke", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Antonis Vradis", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "3da27fb9-7a15-446e-ae0f-258c7dd4fd94", "fullTitle": "Barton Myers: Works of Architecture and Urbanism", "doi": "https://doi.org/10.21983/P3.0249.1.00", "publicationDate": "2019-07-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kris Miller-Fisher", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jocelyn Gibbs", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "f4d42680-8b02-4e3a-9ec8-44aee852b29f", "fullTitle": "Bathroom Songs: Eve Kosofsky Sedgwick as a Poet", "doi": "https://doi.org/10.21983/P3.0189.1.00", "publicationDate": "2017-11-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jason Edwards", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "637566b3-dca3-4a8b-b5bd-01fcbb77ca09", "fullTitle": "Beowulf: A Translation", "doi": "https://doi.org/10.21983/P3.0009.1.00", "publicationDate": "2012-08-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Hadbawnik", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Thomas Meyer", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Daniel C. Remein", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "David Hadbawnik", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 4}]}, {"workId": "9bae1a52-f764-417d-9d45-4df12f71cf07", "fullTitle": "Beowulf by All", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Elaine Treharne", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jean Abbott", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Mateusz Fafinski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "a2ce9f9c-f594-4165-83be-e3751d4d17fe", "fullTitle": "Beta Exercise: The Theory and Practice of Osamu Kanemura", "doi": "https://doi.org/10.21983/P3.0241.1.00", "publicationDate": "2019-01-23", "place": "Earth, Milky Way", "contributions": [{"fullName": "Osamu Kanemura", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Marco Mazzi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Nicholas Marshall", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Michiyo Miyake", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "735d8962-5ec7-41ce-a73a-a43c35cc354f", "fullTitle": "Between Species/Between Spaces: Art and Science on the Outer Cape", "doi": "https://doi.org/10.21983/P3.0325.1.00", "publicationDate": "2020-08-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dylan Gauthier", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Kendra Sullivan", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a871cb31-e158-401d-a639-3767131c0f34", "fullTitle": "Bigger Than You: Big Data and Obesity", "doi": "https://doi.org/10.21983/P3.0135.1.00", "publicationDate": "2016-03-03", "place": "Earth, Milky Way", "contributions": [{"fullName": "Katherine Behar", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "940d0880-83b5-499d-9f39-1bf30ccfc4d0", "fullTitle": "Book of Anonymity", "doi": "https://doi.org/10.21983/P3.0315.1.00", "publicationDate": "2021-03-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Anon Collective", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "006571ae-ac0e-4cb0-8a3f-71280aa7f23b", "fullTitle": "Broken Records", "doi": "https://doi.org/10.21983/P3.0137.1.00", "publicationDate": "2016-03-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sne\u017eana \u017dabi\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "47c71c05-a4f1-48da-b8d5-9e5ba139a8ea", "fullTitle": "Building Black: Towards Antiracist Architecture", "doi": "https://doi.org/10.21983/P3.0372.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Elliot C. Mason", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "dd9008ae-0172-4e07-b3cf-50c35c51b606", "fullTitle": "Bullied: The Story of an Abuse", "doi": "https://doi.org/10.21983/P3.0356.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "46344fe3-1d72-4ddd-a57e-1d3f4377d2a2", "fullTitle": "Centaurs, Rioting in Thessaly: Memory and the Classical World", "doi": "https://doi.org/10.21983/P3.0192.1.00", "publicationDate": "2018-01-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Martyn Hudson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7f1d3e2e-c708-4f59-81cf-104c1ca528d0", "fullTitle": "Chaste Cinematics", "doi": "https://doi.org/10.21983/P3.0117.1.00", "publicationDate": "2015-10-31", "place": "Brooklyn, NY", "contributions": [{"fullName": "Victor J. Vitanza", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b2d1b2e3-226e-43c2-a898-fbad7b410e3f", "fullTitle": "Christina McPhee: A Commonplace Book", "doi": "https://doi.org/10.21983/P3.0186.1.00", "publicationDate": "2017-10-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "45aa16fa-5fd5-4449-a3bd-52d734fcb0a9", "fullTitle": "Cinema's Doppelg\u00e4ngers\n", "doi": "https://doi.org/10.53288/0320.1.00", "publicationDate": "2021-06-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Doug Dibbern", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "84447325-88e2-4658-8597-3f2329451156", "fullTitle": "Clinical Encounters in Sexuality: Psychoanalytic Practice and Queer Theory", "doi": "https://doi.org/10.21983/P3.0167.1.00", "publicationDate": "2017-03-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Eve Watson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Noreen Giffney", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4d0430e3-3640-4d87-8f02-cbb45f6ae83b", "fullTitle": "Comic Providence", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Janet Thormann", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "0ff62120-4478-46dc-8d01-1d7e1dc5b7a6", "fullTitle": "Commonist Tendencies: Mutual Aid beyond Communism", "doi": "https://doi.org/10.21983/P3.0040.1.00", "publicationDate": "2013-07-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d890e88f-16d7-4b75-bef1-5e4d09c8daa0", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea", "doi": "https://doi.org/10.21983/P3.0269.1.00", "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "a603437d-578e-4577-9800-645614b28b4b", "fullTitle": "Complementary Modernisms in China and the United States: Art as Life/Art as Idea [BW]", "doi": null, "publicationDate": "2020-09-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jian Zhang", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bruce Robertson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "93330f65-a84f-4c5c-aa44-f710c714eca2", "fullTitle": "Continent. Year 1: A Selection of Issues 1.1\u20131.4", "doi": "https://doi.org/10.21983/P3.0016.1.00", "publicationDate": "2012-12-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Adam Staley Groves", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Paul Boshears", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Jamie Allen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "3d78e15e-19cb-464a-a238-b5291dbfd49f", "fullTitle": "Creep: A Life, A Theory, An Apology", "doi": "https://doi.org/10.21983/P3.0178.1.00", "publicationDate": "2017-08-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jonathan Alexander", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f2a2626b-4029-4e43-bb84-7b3cacf61b23", "fullTitle": "Crisis States: Governance, Resistance & Precarious Capitalism", "doi": "https://doi.org/10.21983/P3.0146.1.00", "publicationDate": "2016-07-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "639a3c5b-82ad-4557-897b-2bfebe3dc53c", "fullTitle": "Critique of Sovereignty, Book 1: Contemporary Theories of Sovereignty", "doi": "https://doi.org/10.21983/P3.0114.1.00", "publicationDate": "2015-09-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marc Lombardo", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f37627c1-d89f-434c-9915-f1f2f33dc037", "fullTitle": "Crush", "doi": "https://doi.org/10.21983/P3.0063.1.00", "publicationDate": "2014-02-27", "place": "Brooklyn, NY", "contributions": [{"fullName": "Will Stockton", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "D. Gilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "43355368-b29b-4fa1-9ed6-780f4983364a", "fullTitle": "Damayanti and Nala's Tale", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Dan Rudmann", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "11749800-364e-4a27-bf79-9f0ceeacb4d6", "fullTitle": "Dark Chaucer: An Assortment", "doi": "https://doi.org/10.21983/P3.0018.1.00", "publicationDate": "2012-12-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Nicola Masciandaro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Myra Seaman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Eileen A. Joy", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "7fe2c6dc-6673-4537-a397-1f0377c2296f", "fullTitle": "Dear Professor: A Chronicle of Absences", "doi": "https://doi.org/10.21983/P3.0160.1.00", "publicationDate": "2016-12-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "Filip Noterdaeme", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Shuki Cohen", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "0985e294-aa85-40d0-90ce-af53ae37898d", "fullTitle": "Deleuze and the Passions", "doi": "https://doi.org/10.21983/P3.0161.1.00", "publicationDate": "2016-12-21", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sjoerd van Tuinen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Ceciel Meiborg", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9e6bb4d8-4e05-4cd7-abe9-4a795ade0340", "fullTitle": "Derrida and Queer Theory", "doi": "https://doi.org/10.21983/P3.0172.1.00", "publicationDate": "2017-05-26", "place": "Earth, Milky Way", "contributions": [{"fullName": "Christian Hite", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9e11adff-abed-4b5d-adef-b0c4466231e8", "fullTitle": "Desire/Love", "doi": "https://doi.org/10.21983/P3.0015.1.00", "publicationDate": "2012-12-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Lauren Berlant", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6141d35a-a5a6-43ee-b6b6-5caa41bce869", "fullTitle": "Desire/Love", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Lauren Berlant", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "13c12944-701a-41f4-9d85-c753267d564b", "fullTitle": "Destroyer of Naivet\u00e9s", "doi": "https://doi.org/10.21983/P3.0118.1.00", "publicationDate": "2015-11-07", "place": "Brooklyn, NY", "contributions": [{"fullName": "Joseph Nechvatal", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "69c890c5-d8c5-4295-b5a7-688560929d8b", "fullTitle": "Dialectics Unbound: On the Possibility of Total Writing", "doi": "https://doi.org/10.21983/P3.0041.1.00", "publicationDate": "2013-07-28", "place": "Brooklyn, NY", "contributions": [{"fullName": "Maxwell Kennel", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "25be3523-34b5-43c9-a3e2-b12ffb859025", "fullTitle": "Dire Pessimism: An Essay", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Thomas Carl Wall", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "245c521a-5014-4da0-bf2b-35eff9673367", "fullTitle": "dis/cord: Thinking Sound through Agential Realism", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Kevin Toks\u00f6z Fairbarn", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "488c640d-e742-465a-98b4-1234bb09d038", "fullTitle": "Diseases of the Head: Essays on the Horrors of Speculative Philosophy", "doi": "https://doi.org/10.21983/P3.0280.1.00", "publicationDate": "2020-09-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Matt Rosen", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "754c1299-9b8d-41ac-a1d6-534f174fa87b", "fullTitle": "Disturbing Times: Medieval Pasts, Reimagined Futures", "doi": "https://doi.org/10.21983/P3.0313.1.00", "publicationDate": "2020-06-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Anna K\u0142osowska", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Catherine E. Karkov", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "438e0846-b4b9-4c84-9545-d7a6fb13e996", "fullTitle": "Divine Name Verification: An Essay on Anti-Darwinism, Intelligent Design, and the Computational Nature of Reality", "doi": "https://doi.org/10.21983/P3.0043.1.00", "publicationDate": "2013-08-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Noah Horwitz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "9d1f849d-cf0f-4d0c-8dab-8819fad00337", "fullTitle": "Dollar Theater Theory", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Trevor Owen Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "cd037a39-f6b9-462a-a207-5079a000065b", "fullTitle": "Dotawo: A Journal of Nubian Studies 1", "doi": "https://doi.org/10.21983/P3.0071.1.00", "publicationDate": "2014-06-23", "place": "Brooklyn, NY", "contributions": [{"fullName": "Giovanni Ruffini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Angelika Jakobi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "6092f859-05fe-475d-b914-3c1a6534e6b9", "fullTitle": "Down to Earth: A Memoir", "doi": "https://doi.org/10.21983/P3.0306.1.00", "publicationDate": "2020-10-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "G\u00edsli P\u00e1lsson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna Yates", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Katrina Downs-Rose", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "ac6acc15-6927-4cef-95d3-1c71183ef2a6", "fullTitle": "Echoes of No Thing: Thinking between Heidegger and D\u014dgen", "doi": "https://doi.org/10.21983/P3.0239.1.00", "publicationDate": "2019-01-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Nico Jenkins", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "2658fe95-2df3-4e7d-8df6-e86c18359a23", "fullTitle": "Ephemeral Coast, S. Wales", "doi": "https://doi.org/10.21983/P3.0079.1.00", "publicationDate": "2014-11-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Celina Jeffery", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "98ce9caa-487e-4391-86c9-e5d8129be5b6", "fullTitle": "Essays on the Peripheries", "doi": "https://doi.org/10.21983/P3.0291.1.00", "publicationDate": "2021-04-22", "place": "Earth, Milky Way", "contributions": [{"fullName": "Peter Valente", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "19b32470-bf29-48e1-99db-c08ef90516a9", "fullTitle": "Everyday Cinema: The Films of Marc Lafia", "doi": "https://doi.org/10.21983/P3.0164.1.00", "publicationDate": "2017-01-31", "place": "Earth, Milky Way", "contributions": [{"fullName": "Marc Lafia", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "859e72c3-8159-48e4-b2f0-842f3400cb8d", "fullTitle": "Extraterritorialities in Occupied Worlds", "doi": "https://doi.org/10.21983/P3.0131.1.00", "publicationDate": "2016-02-16", "place": "Earth, Milky Way", "contributions": [{"fullName": "Ruti Sela Maayan Amir", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1b870455-0b99-4d0e-af22-49f4ebbb6493", "fullTitle": "Finding Room in Beirut: Places of the Everyday", "doi": "https://doi.org/10.21983/P3.0243.1.00", "publicationDate": "2019-02-08", "place": "Earth, Milky Way", "contributions": [{"fullName": "Carole L\u00e9vesque", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6ca16a49-7c95-4c81-b8f0-8f3c7e42de7d", "fullTitle": "Flash + Cube (1965\u20131975)", "doi": "https://doi.org/10.21983/P3.0036.1.00", "publicationDate": "2013-07-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marget Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "7fbc96cf-4c88-4e70-b1fe-d4e69324184a", "fullTitle": "Flash + Cube (1965\u20131975)", "doi": null, "publicationDate": "2012-01-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Marget Long", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f4a04558-958a-43da-b009-d5b7580c532f", "fullTitle": "Follow for Now, Volume 2: More Interviews with Friends and Heroes", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Roy Christopher", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97a2ac65-5b1b-4ab8-8588-db8340f04d27", "fullTitle": "Fuckhead", "doi": "https://doi.org/10.21983/P3.0048.1.00", "publicationDate": "2013-09-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Rawson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "f3294e78-9a12-49ff-983e-ed6154ff621e", "fullTitle": "Gender Trouble Couplets, Volume 1", "doi": "https://doi.org/10.21983/P3.0266.1.00", "publicationDate": "2019-11-15", "place": "Earth, Milky Way", "contributions": [{"fullName": "A.W. Strouse", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Anna M. K\u0142osowska", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "c80467d8-d472-4643-9a50-4ac489da14dd", "fullTitle": "Geographies of Identity", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Jill Darling", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "bbe77bbb-0242-46d7-92d2-cfd35c17fe8f", "fullTitle": "Heathen Earth: Trumpism and Political Ecology", "doi": "https://doi.org/10.21983/P3.0170.1.00", "publicationDate": "2017-05-09", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kyle McGee", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "875a78d7-fad2-4c22-bb04-35e0456b6efa", "fullTitle": "Heavy Processing (More than a Feeling)", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "T.L. Cowan", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jasmine Rault", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7f72c34d-4515-42eb-a32e-38fe74217b70", "fullTitle": "Hephaestus Reloaded: Composed for Ten Hands / Efesto Reloaded: Composizioni per 10 mani", "doi": "https://doi.org/10.21983/P3.0258.1.00", "publicationDate": "2019-12-13", "place": "Earth, Milky Way", "contributions": [{"fullName": "Adam Berg", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Brunella Antomarini", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Miltos Maneta", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Vladimir D\u2019Amora", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Pietro Traversa", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 8}, {"fullName": "Patrick Camiller", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 7}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 6}]}, {"workId": "b63ffeb5-7906-4c74-8ec2-68cbe87f593c", "fullTitle": "History According to Cattle", "doi": "https://doi.org/10.21983/P3.0116.1.00", "publicationDate": "2015-10-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Terike Haapoja", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Laura Gustafsson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "4f46d026-49c6-4319-b79a-a6f70d412b5c", "fullTitle": "Homotopia? Gay Identity, Sameness & the Politics of Desire", "doi": "https://doi.org/10.21983/P3.0124.1.00", "publicationDate": "2015-12-25", "place": "Brooklyn, NY", "contributions": [{"fullName": "Jonathan Kemp", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b0257269-5ca3-40b3-b4e1-90f66baddb88", "fullTitle": "Humid, All Too Humid: Overheated Observations", "doi": "https://doi.org/10.21983/P3.0132.1.00", "publicationDate": "2016-02-25", "place": "Earth, Milky Way", "contributions": [{"fullName": "Dominic Pettman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "241f9c62-26be-4d0f-864b-ad4b243a03c3", "fullTitle": "Imperial Physique", "doi": "https://doi.org/10.21983/P3.0268.1.00", "publicationDate": "2019-11-19", "place": "Earth, Milky Way", "contributions": [{"fullName": "JH Phrydas", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "aeed0683-e022-42d0-a954-f9f36afc4bbf", "fullTitle": "Incomparable Poetry: An Essay on the Financial Crisis of 2007\u20132008 and Irish Literature", "doi": "https://doi.org/10.21983/P3.0286.1.00", "publicationDate": "2020-05-14", "place": "Earth, Milky Way", "contributions": [{"fullName": "Robert Kiely", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "5ec826f5-18ab-498c-8b66-bd288618df15", "fullTitle": "Insurrectionary Infrastructures", "doi": "https://doi.org/10.21983/P3.0200.1.00", "publicationDate": "2018-05-02", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jeff Shantz", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "89990379-94c2-4590-9037-cbd5052694a4", "fullTitle": "Intimate Bureaucracies", "doi": "https://doi.org/10.21983/P3.0005.1.00", "publicationDate": "2012-03-09", "place": "Brooklyn, NY", "contributions": [{"fullName": "dj readies", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "85a2a2fe-d515-4784-b451-d26ec4c62a4f", "fullTitle": "Iteration:Again: 13 Public Art Projects across Tasmania", "doi": "https://doi.org/10.21983/P3.0037.1.00", "publicationDate": "2013-07-02", "place": "Brooklyn, NY", "contributions": [{"fullName": "David Cross", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael Edwards", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "f3db2a03-75db-4837-af31-4bb0cb189fa2", "fullTitle": "Itinerant Philosophy: On Alphonso Lingis", "doi": "https://doi.org/10.21983/P3.0073.1.00", "publicationDate": "2014-08-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Tom Sparrow", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Bobby George", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1376b0f4-e967-4a6f-8d7d-8ba876bbbdde", "fullTitle": "Itinerant Spectator/Itinerant Spectacle", "doi": "https://doi.org/10.21983/P3.0056.1.00", "publicationDate": "2013-12-20", "place": "Brooklyn, NY", "contributions": [{"fullName": "P.A. Skantze", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "da814d9f-14ff-4660-acfe-52ac2a2058fa", "fullTitle": "Journal of Badiou Studies 3: On Ethics", "doi": "https://doi.org/10.21983/P3.0070.1.00", "publicationDate": "2014-06-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Arthur Rose", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Nicol\u00f2 Fazioni", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "7e2e26fd-4b0b-4c0b-a1fa-278524c43757", "fullTitle": "Journal of Badiou Studies 5: Architheater", "doi": "https://doi.org/10.21983/P3.0173.1.00", "publicationDate": "2017-07-07", "place": "Earth, Milky Way", "contributions": [{"fullName": "Arthur Rose", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Michael J. Kelly", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Adi Efal-Lautenschl\u00e4ger", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "d2e40ec1-5c2a-404d-8e9f-6727c7c178dc", "fullTitle": "Kill Boxes: Facing the Legacy of US-Sponsored Torture, Indefinite Detention, and Drone Warfare", "doi": "https://doi.org/10.21983/P3.0166.1.00", "publicationDate": "2017-03-02", "place": "Earth, Milky Way", "contributions": [{"fullName": "Elisabeth Weber", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Richard Falk", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "75693fd0-e93a-4fc3-b82e-4c83a11f28b1", "fullTitle": "Knocking the Hustle: Against the Neoliberal Turn in Black Politics", "doi": "https://doi.org/10.21983/P3.0121.1.00", "publicationDate": "2015-12-10", "place": "Brooklyn, NY", "contributions": [{"fullName": "Lester K. Spence", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed3ea389-5d5c-430c-9453-814ed94e027b", "fullTitle": "Knowledge, Spirit, Law, Book 1: Radical Scholarship", "doi": "https://doi.org/10.21983/P3.0123.1.00", "publicationDate": "2015-12-24", "place": "Brooklyn, NY", "contributions": [{"fullName": "Gavin Keeney", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "d0d59741-4866-42c3-8528-f65c3da3ffdd", "fullTitle": "Language Parasites: Of Phorontology", "doi": "https://doi.org/10.21983/P3.0169.1.00", "publicationDate": "2017-05-04", "place": "Earth, Milky Way", "contributions": [{"fullName": "Sean Braune", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "1a71ecd5-c868-44af-9b53-b45888fb241c", "fullTitle": "Lapidari 1: Texts", "doi": "https://doi.org/10.21983/P3.0094.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonida Gashi", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "df518095-84ff-4138-b2f9-5d8fe6ddf53a", "fullTitle": "Lapidari 2: Images, Part I", "doi": "https://doi.org/10.21983/P3.0091.1.00", "publicationDate": "2015-02-15", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "a9d68f12-1de4-4c08-84b1-fe9a786ab47f", "fullTitle": "Lapidari 3: Images, Part II", "doi": "https://doi.org/10.21983/P3.0092.1.00", "publicationDate": "2015-02-16", "place": "Brooklyn, NY", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "08788fe1-c17d-4f6b-aeab-c81aa3036940", "fullTitle": "Left Bank Dream", "doi": "https://doi.org/10.21983/P3.0084.1.00", "publicationDate": "2014-12-26", "place": "Brooklyn, NY", "contributions": [{"fullName": "Beryl Scholssman", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b4d68a6d-01fb-48f1-9f64-1fcdaaf1cdfd", "fullTitle": "Leper Creativity: Cyclonopedia Symposium", "doi": "https://doi.org/10.21983/P3.0017.1.00", "publicationDate": "2012-12-22", "place": "Brooklyn, NY", "contributions": [{"fullName": "Eugene Thacker", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Nicola Masciandaro", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Edward Keller", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "00e012c5-9232-472c-bd8b-8ca4ea6d1275", "fullTitle": "Li Bo Unkempt", "doi": "https://doi.org/10.21983/P3.0322.1.00", "publicationDate": "2021-03-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kidder Smith", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Kidder Smith", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Mike Zhai", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Traktung Yeshe Dorje", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 4}, {"fullName": "Maria Dolgenas", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 5}]}, {"workId": "534c3d13-b18b-4be5-91e6-768c0cf09361", "fullTitle": "Living with Monsters", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Ilana Gershon", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Yasmine Musharbash", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "636a5aa6-1d37-4cd2-8742-4dcad8c67e0c", "fullTitle": "Love Don't Need a Reason: The Life & Music of Michael Callen", "doi": "https://doi.org/10.21983/P3.0297.1.00", "publicationDate": "2020-11-05", "place": "Earth, Milky Way", "contributions": [{"fullName": "Matthew J.\n Jones", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6dcf29ea-76c1-4121-ad7f-2341574c45fe", "fullTitle": "Luminol Theory", "doi": "https://doi.org/10.21983/P3.0177.1.00", "publicationDate": "2017-08-24", "place": "Earth, Milky Way", "contributions": [{"fullName": "Laura E. Joyce", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "ed96eea8-82c6-46c5-a19b-dad5e45962c6", "fullTitle": "Make and Let Die: Untimely Sovereignties", "doi": "https://doi.org/10.21983/P3.0136.1.00", "publicationDate": "2016-03-10", "place": "Earth, Milky Way", "contributions": [{"fullName": "Kathleen Biddick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Eileen A. Joy", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "003137ea-4fe6-470d-8bd3-f936ad065f3c", "fullTitle": "Making the Geologic Now: Responses to Material Conditions of Contemporary Life", "doi": "https://doi.org/10.21983/P3.0014.1.00", "publicationDate": "2012-12-04", "place": "Brooklyn, NY", "contributions": [{"fullName": "Elisabeth Ellsworth", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jamie Kruse", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "35ed7096-8218-43d7-a572-6453c9892ed1", "fullTitle": "Manifesto for a Post-Critical Pedagogy", "doi": "https://doi.org/10.21983/P3.0193.1.00", "publicationDate": "2018-01-11", "place": "Earth, Milky Way", "contributions": [{"fullName": "Piotr Zamojski", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Joris Vlieghe", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Naomi Hodgson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": null, "imprintId": "3437ff40-3bff-4cda-9f0b-1003d2980335", "imprintName": "Risking Education", "updatedAt": "2021-07-06T17:43:41.987789+00:00", "createdAt": "2021-07-06T17:43:41.987789+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "a01f41d6-1da8-4b0b-87b4-82ecc41c6d55", "fullTitle": "Nothing As We Need It: A Chimera", "doi": "https://doi.org/10.53288/0382.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Daniela Cascella", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/speculations/", "imprintId": "dcf8d636-38ae-4a63-bae1-40a61b5a3417", "imprintName": "Speculations", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "03da5b84-80ba-48bc-89b9-b63fc56b364b", "fullTitle": "Speculations", "doi": "https://doi.org/10.21983/P3.0343.1.00", "publicationDate": "2020-07-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c00d9a0c-320d-4dfb-ba0c-d1adbdb491ef", "fullTitle": "Speculations 3", "doi": "https://doi.org/10.21983/P3.0010.1.00", "publicationDate": "2012-09-03", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "2c71d808-d1a7-4918-afbb-2dfc121e7768", "fullTitle": "Speculations II", "doi": "https://doi.org/10.21983/P3.0344.1.00", "publicationDate": "2020-07-30", "place": "Earth, Milky Way", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}]}, {"workId": "ee2cb855-4c94-4176-b62c-3114985dd84e", "fullTitle": "Speculations IV: Speculative Realism", "doi": "https://doi.org/10.21983/P3.0032.1.00", "publicationDate": "2013-06-05", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Paul J. Ennis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 4}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Thomas Gokey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 5}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "435a1db3-1bbb-44b2-9368-7b2fd8a4e63e", "fullTitle": "Speculations VI", "doi": "https://doi.org/10.21983/P3.0122.1.00", "publicationDate": "2015-12-12", "place": "Brooklyn, NY", "contributions": [{"fullName": "Michael Austin", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Robert Jackson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Fabio Gironi", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/thought-crimes/", "imprintId": "f2dc7495-17af-4d8a-9306-168fc6fa1f41", "imprintName": "Thought | Crimes", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "1bba80bd-2efd-41a2-9b09-4ff8da0efeb9", "fullTitle": "New Developments in Anarchist Studies", "doi": "https://doi.org/10.21983/P3.0349.1.00", "publicationDate": "2015-06-13", "place": "Brooklyn, NY", "contributions": [{"fullName": "pj lilley", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jeff Shantz", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "5a1cd53e-640b-46e7-82a6-d95bc4907e36", "fullTitle": "The Spectacle of the False Flag: Parapolitics from JFK to Watergate", "doi": "https://doi.org/10.21983/P3.0347.1.00", "publicationDate": "2014-03-01", "place": "Brooklyn, NY", "contributions": [{"fullName": "Eric Wilson", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Guido Giacomo Preparata", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Jeff Shantz", "contributionType": "PREFACE_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "c8245465-2937-40fd-9c3e-7bd33deef477", "fullTitle": "Who Killed the Berkeley School? Struggles Over Radical Criminology ", "doi": "https://doi.org/10.21983/P3.0348.1.00", "publicationDate": "2014-04-21", "place": "Brooklyn, NY", "contributions": [{"fullName": "Julia Schwendinger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Herman Schwendinger", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jeff Shantz", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/tiny-collections/", "imprintId": "be4c8448-93c8-4146-8d9c-84d121bc4bec", "imprintName": "Tiny Collections", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "501a8862-dc30-4d1e-ab47-deb9f5579678", "fullTitle": "Closer to Dust", "doi": "https://doi.org/10.53288/0324.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Sara A. Rich", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "771e1cde-d224-4cb6-bac7-7f5ef4d1a405", "fullTitle": "Coconuts: A Tiny History", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Kathleen E. Kennedy", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "20d15631-f886-43a0-b00b-b62426710bdf", "fullTitle": "Elemental Disappearances", "doi": "https://doi.org/10.21983/P3.0157.1.00", "publicationDate": "2016-11-28", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jason Bahbak Mohaghegh", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Dejan Luki\u0107", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "177e3717-4c07-4f31-9318-616ad3b71e89", "fullTitle": "Sea Monsters: Things from the Sea, Volume 2", "doi": "https://doi.org/10.21983/P3.0182.1.00", "publicationDate": "2017-09-29", "place": "Earth, Milky Way", "contributions": [{"fullName": "Asa Simon Mittman", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Thea Tomaini", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6dd15dd7-ae8c-4438-a597-7c99d5be4138", "fullTitle": "Walk on the Beach: Things from the Sea, Volume 1", "doi": "https://doi.org/10.21983/P3.0143.1.00", "publicationDate": "2016-06-17", "place": "Earth, Milky Way", "contributions": [{"fullName": "Maggie M. Williams", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Karen Eileen Overbey", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}], "__typename": "Imprint"}, {"imprintUrl": "https://punctumbooks.com/imprints/uitgeverij/", "imprintId": "e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1", "imprintName": "Uitgeverij", "updatedAt": "2021-01-07T16:32:40.853895+00:00", "createdAt": "2021-01-07T16:32:40.853895+00:00", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5"}, "works": [{"workId": "b5c810e1-c847-4553-a24e-9893164d9786", "fullTitle": "(((", "doi": "https://doi.org/10.53288/0370.1.00", "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 3}, {"fullName": "Gen Ueda", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "df9bf011-efaf-49a7-9497-2a4d4cfde9e8", "fullTitle": "An Anthology of Asemic Handwriting", "doi": "https://doi.org/10.21983/P3.0220.1.00", "publicationDate": "2013-08-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Michael Jacobson", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Tim Gaze", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "8b77c06a-3c1c-48ac-a32e-466ef37f293e", "fullTitle": "A Neo Tropical Companion", "doi": "https://doi.org/10.21983/P3.0217.1.00", "publicationDate": "2012-01-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jamie Stewart", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "c3c09f99-71f9-431c-b0f4-ff30c3f7fe11", "fullTitle": "Continuum: Writings on Poetry as Artistic Practice", "doi": "https://doi.org/10.21983/P3.0229.1.00", "publicationDate": "2015-11-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "6c30545e-539b-419a-8b96-5f6c475bab9e", "fullTitle": "Disrupting the Digital Humanities", "doi": "https://doi.org/10.21983/P3.0230.1.00", "publicationDate": "2018-11-06", "place": "Earth, Milky Way", "contributions": [{"fullName": "Jesse Stommel", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Dorothy Kim", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "dfe575e1-2836-43f3-a11b-316af9509612", "fullTitle": "Exegesis of a Renunciation \u2013 Esegesi di una rinuncia", "doi": "https://doi.org/10.21983/P3.0226.1.00", "publicationDate": "2014-10-14", "place": "The Hague/Tirana", "contributions": [{"fullName": "Francesco Aprile", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Bartolom\u00e9 Ferrando", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 2}, {"fullName": "Caggiula Cristiano", "contributionType": "AFTERWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "a9b27739-0d29-4238-8a41-47b3ac2d5bd5", "fullTitle": "Filial Arcade & Other Poems", "doi": "https://doi.org/10.21983/P3.0223.1.00", "publicationDate": "2013-12-21", "place": "The Hague/Tirana", "contributions": [{"fullName": "Adam Staley Groves", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Marco Mazzi", "contributionType": "PHOTOGRAPHER", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "c2c22cdf-b9d5-406d-9127-45cea8e741b1", "fullTitle": "Hippolytus", "doi": "https://doi.org/10.21983/P3.0218.1.00", "publicationDate": "2012-08-21", "place": "The Hague/Tirana", "contributions": [{"fullName": "Euripides", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sean Gurd", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "ebeae9d6-7543-4cd4-9fa9-c39c43ba0d4b", "fullTitle": "Men in A\u00efda", "doi": "https://doi.org/10.21983/P3.0224.0.00", "publicationDate": "2014-12-31", "place": "The Hague/Tirana", "contributions": [{"fullName": "David J. Melnick", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sean Gurd", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}]}, {"workId": "d24a0567-d430-4768-8c4d-1b9d59394af2", "fullTitle": "On Blinking", "doi": "https://doi.org/10.21983/P3.0219.1.00", "publicationDate": "2012-08-23", "place": "The Hague/Tirana", "contributions": [{"fullName": "Sarah Brigid Hannis", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeremy Fernando", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "97d205c8-32f0-4e64-a7df-bf56334be638", "fullTitle": "paq'batlh: A Klingon Epic", "doi": null, "publicationDate": null, "place": "Earth, Milky Way", "contributions": [{"fullName": "Floris Sch\u00f6nfeld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. Van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Kees Ligtelijn", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marc Okrand", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "e81ef154-5bc3-481b-9083-64fd7aeb7575", "fullTitle": "paq'batlh: The Klingon Epic", "doi": "https://doi.org/10.21983/P3.0215.1.00", "publicationDate": "2011-10-10", "place": "The Hague/Tirana", "contributions": [{"fullName": "Floris Sch\u00f6nfeld", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vincent W.J. Van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 3}, {"fullName": "Kees Ligtelijn", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Marc Okrand", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 4}]}, {"workId": "119f1640-dfb4-488f-a564-ef507d74b72d", "fullTitle": "Pen in the Park: A Resistance Fairytale \u2013 Pen Parkta: Bir Direni\u015f Masal\u0131", "doi": "https://doi.org/10.21983/P3.0225.1.00", "publicationDate": "2014-02-12", "place": "The Hague/Tirana", "contributions": [{"fullName": "Ra\u015fel Meseri", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Sanne Karssenberg", "contributionType": "ILUSTRATOR", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "0cb39600-2fd2-4a7a-9d3a-6d92b8e32e9e", "fullTitle": "Poetry from Beyond the Grave", "doi": "https://doi.org/10.21983/P3.0222.1.00", "publicationDate": "2013-05-10", "place": "The Hague/Tirana", "contributions": [{"fullName": "Francisco C\u00e2ndido \"Chico\" Xavier", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Vitor Peqeuno", "contributionType": "TRANSLATOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "Jeremy Fernando", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 3}]}, {"workId": "69365c88-4571-45f3-8770-5a94f7c9badc", "fullTitle": "Poetry Vocare", "doi": "https://doi.org/10.21983/P3.0213.1.00", "publicationDate": "2011-01-23", "place": "The Hague/Tirana", "contributions": [{"fullName": "Adam Staley Groves", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Judith Balso", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "bc283f71-9f37-47c4-b30b-8ed9f3be9f9c", "fullTitle": "The Guerrilla I Like a Poet \u2013 Ang Gerilya Ay Tulad ng Makata", "doi": "https://doi.org/10.21983/P3.0221.1.00", "publicationDate": "2013-09-27", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jose Maria Sison", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Jonas Staal", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "7be9aa8c-b8af-4b2f-96ff-16e4532f2b83", "fullTitle": "The Miracle of Saint Mina \u2013 Gis Miinan Nokkor", "doi": "https://doi.org/10.21983/P3.0216.1.00", "publicationDate": "2012-01-05", "place": "The Hague/Tirana", "contributions": [{"fullName": "Vincent W.J. van Gerven Oei", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 2}, {"fullName": "El-Shafie El-Guzuuli", "contributionType": "EDITOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "b55c95a7-ce6e-4cfb-8945-cab4e04001e5", "fullTitle": "To Be, or Not to Be: Paraphrased", "doi": "https://doi.org/10.21983/P3.0227.1.00", "publicationDate": "2016-06-17", "place": "The Hague/Tirana", "contributions": [{"fullName": "Bardsley Rosenbridge", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}]}, {"workId": "367397db-bcb4-4f0e-9185-4be74c119c19", "fullTitle": "Writing Art", "doi": "https://doi.org/10.21983/P3.0228.1.00", "publicationDate": "2015-11-26", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Alessandro De Francesco", "contributionType": "INTRODUCTION_BY", "mainContribution": false, "contributionOrdinal": 2}]}, {"workId": "6a109b6a-55e9-4dd5-b670-61926c10e611", "fullTitle": "Writing Death", "doi": "https://doi.org/10.21983/P3.0214.1.00", "publicationDate": "2011-06-06", "place": "The Hague/Tirana", "contributions": [{"fullName": "Jeremy Fernando", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1}, {"fullName": "Avital Ronell", "contributionType": "FOREWORD_BY", "mainContribution": false, "contributionOrdinal": 2}]}], "__typename": "Imprint"}] diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work.json b/thothlibrary/thoth-0_4_2/tests/fixtures/work.json index 1646e51..39a276e 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/work.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work.json @@ -1 +1 @@ -{"data":{"work":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} +{"data":{"work":{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127.0,"height":203.0,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle index a0ede26..083b4df 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/work.pickle @@ -1 +1 @@ -{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} +{"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127.0, "height": 203.0, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json index 5a529e4..b84e068 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.json @@ -1 +1 @@ -{"data":{"workByDoi":{"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} +{"data":{"workByDoi":{"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127.0,"height":203.0,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle index b7a1a49..1798bfa 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/workByDoi.pickle @@ -1 +1 @@ -{"workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} +{"workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127.0, "height": 203.0, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json index dac1aab..60b5a59 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/works.json +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works.json @@ -1 +1 @@ -{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133,"height":203,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"workId":"b5c810e1-c847-4553-a24e-9893164d9786","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-71-4","publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":3,"__typename":"Contribution"},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"contributionOrdinal":2,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127,"height":203,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}]}} +{"data":{"works":[{"workType":"MONOGRAPH","workStatus":"FORTHCOMING","fullTitle":"(((","title":"(((","subtitle":null,"reference":"0370","edition":1,"imprintId":"e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1","doi":"https://doi.org/10.53288/0370.1.00","publicationDate":null,"place":"Earth, Milky Way","width":133.0,"height":203.0,"pageCount":326,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"De Francesco, Alessandro","landingPage":"https://punctumbooks.com/titles/three-opening-parentheses/","lccn":"2021942134","oclc":null,"shortAbstract":null,"longAbstract":null,"generalNote":null,"toc":null,"workId":"b5c810e1-c847-4553-a24e-9893164d9786","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg","coverCaption":null,"publications":[{"isbn":"978-1-953035-70-7","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-71-4","publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Alessandro De Francesco","contributionType":"AUTHOR","mainContribution":true,"institution":null,"contributor":{"contributorId":"9acfa379-5124-4684-8ce2-8f1235699bb6","orcid":null,"firstName":"Alessandro","lastName":"De Francesco"},"contributionId":"937b81a4-865f-4ada-9ccc-9fc962eb19ee","contributionOrdinal":1,"__typename":"Contribution"},{"fullName":"Andreas Burckhardt","contributionType":"TRANSLATOR","mainContribution":false,"institution":null,"contributor":{"contributorId":"1cfe6939-2545-4fce-a179-b541d9d3e395","orcid":null,"firstName":"Andreas","lastName":"Burckhardt"},"contributionId":"f723d930-77e6-475e-9740-564f29d9d222","contributionOrdinal":3,"__typename":"Contribution"},{"fullName":"Gen Ueda","contributionType":"TRANSLATOR","mainContribution":false,"institution":null,"contributor":{"contributorId":"f5ee51a8-0f27-4375-9450-7128dae26be4","orcid":null,"firstName":"Gen","lastName":"Ueda"},"contributionId":"34a99e53-1be7-4bcd-b6f0-95cef389ce51","contributionOrdinal":2,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"},{"workType":"MONOGRAPH","workStatus":"ACTIVE","fullTitle":"A Bibliography for After Jews and Arabs","title":"A Bibliography for After Jews and Arabs","subtitle":null,"reference":"0314","edition":1,"imprintId":"94c07a94-6a51-4220-983a-2d760dac0f89","doi":"https://doi.org/10.21983/P3.0314.1.00","publicationDate":"2021-02-04","place":"Earth, Milky Way","width":127.0,"height":203.0,"pageCount":120,"pageBreakdown":null,"imageCount":null,"tableCount":null,"audioCount":null,"videoCount":null,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","copyrightHolder":"Alcalay, Ammiel","landingPage":"https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/","lccn":"2021931014","oclc":null,"shortAbstract":null,"longAbstract":"Ammiel Alcalay’s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines—including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology—the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay’s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn’t appear until 1993. In addition, when the book was published, there wasn’t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In “Behind the Scenes: Before After Jews and Arabs,” Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in “On a Bibliography for After Jews and Arabs,” Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.","generalNote":null,"toc":null,"workId":"e0f748b2-984f-45cc-8b9e-13989c31dda4","coverUrl":"https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png","coverCaption":null,"publications":[{"isbn":"978-1-953035-34-9","publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":null,"publicationType":"PAPERBACK","__typename":"Publication"},{"isbn":"978-1-953035-35-6","publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"},{"isbn":null,"publicationType":"PDF","__typename":"Publication"}],"contributions":[{"fullName":"Ammiel Alcalay","contributionType":"AUTHOR","mainContribution":true,"institution":null,"contributor":{"contributorId":"0e1f3e68-2fc8-452a-a1fe-6e1918be6186","orcid":null,"firstName":"Ammiel","lastName":"Alcalay"},"contributionId":"d664e9f3-892f-4770-876a-c267f85eaa20","contributionOrdinal":1,"__typename":"Contribution"}],"imprint":{"__typename":"Imprint","publisher":{"publisherName":"punctum books","publisherId":"9c41b13c-cecc-4f6a-a151-be4682915ef5","__typename":"Publisher"}},"__typename":"Work"}]}} diff --git a/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle b/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle index 37f1039..c966263 100644 --- a/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle +++ b/thothlibrary/thoth-0_4_2/tests/fixtures/works.pickle @@ -1 +1 @@ -[{"workType": "MONOGRAPH", "workStatus": "FORTHCOMING", "fullTitle": "(((", "title": "(((", "subtitle": null, "reference": "0370", "edition": 1, "imprintId": "e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1", "doi": "https://doi.org/10.53288/0370.1.00", "publicationDate": null, "place": "Earth, Milky Way", "width": 133, "height": 203, "pageCount": 326, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "De Francesco, Alessandro", "landingPage": "https://punctumbooks.com/titles/three-opening-parentheses/", "lccn": "2021942134", "oclc": null, "shortAbstract": null, "longAbstract": null, "generalNote": null, "toc": null, "workId": "b5c810e1-c847-4553-a24e-9893164d9786", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg", "coverCaption": null, "publications": [{"isbn": "978-1-953035-70-7", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-71-4", "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 3, "__typename": "Contribution"}, {"fullName": "Gen Ueda", "contributionType": "TRANSLATOR", "mainContribution": false, "contributionOrdinal": 2, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"}, {"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127, "height": 203, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"}] +[{"workType": "MONOGRAPH", "workStatus": "FORTHCOMING", "fullTitle": "(((", "title": "(((", "subtitle": null, "reference": "0370", "edition": 1, "imprintId": "e76c3f59-c8ae-4887-b62c-43ce7b8dbdb1", "doi": "https://doi.org/10.53288/0370.1.00", "publicationDate": null, "place": "Earth, Milky Way", "width": 133.0, "height": 203.0, "pageCount": 326, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "De Francesco, Alessandro", "landingPage": "https://punctumbooks.com/titles/three-opening-parentheses/", "lccn": "2021942134", "oclc": null, "shortAbstract": null, "longAbstract": null, "generalNote": null, "toc": null, "workId": "b5c810e1-c847-4553-a24e-9893164d9786", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/06/210609-cover-front-web.jpg", "coverCaption": null, "publications": [{"isbn": "978-1-953035-70-7", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-71-4", "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Alessandro De Francesco", "contributionType": "AUTHOR", "mainContribution": true, "institution": null, "contributor": {"contributorId": "9acfa379-5124-4684-8ce2-8f1235699bb6", "orcid": null, "firstName": "Alessandro", "lastName": "De Francesco"}, "contributionId": "937b81a4-865f-4ada-9ccc-9fc962eb19ee", "contributionOrdinal": 1, "__typename": "Contribution"}, {"fullName": "Andreas Burckhardt", "contributionType": "TRANSLATOR", "mainContribution": false, "institution": null, "contributor": {"contributorId": "1cfe6939-2545-4fce-a179-b541d9d3e395", "orcid": null, "firstName": "Andreas", "lastName": "Burckhardt"}, "contributionId": "f723d930-77e6-475e-9740-564f29d9d222", "contributionOrdinal": 3, "__typename": "Contribution"}, {"fullName": "Gen Ueda", "contributionType": "TRANSLATOR", "mainContribution": false, "institution": null, "contributor": {"contributorId": "f5ee51a8-0f27-4375-9450-7128dae26be4", "orcid": null, "firstName": "Gen", "lastName": "Ueda"}, "contributionId": "34a99e53-1be7-4bcd-b6f0-95cef389ce51", "contributionOrdinal": 2, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"}, {"workType": "MONOGRAPH", "workStatus": "ACTIVE", "fullTitle": "A Bibliography for After Jews and Arabs", "title": "A Bibliography for After Jews and Arabs", "subtitle": null, "reference": "0314", "edition": 1, "imprintId": "94c07a94-6a51-4220-983a-2d760dac0f89", "doi": "https://doi.org/10.21983/P3.0314.1.00", "publicationDate": "2021-02-04", "place": "Earth, Milky Way", "width": 127.0, "height": 203.0, "pageCount": 120, "pageBreakdown": null, "imageCount": null, "tableCount": null, "audioCount": null, "videoCount": null, "license": "https://creativecommons.org/licenses/by-nc-sa/4.0/", "copyrightHolder": "Alcalay, Ammiel", "landingPage": "https://punctumbooks.com/titles/a-bibliography-for-after-jews-and-arabs/", "lccn": "2021931014", "oclc": null, "shortAbstract": null, "longAbstract": "Ammiel Alcalay\u2019s groundbreaking work, After Jews and Arabs, published in 1993, redrew the geographic, political, cultural, and emotional map of relations between Jews and Arabs in the Levantine/Mediterranean world over a thousand-year period. Based on over a decade of research and fieldwork in many disciplines\u2014including history and historiography; anthropology, ethnography, and ethnomusicology; political economy and geography; linguistics; philosophy; and the history of science and technology\u2014the book presented a radically different perspective than that presented by received opinion.\n\nGiven the radical and iconoclastic nature of Alcalay\u2019s perspective, After Jews and Arabs met great resistance in attempts to publish it. Though completed and already circulating in 1989, it didn\u2019t appear until 1993. In addition, when the book was published, there wasn\u2019t enough space to include its original bibliography, a foundational part of the project.\n\nA Bibliography for After Jews and Arabs presents the original bibliography, as completed in 1992, without changes, as a glimpse into the historical record of a unique scholarly, political, poetic, and cultural journey. The bibliography itself had roots in research begun in the late 1970s and demonstrates a very wide arc.\n\nIn addition to the bibliography, we include two accompanying texts here. In \u201cBehind the Scenes: Before After Jews and Arabs,\u201d Alcalay takes us behind the closed doors of the academic process, reprinting the original readers reports and his detailed rebuttals, and in \u201cOn a Bibliography for After Jews and Arabs,\u201d Alcalay contextualizes his own path to the work he undertook, in methodological, historical, and political terms.", "generalNote": null, "toc": null, "workId": "e0f748b2-984f-45cc-8b9e-13989c31dda4", "coverUrl": "https://punctumbooks.com/punctum/wp-content/uploads/2021/01/210106bibliographyafterjewsandarabs-cover-web-front.png", "coverCaption": null, "publications": [{"isbn": "978-1-953035-34-9", "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": null, "publicationType": "PAPERBACK", "__typename": "Publication"}, {"isbn": "978-1-953035-35-6", "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}, {"isbn": null, "publicationType": "PDF", "__typename": "Publication"}], "contributions": [{"fullName": "Ammiel Alcalay", "contributionType": "AUTHOR", "mainContribution": true, "institution": null, "contributor": {"contributorId": "0e1f3e68-2fc8-452a-a1fe-6e1918be6186", "orcid": null, "firstName": "Ammiel", "lastName": "Alcalay"}, "contributionId": "d664e9f3-892f-4770-876a-c267f85eaa20", "contributionOrdinal": 1, "__typename": "Contribution"}], "imprint": {"__typename": "Imprint", "publisher": {"publisherName": "punctum books", "publisherId": "9c41b13c-cecc-4f6a-a151-be4682915ef5", "__typename": "Publisher"}}, "__typename": "Work"}] From a62f19aac3861a6a32b5a09560433f12266f677b Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 15 Aug 2021 12:45:55 +0100 Subject: [PATCH 102/115] Remove import --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 9d34700..27d4a22 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import os from setuptools import setup -from thothlibrary import __version__, __license__ +#from thothlibrary import __version__, __license__ ROOTDIR = os.path.abspath(os.path.dirname(__file__)) @@ -13,15 +13,15 @@ setup( name="thothlibrary", - version=__version__, + version="0.1", description="Python client for Thoth's GraphQL API", - author="Javier Arias", + author="Javier Arias, Martin Paul Eve", author_email="javier@arias.re", packages=["thothlibrary"], install_requires=["graphqlclient", "requests"], long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", - license=__license__, + license="Apache", platforms=["any"], classifiers=[ "Programming Language :: Python :: 3", From 6f2070fcbbbd3c955932878c6010ea5debb6c798 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 15 Aug 2021 13:01:52 +0100 Subject: [PATCH 103/115] Add Munch requirement --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 27d4a22..5b271ed 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ author="Javier Arias, Martin Paul Eve", author_email="javier@arias.re", packages=["thothlibrary"], - install_requires=["graphqlclient", "requests"], + install_requires=["graphqlclient", "requests", "munch"], long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", license="Apache", From 92de5181360ad0ee29556b687e7694bd9ade419e Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 15 Aug 2021 15:12:49 +0100 Subject: [PATCH 104/115] Add fullName to contributor --- thothlibrary/thoth-0_4_2/fixtures/QUERIES | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thothlibrary/thoth-0_4_2/fixtures/QUERIES b/thothlibrary/thoth-0_4_2/fixtures/QUERIES index 40b9fc8..3888d8c 100644 --- a/thothlibrary/thoth-0_4_2/fixtures/QUERIES +++ b/thothlibrary/thoth-0_4_2/fixtures/QUERIES @@ -555,7 +555,7 @@ "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName } contributionId contributionOrdinal __typename }", + "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName fullName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ], @@ -605,7 +605,7 @@ "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", - "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName } contributionId contributionOrdinal __typename }", + "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName fullName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" ], From 3b104d79336105401f8efdbe61a47ad79f20ac83 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 15 Aug 2021 17:40:40 +0100 Subject: [PATCH 105/115] Add subjects to extracted works --- thothlibrary/thoth-0_4_2/fixtures/QUERIES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/thothlibrary/thoth-0_4_2/fixtures/QUERIES b/thothlibrary/thoth-0_4_2/fixtures/QUERIES index 3888d8c..f7025de 100644 --- a/thothlibrary/thoth-0_4_2/fixtures/QUERIES +++ b/thothlibrary/thoth-0_4_2/fixtures/QUERIES @@ -515,6 +515,7 @@ "publications { isbn publicationType __typename }", "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", + "subjects { subjectId, subjectType, subjectCode, subjectOrdinal, __typename }", "__typename" ], "parameters": [ @@ -555,6 +556,7 @@ "coverUrl", "coverCaption", "publications { isbn publicationType __typename }", + "subjects { subjectId, subjectType, subjectCode, subjectOrdinal, __typename }", "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName fullName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", "__typename" @@ -604,6 +606,7 @@ "workId", "coverUrl", "coverCaption", + "subjects { subjectId, subjectType, subjectCode, subjectOrdinal, __typename }", "publications { isbn publicationType __typename }", "contributions { fullName contributionType mainContribution institution contributor { contributorId orcid firstName lastName fullName } contributionId contributionOrdinal __typename }", "imprint { __typename publisher { publisherName publisherId __typename } }", From c82a9bf89c29765df6a2c2bcdf540edfac7cd357 Mon Sep 17 00:00:00 2001 From: Martin Paul Eve Date: Sun, 29 Aug 2021 09:27:34 +0100 Subject: [PATCH 106/115] Add Django support --- README.md | 3 + thothdjango/__init__.py | 0 thothdjango/admin.py | 71 ++++++ thothdjango/management/__init__.py | 0 thothdjango/management/commands/__init__.py | 0 .../management/commands/install_bic.py | 52 ++++ .../management/commands/install_bisac.py | 43 ++++ .../management/commands/install_thema.py | 42 ++++ thothdjango/management/commands/sync_thoth.py | 222 ++++++++++++++++++ thothdjango/models.py | 135 +++++++++++ 10 files changed, 568 insertions(+) create mode 100644 thothdjango/__init__.py create mode 100644 thothdjango/admin.py create mode 100644 thothdjango/management/__init__.py create mode 100644 thothdjango/management/commands/__init__.py create mode 100644 thothdjango/management/commands/install_bic.py create mode 100644 thothdjango/management/commands/install_bisac.py create mode 100644 thothdjango/management/commands/install_thema.py create mode 100644 thothdjango/management/commands/sync_thoth.py create mode 100644 thothdjango/models.py diff --git a/README.md b/README.md index c78b884..ba5009d 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,9 @@ python3 -m thothrest.cli formats --return-json python3 -m thothrest.cli work onix_3.0::project_muse e0f748b2-984f-45cc-8b9e-13989c31dda4 ``` +## Thoth Django +The thothdjango folder includes models, an import routine, subject-code support, and admin procedures to use Thoth in a django app. The import provides unidirectional synchronization from remote Thoth imports to a local database for use in a Django app. + ## Test Suite Tests for GraphQL queries are versioned in the thoth-[ver] folder of thothlibrary. diff --git a/thothdjango/__init__.py b/thothdjango/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothdjango/admin.py b/thothdjango/admin.py new file mode 100644 index 0000000..a0522d0 --- /dev/null +++ b/thothdjango/admin.py @@ -0,0 +1,71 @@ +""" +(c) ΔQ Programming LLP, 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +from django.contrib import admin + +from thoth import models + + +class WorkAdmin(admin.ModelAdmin): + list_display = ('pk', 'full_title', 'doi', 'publisher') + list_filter = ('publisher',) + + +class ThemaAdmin(admin.ModelAdmin): + list_display = ('pk', 'code', 'heading') + + +class BICAdmin(admin.ModelAdmin): + list_display = ('pk', 'code', 'heading') + + +class SubjectAdmin(admin.ModelAdmin): + list_display = ('pk', 'subject_display', 'subject_code', 'subject_type', + 'work') + list_filter = ('subject_type',) + + +class PublisherAdmin(admin.ModelAdmin): + list_display = ('pk', 'publisher_name') + + +class ContributorAdmin(admin.ModelAdmin): + list_display = ('pk', 'full_name') + + +class ContributionAdmin(admin.ModelAdmin): + list_display = ('pk', 'contributor_name', 'contribution_type', 'work_name') + list_filter = ('work__publisher',) + + def contributor_name(self, obj): + if obj.contributor: + return obj.contributor.full_name + else: + "" + + contributor_name.admin_order_field = 'full_name' + contributor_name.short_description = 'Contributor Name' + + def work_name(self, obj): + if obj.contributor: + return obj.work.full_title + else: + return "" + + work_name.admin_order_field = 'full_title' + work_name.short_description = 'Work Name' + + +admin_list = [ + (models.Work, WorkAdmin), + (models.Publisher, PublisherAdmin), + (models.Contributor, ContributorAdmin), + (models.Contribution, ContributionAdmin), + (models.Subject, SubjectAdmin), + (models.Thema, ThemaAdmin), + (models.BIC, BICAdmin), +] + +[admin.site.register(*t) for t in admin_list] diff --git a/thothdjango/management/__init__.py b/thothdjango/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothdjango/management/commands/__init__.py b/thothdjango/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thothdjango/management/commands/install_bic.py b/thothdjango/management/commands/install_bic.py new file mode 100644 index 0000000..7cbe040 --- /dev/null +++ b/thothdjango/management/commands/install_bic.py @@ -0,0 +1,52 @@ +""" +(c) ΔQ Programming LLP, 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +import os +import pathlib + +from django.core.management.base import BaseCommand +import csv + +from thoth.models import BIC + + +class Command(BaseCommand): + """ + A management command that installs BIC code support + """ + + help = "Installs BIC code functionality into Thoth components" + + def handle(self, *args, **options): + script_dir = pathlib.Path(__file__).parent.parent.parent.resolve() + path = os.path.join(script_dir, 'fixtures', 'BIC.csv') + path_quals = os.path.join(script_dir, 'fixtures', 'BICQuals.csv') + + if not os.path.isfile(path) or not os.path.isfile(path_quals): + print('Please place BIC.csv and BICQuals.csv, converted from ' + 'https://www.bic.org.uk/7/BIC-Standard-Subject-Categories/, ' + 'in the thoth/fixtures directory.') + return + + with open(path, newline='') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + bic_model = BIC.objects.get_or_create( + code=row['Code'], + heading=row['Heading'])[0] + + bic_model.save() + + with open(path_quals, newline='') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + bic_model = BIC.objects.get_or_create( + code=row['Code'], + heading=row['Heading'])[0] + + bic_model.save() + + print("BIC fixtures installed. At next Thoth sync, subject codes will " + "be linked to BIC entries.") diff --git a/thothdjango/management/commands/install_bisac.py b/thothdjango/management/commands/install_bisac.py new file mode 100644 index 0000000..75db6f1 --- /dev/null +++ b/thothdjango/management/commands/install_bisac.py @@ -0,0 +1,43 @@ +""" +(c) ΔQ Programming LLP, 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +import os +import pathlib + +from django.core.management.base import BaseCommand +import csv + +from thoth.models import BISAC + + +class Command(BaseCommand): + """ + A management command that installs Bisac code support + """ + + help = "Installs Bisac code functionality into Thoth components" + + def handle(self, *args, **options): + script_dir = pathlib.Path(__file__).parent.parent.parent.resolve() + path = os.path.join(script_dir, 'fixtures', 'bisac.csv') + + if not os.path.isfile(path): + print('Please place bisac.csv, converted from the BISAC mapping at ' + 'https://www.editeur.org/151/Thema/, ' + 'in the thoth/fixtures directory.') + return + + with open(path, newline='') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + + bisac_model = BISAC.objects.get_or_create( + code=row['BISAC Code'], + heading=row['Thema Literal 1'])[0] + + bisac_model.save() + + print("BISAC fixtures installed. At next Thoth sync, subject codes " + "will be linked to BISAC entries.") diff --git a/thothdjango/management/commands/install_thema.py b/thothdjango/management/commands/install_thema.py new file mode 100644 index 0000000..575e213 --- /dev/null +++ b/thothdjango/management/commands/install_thema.py @@ -0,0 +1,42 @@ +""" +(c) ΔQ Programming LLP, 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +import os +import pathlib + +from django.core.management.base import BaseCommand +import csv + +from thoth.models import Thema + + +class Command(BaseCommand): + """ + A management command that installs Thema code support + """ + + help = "Installs Thema code functionality into Thoth components" + + def handle(self, *args, **options): + script_dir = pathlib.Path(__file__).parent.parent.parent.resolve() + path = os.path.join(script_dir, 'fixtures', 'thema.csv') + + if not os.path.isfile(path): + print('Please place thema.csv, converted from ' + 'https://www.editeur.org/151/Thema/, ' + 'in the thoth/fixtures directory.') + return + + with open(path, newline='') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + thema_model = Thema.objects.get_or_create( + code=row['Code'], + heading=row['English Heading'])[0] + + thema_model.save() + + print("Thema fixtures installed. At next Thoth sync, subject codes " + "will be linked to THEMA entries.") diff --git a/thothdjango/management/commands/sync_thoth.py b/thothdjango/management/commands/sync_thoth.py new file mode 100644 index 0000000..29d2b15 --- /dev/null +++ b/thothdjango/management/commands/sync_thoth.py @@ -0,0 +1,222 @@ +""" +(c) ΔQ Programming LLP, 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +from django.core.management.base import BaseCommand +from thothlibrary import ThothClient +from thoth.models import BIC, BISAC, Contribution, Contributor +from thoth.models import Publisher, Subject, Thema, Work + + +class Command(BaseCommand): + """ + A management command that syncs Thoth entries to the local database + """ + + help = "Syncs Thoth metadata to the platform" + + def handle(self, *args, **options): + """ + A management command that syncs Thoth entries to the local database + :param args: command line arguments + :param options: command line options + """ + default_thoth_endpoint = "https://api.thoth.pub" + + # TODO: these should be specified dynamically as you wish in your code + # the dummy code below fetches punctum books and Open Book Publishers + + to_fetch = [{'publisher': '9c41b13c-cecc-4f6a-a151-be4682915ef5', + 'endpoint': default_thoth_endpoint}, + {'publisher': '85fd969a-a16c-480b-b641-cb9adf979c3b', + 'endpoint': default_thoth_endpoint}] + + for thoth_sync in to_fetch: + # a neater way to do this would be to aggregate together all + # requests that share an endpoint. However, that's more complex + # so we just do standard iter here + + client = ThothClient(thoth_endpoint=thoth_sync['endpoint']) + + # lookup the publisher name for friendly display + # this adds an extra API call + publisher = client.publisher(publisher_id=thoth_sync['publisher']) + + # pull the full list of works for each publisher + # as a note: technically, a work is different to a publication + # a publication is a specific format, at a specific price point + print("Fetching works for " + "publisher {0} [{1}]".format(thoth_sync['publisher'], + publisher.publisherName)) + + publisher_model = Publisher.objects.get_or_create( + thoth_id=publisher.publisherId, + thoth_instance=thoth_sync['endpoint'] + )[0] + + publisher_model.publisher_name = publisher.publisherName + publisher_model.save() + + # we can handle a max of 9999 works at any one time + # Thoth does support pagination, but currently has no way of + # precisely querying the expected number of records + works = client.works(limit=9999, publishers='["{0}"]'.format( + publisher.publisherId)) + + self._sync_works(publisher_model, thoth_sync, works) + + self._verify_exists_in_thoth(thoth_sync, works) + + @staticmethod + def _verify_exists_in_thoth(thoth_sync, works): + """ + Verifies that entries in our database are in remote Thoth servers + :param thoth_sync: the Thoth instance + :param works: a list of works from a Thoth instance to check + """ + + works_in_db = Work.objects.filter( + publisher__thoth_id=thoth_sync['publisher']) + + for work in works_in_db: + if any([x for x in works if str(x.workId) == str(work.thoth_id)]): + print("[Verified] {0} exists in Thoth".format(work)) + else: + print("[Unverified] Could not find {0} in Thoth. " + "Deleting.".format(work)) + work.delete() + + def _sync_works(self, publisher_model, thoth_sync, works): + """ + Synchronizes works from the remote Thoth instance + :param publisher_model: the publisher to use + :param thoth_sync: the Thoth instance + :param works: a list of works from a Thoth instance to sync + """ + for work in works: + # build a work model + work_model, created = Work.objects.get_or_create( + thoth_id=work.workId) + work_model.thoth_id = work.workId + work_model.doi = work.doi + work_model.work_type = work.workType + work_model.full_title = work.fullTitle + work_model.cover_url = work.coverUrl + work_model.cover_caption = work.coverCaption + work_model.publisher = publisher_model + work_model.landing_page = work.landingPage + + if work.license: + work_model.license = work.license + + if work.longAbstract: + work_model.long_abstract = work.longAbstract + + if work.shortAbstract: + work_model.short_abstract = work.shortAbstract + + if work.publicationDate: + work_model.published_date = work.publicationDate + + work_model.save() + + self._sync_contributions(thoth_sync, work, work_model) + + self._sync_subjects(thoth_sync, work, work_model) + + @staticmethod + def _sync_subjects(thoth_sync, work, work_model): + """ + Synchronizes Thoth subject codes to the local database + :param thoth_sync: the Thoth sync object + :param work: the work to sync to + :param work_model: the database work model + """ + # save the subjects + for subject in work.subjects: + subject_model = Subject.objects.get_or_create( + thoth_id=subject.subjectId, + thoth_instance=thoth_sync['endpoint'], + work=work_model + )[0] + + subject_model.subject_type = subject.subjectType + subject_model.subject_code = subject.subjectCode + subject_model.subject_ordinal = subject.subjectOrdinal + subject_model.thoth_id = subject.subjectId + + # see if there's a BIC entry + if subject.subjectType == "THEMA": + try: + thema_model = Thema.objects.get( + code=subject.subjectCode + ) + + subject_model.thema_code = thema_model + except Thema.DoesNotExist: + pass + elif subject.subjectType == "BIC": + try: + bic_model = BIC.objects.get( + code=subject.subjectCode + ) + + subject_model.BIC_code = bic_model + except BIC.DoesNotExist: + pass + elif subject.subjectType == "BISAC": + try: + bisac_model = BISAC.objects.get( + code=subject.subjectCode + ) + + subject_model.BISAC_code = bisac_model + except BISAC.DoesNotExist: + pass + + subject_model.save() + + @staticmethod + def _sync_contributions(thoth_sync, work, work_model): + """ + Synchronize contributors from Thoth to the local DB + :param thoth_sync: the Thoth instance + :param work: the work instance + :param work_model: the work model instance + """ + # build the contributions and contributors + for contribution in work.contributions: + # find or build the contributor and then update it + contributor = contribution.contributor + + contributor_model = Contributor.objects.get_or_create( + thoth_id=contributor.contributorId, + thoth_instance=thoth_sync['endpoint'])[0] + + contributor_model.first_name = contributor.firstName + contributor_model.last_name = contributor.lastName + contributor_model.full_name = contributor.fullName + contributor_model.orcid = contributor.orcid + contributor_model.thoth_id = contributor.contributorId + + contributor_model.save() + + # now save the contribution + + contribution_model = Contribution.objects.get_or_create( + thoth_id=contribution.contributionId, + thoth_instance=thoth_sync['endpoint'])[0] + + contribution_model.institution = contribution.institution + contribution_model.contribution_ordinal \ + = contribution.contributionOrdinal + contribution_model.contribution_type = \ + contribution.contributionType + contributor_model.thoth_id = contribution.contributionId + + contribution_model.work = work_model + + contribution_model.contributor = contributor_model + + contribution_model.save() diff --git a/thothdjango/models.py b/thothdjango/models.py new file mode 100644 index 0000000..35d8427 --- /dev/null +++ b/thothdjango/models.py @@ -0,0 +1,135 @@ +""" +(c) ΔQ Programming LLP, 2021 +This program is free software; you may redistribute and/or modify +it under the terms of the Apache License v2.0. +""" +from datetime import datetime + +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class Publisher(models.Model): + publisher_name = models.TextField(blank=True, null=True) + thoth_id = models.UUIDField() + thoth_instance = models.URLField(default='https://api.thoth.pub') + + def __str__(self): + return self.publisher_name + + +class BIC(models.Model): + class Meta: + verbose_name = _("BIC Code") + verbose_name_plural = _("BIC Codes") + code = models.CharField(max_length=20) + heading = models.CharField(max_length=255) + + +class BISAC(models.Model): + class Meta: + verbose_name = _("BISAC Code") + verbose_name_plural = _("BISAC Codes") + code = models.CharField(max_length=20) + heading = models.CharField(max_length=255) + + +class Thema(models.Model): + class Meta: + verbose_name = _("Thema Code") + verbose_name_plural = _("Thema Codes") + + code = models.CharField(max_length=20) + heading = models.CharField(max_length=255) + + +class Work(models.Model): + work_id = models.AutoField(primary_key=True) + work_type = models.CharField(max_length=255, blank=True, null=True) + full_title = models.TextField(blank=True, null=True) + doi = models.CharField(max_length=255, blank=True, null=True) + cover_url = models.URLField(blank=True, null=True) + cover_caption = models.TextField(blank=True, null=True) + thoth_id = models.UUIDField() + thoth_instance = models.URLField(default='https://api.thoth.pub') + landing_page = models.URLField(default=None, null=True, blank=True) + long_abstract = models.TextField(default='') + short_abstract = models.TextField(default='') + publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, + null=True) + license = models.CharField(max_length=255, default='') + published_date = models.CharField(max_length=255, default='n.d.') + + @property + def thoth_export_url(self): + return self.thoth_instance.replace('api', 'export') + + def __str__(self): + try: + dt = datetime.strptime(self.published_date, '%Y-%m-%d') + return '{0} ({1}, {2})'.format(self.full_title, + self.publisher, + dt.year) + except ValueError as e: + return '{0} ({1}, {2})'.format(self.full_title, + self.publisher, + self.published_date) + + +class Subject(models.Model): + thoth_id = models.UUIDField() + thoth_instance = models.URLField(default='https://api.thoth.pub') + subject_type = models.CharField(max_length=255) + subject_ordinal = models.IntegerField(blank=True, null=True) + subject_code = models.CharField(max_length=255) + BIC_code = models.ForeignKey(BIC, null=True, on_delete=models.CASCADE) + thema_code = models.ForeignKey(Thema, null=True, on_delete=models.CASCADE) + BISAC_code = models.ForeignKey(BISAC, null=True, on_delete=models.CASCADE) + work = models.ForeignKey(Work, on_delete=models.CASCADE) + + @property + def subject_display(self): + if self.subject_type == "BIC" and self.BIC_code: + return self.BIC_code.heading + elif self.subject_type == "THEMA" and self.thema_code: + return self.thema_code.heading + elif self.subject_type == "BISAC" and self.BISAC_code: + return self.BISAC_code.heading + else: + return self.subject_code + + +class Contributor(models.Model): + contributor_id = models.AutoField(primary_key=True) + first_name = models.TextField(blank=True, null=True) + last_name = models.TextField(blank=True, null=True) + full_name = models.TextField(blank=True, null=True) + orcid = models.URLField(blank=True, null=True) + thoth_id = models.UUIDField() + thoth_instance = models.URLField(default='https://api.thoth.pub') + + def __str__(self): + return self.full_name + + +class Contribution(models.Model): + contribution_id = models.AutoField(primary_key=True) + institution = models.TextField(blank=True, null=True) + contribution_ordinal = models.IntegerField(blank=True, null=True) + thoth_id = models.UUIDField() + contribution_type = models.CharField(max_length=255, blank=True, null=True) + work = models.ForeignKey(Work, on_delete=models.CASCADE, null=True) + contributor = models.ForeignKey(Contributor, on_delete=models.CASCADE, + null=True) + thoth_instance = models.URLField(default='https://api.thoth.pub') + + def __str__(self): + if self.contributor and self.work: + return '{0} as {1} on {2}'.format(self.contributor.full_name, + self.contribution_type, + self.work) + else: + return "Contribution" + + + From 3e7836049ecfd0eed22f58ea34c4845fb3809f44 Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:31:50 +0100 Subject: [PATCH 107/115] Setup version from thothlibrary --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 5b271ed..5d2fde1 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import os from setuptools import setup -#from thothlibrary import __version__, __license__ +from thothlibrary import __version__ ROOTDIR = os.path.abspath(os.path.dirname(__file__)) @@ -13,7 +13,7 @@ setup( name="thothlibrary", - version="0.1", + version=__version__, description="Python client for Thoth's GraphQL API", author="Javier Arias, Martin Paul Eve", author_email="javier@arias.re", From dee5bbae02ba241a9a139746b3827e440fdbe94c Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:32:22 +0100 Subject: [PATCH 108/115] Add licence version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5d2fde1..27c9419 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ install_requires=["graphqlclient", "requests", "munch"], long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", - license="Apache", + license="Apache 2.0", platforms=["any"], classifiers=[ "Programming Language :: Python :: 3", From f10a863eb3909f60b12e4a55b90d9b4601968e5f Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:32:57 +0100 Subject: [PATCH 109/115] Add missing modules to list of packages --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 27c9419..ca34111 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ description="Python client for Thoth's GraphQL API", author="Javier Arias, Martin Paul Eve", author_email="javier@arias.re", - packages=["thothlibrary"], + packages=["thothlibrary", "thothrest", "thothdjango"], install_requires=["graphqlclient", "requests", "munch"], long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", From 6a1948463afd2be28483318a05d5bb63d0805907 Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:39:06 +0100 Subject: [PATCH 110/115] Update package description --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ca34111..fe7705c 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setup( name="thothlibrary", version=__version__, - description="Python client for Thoth's GraphQL API", + description="Python client for Thoth's APIs", author="Javier Arias, Martin Paul Eve", author_email="javier@arias.re", packages=["thothlibrary", "thothrest", "thothdjango"], From 7d7a5281b736e9fd89baae5b3919dfebcc028ba8 Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:51:23 +0100 Subject: [PATCH 111/115] Fix false error --- thothlibrary/query.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index 320ef62..fffe3a2 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -61,11 +61,12 @@ def run(self, client): result = "" try: result = client.execute(self.request) - if "errors" in result: + serialised = json.loads(result) + if "errors" in serialised: raise AssertionError elif self.raw: return result - return json.loads(result)["data"][self.query_name] + return serialised["data"][self.query_name] except (KeyError, TypeError, ValueError, AssertionError, json.decoder.JSONDecodeError, requests.exceptions.RequestException): From 4fc7cb932c9b70cc63dc3b03dc5c31804a34a3b4 Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:51:52 +0100 Subject: [PATCH 112/115] Remove unnecessary elif after raise --- thothlibrary/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index fffe3a2..3b28d23 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -64,7 +64,7 @@ def run(self, client): serialised = json.loads(result) if "errors" in serialised: raise AssertionError - elif self.raw: + if self.raw: return result return serialised["data"][self.query_name] except (KeyError, TypeError, ValueError, AssertionError, From 5093476cfd14f9741027cf85f570f3804459a17d Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:52:24 +0100 Subject: [PATCH 113/115] Remove unnecessary else after return --- thothlibrary/query.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/thothlibrary/query.py b/thothlibrary/query.py index 3b28d23..8199137 100644 --- a/thothlibrary/query.py +++ b/thothlibrary/query.py @@ -88,5 +88,4 @@ def prepare_fields(self): if self.query_name in self.QUERIES and \ 'fields' in self.QUERIES[self.query_name]: return "\n".join(self.QUERIES[self.query_name]["fields"]) - else: - return '' + return '' From de347517e88113c2805fc8148e70b452efb8b044 Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 11:55:41 +0100 Subject: [PATCH 114/115] Pin requirements versions --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index fd19a02..d82b064 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ requests==2.24.0 -fire -munch -requests_mock -ascii_magic \ No newline at end of file +fire==0.4.0 +munch==2.5.0 +requests_mock==1.9.3 +ascii_magic==1.6 From 41577ff6040b2650993db59a67c8426d2d2911f8 Mon Sep 17 00:00:00 2001 From: Javier Arias Date: Fri, 22 Oct 2021 12:01:47 +0100 Subject: [PATCH 115/115] Bump v0.6.0 --- README.md | 2 +- thothlibrary/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ba5009d..5854eac 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Install is either via pip or cloning the repository. From pip: ```sh -python3 -m pip install thothlibrary==0.5.0 +python3 -m pip install thothlibrary==0.6.0 ``` Or from the repo: diff --git a/thothlibrary/__init__.py b/thothlibrary/__init__.py index 0337dfb..79c0943 100644 --- a/thothlibrary/__init__.py +++ b/thothlibrary/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """GraphQL client for Thoth""" -__version__ = "0.5.0" +__version__ = "0.6.0" __author__ = "Javier Arias " __copyright__ = "Copyright (c) 2020 Open Book Publishers" __license__ = "Apache 2.0"