Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9347147
renderers.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Subscribers
None
renderers.py
View Options
# Copyright (C) 2015 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information
import
re
import
yaml
import
json
import
sys
from
docutils.core
import
publish_parts
from
docutils.writers.html4css1
import
Writer
,
HTMLTranslator
from
flask
import
request
,
Response
,
render_template
from
flask
import
g
from
swh.web.ui
import
utils
class
SWHFilterEnricher
():
"""Global filter on fields.
"""
def
filter_by_fields
(
self
,
data
):
"""Extract a request parameter 'fields' if it exists to permit the
filtering on the data dict's keys.
If such field is not provided, returns the data as is.
"""
fields
=
request
.
args
.
get
(
'fields'
)
if
fields
:
fields
=
set
(
fields
.
split
(
','
))
data
=
utils
.
filter_field_keys
(
data
,
fields
)
return
data
class
SWHMultiResponse
(
Response
,
SWHFilterEnricher
):
"""
A Flask Response subclass.
Override force_type to transform dict responses into callable Flask
response objects whose mimetype matches the request's Accept header: HTML
template render, YAML dump or default to a JSON dump.
"""
@classmethod
def
make_response_from_mimetype
(
cls
,
rv
,
options
=
{}):
if
not
(
isinstance
(
rv
,
list
)
or
isinstance
(
rv
,
dict
)):
return
rv
def
wants_html
(
best_match
):
return
best_match
==
'text/html'
and
\
request
.
accept_mimetypes
[
best_match
]
>
\
request
.
accept_mimetypes
[
'application/json'
]
def
wants_yaml
(
best_match
):
return
best_match
==
'application/yaml'
and
\
request
.
accept_mimetypes
[
best_match
]
>
\
request
.
accept_mimetypes
[
'application/json'
]
rv
=
cls
.
filter_by_fields
(
cls
,
rv
)
acc_mime
=
[
'application/json'
,
'application/yaml'
,
'text/html'
]
best_match
=
request
.
accept_mimetypes
.
best_match
(
acc_mime
)
# return a template render
if
wants_html
(
best_match
):
data
=
json
.
dumps
(
rv
,
sort_keys
=
True
,
indent
=
4
,
separators
=
(
','
,
': '
))
env
=
g
.
get
(
'doc_env'
,
{})
env
[
'response_data'
]
=
data
env
[
'request'
]
=
request
rv
=
Response
(
render_template
(
'apidoc.html'
,
**
env
),
content_type
=
'text/html'
,
**
options
)
# return formatted yaml
elif
wants_yaml
(
best_match
):
rv
=
Response
(
yaml
.
dump
(
rv
),
content_type
=
'application/yaml'
,
**
options
)
# return formatted json
else
:
# jsonify is unhappy with lists in Flask 0.10.1, use json.dumps
rv
=
Response
(
json
.
dumps
(
rv
),
content_type
=
'application/json'
,
**
options
)
return
rv
@classmethod
def
force_type
(
cls
,
rv
,
environ
=
None
):
if
isinstance
(
rv
,
dict
)
or
isinstance
(
rv
,
list
):
rv
=
cls
.
make_response_from_mimetype
(
rv
)
return
super
()
.
force_type
(
rv
,
environ
)
def
error_response
(
error_code
,
error
):
"""Private function to create a custom error response.
"""
error_opts
=
{
'status'
:
error_code
}
error_data
=
{
'error'
:
str
(
error
)}
return
SWHMultiResponse
.
make_response_from_mimetype
(
error_data
,
options
=
error_opts
)
def
urlize_api_links
(
content
):
"""Utility function for decorating api links in browsable api."""
return
re
.
sub
(
r'"(/api/.*|/browse/.*)"'
,
r'"<a href="\1">\1</a>"'
,
content
)
class
NoHeaderHTMLTranslator
(
HTMLTranslator
):
"""
Docutils translator subclass to customize the generation of HTML
from reST-formatted docstrings
"""
def
__init__
(
self
,
document
):
super
()
.
__init__
(
document
)
self
.
body_prefix
=
[]
self
.
body_suffix
=
[]
def
visit_bullet_list
(
self
,
node
):
self
.
context
.
append
((
self
.
compact_simple
,
self
.
compact_p
))
self
.
compact_p
=
None
self
.
compact_simple
=
self
.
is_compactable
(
node
)
self
.
body
.
append
(
self
.
starttag
(
node
,
'ul'
,
CLASS
=
'docstring'
))
DOCSTRING_WRITER
=
Writer
()
DOCSTRING_WRITER
.
translator_class
=
NoHeaderHTMLTranslator
def
safe_docstring_display
(
docstring
):
"""
Utility function to htmlize reST-formatted documentation in browsable
api.
"""
def
trim
(
docstring
):
"""Correctly trim triple-quoted docstrings, taking into account
first-line indentation inconsistency.
Sourced from PEP257.
"""
if
not
docstring
:
return
''
lines
=
docstring
.
expandtabs
()
.
splitlines
()
indent
=
sys
.
maxsize
for
line
in
lines
[
1
:]:
stripped
=
line
.
lstrip
()
if
stripped
:
indent
=
min
(
indent
,
len
(
line
)
-
len
(
stripped
))
trimmed
=
[
lines
[
0
]
.
strip
()]
if
indent
<
sys
.
maxsize
:
for
line
in
lines
[
1
:]:
trimmed
.
append
(
line
[
indent
:]
.
rstrip
())
while
trimmed
and
not
trimmed
[
-
1
]:
trimmed
.
pop
()
while
trimmed
and
not
trimmed
[
0
]:
trimmed
.
pop
(
0
)
return
'
\n
'
.
join
(
trimmed
)
docstring
=
trim
(
docstring
)
return
publish_parts
(
docstring
,
writer
=
DOCSTRING_WRITER
)[
'html_body'
]
def
revision_id_from_url
(
url
):
"""Utility function to obtain a revision's ID from its browsing URL."""
return
re
.
sub
(
r'/browse/revision/([0-9a-f]{40}|[0-9a-f]{64})/.*'
,
r'\1'
,
url
)
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Fri, Jul 4, 5:02 PM (3 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3431385
Attached To
rDWAPPS Web applications
Event Timeline
Log In to Comment