Changeset View
Changeset View
Standalone View
Standalone View
swh/web/browse/views/revision.py
# Copyright (C) 2017-2018 The Software Heritage developers | # Copyright (C) 2017-2018 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import hashlib | import hashlib | ||||
import json | import json | ||||
import textwrap | import textwrap | ||||
from django.http import HttpResponse | from django.http import HttpResponse | ||||
from django.shortcuts import render, redirect | from django.shortcuts import render, redirect | ||||
from django.template.defaultfilters import filesizeformat | from django.template.defaultfilters import filesizeformat | ||||
from django.utils.safestring import mark_safe | from django.utils.safestring import mark_safe | ||||
from swh.model.identifiers import persistent_identifier | from swh.model.identifiers import persistent_identifier | ||||
from swh.web.algos.revisions_walker import get_revisions_walker | |||||
from swh.web.common import service | from swh.web.common import service | ||||
from swh.web.common.utils import ( | from swh.web.common.utils import ( | ||||
reverse, format_utc_iso_date, gen_path_info | reverse, format_utc_iso_date, gen_path_info | ||||
) | ) | ||||
from swh.web.common.exc import NotFoundExc, handle_view_exception | from swh.web.common.exc import NotFoundExc, handle_view_exception | ||||
from swh.web.browse.browseurls import browse_route | from swh.web.browse.browseurls import browse_route | ||||
from swh.web.browse.utils import ( | from swh.web.browse.utils import ( | ||||
gen_link, gen_person_link, gen_revision_link, | gen_link, gen_person_link, gen_revision_link, | ||||
prepare_revision_log_for_display, | format_log_entries, | ||||
get_snapshot_context, gen_snapshot_directory_link, | get_snapshot_context, gen_snapshot_directory_link, | ||||
get_revision_log_url, get_directory_entries, | get_revision_log_url, get_directory_entries, | ||||
gen_directory_link, request_content, prepare_content_for_display, | gen_directory_link, request_content, prepare_content_for_display, | ||||
content_display_max_size, gen_snapshot_link, get_readme_to_display, | content_display_max_size, gen_snapshot_link, get_readme_to_display, | ||||
get_swh_persistent_ids | get_swh_persistent_ids | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | diff_data = { | ||||
'total_nb_changes': len(changes), | 'total_nb_changes': len(changes), | ||||
'changes': changes[:_max_displayed_file_diffs], | 'changes': changes[:_max_displayed_file_diffs], | ||||
'changes_msg': changes_msg | 'changes_msg': changes_msg | ||||
} | } | ||||
diff_data_json = json.dumps(diff_data, separators=(',', ': ')) | diff_data_json = json.dumps(diff_data, separators=(',', ': ')) | ||||
return HttpResponse(diff_data_json, content_type='application/json') | return HttpResponse(diff_data_json, content_type='application/json') | ||||
NB_LOG_ENTRIES = 20 | NB_LOG_ENTRIES = 100 | ||||
@browse_route(r'revision/(?P<sha1_git>[0-9a-f]+)/log/', | @browse_route(r'revision/(?P<sha1_git>[0-9a-f]+)/log/', | ||||
view_name='browse-revision-log') | view_name='browse-revision-log') | ||||
def revision_log_browse(request, sha1_git): | def revision_log_browse(request, sha1_git): | ||||
""" | """ | ||||
Django view that produces an HTML display of the history | Django view that produces an HTML display of the history | ||||
log for a SWH revision identified by its id. | log for a SWH revision identified by its id. | ||||
The url that points to it is :http:get:`/browse/revision/(sha1_git)/log/`. | The url that points to it is :http:get:`/browse/revision/(sha1_git)/log/` | ||||
""" # noqa | """ # noqa | ||||
try: | try: | ||||
per_page = int(request.GET.get('per_page', NB_LOG_ENTRIES)) | per_page = int(request.GET.get('per_page', NB_LOG_ENTRIES)) | ||||
revision_log = service.lookup_revision_log(sha1_git, | offset = int(request.GET.get('offset', 0)) | ||||
limit=per_page+1) | revs_ordering = request.GET.get('revs_ordering', 'committer_date') | ||||
revision_log = list(revision_log) | session_key = 'rev_%s_log_ordering_%s' % (sha1_git, revs_ordering) | ||||
rev_log_session = request.session.get(session_key, None) | |||||
rev_log = [] | |||||
revs_walker_state = None | |||||
if rev_log_session: | |||||
rev_log = rev_log_session['rev_log'] | |||||
revs_walker_state = rev_log_session['revs_walker_state'] | |||||
if len(rev_log) < offset+per_page: | |||||
revs_walker = get_revisions_walker(revs_ordering, sha1_git, | |||||
max_revs=offset+per_page+1, | |||||
state=revs_walker_state) | |||||
rev_log += list(revs_walker) | |||||
revs_walker_state = revs_walker.export_state() | |||||
revision_log = rev_log[offset:offset+per_page] | |||||
request.session[session_key] = { | |||||
'rev_log': rev_log, | |||||
'revs_walker_state': revs_walker_state | |||||
} | |||||
except Exception as exc: | except Exception as exc: | ||||
return handle_view_exception(request, exc) | return handle_view_exception(request, exc) | ||||
revs_breadcrumb = request.GET.get('revs_breadcrumb', None) | revs_ordering = request.GET.get('revs_ordering', '') | ||||
revision_log_display_data = prepare_revision_log_for_display( | |||||
revision_log, per_page, revs_breadcrumb) | |||||
prev_rev = revision_log_display_data['prev_rev'] | |||||
prev_revs_breadcrumb = revision_log_display_data['prev_revs_breadcrumb'] | |||||
prev_log_url = None | prev_log_url = None | ||||
if prev_rev: | if len(rev_log) > offset + per_page: | ||||
prev_log_url = \ | prev_log_url = reverse('browse-revision-log', | ||||
reverse('browse-revision-log', | kwargs={'sha1_git': sha1_git}, | ||||
kwargs={'sha1_git': prev_rev}, | query_params={'per_page': per_page, | ||||
query_params={'revs_breadcrumb': prev_revs_breadcrumb, | 'offset': offset + per_page, | ||||
'per_page': per_page}) | 'revs_ordering': revs_ordering}) | ||||
next_rev = revision_log_display_data['next_rev'] | |||||
next_revs_breadcrumb = revision_log_display_data['next_revs_breadcrumb'] | |||||
next_log_url = None | next_log_url = None | ||||
if next_rev: | if offset != 0: | ||||
next_log_url = \ | next_log_url = reverse('browse-revision-log', | ||||
reverse('browse-revision-log', | kwargs={'sha1_git': sha1_git}, | ||||
kwargs={'sha1_git': next_rev}, | query_params={'per_page': per_page, | ||||
query_params={'revs_breadcrumb': next_revs_breadcrumb, | 'offset': offset - per_page, | ||||
'per_page': per_page}) | 'revs_ordering': revs_ordering}) | ||||
revision_log_data = revision_log_display_data['revision_log_data'] | revision_log_data = format_log_entries(revision_log, per_page) | ||||
for log in revision_log_data: | |||||
log['directory'] = gen_directory_link( | |||||
log['directory'], | |||||
link_text='<i class="fa fa-folder-open fa-fw" aria-hidden="true">' | |||||
'</i>Browse files', | |||||
link_attrs={'class': 'btn btn-default btn-sm', | |||||
'role': 'button'}) | |||||
swh_rev_id = persistent_identifier('revision', sha1_git) | swh_rev_id = persistent_identifier('revision', sha1_git) | ||||
return render(request, 'browse/revision-log.html', | return render(request, 'browse/revision-log.html', | ||||
{'heading': 'Revision history', | {'heading': 'Revision history', | ||||
'swh_object_id': swh_rev_id, | 'swh_object_id': swh_rev_id, | ||||
'swh_object_name': 'Revision history', | 'swh_object_name': 'Revision history', | ||||
'swh_object_metadata': None, | 'swh_object_metadata': None, | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if revision['author']: | ||||
revision_data['author'] = \ | revision_data['author'] = \ | ||||
gen_person_link(revision['author']['id'], author_name, | gen_person_link(revision['author']['id'], author_name, | ||||
snapshot_context) | snapshot_context) | ||||
revision_data['committer'] = 'None' | revision_data['committer'] = 'None' | ||||
if revision['committer']: | if revision['committer']: | ||||
revision_data['committer'] = \ | revision_data['committer'] = \ | ||||
gen_person_link(revision['committer']['id'], | gen_person_link(revision['committer']['id'], | ||||
revision['committer']['name'], snapshot_context) | revision['committer']['name'], snapshot_context) | ||||
revision_data['committer date'] = format_utc_iso_date( | revision_data['committer_date'] = format_utc_iso_date( | ||||
revision['committer_date']) | revision['committer_date']) | ||||
revision_data['date'] = format_utc_iso_date(revision['date']) | revision_data['date'] = format_utc_iso_date(revision['date']) | ||||
if snapshot_context: | if snapshot_context: | ||||
revision_data['snapshot id'] = snapshot_id | revision_data['snapshot id'] = snapshot_id | ||||
revision_data['directory'] = \ | revision_data['directory'] = \ | ||||
gen_snapshot_directory_link(snapshot_context, sha1_git, | gen_snapshot_directory_link(snapshot_context, sha1_git, | ||||
link_text='Browse', | link_text='Browse', | ||||
link_attrs={'class': 'btn btn-default btn-sm', # noqa | link_attrs={'class': 'btn btn-default btn-sm', # noqa | ||||
▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | else: | ||||
query_params=query_params) | query_params=query_params) | ||||
if f['length'] is not None: | if f['length'] is not None: | ||||
f['length'] = filesizeformat(f['length']) | f['length'] = filesizeformat(f['length']) | ||||
if f['name'].lower().startswith('readme'): | if f['name'].lower().startswith('readme'): | ||||
readmes[f['name']] = f['checksums']['sha1'] | readmes[f['name']] = f['checksums']['sha1'] | ||||
readme_name, readme_url, readme_html = get_readme_to_display(readmes) | readme_name, readme_url, readme_html = get_readme_to_display(readmes) | ||||
top_right_link = get_revision_log_url(sha1_git, snapshot_context) | top_right_link = get_revision_log_url(sha1_git, snapshot_context, path) | ||||
top_right_link_text = mark_safe( | top_right_link_text = mark_safe( | ||||
'<i class="fa fa-history fa-fw" aria-hidden="true"></i>' | '<i class="fa fa-history fa-fw" aria-hidden="true"></i>' | ||||
'History') | 'History') | ||||
vault_cooking['directory_context'] = True | vault_cooking['directory_context'] = True | ||||
vault_cooking['directory_id'] = dir_id | vault_cooking['directory_id'] = dir_id | ||||
swh_objects.append({'type': 'directory', | swh_objects.append({'type': 'directory', | ||||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |