Skip to content

Commit e74256b

Browse files
Merge pull request #2247 from specify/statspage
Statspage
2 parents 62c3a87 + 67c0239 commit e74256b

File tree

151 files changed

+6484
-1170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+6484
-1170
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
from specifyweb.context.app_resource import get_usertype
2+
from specifyweb.specify import models, api
3+
from specifyweb.specify.views import openapi
4+
from specifyweb.context.resources import Resource, Resources
5+
6+
Spappresource = getattr(models, 'Spappresource')
7+
Spappresourcedir = getattr(models, 'Spappresourcedir')
8+
9+
10+
collection_resources = openapi(schema={
11+
"get": {
12+
"responses": {
13+
"200": {
14+
"description": "Returns list of public app resources in the logged in collection.",
15+
"content": {
16+
"application/json": {
17+
"schema": {
18+
"type": "array",
19+
"items": {
20+
"type": "object",
21+
"properties": {
22+
"id": { "type": "integer", "description": "The appresource id." },
23+
"name": { "type": "string", "description": "The appresource name." },
24+
"mimetype": { "type": "string" },
25+
"metadata": { "type": "string" },
26+
},
27+
'required': ['id', 'name', 'mimetype', 'metadata'],
28+
'additionalProperties': False
29+
}
30+
}
31+
}
32+
}
33+
}
34+
}
35+
},
36+
"post": {
37+
"requestBody": {
38+
"required": True,
39+
"description": "Creates appresource in the logged in collection owned by the logged in user.",
40+
"content": {
41+
"application/json": {
42+
"schema": {
43+
"type": "object",
44+
"properties": {
45+
"name": { "type": "string", "description": "The appresource name." },
46+
"mimetype": { "type": "string" },
47+
"metadata": { "type": "string" },
48+
"data": { "type": "string", "description": "The data to be stored in the appresource." },
49+
},
50+
'required': ['name', 'mimetype', 'metadata', 'data'],
51+
'additionalProperties': False
52+
}
53+
}
54+
}
55+
},
56+
"responses": {
57+
"201": {
58+
"description": "The user resource was created.",
59+
"content": {
60+
"application/json": {
61+
"schema": {
62+
"type": "object",
63+
"properties": {
64+
"id": { "type": "integer", "description": "The appresource id." },
65+
"name": { "type": "string", "description": "The appresource name." },
66+
"mimetype": { "type": "string" },
67+
"metadata": { "type": "string" },
68+
"data": { "type": "string", "description": "The data to be stored in the appresource." },
69+
},
70+
'required': ['name', 'mimetype', 'metadata', 'data'],
71+
'additionalProperties': False
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}
78+
})(Resources.as_view(_spappresourcedirfilter= lambda request: {
79+
'ispersonal': False,
80+
'specifyuser__isnull': True,
81+
'usertype__isnull': True,
82+
}, _spappresourcefilter= lambda request: {
83+
'spappresourcedir__ispersonal':False,
84+
'spappresourcedir__specifyuser__isnull': True,
85+
'spappresourcedir__usertype__isnull': True,
86+
}, _spappresourcefilterpost=lambda request: {
87+
'specifyuser': request.specify_user
88+
}))
89+
90+
91+
collection_resource = openapi(schema={
92+
"get": {
93+
"responses": {
94+
"200": {
95+
"description": "The public app resource of the given id in the logged in collection ",
96+
"content": {
97+
"application/json": {
98+
"schema": {
99+
"type": "object",
100+
"properties": {
101+
"id": { "type": "integer", "description": "The appresource id." },
102+
"name": { "type": "string", "description": "The appresource name." },
103+
"mimetype": { "type": "string" },
104+
"metadata": { "type": "string" },
105+
"data": { "type": "string", "description": "The data to be stored in the appresource." },
106+
},
107+
'required': ['id', 'name', 'mimetype', 'metadata', 'data'],
108+
'additionalProperties': False
109+
}
110+
}
111+
}
112+
}
113+
}
114+
},
115+
"put": {
116+
"requestBody": {
117+
"required": True,
118+
"description": "Updates the appresource with the given id in the logged in collection",
119+
"content": {
120+
"application/json": {
121+
"schema": {
122+
"type": "object",
123+
"properties": {
124+
"name": { "type": "string", "description": "The appresource name." },
125+
"mimetype": { "type": "string" },
126+
"metadata": { "type": "string" },
127+
"data": { "type": "string", "description": "The data to be stored in the appresource." },
128+
},
129+
'required': ['name', 'mimetype', 'metadata', 'data'],
130+
'additionalProperties': False
131+
}
132+
}
133+
}
134+
},
135+
"responses": {
136+
"204": { "description": "The resource was updated.", },
137+
}
138+
},
139+
"delete": {
140+
"responses": {
141+
"204": {"description": "The resource was deleted.",}
142+
}
143+
}
144+
})(Resource.as_view(_spappresourcefilter= lambda request: {
145+
'spappresourcedir__ispersonal': False,
146+
}))
147+
148+
149+
150+

specifyweb/context/resources.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import json
2+
3+
from django import http
4+
from django.db import transaction
5+
from django.shortcuts import get_object_or_404
6+
from django.views import View
7+
from specifyweb.specify import models, api
8+
9+
Spappresource = getattr(models, 'Spappresource')
10+
Spappresourcedir = getattr(models, 'Spappresourcedir')
11+
12+
class Resources(View):
13+
_spappresourcefilter = None
14+
_spappresourcedirfilter = None
15+
_spappresourcefilterpost = None
16+
def get(self, request) -> http.HttpResponse:
17+
resources = Spappresource.objects.filter(
18+
spappresourcedir__collection=request.specify_collection,
19+
**self._spappresourcefilter(request)
20+
)
21+
return http.JsonResponse([
22+
{
23+
'id': r.id,
24+
'name': r.name,
25+
'mimetype': r.mimetype,
26+
'metadata': r.metadata,
27+
}
28+
for r in resources
29+
], safe=False)
30+
31+
def post(self, request) -> http.HttpResponse:
32+
post_data = json.loads(request.body)
33+
with transaction.atomic():
34+
directory, _ = Spappresourcedir.objects.get_or_create(
35+
collection=request.specify_collection,
36+
discipline=request.specify_collection.discipline,
37+
**self._spappresourcedirfilter(request)
38+
)
39+
resource = Spappresource.objects.create(
40+
spappresourcedir=directory,
41+
level=0,
42+
name=post_data['name'],
43+
mimetype=post_data['mimetype'],
44+
metadata=post_data['metadata'],
45+
**self._spappresourcefilterpost(request)
46+
)
47+
data = resource.spappresourcedatas.create(
48+
data=post_data['data'],
49+
)
50+
51+
response_data = {
52+
'id': resource.id,
53+
'name': resource.name,
54+
'mimetype': resource.mimetype,
55+
'metadata': resource.metadata,
56+
'data': data.data,
57+
}
58+
return http.HttpResponse(api.toJson(response_data),
59+
content_type="application/json",
60+
status=201)
61+
62+
63+
class Resource(View):
64+
_spappresourcefilter = None
65+
def get(self, request, resourceid: int) -> http.HttpResponse:
66+
resource = get_object_or_404(
67+
Spappresource,
68+
pk=resourceid,
69+
spappresourcedir__collection=request.specify_collection,
70+
**self._spappresourcefilter(request)
71+
)
72+
73+
data = resource.spappresourcedatas.get()
74+
response_data = {
75+
'id': resource.id,
76+
'name': resource.name,
77+
'mimetype': resource.mimetype,
78+
'metadata': resource.metadata,
79+
'data': data.data,
80+
}
81+
return http.HttpResponse(api.toJson(response_data),
82+
content_type="application/json")
83+
84+
def put(self, request, resourceid: int) -> http.HttpResponse:
85+
put_data = json.loads(request.body)
86+
87+
with transaction.atomic():
88+
resource = get_object_or_404(
89+
Spappresource,
90+
pk=resourceid,
91+
spappresourcedir__collection=request.specify_collection,
92+
**self._spappresourcefilter(request),
93+
)
94+
95+
resource.name = put_data['name']
96+
resource.mimetype = put_data['mimetype']
97+
resource.metadata = put_data['metadata']
98+
resource.save()
99+
100+
data = resource.spappresourcedatas.get()
101+
data.data = put_data['data']
102+
data.save()
103+
104+
return http.HttpResponse('', status=204)
105+
106+
def delete(self, request, resourceid: int) -> http.HttpResponse:
107+
with transaction.atomic():
108+
resource = get_object_or_404(
109+
Spappresource,
110+
pk=resourceid,
111+
spappresourcedir__collection=request.specify_collection,
112+
**self._spappresourcefilter(request)
113+
)
114+
resource.delete()
115+
116+
return http.HttpResponse('', status=204)
117+
118+
119+

specifyweb/context/urls.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.conf.urls import include, url
66
from django.urls import path
77

8-
from . import views, user_resources
8+
from . import views, user_resources, collection_resources
99
from ..attachment_gw.views import get_settings as attachment_settings
1010
from ..report_runner.views import get_status as report_runner_status
1111

@@ -31,6 +31,11 @@
3131
url(r'^attachment_settings.json$', attachment_settings),
3232
url(r'^report_runner_status.json$', report_runner_status),
3333

34-
path('user_resource/', user_resources.resources),
35-
path('user_resource/<int:resourceid>/', user_resources.resource),
34+
path('user_resource/', user_resources.user_resources),
35+
path('user_resource/<int:resourceid>/', user_resources.user_resource),
36+
37+
path('collection_resource/', collection_resources.collection_resources),
38+
path('collection_resource/<int:resourceid>/', collection_resources.collection_resource),
39+
40+
3641
]

0 commit comments

Comments
 (0)