|
2 | 2 | import json |
3 | 3 | import re |
4 | 4 | import sqlite3 |
5 | | -import os, time |
| 5 | +import os |
| 6 | +import time |
6 | 7 | import socket |
7 | 8 | import logging |
8 | 9 |
|
|
12 | 13 |
|
13 | 14 | # fff_dqmtools fixed the imports for us |
14 | 15 | import bottle |
| 16 | +from bottle import abort |
15 | 17 | import zlib |
16 | 18 | import itertools |
17 | 19 | import requests |
| 20 | +from pathlib import Path |
18 | 21 |
|
19 | 22 | log = logging.getLogger(__name__) |
20 | 23 |
|
@@ -403,6 +406,42 @@ def __init__(self, str): |
403 | 406 | return output_messages |
404 | 407 |
|
405 | 408 |
|
| 409 | +def get_list_of_release_comparisons(cmssw_comparison_reports_path: Path): |
| 410 | + valid_reports = [] |
| 411 | + for subdir in cmssw_comparison_reports_path.iterdir(): |
| 412 | + m = re.match( |
| 413 | + r"^(?P<timestamp>\d{8}-\d{6})_" |
| 414 | + + r"comparison_base_\d{4}_" |
| 415 | + + r"CMSSW_(?P<cmssw_base>\d{1,2}_\d{1,2}_\d{1,2}(_pre\d|_patch\d)?)(?P<base_prs>(_\d{1,5})*?)" |
| 416 | + + r"_vs_comparison_comp_\d{4}_" |
| 417 | + + r"CMSSW_(?P<cmssw_comp>\d{1,2}_\d{1,2}_\d{1,2}(_pre\d|_patch\d)?)(?P<comp_prs>(_\d{1,5})*?)$", |
| 418 | + subdir.name, |
| 419 | + ) |
| 420 | + |
| 421 | + if m and subdir.joinpath("dqm-histo-comparison-summary.html").exists(): |
| 422 | + # Path matches comparison results regex, |
| 423 | + # and the expected html report is in there. |
| 424 | + # Convert to str because Path is not JSON serializable. |
| 425 | + answer = { |
| 426 | + "timestamp": m["timestamp"], |
| 427 | + "base": m["cmssw_base"], |
| 428 | + "base_prs": ( |
| 429 | + [] |
| 430 | + if "base_prs" not in m.groupdict() |
| 431 | + else [pr for pr in m["base_prs"].split("_") if pr] |
| 432 | + ), |
| 433 | + "comp": m["cmssw_comp"], |
| 434 | + "comp_prs": ( |
| 435 | + [] |
| 436 | + if "comp_prs" not in m.groupdict() |
| 437 | + else [pr for pr in m["comp_prs"].split("_") if pr] |
| 438 | + ), |
| 439 | + "id": subdir.name, |
| 440 | + } |
| 441 | + valid_reports.append(answer) |
| 442 | + return valid_reports |
| 443 | + |
| 444 | + |
406 | 445 | class WebServer(bottle.Bottle): |
407 | 446 | def __init__(self, db=None, opts={}): |
408 | 447 | bottle.Bottle.__init__(self) |
@@ -1020,13 +1059,44 @@ def cr_api(): |
1020 | 1059 | sock.shutdown(socket.SHUT_WR) |
1021 | 1060 | sock.close() |
1022 | 1061 | return "start_playback_run Ok" |
| 1062 | + elif what == "cmssw_comparison_reports": |
| 1063 | + """ |
| 1064 | + Return a list of directories created by cmssw_release_comparison. |
| 1065 | +
|
| 1066 | + If 'id' is also passed as an argument, use it to serve |
| 1067 | + the comparison result |
| 1068 | + """ |
| 1069 | + cmssw_comparison_reports_path = Path( |
| 1070 | + self.opts["cmssw_comparison_reports"] |
| 1071 | + ) |
| 1072 | + assert cmssw_comparison_reports_path.exists() |
| 1073 | + |
| 1074 | + comparison_id = bottle.request.query.get("id") |
| 1075 | + if comparison_id: |
| 1076 | + if cmssw_comparison_reports_path.joinpath( |
| 1077 | + comparison_id, "dqm-histo-comparison-summary.html" |
| 1078 | + ).exists(): |
| 1079 | + return bottle.static_file( |
| 1080 | + "dqm-histo-comparison-summary.html", |
| 1081 | + root=cmssw_comparison_reports_path.joinpath( |
| 1082 | + comparison_id |
| 1083 | + ), |
| 1084 | + ) |
| 1085 | + else: |
| 1086 | + abort(400, f"Comparison with id {comparison_id} not found") |
| 1087 | + |
| 1088 | + # Populate directory of release comparisons and return it as JSON |
| 1089 | + valid_reports = get_list_of_release_comparisons( |
| 1090 | + cmssw_comparison_reports_path |
| 1091 | + ) |
| 1092 | + return json.dumps(valid_reports) |
1023 | 1093 |
|
1024 | | - except Exception as error_log: |
1025 | | - msg = f"cr_api@{what}: error: {error_log}" |
| 1094 | + except Exception as e: |
| 1095 | + msg = f"cr_api@{what}: error: {e}" |
1026 | 1096 | log.error(msg, exc_info=True) |
1027 | | - return msg, 400 |
| 1097 | + abort(400, msg) |
1028 | 1098 | log.warning(f"cr_api@{what} : No actions defined for that request") |
1029 | | - return f"No actions defined for request {what}", 400 |
| 1099 | + abort(400, f"Invalid request '{what}'") |
1030 | 1100 |
|
1031 | 1101 |
|
1032 | 1102 | def run_web_greenlet(db, host="0.0.0.0", port=9215, opts={}, **kwargs): |
|
0 commit comments