Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9348629
browse.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
33 KB
Subscribers
None
browse.py
View Options
# Copyright (C) 2015-2016 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
from
encodings.aliases
import
aliases
from
flask
import
render_template
,
request
,
url_for
,
redirect
from
swh.core.hashutil
import
ALGORITHMS
from
swh.core.utils
import
grouper
from
..
import
service
,
utils
from
..exc
import
BadInputExc
,
NotFoundExc
from
..main
import
app
from
.
import
api
hash_filter_keys
=
ALGORITHMS
def
api_lookup
(
api_fn
,
query
):
"""Lookup api with api_fn function with parameter query.
Example:
filetype = api_lookup('api_content_filetype', 'sha1:blah')
if filetype:
content['mimetype'] = filetype['mimetype']
"""
try
:
return
api_fn
(
query
)
except
(
NotFoundExc
,
BadInputExc
):
return
None
@app.route
(
'/origin/search/'
)
def
search_origin
():
"""
Redirect request with GET params for an origin to our fragmented URI scheme
"""
if
request
.
method
==
'GET'
:
data
=
request
.
args
origin_id
=
data
.
get
(
'origin_id'
)
if
origin_id
:
return
redirect
(
url_for
(
'browse_origin'
,
origin_id
=
origin_id
))
args
=
[
'origin_type'
,
'origin_url'
]
values
=
{
arg
:
data
.
get
(
arg
)
for
arg
in
args
if
data
.
get
(
arg
)}
if
'origin_type'
in
values
and
'origin_url'
in
values
:
return
redirect
(
url_for
(
'browse_origin'
,
**
values
))
@app.route
(
'/directory/search/'
)
def
search_directory
():
"""
Redirect request with GET params for a directory to our fragmented
URI scheme
"""
def
url_for_filtered
(
endpoint
,
**
kwargs
):
"""Make url_for ignore keyword args that have an empty string for value
"""
filtered
=
{
k
:
v
for
k
,
v
in
kwargs
.
items
()
if
kwargs
[
k
]}
return
url_for
(
endpoint
,
**
filtered
)
if
request
.
method
==
'GET'
:
data
=
request
.
args
sha1_git
=
data
.
get
(
'sha1_git'
)
if
sha1_git
:
if
'dir_path'
in
data
:
# dir_path exists only in requests for a revision's directory
return
redirect
(
url_for_filtered
(
'browse_revision_directory'
,
sha1_git
=
sha1_git
,
dir_path
=
data
.
get
(
'dir_path'
)
))
return
redirect
(
url_for_filtered
(
'browse_directory'
,
sha1_git
=
sha1_git
,
path
=
data
.
get
(
'path'
)
))
args
=
[
'origin_id'
,
'branch_name'
,
'ts'
,
'path'
]
values
=
{
arg
:
data
.
get
(
arg
)
for
arg
in
args
if
data
.
get
(
arg
)}
if
'origin_id'
in
values
:
return
redirect
(
url_for
(
'browse_revision_directory_through_origin'
,
**
values
))
@app.route
(
'/revision/search/'
)
def
search_revision
():
"""
Redirect request with GET params for a revision to our fragmented
URI scheme
"""
if
request
.
method
==
'GET'
:
data
=
request
.
args
sha1_git
=
data
.
get
(
'sha1_git'
)
if
sha1_git
:
return
redirect
(
url_for
(
'browse_revision'
,
sha1_git
=
sha1_git
))
args
=
[
'origin_id'
,
'branch_name'
,
'ts'
]
values
=
{
arg
:
data
.
get
(
arg
)
for
arg
in
args
if
data
.
get
(
arg
)}
if
'origin_id'
in
values
:
return
redirect
(
url_for
(
'browse_revision_with_origin'
,
**
values
))
@app.route
(
'/content/symbol/'
,
methods
=
[
'GET'
])
def
search_symbol
():
"""Search for symbols in contents.
Returns:
dict representing data to look for in swh storage.
"""
env
=
{
'result'
:
None
,
'per_page'
:
None
,
'message'
:
''
,
'linknext'
:
None
,
'linkprev'
:
None
,
}
# Read form or get information
data
=
request
.
args
q
=
data
.
get
(
'q'
)
per_page
=
data
.
get
(
'per_page'
)
env
[
'q'
]
=
q
if
per_page
:
env
[
'per_page'
]
=
per_page
if
q
:
try
:
result
=
api
.
api_content_symbol
(
q
)
if
result
:
headers
=
result
.
get
(
'headers'
)
result
=
utils
.
prepare_data_for_view
(
result
[
'results'
])
env
[
'result'
]
=
result
if
headers
:
if
'link-next'
in
headers
:
next_last_sha1
=
result
[
-
1
][
'sha1'
]
params
=
{
'q'
:
q
,
'last_sha1'
:
next_last_sha1
,
}
if
per_page
:
params
[
'per_page'
]
=
per_page
env
[
'linknext'
]
=
url_for
(
'search_symbol'
,
**
params
)
except
BadInputExc
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'symbols.html'
,
**
env
)
@app.route
(
'/content/search/'
,
methods
=
[
'GET'
,
'POST'
])
def
search_content
():
"""Search for hashes in swh-storage.
One form to submit either:
- hash query to look up in swh storage
- file hashes calculated client-side to be queried in swh storage
- both
Returns:
dict representing data to look for in swh storage.
The following keys are returned:
- search_stats: {'nbfiles': X, 'pct': Y} the number of total
queried files and percentage of files not in storage respectively
- responses: array of {'filename': X, 'sha1': Y, 'found': Z}
- messages: General messages.
TODO:
Batch-process with all checksums, not just sha1
"""
env
=
{
'search_res'
:
None
,
'search_stats'
:
None
,
'message'
:
[]}
search_stats
=
{
'nbfiles'
:
0
,
'pct'
:
0
}
search_res
=
None
message
=
''
# Get with a single hash request
if
request
.
method
==
'POST'
:
# Post form submission with many hash requests
q
=
None
else
:
data
=
request
.
args
q
=
data
.
get
(
'q'
)
try
:
search
=
api
.
api_check_content_known
(
q
)
search_res
=
search
[
'search_res'
]
search_stats
=
search
[
'search_stats'
]
except
BadInputExc
as
e
:
message
=
str
(
e
)
env
[
'search_stats'
]
=
search_stats
env
[
'search_res'
]
=
search_res
env
[
'message'
]
=
message
return
render_template
(
'search.html'
,
**
env
)
@app.route
(
'/browse/'
)
def
browse
():
"""Render the user-facing browse view
"""
return
render_template
(
'browse.html'
)
@app.route
(
'/browse/content/<string:q>/'
)
def
browse_content
(
q
):
"""Given a hash and a checksum, display the content's meta-data.
Args:
q is of the form algo_hash:hash with algo_hash in
(sha1, sha1_git, sha256)
Returns:
Information on one possible origin for such content.
Raises:
BadInputExc in case of unknown algo_hash or bad hash
NotFoundExc if the content is not found.
"""
env
=
{
'q'
:
q
,
'message'
:
None
,
'content'
:
None
}
encoding
=
request
.
args
.
get
(
'encoding'
,
'utf8'
)
if
encoding
not
in
aliases
:
env
[
'message'
]
=
'Encoding
%s
not supported.'
\
'Supported Encodings:
%s
'
%
(
encoding
,
list
(
aliases
.
keys
()))
return
render_template
(
'content.html'
,
**
env
)
try
:
content
=
api
.
api_content_metadata
(
q
)
filetype
=
api_lookup
(
api
.
api_content_filetype
,
q
)
if
filetype
:
content
[
'mimetype'
]
=
filetype
.
get
(
'mimetype'
)
content
[
'encoding'
]
=
filetype
.
get
(
'encoding'
)
else
:
content
[
'mimetype'
]
=
None
content
[
'encoding'
]
=
None
language
=
api_lookup
(
api
.
api_content_language
,
q
)
if
language
:
content
[
'language'
]
=
language
.
get
(
'lang'
)
else
:
content
[
'language'
]
=
None
licenses
=
api_lookup
(
api
.
api_content_license
,
q
)
if
licenses
:
content
[
'licenses'
]
=
', '
.
join
(
licenses
.
get
(
'licenses'
,
[]))
else
:
content
[
'licenses'
]
=
None
content_raw
=
service
.
lookup_content_raw
(
q
)
if
content_raw
:
content
[
'data'
]
=
content_raw
[
'data'
]
else
:
content
[
'data'
]
=
None
ctags
=
api_lookup
(
api
.
api_content_ctags
,
q
)
if
ctags
:
url
=
url_for
(
'browse_content'
,
q
=
q
)
content
[
'ctags'
]
=
grouper
((
'<a href="
%s
#l-
%s
">
%s
</a>'
%
(
url
,
ctag
[
'line'
],
ctag
[
'line'
])
for
ctag
in
ctags
),
20
)
else
:
content
[
'ctags'
]
=
None
env
[
'content'
]
=
utils
.
prepare_data_for_view
(
content
,
encoding
=
encoding
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'content.html'
,
**
env
)
@app.route
(
'/browse/content/<string:q>/raw/'
)
def
browse_content_raw
(
q
):
"""Given a hash and a checksum, display the content's raw data.
Args:
q is of the form algo_hash:hash with algo_hash in
(sha1, sha1_git, sha256)
Returns:
Information on one possible origin for such content.
Raises:
BadInputExc in case of unknown algo_hash or bad hash
NotFoundExc if the content is not found.
"""
return
redirect
(
url_for
(
'api_content_raw'
,
q
=
q
))
def
_origin_seen
(
q
,
data
):
"""Given an origin, compute a message string with the right information.
Args:
origin: a dictionary with keys:
- origin: a dictionary with type and url keys
- occurrence: a dictionary with a validity range
Returns:
Message as a string
"""
origin_type
=
data
[
'origin_type'
]
origin_url
=
data
[
'origin_url'
]
revision
=
data
[
'revision'
]
branch
=
data
[
'branch'
]
path
=
data
[
'path'
]
return
"""The content with hash %s has been seen on origin with type '%s'
at url '%s'. The revision was identified at '%s' on branch '%s'.
The file's path referenced was '%s'."""
%
(
q
,
origin_type
,
origin_url
,
revision
,
branch
,
path
)
# @app.route('/browse/content/<string:q>/origin/')
def
browse_content_with_origin
(
q
):
"""Show content information.
Args:
- q: query string of the form <algo_hash:hash> with
`algo_hash` in sha1, sha1_git, sha256.
This means that several different URLs (at least one per
HASH_ALGO) will point to the same content sha: the sha with
'hash' format
Returns:
The content's information at for a given checksum.
"""
env
=
{
'q'
:
q
}
try
:
origin
=
api
.
api_content_checksum_to_origin
(
q
)
message
=
_origin_seen
(
q
,
origin
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
message
=
str
(
e
)
env
[
'message'
]
=
message
return
render_template
(
'content-with-origin.html'
,
**
env
)
@app.route
(
'/browse/directory/<string:sha1_git>/'
)
@app.route
(
'/browse/directory/<string:sha1_git>/<path:path>/'
)
def
browse_directory
(
sha1_git
,
path
=
None
):
"""Show directory information.
Args:
- sha1_git: the directory's sha1 git identifier. If path
is set, the base directory for the relative path to the entry
- path: the path to the requested entry, relative to
the directory pointed by sha1_git
Returns:
The content's information at sha1_git, or at sha1_git/path if
path is set.
"""
env
=
{
'sha1_git'
:
sha1_git
,
'files'
:
[]}
try
:
if
path
:
env
[
'message'
]
=
(
'Listing for directory with path
%s
from
%s
:'
%
(
path
,
sha1_git
))
dir_or_file
=
service
.
lookup_directory_with_path
(
sha1_git
,
path
)
if
dir_or_file
[
'type'
]
==
'file'
:
fsha
=
'sha256:
%s
'
%
dir_or_file
[
'sha256'
]
content
=
api
.
api_content_metadata
(
fsha
)
content_raw
=
service
.
lookup_content_raw
(
fsha
)
if
content_raw
:
# FIXME: currently assuming utf8 encoding
content
[
'data'
]
=
content_raw
[
'data'
]
env
[
'content'
]
=
utils
.
prepare_data_for_view
(
content
,
encoding
=
'utf-8'
)
return
render_template
(
'content.html'
,
**
env
)
else
:
directory_files
=
api
.
api_directory
(
dir_or_file
[
'target'
])
env
[
'files'
]
=
utils
.
prepare_data_for_view
(
directory_files
)
else
:
env
[
'message'
]
=
"Listing for directory
%s
:"
%
sha1_git
directory_files
=
api
.
api_directory
(
sha1_git
)
env
[
'files'
]
=
utils
.
prepare_data_for_view
(
directory_files
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'directory.html'
,
**
env
)
@app.route
(
'/browse/origin/<string:origin_type>/url/<path:origin_url>/'
)
@app.route
(
'/browse/origin/<int:origin_id>/'
)
def
browse_origin
(
origin_id
=
None
,
origin_type
=
None
,
origin_url
=
None
):
"""Browse origin matching given criteria - either origin_id or
origin_type and origin_path.
Args:
- origin_id: origin's swh identifier
- origin_type: origin's type
- origin_url: origin's URL
"""
# URLs for the calendar JS plugin
env
=
{
'browse_url'
:
None
,
'visit_url'
:
None
,
'origin'
:
None
}
try
:
origin
=
api
.
api_origin
(
origin_id
,
origin_type
,
origin_url
)
env
[
'origin'
]
=
origin
env
[
'browse_url'
]
=
url_for
(
'browse_revision_with_origin'
,
origin_id
=
origin
[
'id'
])
env
[
'visit_url'
]
=
url_for
(
'api_origin_visits'
,
origin_id
=
origin
[
'id'
])
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'origin.html'
,
**
env
)
@app.route
(
'/browse/person/<int:person_id>/'
)
def
browse_person
(
person_id
):
"""Browse person with id id.
"""
env
=
{
'person_id'
:
person_id
,
'person'
:
None
,
'message'
:
None
}
try
:
env
[
'person'
]
=
api
.
api_person
(
person_id
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'person.html'
,
**
env
)
@app.route
(
'/browse/release/<string:sha1_git>/'
)
def
browse_release
(
sha1_git
):
"""Browse release with sha1_git.
"""
env
=
{
'sha1_git'
:
sha1_git
,
'message'
:
None
,
'release'
:
None
}
try
:
rel
=
api
.
api_release
(
sha1_git
)
env
[
'release'
]
=
utils
.
prepare_data_for_view
(
rel
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'release.html'
,
**
env
)
@app.route
(
'/browse/revision/<string:sha1_git>/'
)
@app.route
(
'/browse/revision/<string:sha1_git>/prev/<path:prev_sha1s>/'
)
def
browse_revision
(
sha1_git
,
prev_sha1s
=
None
):
"""Browse the revision with git SHA1 sha1_git_cur, while optionally keeping
the context from which we came as a list of previous (i.e. later)
revisions' sha1s.
Args:
sha1_git: the requested revision's sha1_git.
prev_sha1s: an optional string of /-separated sha1s representing our
context, ordered by descending revision date.
Returns:
Information about revision of git SHA1 sha1_git_cur, with relevant URLS
pointing to the context augmented with sha1_git_cur.
Example:
GET /browse/revision/
"""
env
=
{
'sha1_git'
:
sha1_git
,
'message'
:
None
,
'revision'
:
None
}
try
:
rev
=
api
.
api_revision
(
sha1_git
,
prev_sha1s
)
env
[
'revision'
]
=
utils
.
prepare_data_for_view
(
rev
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision.html'
,
**
env
)
@app.route
(
'/browse/revision/<string:sha1_git>/raw/'
)
def
browse_revision_raw_message
(
sha1_git
):
"""Given a sha1_git, display the corresponding revision's raw message.
"""
return
redirect
(
url_for
(
'api_revision_raw_message'
,
sha1_git
=
sha1_git
))
@app.route
(
'/browse/revision/<string:sha1_git>/log/'
)
@app.route
(
'/browse/revision/<string:sha1_git>/prev/<path:prev_sha1s>/log/'
)
def
browse_revision_log
(
sha1_git
,
prev_sha1s
=
None
):
"""Browse revision with sha1_git's log. If the navigation path through the
commit tree is specified, we intersect the earliest revision's log with the
revisions the user browsed through - ie the path taken to the specified
revision.
Args:
sha1_git: the current revision's SHA1_git checksum
prev_sha1s: optionally, the path through which we want log information
"""
env
=
{
'sha1_git'
:
sha1_git
,
'sha1_url'
:
'/browse/revision/
%s
/'
%
sha1_git
,
'message'
:
None
,
'revisions'
:
[]}
try
:
revision_data
=
api
.
api_revision_log
(
sha1_git
,
prev_sha1s
)
revisions
=
revision_data
[
'revisions'
]
next_revs_url
=
revision_data
[
'next_revs_url'
]
env
[
'revisions'
]
=
map
(
utils
.
prepare_data_for_view
,
revisions
)
env
[
'next_revs_url'
]
=
utils
.
prepare_data_for_view
(
next_revs_url
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision-log.html'
,
**
env
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>/log/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>/log/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>/log/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/ts/<string:ts>/log/'
)
def
browse_revision_log_by
(
origin_id
,
branch_name
=
'refs/heads/master'
,
timestamp
=
None
):
"""Browse the revision described by origin, branch name and timestamp's
log
Args:
origin_id: the revision's origin
branch_name: the revision's branch
timestamp: the requested timeframe for the revision
Returns:
The revision log of the described revision as a list of revisions
if it is found.
"""
env
=
{
'sha1_git'
:
None
,
'origin_id'
:
origin_id
,
'origin_url'
:
'/browse/origin/
%d
/'
%
origin_id
,
'branch_name'
:
branch_name
,
'timestamp'
:
timestamp
,
'message'
:
None
,
'revisions'
:
[]}
try
:
revisions
=
api
.
api_revision_log_by
(
origin_id
,
branch_name
,
timestamp
)
env
[
'revisions'
]
=
map
(
utils
.
prepare_data_for_view
,
revisions
)
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision-log.html'
,
**
env
)
@app.route
(
'/browse/revision/<string:sha1_git_cur>/prev/<path:sha1s>/'
)
def
browse_with_rev_context
(
sha1_git_cur
,
sha1s
):
"""Browse the revision with git SHA1 sha1_git_cur, while keeping the context
from which we came as a list of previous (i.e. later) revisions' sha1s.
Args:
sha1_git_cur: the requested revision's sha1_git.
sha1s: a string of /-separated sha1s representing our context, ordered
by descending revision date.
Returns:
Information about revision of git SHA1 sha1_git_cur, with relevant URLS
pointing to the context augmented with sha1_git_cur.
Example:
GET /browse/revision/
"""
env
=
{
'sha1_git'
:
sha1_git_cur
,
'message'
:
None
,
'revision'
:
None
}
try
:
revision
=
api
.
api_revision
(
sha1_git_cur
,
sha1s
)
env
[
'revision'
]
=
utils
.
prepare_data_for_view
(
revision
)
except
(
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision.html'
,
**
env
)
@app.route
(
'/browse/revision/<string:sha1_git_root>/history/<sha1_git>/'
)
def
browse_revision_history
(
sha1_git_root
,
sha1_git
):
"""Display information about revision sha1_git, limited to the
sub-graph of all transitive parents of sha1_git_root.
In other words, sha1_git is an ancestor of sha1_git_root.
Args:
sha1_git_root: latest revision of the browsed history.
sha1_git: one of sha1_git_root's ancestors.
limit: optional query parameter to limit the revisions log
(default to 100). For now, note that this limit could impede the
transitivity conclusion about sha1_git not being an ancestor of
sha1_git_root (even if it is).
Returns:
Information on sha1_git if it is an ancestor of sha1_git_root
including children leading to sha1_git_root.
"""
env
=
{
'sha1_git_root'
:
sha1_git_root
,
'sha1_git'
:
sha1_git
,
'message'
:
None
,
'keys'
:
[],
'revision'
:
None
}
if
sha1_git
==
sha1_git_root
:
return
redirect
(
url_for
(
'browse_revision'
,
sha1_git
=
sha1_git
))
try
:
revision
=
api
.
api_revision_history
(
sha1_git_root
,
sha1_git
)
env
[
'revision'
]
=
utils
.
prepare_data_for_view
(
revision
)
except
(
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision.html'
,
**
env
)
@app.route
(
'/browse/revision/<string:sha1_git>/directory/'
)
@app.route
(
'/browse/revision/<string:sha1_git>/directory/<path:dir_path>/'
)
def
browse_revision_directory
(
sha1_git
,
dir_path
=
None
):
"""Browse directory from revision with sha1_git.
"""
env
=
{
'sha1_git'
:
sha1_git
,
'path'
:
'.'
if
not
dir_path
else
dir_path
,
'message'
:
None
,
'result'
:
None
}
encoding
=
request
.
args
.
get
(
'encoding'
,
'utf8'
)
if
encoding
not
in
aliases
:
env
[
'message'
]
=
'Encoding
%s
not supported.'
\
'Supported Encodings:
%s
'
%
(
encoding
,
list
(
aliases
.
keys
()))
return
render_template
(
'revision-directory.html'
,
**
env
)
try
:
result
=
api
.
api_revision_directory
(
sha1_git
,
dir_path
,
with_data
=
True
)
result
[
'content'
]
=
utils
.
prepare_data_for_view
(
result
[
'content'
],
encoding
=
encoding
)
env
[
'revision'
]
=
result
[
'revision'
]
env
[
'result'
]
=
result
except
(
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision-directory.html'
,
**
env
)
@app.route
(
'/browse/revision/<string:sha1_git_root>'
'/history/<sha1_git>'
'/directory/'
)
@app.route
(
'/browse/revision/<string:sha1_git_root>'
'/history/<sha1_git>'
'/directory/<path:path>/'
)
def
browse_revision_history_directory
(
sha1_git_root
,
sha1_git
,
path
=
None
):
"""Return information about directory pointed to by the revision
defined as: revision sha1_git, limited to the sub-graph of all
transitive parents of sha1_git_root.
Args:
sha1_git_root: latest revision of the browsed history.
sha1_git: one of sha1_git_root's ancestors.
path: optional directory pointed to by that revision.
limit: optional query parameter to limit the revisions log
(default to 100). For now, note that this limit could impede the
transitivity conclusion about sha1_git not being an ancestor of
sha1_git_root (even if it is).
Returns:
Information on the directory pointed to by that revision.
Raises:
BadInputExc in case of unknown algo_hash or bad hash.
NotFoundExc if either revision is not found or if sha1_git is not an
ancestor of sha1_git_root or the path referenced does not exist
"""
env
=
{
'sha1_git_root'
:
sha1_git_root
,
'sha1_git'
:
sha1_git
,
'path'
:
'.'
if
not
path
else
path
,
'message'
:
None
,
'result'
:
None
}
encoding
=
request
.
args
.
get
(
'encoding'
,
'utf8'
)
if
encoding
not
in
aliases
:
env
[
'message'
]
=
'Encoding
%s
not supported.'
\
'Supported Encodings:
%s
'
%
(
encoding
,
list
(
aliases
.
keys
()))
return
render_template
(
'revision-directory.html'
,
**
env
)
if
sha1_git
==
sha1_git_root
:
return
redirect
(
url_for
(
'browse_revision_directory'
,
sha1_git
=
sha1_git
,
path
=
path
,
encoding
=
encoding
),
code
=
301
)
try
:
result
=
api
.
api_revision_history_directory
(
sha1_git_root
,
sha1_git
,
path
,
with_data
=
True
)
env
[
'revision'
]
=
result
[
'revision'
]
env
[
'content'
]
=
utils
.
prepare_data_for_view
(
result
[
'content'
],
encoding
=
encoding
)
env
[
'result'
]
=
result
except
(
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision-directory.html'
,
**
env
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/history/<sha1_git>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/history/<sha1_git>'
'/directory/<path:path>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/history/<sha1_git>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/history/<sha1_git>'
'/directory/<path:path>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/ts/<string:ts>'
'/history/<sha1_git>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/ts/<string:ts>'
'/history/<sha1_git>'
'/directory/<path:path>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>'
'/history/<sha1_git>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>'
'/history/<sha1_git>'
'/directory/<path:path>/'
)
def
browse_directory_through_revision_with_origin_history
(
origin_id
,
branch_name
=
"refs/heads/master"
,
ts
=
None
,
sha1_git
=
None
,
path
=
None
):
env
=
{
'origin_id'
:
origin_id
,
'branch_name'
:
branch_name
,
'ts'
:
ts
,
'sha1_git'
:
sha1_git
,
'path'
:
'.'
if
not
path
else
path
,
'message'
:
None
,
'result'
:
None
}
encoding
=
request
.
args
.
get
(
'encoding'
,
'utf8'
)
if
encoding
not
in
aliases
:
env
[
'message'
]
=
((
'Encoding
%s
not supported.'
'Supported Encodings:
%s
'
)
%
(
encoding
,
list
(
aliases
.
keys
())))
return
render_template
(
'revision-directory.html'
,
**
env
)
try
:
result
=
api
.
api_directory_through_revision_with_origin_history
(
origin_id
,
branch_name
,
ts
,
sha1_git
,
path
,
with_data
=
True
)
env
[
'revision'
]
=
result
[
'revision'
]
env
[
'content'
]
=
utils
.
prepare_data_for_view
(
result
[
'content'
],
encoding
=
encoding
)
env
[
'result'
]
=
result
except
(
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision-directory.html'
,
**
env
)
@app.route
(
'/browse/revision'
'/origin/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/ts/<string:ts>/'
)
def
browse_revision_with_origin
(
origin_id
,
branch_name
=
"refs/heads/master"
,
ts
=
None
):
"""Instead of having to specify a (root) revision by SHA1_GIT, users
might want to specify a place and a time. In SWH a "place" is an
origin; a "time" is a timestamp at which some place has been
observed by SWH crawlers.
Args:
origin_id: origin's identifier (default to 1).
branch_name: the optional branch for the given origin (default
to master).
timestamp: optional timestamp (default to the nearest time
crawl of timestamp).
Returns:
Information on the revision if found.
Raises:
BadInputExc in case of unknown algo_hash or bad hash.
NotFoundExc if the revision is not found.
"""
env
=
{
'message'
:
None
,
'revision'
:
None
}
try
:
revision
=
api
.
api_revision_with_origin
(
origin_id
,
branch_name
,
ts
)
env
[
'revision'
]
=
utils
.
prepare_data_for_view
(
revision
)
except
(
ValueError
,
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision.html'
,
**
env
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/history/<sha1_git>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/history/<sha1_git>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>'
'/history/<sha1_git>/'
)
def
browse_revision_history_through_origin
(
origin_id
,
branch_name
=
'refs/heads/master'
,
ts
=
None
,
sha1_git
=
None
):
"""Return information about revision sha1_git, limited to the
sub-graph of all transitive parents of the revision root identified
by (origin_id, branch_name, ts).
Given sha1_git_root such root revision's identifier, in other words,
sha1_git is an ancestor of sha1_git_root.
Args:
origin_id: origin's identifier (default to 1).
branch_name: the optional branch for the given origin (default
to master).
timestamp: optional timestamp (default to the nearest time
crawl of timestamp).
sha1_git: one of sha1_git_root's ancestors.
limit: optional query parameter to limit the revisions log
(default to 100). For now, note that this limit could impede the
transitivity conclusion about sha1_git not being an ancestor of
sha1_git_root (even if it is).
Returns:
Information on sha1_git if it is an ancestor of sha1_git_root
including children leading to sha1_git_root.
"""
env
=
{
'message'
:
None
,
'revision'
:
None
}
try
:
revision
=
api
.
api_revision_history_through_origin
(
origin_id
,
branch_name
,
ts
,
sha1_git
)
env
[
'revision'
]
=
utils
.
prepare_data_for_view
(
revision
)
except
(
ValueError
,
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision.html'
,
**
env
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/directory/<path:path>'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/directory/<path:path>/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>'
'/directory/'
)
@app.route
(
'/browse/revision'
'/origin/<int:origin_id>'
'/branch/<path:branch_name>'
'/ts/<string:ts>'
'/directory/<path:path>/'
)
def
browse_revision_directory_through_origin
(
origin_id
,
branch_name
=
'refs/heads/master'
,
ts
=
None
,
path
=
None
):
env
=
{
'message'
:
None
,
'origin_id'
:
origin_id
,
'ts'
:
ts
,
'path'
:
'.'
if
not
path
else
path
,
'result'
:
None
}
encoding
=
request
.
args
.
get
(
'encoding'
,
'utf8'
)
if
encoding
not
in
aliases
:
env
[
'message'
]
=
'Encoding
%s
not supported.'
\
'Supported Encodings:
%s
'
%
(
encoding
,
list
(
aliases
.
keys
()))
return
render_template
(
'revision-directory.html'
,
**
env
)
try
:
result
=
api
.
api_directory_through_revision_origin
(
origin_id
,
branch_name
,
ts
,
path
,
with_data
=
True
)
result
[
'content'
]
=
utils
.
prepare_data_for_view
(
result
[
'content'
],
encoding
=
encoding
)
env
[
'revision'
]
=
result
[
'revision'
]
env
[
'result'
]
=
result
except
(
ValueError
,
BadInputExc
,
NotFoundExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'revision-directory.html'
,
**
env
)
@app.route
(
'/browse/entity/'
)
@app.route
(
'/browse/entity/<string:uuid>/'
)
def
browse_entity
(
uuid
):
env
=
{
'entities'
:
[],
'message'
:
None
}
try
:
entities
=
api
.
api_entity_by_uuid
(
uuid
)
env
[
'entities'
]
=
entities
except
(
NotFoundExc
,
BadInputExc
)
as
e
:
env
[
'message'
]
=
str
(
e
)
return
render_template
(
'entity.html'
,
**
env
)
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Jul 4 2025, 6:40 PM (5 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3365798
Attached To
rDWAPPS Web applications
Event Timeline
Log In to Comment