Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F11723399
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/tools/nasqueron-reports/bin/run-report b/tools/nasqueron-reports/bin/run-report
index 2c0a843..c918d9b 100755
--- a/tools/nasqueron-reports/bin/run-report
+++ b/tools/nasqueron-reports/bin/run-report
@@ -1,110 +1,48 @@
#!/usr/bin/env python3
# -------------------------------------------------------------
# Run report
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Description: Run a specific report and format data accordingly
# License: BSD-2-Clause
# -------------------------------------------------------------
import sys
+from nasqueron_reports.actions.reports import generate_report
from nasqueron_reports.config import parse_report_config
-from nasqueron_reports.connectors import db_mysql
from nasqueron_reports.errors import *
-from nasqueron_reports.formats import mediawiki
-
-
-# -------------------------------------------------------------
-# Connectors wiring
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-def fetch_mysql_report(config):
- try:
- return db_mysql.fetch_report(config)
- except NasqueronReportDatabaseError as e:
- print(f"An error occurred at database level: {e}", file=sys.stderr)
- sys.exit(8)
- except NasqueronReportQueryError as e:
- print(e, file=sys.stderr)
- sys.exit(4)
-
-
-CONNECTORS_MAP = {
- "MariaDB": fetch_mysql_report,
- "MySQL": fetch_mysql_report,
-}
-
-
-# -------------------------------------------------------------
-# Formatters wiring
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-FORMATS_MAP = {
- "mediawiki": mediawiki.to_table,
-}
# -------------------------------------------------------------
# Application entry point
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-def wire(report_config):
- if "connector" not in report_config["service_options"]:
- service_name = report_config["service"]
- print(
- f"Service connector missing in configuration for service {service_name}",
- file=sys.stderr,
- )
- sys.exit(16)
-
- if "format" not in report_config:
- print(f"Format missing in report configuration", file=sys.stderr)
- sys.exit(16)
-
- report_connector = report_config["service_options"]["connector"]
- if report_connector not in CONNECTORS_MAP:
- print(f"Unknown connector: {report_connector}", file=sys.stderr)
- sys.exit(32)
-
- report_format = report_config["format"]
- if report_format not in FORMATS_MAP:
- print(f"Unknown format: {report_format}", file=sys.stderr)
- sys.exit(32)
-
- return CONNECTORS_MAP[report_connector], FORMATS_MAP[report_format]
-
-
-def generate_report(report_config):
- connector_cb, format_cb = wire(report_config)
-
- headers, rows = connector_cb(report_config)
-
- format_options = report_config["format_options"]
- return format_cb(headers, rows, format_options)
-
-
def run(report_name):
try:
report_config = parse_report_config(report_name)
+ report = generate_report(report_config)
except NasqueronReportConfigError as e:
print(e, file=sys.stderr)
sys.exit(2)
+ except NasqueronReportQueryError as e:
+ print(e, file=sys.stderr)
+ sys.exit(4)
+ except NasqueronReportDatabaseError as e:
+ print(f"An error occurred at database level: {e}", file=sys.stderr)
+ sys.exit(8)
- output = generate_report(report_config)
- print(output)
+ print(report.formatted)
if __name__ == "__main__":
argc = len(sys.argv)
if argc < 2:
print(f"Usage: {sys.argv[0]} <report name>", file=sys.stderr)
sys.exit(1)
run(sys.argv[1])
diff --git a/tools/nasqueron-reports/bin/sql-result-to-mediawiki-table b/tools/nasqueron-reports/bin/sql-result-to-mediawiki-table
index 33f32af..78d659b 100755
--- a/tools/nasqueron-reports/bin/sql-result-to-mediawiki-table
+++ b/tools/nasqueron-reports/bin/sql-result-to-mediawiki-table
@@ -1,79 +1,78 @@
#!/usr/bin/env python3
# -------------------------------------------------------------
# SQL result to MediaWiki table
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Description: Format a SQL query output as a MediaWiki table
# Currently supports MySQL/MariaDB format
# Usage: mysql ... | sql-result-to-mediawiki-table
# License: BSD-2-Clause
# -------------------------------------------------------------
import sys
+from nasqueron_reports import RawReport
from nasqueron_reports.formats import mediawiki
# -------------------------------------------------------------
# MySQL client parser
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def parse_mysql_client_output(stream):
"""
Parse MySQL client tabular output into list of rows.
Safer version: assumes MySQL output uses tab as delimiter.
"""
rows = []
for line in stream.splitlines():
line = line.rstrip()
if not line:
continue
parts = line.split("\t")
rows.append(parts)
return rows
def format_header(header):
return header.replace("_", " ").capitalize()
def infer_headers_map(headers):
"""
Given a list of raw SQL column names, return a dict mapping
to human-friendly MediaWiki table headers.
Example:
["page_link", "age"] ->
{"page_link": "Page link", "age": "Age"}
"""
return {header: format_header(header) for header in headers}
# -------------------------------------------------------------
# Application entry point
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def run():
stream = sys.stdin.read()
-
rows = parse_mysql_client_output(stream)
- headers = rows[0]
- rows = rows[1:]
+ report = RawReport(headers=rows[0], rows=rows[1:])
options = {
- "cols": infer_headers_map(headers),
+ "cols": infer_headers_map(report.headers),
}
- output = mediawiki.to_table(headers, rows, options)
+ output = mediawiki.to_table(report, options)
print(output)
if __name__ == "__main__":
run()
diff --git a/tools/nasqueron-reports/src/nasqueron_reports/__init__.py b/tools/nasqueron-reports/src/nasqueron_reports/__init__.py
index ab54744..a0d7296 100644
--- a/tools/nasqueron-reports/src/nasqueron_reports/__init__.py
+++ b/tools/nasqueron-reports/src/nasqueron_reports/__init__.py
@@ -1,9 +1,11 @@
# -------------------------------------------------------------
# Nasqueron Reports
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: BSD-2-Clause
# -------------------------------------------------------------
from . import config
from . import errors
+
+from .report import Report, RawReport
diff --git a/tools/nasqueron-reports/src/nasqueron_reports/actions/reports.py b/tools/nasqueron-reports/src/nasqueron_reports/actions/reports.py
new file mode 100644
index 0000000..9ce8117
--- /dev/null
+++ b/tools/nasqueron-reports/src/nasqueron_reports/actions/reports.py
@@ -0,0 +1,67 @@
+# -------------------------------------------------------------
+# Nasqueron Reports :: Actions :: Reports
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Generate a report
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+from nasqueron_reports import Report
+from nasqueron_reports.connectors import db_mysql
+from nasqueron_reports.formats import mediawiki
+from nasqueron_reports.errors import *
+
+
+# -------------------------------------------------------------
+# Action
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def generate_report(report_config):
+ connector_cb, format_cb = wire(report_config)
+
+ # Fetch the data for the report
+ report = Report()
+ report.raw.headers, report.raw.rows = connector_cb(report_config)
+
+ # Format
+ format_options = report_config["format_options"]
+ report.formatted = format_cb(report.raw, format_options)
+
+ return report
+
+
+# -------------------------------------------------------------
+# Wiring
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+CONNECTORS_MAP = {
+ "MariaDB": db_mysql.fetch_report,
+ "MySQL": db_mysql.fetch_report,
+}
+
+
+FORMATS_MAP = {
+ "mediawiki": mediawiki.to_table,
+}
+
+
+def wire(report_config):
+ if "connector" not in report_config["service_options"]:
+ service_name = report_config["service"]
+ raise NasqueronReportConfigError(f"Service connector missing in configuration for service {service_name}")
+
+ if "format" not in report_config:
+ raise NasqueronReportConfigError(f"Format missing in report configuration")
+
+ report_connector = report_config["service_options"]["connector"]
+ if report_connector not in CONNECTORS_MAP:
+ raise NasqueronReportConfigError(f"Unknown connector: {report_connector}")
+
+ report_format = report_config["format"]
+ if report_format not in FORMATS_MAP:
+ raise NasqueronReportConfigError(f"Unknown format: {report_format}")
+
+ return CONNECTORS_MAP[report_connector], FORMATS_MAP[report_format]
diff --git a/tools/nasqueron-reports/src/nasqueron_reports/formats/mediawiki.py b/tools/nasqueron-reports/src/nasqueron_reports/formats/mediawiki.py
index 0643152..98e2027 100644
--- a/tools/nasqueron-reports/src/nasqueron_reports/formats/mediawiki.py
+++ b/tools/nasqueron-reports/src/nasqueron_reports/formats/mediawiki.py
@@ -1,42 +1,42 @@
# -------------------------------------------------------------
# Nasqueron Reports :: Formats :: MediaWiki
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Description: Format report as MediaWiki table
# License: BSD-2-Clause
# -------------------------------------------------------------
from datetime import date
def read_as_str(value):
if type(value) == bytes:
return value.decode()
return str(value)
def to_row(row):
return ["|-", "| " + " || ".join(read_as_str(val) for val in row)]
def to_rows(rows):
mediawiki_rows = [to_row(row) for row in rows]
return [line for lines in mediawiki_rows for line in lines]
-def to_table(columns_names, rows, options):
+def to_table(report, options):
"""Format query result as MediaWiki table."""
today = date.today().isoformat()
lines = ['{| class="wikitable sortable"', f"|+ {today} report", "|-"]
columns_map = options.get("cols", {})
- headers = [columns_map.get(c, c) for c in columns_names]
+ headers = [columns_map.get(c, c) for c in report.headers]
lines.append("! " + " !! ".join(headers))
- lines.extend(to_rows(rows))
+ lines.extend(to_rows(report.rows))
lines.append("|}")
return "\n".join(lines)
diff --git a/tools/nasqueron-reports/src/nasqueron_reports/report.py b/tools/nasqueron-reports/src/nasqueron_reports/report.py
new file mode 100644
index 0000000..7cff4d6
--- /dev/null
+++ b/tools/nasqueron-reports/src/nasqueron_reports/report.py
@@ -0,0 +1,25 @@
+# -------------------------------------------------------------
+# Nasqueron Reports :: Reports
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Underlying types to represent a report
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+class RawReport:
+ """The report fetched from the datasource"""
+ def __init__(self, headers=None, rows=None):
+ self.headers = headers
+ self.rows = rows
+
+
+class Report:
+ """The report with access to raw report and formatted version"""
+ def __init__(self, raw=None, formatted=None):
+ if raw is None:
+ self.raw = RawReport()
+ else:
+ self.raw = raw
+
+ self.formatted = formatted
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Sep 18, 10:16 (18 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2987064
Default Alt Text
(12 KB)
Attached To
Mode
rRPRT Nasqueron internal reports
Attached
Detach File
Event Timeline
Log In to Comment