From 784a511708b5d756e20b9b3eecd7892948170b2f Mon Sep 17 00:00:00 2001 From: Markus Birth Date: Fri, 9 Feb 2018 00:17:08 +0100 Subject: [PATCH] Added standalone DumpMgr class. --- tclcheck_allfull.py | 3 +- tclcheck_allota.py | 4 +-- tcllib/requests/__init__.py | 1 + tcllib/requests/dumpmgr.py | 58 ++++++++++++++++++++++++++++++++++++ tcllib/requests/tclresult.py | 12 ++++++-- 5 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 tcllib/requests/dumpmgr.py diff --git a/tclcheck_allfull.py b/tclcheck_allfull.py index 2286b39..4c18be2 100644 --- a/tclcheck_allfull.py +++ b/tclcheck_allfull.py @@ -13,6 +13,7 @@ import tcllib import tcllib.argparser from tcllib import ansi, devlist from tcllib.devices import DesktopDevice +from tcllib.requests import RequestRunner, CheckRequest, ServerVoteSelector, write_info_if_dumps_found dev = DesktopDevice() @@ -56,4 +57,4 @@ for prd, variant in prds.items(): print("{}: {}".format(prd, str(e))) continue -tcllib.FotaCheck.write_info_if_dumps_found() +write_info_if_dumps_found() diff --git a/tclcheck_allota.py b/tclcheck_allota.py index 70705d6..6636750 100644 --- a/tclcheck_allota.py +++ b/tclcheck_allota.py @@ -11,7 +11,7 @@ import tcllib import tcllib.argparser from tcllib import ansi, devlist from tcllib.devices import MobileDevice -from tcllib.requests import RequestRunner, CheckRequest, ServerVoteSelector +from tcllib.requests import RequestRunner, CheckRequest, ServerVoteSelector, write_info_if_dumps_found dev = MobileDevice() @@ -59,4 +59,4 @@ for prd, variant in prds.items(): else: print("{} ({}): {}".format(prd, lastver, chk.error)) -tcllib.FotaCheck.write_info_if_dumps_found() +write_info_if_dumps_found() diff --git a/tcllib/requests/__init__.py b/tcllib/requests/__init__.py index c06739f..550f737 100644 --- a/tcllib/requests/__init__.py +++ b/tcllib/requests/__init__.py @@ -3,3 +3,4 @@ from .tcl import * from .runner import * from .serverselector import * +from .dumpmgr import write_info_if_dumps_found diff --git a/tcllib/requests/dumpmgr.py b/tcllib/requests/dumpmgr.py new file mode 100644 index 0000000..57796c8 --- /dev/null +++ b/tcllib/requests/dumpmgr.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# pylint: disable=C0111,C0326,C0103 + +"""Tools to manage dumps of API requests.""" + +import errno +import glob +import os +import random +import time +from math import floor + +from .. import ansi + + +def get_timestamp_random(): + """Generate timestamp + random part to avoid collisions.""" + millis = floor(time.time() * 1000) + tail = "{:06d}".format(random.randint(0, 999999)) + return "{}_{}".format(str(millis), tail) + +def write_info_if_dumps_found(): + """Notify user to upload dumps if present.""" + # To disable this info, uncomment the following line. + # return + files = glob.glob(os.path.normpath("logs/*.xml")) + if files: + print() + print("{}There are {} logs collected in the logs/ directory.{} Please consider uploading".format(ansi.YELLOW, len(files), ansi.RESET)) + print("them to https://tclota.birth-online.de/ by running {}./upload_logs.py{}.".format(ansi.CYAN, ansi.RESET)) + +class DumpMgr: + """A class for XML dump management.""" + + def __init__(self): + """Populate dump file name.""" + self.last_dump_filename = None + + def write_dump(self, data): + """Write dump to file.""" + outfile = os.path.normpath("logs/{}.xml".format(get_timestamp_random())) + if not os.path.exists(os.path.dirname(outfile)): + try: + os.makedirs(os.path.dirname(outfile)) + except OSError as err: + if err.errno != errno.EEXIST: + raise + with open(outfile, "w", encoding="utf-8") as fhandle: + fhandle.write(data) + self.last_dump_filename = outfile + + def delete_last_dump(self): + """Delete last dump.""" + if self.last_dump_filename: + os.unlink(self.last_dump_filename) + self.last_dump_filename = None diff --git a/tcllib/requests/tclresult.py b/tcllib/requests/tclresult.py index e801956..ced8ebb 100644 --- a/tcllib/requests/tclresult.py +++ b/tcllib/requests/tclresult.py @@ -2,13 +2,21 @@ from defusedxml import ElementTree +from . import dumpmgr + class TclResult: - pass + def __init__(self, xml: str): + self.raw_xml = xml + self.dumper = dumpmgr.DumpMgr() + self.dumper.write_dump(xml) + + def delete_dump(self): + self.dumper.delete_last_dump() class CheckResult(TclResult): def __init__(self, xml: str): - self.raw_xml = xml + super().__init__(xml) root = ElementTree.fromstring(xml) self.curef = root.find("CUREF").text self.fvver = root.find("VERSION").find("FV").text