diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2021-11-18 12:37:29 -0800 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2021-11-18 12:37:33 -0800 | 
| commit | 7163f36a5e9f159def223a76953505ffff9a56c7 (patch) | |
| tree | 2578a54eef3bb079caf4ee86e3ab6b51876ed90e /python | |
| parent | e7ad9a390584ac9df0f7c03dc687e38ca4e073e3 (diff) | |
| download | fatcat-7163f36a5e9f159def223a76953505ffff9a56c7.tar.gz fatcat-7163f36a5e9f159def223a76953505ffff9a56c7.zip | |
polish editgroup diff view
Still not as great as it could be, but useful in this state.
Diffstat (limited to 'python')
| -rw-r--r-- | python/fatcat_web/entity_helpers.py | 53 | ||||
| -rw-r--r-- | python/fatcat_web/templates/editgroup_diff.html | 52 | ||||
| -rw-r--r-- | python/fatcat_web/templates/editgroup_view.html | 62 | ||||
| -rw-r--r-- | python/tests/web_editgroup.py | 8 | 
4 files changed, 83 insertions, 92 deletions
| diff --git a/python/fatcat_web/entity_helpers.py b/python/fatcat_web/entity_helpers.py index bf81dfce..24f380c8 100644 --- a/python/fatcat_web/entity_helpers.py +++ b/python/fatcat_web/entity_helpers.py @@ -1,5 +1,5 @@  import difflib -from typing import Any, Dict, Tuple +from typing import Any, Dict, List, Tuple  from fatcat_openapi_client import (      ContainerEntity, @@ -262,47 +262,52 @@ def generic_get_editgroup_entity(      return entity, edit -def _entity_edit_diff(entity_type: str, entity_edit: EntityEdit) -> Dict[str, Any]: +def _entity_edit_diff(entity_type: str, entity_edit: EntityEdit) -> List[str]:      """ -    entity_edit -        ident -        revision -        prev_revision -        redirect_ident +    Helper to generate diff lines for a single entity edit. + +    Schema of entity_edit (as a reminder): + +        entity_edit +            ident +            revision +            prev_revision +            redirect_ident      """      pop_fields = ["revision", "state"]      new_rev = generic_get_entity_revision(entity_type, entity_edit.revision) -    new_toml = entity_to_toml(new_rev, pop_fields=pop_fields) +    new_toml = entity_to_toml(new_rev, pop_fields=pop_fields).split("\n") +    if len(new_toml) == 1 and not new_toml[0].strip(): +        new_toml = []      if entity_edit.prev_revision:          old_rev = generic_get_entity_revision(entity_type, entity_edit.prev_revision) -        old_toml = entity_to_toml(old_rev, pop_fields=pop_fields) +        old_toml = entity_to_toml(old_rev, pop_fields=pop_fields).split("\n")          fromdesc = f"/{entity_type}/rev/{entity_edit.prev_revision}.toml"      else: -        old_toml = "" +        old_toml = []          fromdesc = "(created)" -    # differ = difflib.HtmlDiff(tabsize=4) -    # html_table = differ.make_table( -    #    old_toml.split('\n'), -    #    new_toml.split('\n'), -    #    fromdesc=fromdesc, -    #    todesc=entity_edit.revision, -    #    context=True, -    #    numlines=3, -    # ) -    # return dict(html_table=html_table)      diff_lines = list(          difflib.unified_diff( -            old_toml.split("\n"), -            new_toml.split("\n"), +            old_toml, +            new_toml,              fromfile=fromdesc,              tofile=f"/{entity_type}/rev/{entity_edit.revision}.toml",          )      ) -    return dict(diff_lines=diff_lines) +    return diff_lines  def editgroup_get_diffs(editgroup: Editgroup) -> Dict[str, Any]: +    """ +    Fetches before/after entity revisions, and computes "diffs" of TOML representations. + +    Returns a dict with entity type (pluralized, like "files"), then within +    that a dict with entity ident (without prefix) containing a list of +    strings, one per line of the "unified diff" format. If there is no diff for +    an edited entity (eg, it was or redirected), instead `None` is returned for +    that entity. +    """      diffs: Dict[str, Any] = {}      for entity_type in [ @@ -322,6 +327,4 @@ def editgroup_get_diffs(editgroup: Editgroup) -> Dict[str, Any]:                  diffs[entity_type][ed.ident] = _entity_edit_diff(entity_type, ed)              else:                  diffs[entity_type][ed.ident] = None -        # XXX: -        print(diffs.keys())      return diffs diff --git a/python/fatcat_web/templates/editgroup_diff.html b/python/fatcat_web/templates/editgroup_diff.html index de6a800d..4b32fbf5 100644 --- a/python/fatcat_web/templates/editgroup_diff.html +++ b/python/fatcat_web/templates/editgroup_diff.html @@ -2,56 +2,31 @@  {% macro edit_diff_list(auth_to, editgroup, edits, diffs, entity_type, entity_name) -%}  {% if edits %} -  <h3>{{ entity_name }} Edits ({{ edits|count }})</h3> +  <h3>{{ entity_name }} Edit Diffs ({{ edits|count }})</h3>    <hr>    <div class="ui divided list">      {% for edit in edits %} -    <div class="item"> +    <div class="item" id="{{ entity_type }}_{{ edit.ident }}">        <div class="content" style="padding-bottom: 0.5em;"> -        <div style="float: right; font-weight: bold;"> -          <a href="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/{{ edit.ident }}">[view]</a> -          {% if auth_to.edit and not editgroup.changelog_index and not editgroup.submitted %} -            <br><a href="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/{{ edit.ident }}/edit" style="color: green;">[re-edit]</a> -            <br> -            <form id="submit_edit_delete" method="POST" action="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/edit/{{ edit.edit_id }}/delete" style="display:inline;"> -                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> -                <input type="submit" value="[delete]" style="background:none; color: red; border: none; font-weight:bold; cursor:pointer; padding: 0;"></input> -            </form> -          {% endif %} -        </div> -        <div class="header"> -          <a href="/{{ entity_type }}/{{ edit.ident }}">{{ entity_type }}_{{ edit.ident }}</a> -          {% if edit.redirect_ident %} -            => redirect to <a href="/{{ entity_type }}/{{ edit.redirect_ident }}">{{ entity_type }}/{{ edit.redirect_ident }}</a> -          {% elif not edit.revision %} -            deleted -          {% elif not edit.prev_revision %} -            created -          {% else %} -            updated -          {% endif %} -        </div> -        {% if edit.revision %} -          Revision: <small><code><a href="/{{ entity_type }}/rev/{{ edit.revision }}">{{ edit.revision }}</a></code></small> -        {% endif %} +        {{ entity_edit_header(auth_to, editgroup, edit, entity_type, entity_name) }}          {% if edit.extra %}            {{ entity_macros.extra_metadata(edit.extra) }}          {% endif %} -        {% if edit.revision and not edit.redirect_ident and edit.ident in diffs %} -          <div style="border: 2px solid black; overflow-x:scroll; margin: 0.5em;"> -          {% for line in diffs[edit.ident]['diff_lines'] %} +        {% if edit.revision and not edit.redirect_ident and edit.ident in diffs and diffs[edit.ident] != None %} +          <div style="border: 1px solid black; font-size: smaller; font-color: #222; word-break: break-all; margin-top: 0.5em; margin-bottom: 0.5em;"> +          {% for line in diffs[edit.ident] %}              {% set line_space = false %}              {% if line.startswith('@@') or line.startswith('---') or line.startswith('+++') %} -              {% set line_color = "lightblue" %} +              {% set line_color = "lightblue" %}{# a light blue #}              {% elif line.startswith('+') %} -              {% set line_color = "lightgreen" %} +              {% set line_color = "#a4efa4" %}{# a light green #}              {% elif line.startswith('-') %} -              {% set line_color = "#ffa3a3" %} +              {% set line_color = "#ffa3a3" %}{# a light red #}              {% else %} -              {% set line_color = "#ddd" %} +              {% set line_color = "#eee" %}{# almost white #}                {% set line_space = true %}              {% endif %} -            <pre style="background-color: {{ line_color }}; margin: 0px;">{% if line_space %} {% endif %}{{ line.strip() }}</pre> +            <pre style="background-color: {{ line_color }}; white-space: pre-wrap; margin: 0px;">{% if line_space %} {% endif %}{{ line.strip() }}</pre>            {% endfor %}            </div>          {% endif %} @@ -62,10 +37,11 @@  {% endif %}  {%- endmacro %} -{% block title %}Editgroup diff{% endblock %} +{% block title %}Editgroup Diff{% endblock %} + +{% block pagetitle %}Editgroup Diff{% endblock %}  {% block editgroupedits %} -<h3 class="ui header">All Entity Change Diffs</h3>  {{ edit_diff_list(auth_to, editgroup, editgroup.edits.releases, editgroup_diffs.release, "release", "Release") }}  {{ edit_diff_list(auth_to, editgroup, editgroup.edits.works, editgroup_diffs.work, "work", "Work") }}  {{ edit_diff_list(auth_to, editgroup, editgroup.edits.containers, editgroup_diffs.container, "container", "Container") }} diff --git a/python/fatcat_web/templates/editgroup_view.html b/python/fatcat_web/templates/editgroup_view.html index de904c2a..0142a46b 100644 --- a/python/fatcat_web/templates/editgroup_view.html +++ b/python/fatcat_web/templates/editgroup_view.html @@ -1,40 +1,45 @@  {% extends "base.html" %}  {% import "entity_macros.html" as entity_macros %} +{% macro entity_edit_header(auth_to, editgroup, edit, entity_type, entity_name) -%} +  <div style="float: right; font-weight: bold;"> +    <a href="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/{{ edit.ident }}">[view]</a> +    <a href="/editgroup/{{ editgroup.editgroup_id }}/diff#{{ entity_type }}_{{ edit.ident }}">[diff]</a> +    {% if auth_to.edit and not editgroup.changelog_index and not editgroup.submitted %} +      <br><a href="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/{{ edit.ident }}/edit" style="color: green;">[re-edit]</a> +      <br> +      <form id="submit_edit_delete" method="POST" action="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/edit/{{ edit.edit_id }}/delete" style="display:inline;"> +          <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> +          <input type="submit" value="[delete]" style="background:none; color: red; border: none; font-weight:bold; cursor:pointer; padding: 0;"></input> +      </form> +    {% endif %} +  </div> +  <div class="header"> +    <a href="/{{ entity_type }}/{{ edit.ident }}">{{ entity_type }}_{{ edit.ident }}</a> +    {% if edit.redirect_ident %} +      => redirect to <a href="/{{ entity_type }}/{{ edit.redirect_ident }}">{{ entity_type }}/{{ edit.redirect_ident }}</a> +    {% elif not edit.revision %} +      deleted +    {% elif not edit.prev_revision %} +      created +    {% else %} +      updated +    {% endif %} +  </div> +  {% if edit.revision %} +    Revision: <small><code><a href="/{{ entity_type }}/rev/{{ edit.revision }}">{{ edit.revision }}</a></code></small> +  {% endif %} +{%- endmacro %} +  {% macro edit_list(auth_to, editgroup, edits, entity_type, entity_name) -%}  <div class="{% if edits %}active{% endif %} title">    <h3><i class="dropdown icon"></i>{{ entity_name }} Edits ({{ edits|count }})</h3>  </div><div class="{% if edits %}active{% endif %} content" style="padding-bottom: 0.5em;">    <div class="ui divided list">      {% for edit in edits %} -    <div class="item"> +    <div class="item" id="{{ entity_type }}_{{ edit.ident }}">        <div class="content" style="padding-bottom: 0.5em;"> -        <div style="float: right; font-weight: bold;"> -          <a href="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/{{ edit.ident }}">[view]</a> -          {% if auth_to.edit and not editgroup.changelog_index and not editgroup.submitted %} -            <br><a href="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/{{ edit.ident }}/edit" style="color: green;">[re-edit]</a> -            <br> -            <form id="submit_edit_delete" method="POST" action="/editgroup/{{ editgroup.editgroup_id }}/{{ entity_type }}/edit/{{ edit.edit_id }}/delete" style="display:inline;"> -                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> -                <input type="submit" value="[delete]" style="background:none; color: red; border: none; font-weight:bold; cursor:pointer; padding: 0;"></input> -            </form> -          {% endif %} -        </div> -        <div class="header"> -          <a href="/{{ entity_type }}/{{ edit.ident }}">{{ entity_type }}_{{ edit.ident }}</a> -          {% if edit.redirect_ident %} -            => redirect to <a href="/{{ entity_type }}/{{ edit.redirect_ident }}">{{ entity_type }}/{{ edit.redirect_ident }}</a> -          {% elif not edit.revision %} -            deleted -          {% elif not edit.prev_revision %} -            created -          {% else %} -            updated -          {% endif %} -        </div> -        {% if edit.revision %} -          Revision: <small><code><a href="/{{ entity_type }}/rev/{{ edit.revision }}">{{ edit.revision }}</a></code></small> -        {% endif %} +        {{ entity_edit_header(auth_to, editgroup, edit, entity_type, entity_name) }}          {% if edit.extra %}            {{ entity_macros.extra_metadata(edit.extra) }}          {% endif %} @@ -51,11 +56,10 @@  {# extended by changelog_entry #}  {% block editgroupheader %} -<h1 class="ui header">Editgroup +<h1 class="ui header">{% block pagetitle %}Editgroup{% endblock %}  <span class="sub header"><code>editgroup_{{ editgroup.editgroup_id }}</code></span></h1>  {% if not auth_to.submit %} -<br clear="all">  <div class="ui info small message">    <div class="header">      What is an editgroup? diff --git a/python/tests/web_editgroup.py b/python/tests/web_editgroup.py index 62a5df2e..906c18e6 100644 --- a/python/tests/web_editgroup.py +++ b/python/tests/web_editgroup.py @@ -5,8 +5,16 @@ def test_editgroup_basics(app):      rv = app.get("/editgroup/aaaaaaaaaaaabo53aaaaaaaaae")      assert rv.status_code == 200 +    rv = app.get("/editgroup/aaaaaaaaaaaabo53aaaaaaaaae/diff") +    assert rv.status_code == 200 +    rv = app.get("/editgroup/aaaaaaaaaaaabo53aaaaaaaaa4/diff") +    assert rv.status_code == 200 +    rv = app.get("/editgroup/aaaaaaaaaaaabo53aaaaaaaaaq/diff") +    assert rv.status_code == 200      rv = app.get("/editgroup/ccccccccccccccccccccccccca")      assert rv.status_code == 404 +    rv = app.get("/editgroup/ccccccccccccccccccccccccca/diff") +    assert rv.status_code == 404      rv = app.get("/editor/aaaaaaaaaaaabkvkaaaaaaaaae")      assert rv.status_code == 200 | 
