-
Notifications
You must be signed in to change notification settings - Fork 16
/
articles.py
98 lines (83 loc) · 4.03 KB
/
articles.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# ~~APIBulkArticles:Feature->APIBulk:Feature~~
from portality.api.common import Api, Api404Error, Api400Error, Api403Error, Api401Error
from portality.api.current.crud import ArticlesCrudApi
from portality.bll import DOAJ
from portality.bll import exceptions
from copy import deepcopy
from portality.bll.exceptions import DuplicateArticleException
class ArticlesBulkApi(Api):
#~~->Swagger:Feature~~
# ~~->API:Documentation~~
SWAG_TAG = 'Bulk API'
@classmethod
def create_swag(cls):
template = deepcopy(cls.SWAG_TEMPLATE)
template['parameters'].append(
{
"description": "<div class=\"search-query-docs\">A list/array of article JSON objects that you would like to create or update. The contents should be a list, and each object in the list should comply with the schema displayed in the <a href=\"/api/docs#CRUD_Articles_get_api_articles_article_id\"> GET (Retrieve) an article route</a>. Partial updates are not allowed, you have to supply the full JSON.</div>",
"required": True,
"schema": {"type" : "string"},
"name": "article_json",
"in": "body"
}
)
template['parameters'].append(cls.SWAG_API_KEY_REQ_PARAM)
template['responses']['201'] = cls.R201_BULK
template['responses']['400'] = cls.R400
template['responses']['401'] = cls.R401
template['responses']['403'] = cls.R403
return cls._build_swag_response(template)
@classmethod
def create(cls, articles, account):
# We run through the articles once, validating in dry-run mode
# and deduplicating as we go. Then we .save() everything once
# we know all incoming articles are valid.
# as long as authentication (in the layer above) has been successful, and the account exists, then
# we are good to proceed
if account is None:
raise Api401Error()
# convert the data into a suitable article models
articles = [ArticlesCrudApi.prep_article(data, account) for data in articles]
# ~~->Article:Service~~
articleService = DOAJ.articleService()
try:
# ~~->BatchCreateArticles:Feature~~
result = articleService.batch_create_articles(articles, account, add_journal_info=True)
return [a.id for a in articles]
except DuplicateArticleException as e:
raise Api403Error(str(e))
except exceptions.IngestException as e:
raise Api400Error(str(e))
except exceptions.ArticleNotAcceptable as e:
raise Api400Error(str(e))
@classmethod
def delete_swag(cls):
template = deepcopy(cls.SWAG_TEMPLATE)
template['parameters'].append(
{
"description": "<div class=\"search-query-docs\">A list/array of DOAJ article IDs. E.g. [\"4cf8b72139a749c88d043129f00e1b07\", \"232b53726fb74cc4a8eb4717e5a43193\"].</div>",
"required": True,
"schema": {"type" : "string"},
"name": "article_ids",
"in": "body"
}
)
template['parameters'].append(cls.SWAG_API_KEY_REQ_PARAM)
template['responses']['204'] = cls.R204
template['responses']['400'] = cls.R400
template['responses']['401'] = cls.R401
return cls._build_swag_response(template)
@classmethod
def delete(cls, article_ids, account):
# we run through delete twice, once as a dry-run and the second time
# as the real deal
# ~~->APICrudArticles:Feature~~
for id in article_ids:
try:
ArticlesCrudApi.delete(id, account, dry_run=True)
except Api404Error as e:
raise Api400Error("Id {x} does not exist or does not belong to this user account".format(x=id))
except Api403Error as e:
raise Api400Error("Id {x} is not in a state which allows it to be deleted".format(x=id))
for id in article_ids:
ArticlesCrudApi.delete(id, account)