-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #308 from euphorie/quaive-app-for-merge-part2
Quaive app for merge part 2: services
- Loading branch information
Showing
6 changed files
with
183 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<configure | ||
xmlns="http://namespaces.zope.org/zope" | ||
xmlns:plone="http://namespaces.plone.org/plone" | ||
> | ||
|
||
<plone:service | ||
method="GET" | ||
factory=".surveys.ToolVersionsGet" | ||
for="euphorie.content.surveygroup.ISurveyGroup" | ||
permission="zope2.View" | ||
layer="osha.oira.interfaces.IOSHAContentSkinLayer" | ||
name="@tool-versions" | ||
/> | ||
|
||
<plone:service | ||
method="GET" | ||
factory=".navigation.NavigationService" | ||
permission="zope2.View" | ||
for="*" | ||
layer="osha.oira.interfaces.IOSHAContentSkinLayer" | ||
name="@navtree" | ||
/> | ||
|
||
</configure> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from plone import api | ||
from plone.restapi.services import Service | ||
|
||
|
||
class NavigationService(Service): | ||
"""This JSON service reuses the navigation tile to serve through the | ||
REST API the navigation tree of this context. | ||
The nodes of the tree should be prepared to have a successful | ||
JSON serialization. | ||
This method removes the keys: | ||
- brain (which is not serializable) | ||
- parent (which will create a circular reference) | ||
and renames some keys to match the plone.restapi standards: | ||
- portal_type -> @type | ||
- url -> @id | ||
It also fixes the portal_type which is returned normalized | ||
with a dash instead of a dot. | ||
""" | ||
|
||
def fix_node(self, node): | ||
"""Prepare a node for serialization""" | ||
banned_keys = [ | ||
"brain", # not serializable | ||
"parent", # creates a circular reference | ||
] | ||
for key in banned_keys: | ||
if key in node: | ||
del node[key] | ||
|
||
# Rename keys to match plone.restapi standards | ||
mapping = { | ||
"portal_type": "@type", | ||
"url": "@id", | ||
"children": "items", | ||
} | ||
for old_key, new_key in mapping.items(): | ||
if old_key in node: | ||
node[new_key] = node.pop(old_key) | ||
|
||
# Fix the portal_type | ||
if "@type" in node: | ||
node["@type"] = node["@type"].replace("-", ".") | ||
|
||
# Recurse into children | ||
if "items" in node: | ||
for child in node["items"]: | ||
self.fix_node(child) | ||
|
||
return node | ||
|
||
def reply(self): | ||
"""We use the navtree tile to get the navigation tree, | ||
but we have to fiddle with the nodes to have a proper serialization. | ||
""" | ||
navtree_tile = api.content.get_view("navtree", self.context, self.request) | ||
navtree_tile.update() | ||
tree = [self.fix_node(node) for node in navtree_tile.tree] | ||
return { | ||
"@id": self.request.getURL(), | ||
"items": tree, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
from Acquisition import aq_base | ||
from Acquisition import aq_inner | ||
from plone import api | ||
from plone.base.utils import base_hasattr | ||
from plone.restapi.serializer.converters import json_compatible | ||
from plone.restapi.services import Service | ||
|
||
|
||
class ToolVersionsGet(Service): | ||
"""Get info from the oira tool (survey group) and its versions (surveys).""" | ||
|
||
@property | ||
def default_image_url(self): | ||
portal_url = api.portal.get().absolute_url() | ||
return f"{portal_url}/++resource++osha.oira.content/clipboard.svg" | ||
|
||
def get_survey_info(self, survey): | ||
# Is this survey the tool version that is published on the client? | ||
published_on_client = self.published_tool_version_id == survey.id | ||
# Note that if 'published_on_client' is true, the review_state | ||
# should be 'published', otherwise 'draft', but this is not always | ||
# in sync. So instead of 'api.content.get_state(obj=survey)', | ||
# let's report what the state is meant to be. | ||
review_state = "published" if published_on_client else "draft" | ||
# The 'published' attribute should be the date of publication of this | ||
# survey, but we could inherit this attribute from the surveygroup, | ||
# where it would contain the id of the client-published tool version. | ||
# So do not inherit this. | ||
published_date = getattr(aq_base(survey), "published", None) | ||
return { | ||
"@id": survey.absolute_url(), | ||
"id": survey.id, | ||
"title": survey.Title(), | ||
"created": json_compatible(survey.created()), | ||
"modified": json_compatible(survey.modified()), | ||
"published": json_compatible(published_date), | ||
"review_state": review_state, | ||
} | ||
|
||
def reply(self): | ||
surveygroup = aq_inner(self.context) | ||
# The 'published' attribute of the surveygroup has the id of the tool | ||
# version that is currently published on the OiRA client side. | ||
self.published_tool_version_id = getattr(surveygroup, "published", None) | ||
|
||
# First gather info about the survey group. | ||
result = { | ||
"@id": f"{surveygroup.absolute_url()}/@tool-versions", | ||
"id": surveygroup.id, | ||
"title": surveygroup.Title(), | ||
"published_tool_version_id": self.published_tool_version_id, | ||
"@type": surveygroup.portal_type, | ||
# We will try to get the next ones from one of the surveys. | ||
"image_url": "", | ||
"summary": "", | ||
"introduction": "", | ||
} | ||
|
||
# Now add info for each tool version. | ||
items = [] | ||
surveys = surveygroup.contentValues() | ||
for survey in surveys: | ||
items.append(self.get_survey_info(survey)) | ||
result["versions"] = items | ||
|
||
# Get some more info from the published survey, or from the first one. | ||
survey = ( | ||
surveygroup.get(self.published_tool_version_id) | ||
if self.published_tool_version_id | ||
else None | ||
) | ||
if survey is None and surveys: | ||
survey = surveys[0] | ||
if survey is not None: | ||
if base_hasattr(survey, "image") and survey.image: | ||
# The survey has a not inherited image attribute and it is not empty. | ||
result["image_url"] = f"{survey.absolute_url()}/@@images/image" | ||
if base_hasattr(survey, "introduction"): | ||
result["introduction"] = survey.introduction | ||
# The description field always exists. | ||
result["summary"] = survey.Description() | ||
if not result["image_url"]: | ||
result["image_url"] = self.default_image_url | ||
|
||
return result |