Skip to content

Commit

Permalink
GraphViewer: Error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
thvitt committed Apr 17, 2019
1 parent cfcb48e commit bd7e741
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 9 deletions.
23 changes: 18 additions & 5 deletions graphviewer/graphviewer.py
Expand Up @@ -2,7 +2,7 @@
import subprocess

import networkx as nx
from flask import Flask, render_template, request, Response
from flask import Flask, render_template, request, Response, flash
from markupsafe import Markup
from networkx import DiGraph

Expand All @@ -11,6 +11,14 @@

app = Flask(__name__)

try:
from gv_config import SECRET_KEY
app.secret_key = SECRET_KEY
except ImportError:
app.logger.error('No secret key config -- using unsafe default')
app.secret_key = b'not-really-a-secret-key'


info = MacrogenesisInfo('target/macrogenesis/macrogen-info.zip') # FIXME evil


Expand All @@ -20,10 +28,14 @@ class NoNodes(ValueError):

def prepare_agraph():
node_str = request.args.get('nodes')
nodes = info.nodes(node_str)
nodes, errors = info.nodes(node_str, report_errors=True)
if errors:
flash('Die folgenden zentralen Knoten wurden nicht gefunden: ' + ', '.join(errors), 'warning')
context = request.args.get('context', False)
abs_dates = request.args.get('abs_dates', False)
extra = info.nodes(request.args.get('extra', ''))
extra, errors = info.nodes(request.args.get('extra', ''), report_errors=True)
if errors:
flash('Die folgenden Pfadziele wurden nicht gefunden: ' + ', '.join(errors), 'warning')
induced_edges = request.args.get('induced_edges', False)
ignored_edges = request.args.get('ignored_edges', False)
direct_assertions = request.args.get('assertions', False)
Expand All @@ -45,7 +57,7 @@ def prepare_agraph():
reduction = nx.transitive_reduction(g)
g = g.edge_subgraph([(u, v, k) for u, v, k, _ in expand_edges(g, reduction.edges)])
else:
g.add_node('Cannot produce DAG!?') # FIXME improve error reporting
flash('Cannot produce DAG – subgraph is not acyclic!?', 'error')
g = simplify_timeline(g)
g.add_nodes_from(nodes)
agraph = write_dot(g, target=None, highlight=nodes, edge_labels=not no_edge_labels)
Expand All @@ -68,7 +80,8 @@ def render_form():
output = subprocess.check_output(['dot', '-T', 'svg'], input=codecs.encode(agraph.to_string()), timeout=30)
svg = Markup(codecs.decode(output))
except NoNodes:
svg = 'Bitte Knoten und Optionen im Formular angeben.'
flash(Markup('<strong>Keine Knoten im Graphen.</strong> Bitte mindestens einen Knoten im Feld <em>Zentrale Knoten</em> eingeben.'), 'danger')
svg = ''
return render_template('form.html', svg=svg, query=codecs.decode(request.query_string), **_normalize_args(request.args))


Expand Down
15 changes: 15 additions & 0 deletions graphviewer/templates/faustedition.html
Expand Up @@ -42,6 +42,21 @@
</nav>
</header>
<main>
{% block errors %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="error-container center pure-g-r">
{% for category, message in messages %}
<div class="pure-u-1 pure-alert pure-alert-{{ category }}">
<i class="fa fa-cancel pure-pull-right closebtn"
onclick="this.parentElement.parentElement.removeChild(this.parentElement);"></i>
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% endblock %}
{% block content %}
{% endblock %}
</main>
Expand Down
2 changes: 1 addition & 1 deletion graphviewer/templates/form.html
Expand Up @@ -12,7 +12,7 @@ <h3>Zentrale Knoten</h3>
<p><input type="text" name="nodes" id="nodes" value="{{ nodes }}" style="width: 100%;" placeholder="2 V H.13"></p>
<p><input type="checkbox" name="context" id="context" {% if context %}checked{% endif %}> <label for="context">Nachbarknoten</label></p>
<p><input type="checkbox" name="assertions" id="assertions" {% if assertions %}checked{% endif %} <label for="assertions">unmittelbare Aussagen über Kernknoten</label> </p>
<p><input type="submit"></p></section>
<p><input type="submit" class="pure-button pure-button-primary" value="Teilgraph zeichnen"></p></section>
</section>
<section class="pure-u-1-3">
<h3>Zusätzliche Pfade</h3>
Expand Down
15 changes: 12 additions & 3 deletions src/macrogen/graph.py
Expand Up @@ -366,32 +366,41 @@ def first(iterable):
else:
return default

def nodes(self, node_str: str, check: bool = False) -> List[Node]:
def nodes(self, node_str: str, check: bool = False, report_errors: bool = False) -> Union[List[Node], Tuple[List[Node], List[str]]]:
"""
Find nodes for a comma-separated list of node strings.
Args:
node_str:
check: if true, raise exception when a node has not been found
report_errors: if True, return an additional list of strings that couldn’t be resolved
See also:
MacrogenesisInfo.node
Returns:
unless report_errors, a list of Nodes (i.e. each item is either a Reference or a date).
Otherwise, a pair: first a list of Nodes, then a list of strings which could not be resolved; both possibly empty.
"""
nodes = []
nodes: List[Node] = []
errors: List[str] = []
if node_str:
for node_spec in node_str.split(','):
try:
stripped = node_spec.strip()
nodes.append(self.node(stripped))
except KeyError:
if report_errors:
errors.append(node_spec)
if check:
raise
else:
logger.warning('Requested node %s not found in the graph', stripped)
return nodes
if report_errors:
return nodes, errors
else:
return nodes

def add_path(self, graph: nx.MultiDiGraph, source: Node, target: Node, weight='iweight', method='dijkstra',
must_exist=False, edges_from: Optional[nx.MultiDiGraph] = None):
Expand Down

0 comments on commit bd7e741

Please sign in to comment.