Fix T56372: Properly show error messages when submission fails

This also introduces a word-wrapping function that takes variable character
widths into account.
This commit is contained in:
2018-08-14 15:05:37 +02:00
parent 9ed933760c
commit 7b88d7704c
4 changed files with 100 additions and 6 deletions

View File

@@ -4,11 +4,12 @@ import blf
import bpy
from ..foundation import util
from ..submission.client import CommunicationError
from . import G
WELCOME_TEXT = "Run the Quick Benchmark on the selected device to\n" \
WELCOME_TEXT = "Run the Quick Benchmark on the selected device to " \
"get a fast measurement of your hardware's performance.\n" \
"Usually takes less than 30 minutes."
@@ -147,7 +148,9 @@ def _draw_introduction(image_y, ui_scale, window_width, window_height):
x = 50.0 * ui_scale
y = image_y - (image_y - 52 * ui_scale - 18 * 3 * ui_scale) * 0.5
blf.size(font_id, int(12 * ui_scale), 72)
draw_text_multiline(WELCOME_TEXT, x, y)
text = word_wrap(WELCOME_TEXT, window_width * 0.45)
draw_text_multiline(text, x, y)
def _draw_benchmark_is_running(image_y, result_platform, result_stats, ui_scale, window_width):
@@ -208,4 +211,74 @@ def _draw_benchmark_has_run(image_y, ui_scale, window_width, window_height):
x = 50.0 * ui_scale
y = image_y - (image_y - 52 * ui_scale - 18 * 3 * ui_scale) * 0.5
blf.size(font_id, int(12 * ui_scale), 72)
draw_text_multiline(BLURB_TEXT, x, y)
text = _after_submission_text()
text = word_wrap(text, window_width * 0.45)
draw_text_multiline(text, x, y)
def _after_submission_text() -> str:
ex = G.submission_exception
# Nothing wrong, just show the default text.
if not ex:
return BLURB_TEXT
# If not our own exception class, show generic message.
if not isinstance(ex, CommunicationError):
return f'Error submitting your results: {ex}'
# Return proper message based on the HTTP status code of the response.
if ex.status_code in {502, 503}:
# 502 Bad Gateway, happens when restarting uWSGI.
# 503 Service Unavailable, happens when OpenData is down.
text = f'There was a hickups with code {ex.status_code} ' \
f'in the Open Data platform, please try submitting again.'
elif ex.status_code == 422:
# 422 Unprocessable Entity, happens when the JSON doesn't pass schema validation.
text = f'We somehow submitted invalid data, see below for details.'
else:
text = f'Error {ex.status_code} submitting your results.'
if not ex.json:
return text
msg = ex.json.get('message')
if msg:
return f'{text}\nThe server said: {msg}'
return text
def word_wrap(string: str, width_in_px: int) -> str:
"""Word-wrapping with variable character width.
Newlines in the input string are kept in the output.
"""
if '\n' in string:
# If the string already consists of multiple lines, wrap each line individually.
return '\n'.join(word_wrap(line, width_in_px)
for line in string.splitlines(keepends=False))
# Do an estimate of the maximum number of characters to fit on a line.
char_width = blf.dimensions(font_id, "i")[0]
max_chars = int(width_in_px // char_width)
wrapped_lines = []
while string:
# The line won't be longer than max_chars, so start there.
candidate_line = string[:max_chars]
line_width = blf.dimensions(font_id, candidate_line)[0]
# Keep removing the last word until the line fits the width.
while line_width >= width_in_px:
marker = len(candidate_line) - 1
while not candidate_line[marker].isspace():
marker -= 1
candidate_line = candidate_line[:marker]
line_width = blf.dimensions(font_id, candidate_line)[0]
string = string[len(candidate_line):]
wrapped_lines.append(candidate_line.strip())
return '\n'.join(wrapped_lines)