← Back to team overview

ubuntu-support-team team mailing list archive

[Merge] ~rodrigo-barbieri2010/sftools:sftc into sftools:main

 

Rodrigo Barbieri has proposed merging ~rodrigo-barbieri2010/sftools:sftc into sftools:main.

Requested reviews:
  Dan Streetman (ddstreet)

For more details, see:
https://code.launchpad.net/~rodrigo-barbieri2010/sftools/+git/sftools/+merge/426958
-- 
Your team Ubuntu Support Team is subscribed to branch sftools:main.
diff --git a/scripts/sftc_insert b/scripts/sftc_insert
new file mode 100755
index 0000000..5f9d982
--- /dev/null
+++ b/scripts/sftc_insert
@@ -0,0 +1,145 @@
+#!/usr/bin/python3
+
+import logging
+import pytz
+import sys
+
+from datetime import datetime
+from pathlib import Path
+
+# if called from git source, add parent dir to python path
+if Path(__file__).parent.name == 'scripts':
+    sys.path.insert(0, str(Path(__file__).parent.parent))
+
+from sftools.argparse import SFObjectArgumentParser
+from sftools.sf import SF
+
+
+LOG = logging.getLogger(__name__)
+
+
+def parse_params(data, sf=None):
+
+    if sf is None:
+        sf = SF()
+
+    # Param Minutes
+    LOG.debug(f"Minutes Input: {data['minutes']}")
+    if not isinstance(data['minutes'], int):
+        LOG.error("Minutes parameter is not an integer")
+        exit(1)
+
+    # Param Case Number
+    LOG.debug(f"Case Input: {data['case']}")
+    if not isinstance(data['case'], str):
+        LOG.error("Case number or ID must be a string")
+        exit(1)
+    if len(data['case']) not in (18, 8):
+        LOG.error("Double check your case number or ID param, it should be "
+                  "either 8 number digits or 18 chars ID")
+        exit(1)
+    case = sf.Case(data['case'])
+    if not case:
+        LOG.error(f"Case {data['case']} not found")
+        exit(1)
+    LOG.debug(f"Case ID: {case.Id}")
+
+    # Param Start Time
+    LOG.debug(f"Start time Input: {data.get('starttime')}")
+    if data.get('starttime'):
+        try:
+            starttime = datetime.strptime(data['starttime'],'%Y-%m-%d-%H-%M')
+        except ValueError:
+            LOG.error("Wrong timestamp format for Timecard start time, "
+                      "check your format is 'yyyy-mm-dd-hh-mm'")
+            exit(1)
+        starttime = starttime.replace(tzinfo=pytz.UTC)
+    else:
+        starttime = datetime.now(pytz.UTC)
+    starttime_str = starttime.isoformat()
+    LOG.debug(f"Start time Parsed: {starttime_str}")
+
+    # Param Work Performed
+    LOG.debug(f"Work performed Input: {data['workperformed']}")
+    if not isinstance(data['case'], str):
+        LOG.error("Data for 'Work performed' field must be a string")
+        exit(1)
+    if len(data['workperformed']) > 254:
+        LOG.error("Length of 'Work performed' string should not exceed 254 chars")
+        exit(1)
+
+    # Dict
+    params = {
+        'TotalMinutesStatic__c': data['minutes'],
+        'CaseId__c': case.Id,
+        'StartTime__c': starttime_str,
+        'WorkPerformed__c': data['workperformed'],
+    }
+    LOG.debug(f"Insert Dict: {params}")
+    LOG.info(f"Parsed Timecard ( Case Number/ID: {case.CaseNumber} / {case.Id}"
+             f", Minutes: {data['minutes']}, Start Time: {starttime_str}"
+             f", Work Performed: {data['workperformed']} )")
+    return params
+
+
+def insert(params, sf=None):
+
+    if sf is None:
+        sf = SF()
+
+    result = sf.TimeCard__c.create(params)
+    LOG.debug(f"Result: {result}")
+    if result and result.get('success') == True and result.get('errors') == []:
+        LOG.info(f"Inserted Timecard Successfully ( "
+                 f"Case ID: {params['CaseId__c']}, "
+                 f"Minutes: {params['TotalMinutesStatic__c']}, "
+                 f"Start Time: {params['StartTime__c']}, "
+                 f"Work Performed: {params['WorkPerformed__c']} )")
+    else:
+        LOG.error(f"Failed to insert Timecard ( "
+                  f"Case ID: {params['CaseId__c']}, "
+                  f"Minutes: {params['TotalMinutesStatic__c']}, "
+                  f"Start Time: {params['StartTime__c']}, "
+                  f"Work Performed: {params['WorkPerformed__c']} )"
+                  f" : Response: {result}")
+
+
+def main():
+
+    parser = SFObjectArgumentParser()
+
+    parser.add_argument('-m', '--minutes', required=True, type=int,
+                        help='Timecard minutes')
+    parser.add_argument('-c', '--case', required=True,
+                        help='Case number (or Case ID)')
+    parser.add_argument('-w', '--workperformed', required=True,
+                        help='Work performed (Timecard description)')
+    parser.add_argument('-t', '--starttime', required=False, type=str,
+                        help='Start time of timecard '
+                             '(Format: yyyy-mm-dd-hh-mm) in UTC. If not '
+                             'specified, defaults to current timestamp')
+
+    opts = parser.parse_args()
+
+    logging.basicConfig(level='DEBUG' if opts.verbose else 'INFO',
+                        format='%(message)s')
+
+    sf = opts.functions.SF()
+    data = {
+        'minutes': opts.minutes,
+        'case': opts.case,
+        'workperformed': opts.workperformed,
+        'starttime': opts.starttime,
+    }
+
+    params = parse_params(data, sf=sf)
+
+    if opts.dry_run:
+        LOG.info("Dry run completed")
+        exit(0)
+
+    insert(params, sf=sf)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/sftc_reader b/scripts/sftc_reader
new file mode 100755
index 0000000..c503176
--- /dev/null
+++ b/scripts/sftc_reader
@@ -0,0 +1,93 @@
+#!/usr/bin/python3
+
+from sftc_insert import parse_params, insert
+import argparse
+import logging
+import sys
+
+from pathlib import Path
+
+# if called from git source, add parent dir to python path
+if Path(__file__).parent.name == 'scripts':
+    sys.path.insert(0, str(Path(__file__).parent.parent))
+
+from sftools.sf import SF
+
+LOG = logging.getLogger(__name__)
+
+
+def read(filename, translation_dict=None):
+
+    if translation_dict is None:
+        translation_dict = {}
+
+    with open(filename, 'r') as file:
+        lines = file.readlines()
+
+    timecards = []
+
+    for line in lines:
+        if not line.strip():
+            continue
+        contents = line.split('===')
+        if len(contents) < 3:
+            LOG.error("Incorrect format, please use: "
+                      "'case === minutes === workperformed'")
+        case = contents[0].strip()
+        case = translation_dict.get(case) or case
+        minutes = int(contents[1].strip())
+        workperformed = contents[2].strip()
+        starttime = None
+        if len(contents) > 3:
+            starttime = contents[3].strip()
+        data = {
+            'case': case,
+            'minutes': minutes,
+            'workperformed': workperformed,
+            'starttime': starttime,
+        }
+        timecards.append(data)
+
+    LOG.debug(f"Timecard data parsed from file {timecards}")
+    return timecards
+
+
+def main(translation_dict=None, sf=None):
+
+    if translation_dict is None:
+        translation_dict = {}
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--dry-run', action='store_true',
+                        help="Dry-run only, do not make any changes")
+    parser.add_argument('-f', '--filename', type=str, default="timecards.txt",
+                        help="File name to open and parse timecards to "
+                        "insert. Default is timecards.txt")
+    parser.add_argument('-v', '--verbose', action='store_true', default=False,
+                        help="Enable verbose logging")
+
+    opts = parser.parse_args()
+
+    logging.basicConfig(level='DEBUG' if opts.verbose else 'INFO',
+                        format='%(message)s')
+
+    timecards = read(opts.filename, translation_dict=translation_dict)
+
+    if sf is None:
+        sf = SF()
+
+    req_params = []
+    for timecard in timecards:
+        params = parse_params(timecard, sf=sf)
+        req_params.append(params)
+
+    if opts.dry_run:
+        LOG.info("Dry run completed")
+        exit(0)
+
+    for params in req_params:
+        insert(params, sf=sf)
+
+
+if __name__ == "__main__":
+    main()

Follow ups