from bugzilla import Bugzilla
import logging
+import argparse
+from pathlib import Path
from budget_sync.util import all_bugs
+from budget_sync.config import Config, ConfigParseError
from budget_sync.budget_graph import BudgetGraph, BudgetGraphBaseError
-
-
-BUGZILLA_URL = "https://bugs.libre-soc.org"
+from budget_sync.write_budget_markdown import write_budget_markdown
def main():
- logging.info("Using Bugzilla instance at %s", BUGZILLA_URL)
- bz = Bugzilla(BUGZILLA_URL)
+ parser = argparse.ArgumentParser(
+ description="Check for errors in "
+ "Libre-SOC's style of budget tracking in Bugzilla.")
+ parser.add_argument(
+ "-c", "--config", type=argparse.FileType('r'),
+ required=True, help="The path to the configuration TOML file",
+ dest="config", metavar="<path/to/budget-sync-config.toml>")
+ parser.add_argument(
+ "-o", "--output-dir", type=Path, default=None,
+ help="The path to the output directory, will be created if it "
+ "doesn't exist",
+ dest="output_dir", metavar="<path/to/output/dir>")
+ args = parser.parse_args()
+ try:
+ with args.config as config_file:
+ config = Config.from_file(config_file)
+ except (IOError, ConfigParseError) as e:
+ logging.error("Failed to parse config file: %s", e)
+ return
+ logging.info("Using Bugzilla instance at %s", config.bugzilla_url)
+ bz = Bugzilla(config.bugzilla_url)
logging.debug("Connected to Bugzilla")
- budget_graph = BudgetGraph(all_bugs(bz))
+ budget_graph = BudgetGraph(all_bugs(bz), config)
for error in budget_graph.get_errors():
logging.error("%s", error)
+ if args.output_dir is not None:
+ write_budget_markdown(budget_graph, args.output_dir)
+
+ # quick hack to display total payment amounts per-milestone
+ for milestone, payments in budget_graph.milestone_payments.items():
+ print (milestone)
+ total = 0
+ total_requested = 0
+ total_req_or_paid = 0
+ total_paid = 0
+ for payment in payments:
+ print("\t", payment)
+ total += payment.amount
+ if payment.submitted is not None:
+ total_requested += payment.amount
+ if payment.paid is not None:
+ total_paid += payment.amount
+ if payment.submitted or payment.paid is not None:
+ total_req_or_paid += payment.amount
+
+ print ("\t %-9s" % total,
+ "submitted %-9s" % total_requested,
+ "paid %-9s" % total_paid,
+ "submitted or paid %-9s" % total_req_or_paid)
+ print ()
+
+ # and one to display peole
+ milestones_people = budget_graph.get_milestone_people()
+ for milestone, people in milestones_people.items():
+ print (milestone)
+ for person in people:
+ print("\t", person)
+ # even quicker hack to create something vaguely resembling a CSV file
+ milestone_csvs = {}
+ for milestone, payments in budget_graph.milestone_payments.items():
+ # first get the list of people, then create some columns
+ people = milestones_people[milestone]
+ headings = []
+ for person in people:
+ name = str(person).replace(" ", "_")
+ # name, amount, requested (submitted), paid
+ headings.append(name+"_amount")
+ headings.append(name+"_req")
+ headings.append(name+"_paid")
+ # now we go through the whole "payments" thing again...
+ milestone_csvs[milestone] = [] # rows in the CSV file
+ row = {}
+ for payment in payments:
+ name = str(payment.payee.identifier).replace(" ", "_")
+ row[name+"_amount"] = str(payment.amount)
+ if payment.submitted is not None:
+ requested = str(payment.submitted)
+ else:
+ requested = ""
+ if payment.paid is not None:
+ paid = str(payment.paid)
+ else:
+ paid = ""
+ row[name+"_req"] = requested
+ row[name+"_paid"] = paid
+ print (row)
+ milestone_csvs[milestone].append(row)
if __name__ == "__main__":
main()