def testRangeSansStep(self): "range w/o step" df = Datefile(datetime.strptime('2009-10-31', '%Y-%m-%d'), persistence_file=self.persistence_file, direction='forwards') start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2009-10-31') self.assertEquals(end.strftime('%Y-%m-%d'), '2009-10-31')
def testRangeSansFile(self): "range w/o step" df = Datefile(datetime.strptime('2009-10-31', '%Y-%m-%d')) start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2009-10-31') self.assertEquals(end.strftime('%Y-%m-%d'), '2009-10-31')
def testStepDatesBackThrice(self): "steping backward three times, duplication avoided?" df = Datefile(datetime.strptime('2011-04-30', '%Y-%m-%d'), persistence_file=self.persistence_file, direction='backwards', step=10) start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2011-04-21') self.assertEquals(end.strftime('%Y-%m-%d'), '2011-04-30') df.bump_date() start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2011-04-11') self.assertEquals(end.strftime('%Y-%m-%d'), '2011-04-20') df.bump_date() start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2011-04-01') self.assertEquals(end.strftime('%Y-%m-%d'), '2011-04-10')
def testRangeStepSansDirection(self): "give step and no directon" df = Datefile(datetime.strptime('2009-10-31', '%Y-%m-%d'), persistence_file=self.persistence_file, step=30) start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2009-10-02') self.assertEquals(end.strftime('%Y-%m-%d'), '2009-10-31')
def testStepDatesBack(self): "steping backward, end date should be step-1 days before start" df = Datefile(datetime.strptime('2009-01-31', '%Y-%m-%d'), persistence_file=self.persistence_file, direction='backwards', step=10) start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2009-01-22') self.assertEquals(end.strftime('%Y-%m-%d'), '2009-01-31')
def testStepDatesFwd(self): "steping forward, end date should be step-1 days after start" df = Datefile(datetime.strptime('2009-02-01', '%Y-%m-%d'), persistence_file=self.persistence_file, direction='forwards', step=10) start, end = df.get_date_range() self.assertEquals(start.strftime('%Y-%m-%d'), '2009-02-01') self.assertEquals(end.strftime('%Y-%m-%d'), '2009-02-10')
class ReportCommandLineInterface(object): """Command line interface to generating reports Collects arguments and assembles classes needed to generate any report. """ def __init__(self): """initializer for CLI""" # All criteria used to uniquely define a report self.criteria = ReportCriteria() # Any additional attributes collected but not necessarily # unique to recreating a like report self.verbosity = 0 self.datefile = None self.user = None self._password = None self.save_report = False self.transmit_report = False self.transmit_differences = False @property def password(self): return self._password @password.setter def password(self, value): """Password may be plain text or a file containing it""" # If the password argment is a readable file, fetch the # password from within if value and os.path.exists(value): passwordFile = open(value, 'r') value = passwordFile.readline().rstrip() passwordFile.close() self._password = value def process_args(self): """Process any optional arguments and possitional parameters Using the values provided, assemble ReportCriteria and Datefile instances to control report generation. """ parser = OptionParser(usage=usage) # Provide the ReportCriteria instance an error callback so any # command line errors provoke the standard graceful exit with # warning text. self.criteria.error_callback = parser.error parser.add_option("-u", "--user", dest="user", default=self.user, help="database user") parser.add_option("-p", "--password", dest="password", default=self.password, help="database password, or file containing "\ "just the password") parser.add_option("-c", "--countdown", dest="countdown", default=None, help="count {down,up} the start and end dates "\ "set to 'forwards' or 'backwards' "\ "if desired") parser.add_option("-i", "--include-updates", action='store_true', dest="includeUpdates", default=False, help="include "\ "visits updated since last similar report") parser.add_option("--include-vitals", action='store_true', dest="includeVitals", default=False, help="include "\ "vitals (measured temperature, O2 "\ "saturation, influenza and H1N1 vaccine "\ "data) as additional columns in the "\ "report") parser.add_option("-k", "--patient-class", dest="patient_class", default=None, help="use "\ "to filter report on a specific patient "\ "class [E,I,O]") parser.add_option("-r", "--region", dest="region", default=None, help="reportable region defining limited set "\ "of facilities to include, by default "\ "all facilities are included") parser.add_option("-s", "--save-and-upload", action='store_true', dest="save_upload", default=False, help="save file and upload to "\ "DOH") parser.add_option("-x", "--save-without-upload", action='store_true', dest="save_only", default=False, help="save file but don't upload") parser.add_option("-d", "--upload-diff", action='store_true', dest="upload_diff", default=False, help="upload differences only "\ "(from yesterdays like report) to DOH") parser.add_option("-t", "--thirty-days", action='store_true', dest="thirty_days", default=False, help="include 30 days up to "\ "requested date ") parser.add_option("-v", "--verbose", dest="verbosity", action="count", default=self.verbosity, help="increase output verbosity") (options, args) = parser.parse_args() if len(args) != 2: parser.error("incorrect number of arguments") # Database to query self.criteria.database = args[0] self.user = options.user self.password = options.password self.criteria.credentials(user=self.user, password=self.password) # Potential region restriction self.criteria.reportable_region = options.region # Potential patient class restriction self.criteria.patient_class = options.patient_class # Potential to include vitals (not tied to gipse format) self.criteria.include_vitals = options.includeVitals # Potential inclusion of updates self.criteria.include_updates = options.includeUpdates # Report date(s) and potential step direction. # NB - several options affect report_method and must be set # first! initial_date = parseDate(args[1]) config = Config() ps_file = os.path.join( config.get('general', 'tmp_dir', default='/tmp'), self.criteria.report_method) step = options.thirty_days and 30 or None direction = options.countdown self.datefile = Datefile(initial_date=initial_date, persistence_file=ps_file, direction=direction, step=step) self.criteria.start_date, self.criteria.end_date =\ self.datefile.get_date_range() # What to do once report is completed. Complicated, protect # user from themselves! self.save_report = options.save_upload or \ options.save_only or options.upload_diff self.transmit_report = options.save_upload self.transmit_differences = options.upload_diff if options.save_only and options.save_upload: parser.error("save-without-upload and save-and-upload "\ "are mutually exclusive") if options.save_only and options.upload_diff: parser.error("save-without-upload and upload-diff "\ "are mutually exclusive") if options.upload_diff and options.save_upload: parser.error("upload-diff and save-and-upload"\ "are mutually exclusive") # Can't transmit w/o saving if options.save_upload or options.upload_diff: assert (self.save_report) # Sanity check if options.save_only: assert (self.save_report and not self.transmit_report and not self.transmit_differences) # How verbosely to log self.verbosity = options.verbosity def execute(self): """Use the collected info to launch execution""" configure_logging(verbosity=self.verbosity, logfile="%s.log" % self.criteria.report_method) gr = GenerateReport(user=self.user, password=self.password, report_criteria=self.criteria, datefile=self.datefile) gr.execute(save_report=self.save_report, transmit_report=self.transmit_report, transmit_differences=self.transmit_differences)
class ReportCommandLineInterface(object): """Command line interface to generating reports Collects arguments and assembles classes needed to generate any report. """ def __init__(self): """initializer for CLI""" # All criteria used to uniquely define a report self.criteria = ReportCriteria() # Any additional attributes collected but not necessarily # unique to recreating a like report self.verbosity = 0 self.datefile = None self.user = None self._password = None self.save_report = False self.transmit_report = False self.transmit_differences = False @property def password(self): return self._password @password.setter def password(self, value): """Password may be plain text or a file containing it""" # If the password argment is a readable file, fetch the # password from within if value and os.path.exists(value): passwordFile = open(value, 'r') value = passwordFile.readline().rstrip() passwordFile.close() self._password = value def process_args(self): """Process any optional arguments and possitional parameters Using the values provided, assemble ReportCriteria and Datefile instances to control report generation. """ parser = OptionParser(usage=usage) # Provide the ReportCriteria instance an error callback so any # command line errors provoke the standard graceful exit with # warning text. self.criteria.error_callback = parser.error parser.add_option("-u", "--user", dest="user", default=self.user, help="database user") parser.add_option("-p", "--password", dest="password", default=self.password, help="database password, or file containing "\ "just the password") parser.add_option("-c", "--countdown", dest="countdown", default=None, help="count {down,up} the start and end dates "\ "set to 'forwards' or 'backwards' "\ "if desired") parser.add_option("-i", "--include-updates", action='store_true', dest="includeUpdates", default=False, help="include "\ "visits updated since last similar report") parser.add_option("--include-vitals", action='store_true', dest="includeVitals", default=False, help="include "\ "vitals (measured temperature, O2 "\ "saturation, influenza and H1N1 vaccine "\ "data) as additional columns in the "\ "report") parser.add_option("-k", "--patient-class", dest="patient_class", default=None, help="use "\ "to filter report on a specific patient "\ "class [E,I,O]") parser.add_option("-r", "--region", dest="region", default=None, help="reportable region defining limited set "\ "of facilities to include, by default "\ "all facilities are included") parser.add_option("-s", "--save-and-upload", action='store_true', dest="save_upload", default=False, help="save file and upload to "\ "DOH") parser.add_option("-x", "--save-without-upload", action='store_true', dest="save_only", default=False, help="save file but don't upload") parser.add_option("-d", "--upload-diff", action='store_true', dest="upload_diff", default=False, help="upload differences only "\ "(from yesterdays like report) to DOH") parser.add_option("-t", "--thirty-days", action='store_true', dest="thirty_days", default=False, help="include 30 days up to "\ "requested date ") parser.add_option("-v", "--verbose", dest="verbosity", action="count", default=self.verbosity, help="increase output verbosity") (options, args) = parser.parse_args() if len(args) != 2: parser.error("incorrect number of arguments") # Database to query self.criteria.database = args[0] self.user = options.user self.password = options.password self.criteria.credentials(user=self.user, password=self.password) # Potential region restriction self.criteria.reportable_region = options.region # Potential patient class restriction self.criteria.patient_class = options.patient_class # Potential to include vitals (not tied to gipse format) self.criteria.include_vitals = options.includeVitals # Potential inclusion of updates self.criteria.include_updates = options.includeUpdates # Report date(s) and potential step direction. # NB - several options affect report_method and must be set # first! initial_date = parseDate(args[1]) config = Config() ps_file = os.path.join(config.get('general', 'tmp_dir', default='/tmp'), self.criteria.report_method) step = options.thirty_days and 30 or None direction = options.countdown self.datefile = Datefile(initial_date=initial_date, persistence_file=ps_file, direction=direction, step=step) self.criteria.start_date, self.criteria.end_date =\ self.datefile.get_date_range() # What to do once report is completed. Complicated, protect # user from themselves! self.save_report = options.save_upload or \ options.save_only or options.upload_diff self.transmit_report = options.save_upload self.transmit_differences = options.upload_diff if options.save_only and options.save_upload: parser.error("save-without-upload and save-and-upload "\ "are mutually exclusive") if options.save_only and options.upload_diff: parser.error("save-without-upload and upload-diff "\ "are mutually exclusive") if options.upload_diff and options.save_upload: parser.error("upload-diff and save-and-upload"\ "are mutually exclusive") # Can't transmit w/o saving if options.save_upload or options.upload_diff: assert(self.save_report) # Sanity check if options.save_only: assert(self.save_report and not self.transmit_report and not self.transmit_differences) # How verbosely to log self.verbosity = options.verbosity def execute(self): """Use the collected info to launch execution""" configure_logging(verbosity=self.verbosity, logfile="%s.log" % self.criteria.report_method) gr = GenerateReport(user=self.user, password=self.password, report_criteria=self.criteria, datefile=self.datefile) gr.execute(save_report=self.save_report, transmit_report=self.transmit_report, transmit_differences=self.transmit_differences)