Utilitaires Python, méthodes statiques
Voici un fichier « helper » Python mis à disposition pour vos développements (classes et méthodes statiques):
Prérequis:
- Python 2.5
- La librairie Python config: Librairie Python config
- La librairie lib.xml.etree, documentation: lib.xml.etree
- La librairie xml.parsers.expat, documentation: xml.parsers.expat
# Mode: Python; tab-width: 4 # Id: helper_misc.py # Author: David REGNIER # Description: # ====================================================================== # Copyright 2014 by David REGNIER # # All Rights Reserved # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby # granted, provided that the above copyright notice appear in all # copies and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of David # REGNIER be used in advertising or publicity pertaining to # distribution of the software without specific, written prior # permission. # ====================================================================== # Import common lib import xml.parsers.expat import py_compile, traceback import os, re, sys, time from datetime import datetime # Lib for XML try: from lib.xml.etree import ElementTree except ImportError: ElementTree = None sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit(); """Begin LogStats class""" class LogStats(object): # Description: Constructor # Init stats log file # Call sample: sys.stdout = LogStats() # @return: void def __init__(self, sOutputFile = os.getcwd() + "\\log\\" + 'stats.log'): self.oConsole = sys.stdout self.sFile = open(sOutputFile, 'w') # Description: Write flow to console and file # # @param self: Constructor parameters # @param sFlow: String to write # @return: int def write(self, sFlow): try: if sFlow <> '': self.oConsole.write(sFlow) # Write to console self.sFile.write(sFlow) # Write to stats log file return 0 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 """End LogStats class""" """Begin ToolsBox class""" class ToolsBox(object): # Description: Create folder tree for module # Call sample: ToolsBox.init_folder_tree(sFolder1, sFolder2, ...) # @param *args: Folder1, Folder2, ... # @return: int @staticmethod def init_folder_tree(*args): try: for element in args: if not os.path.exists(element): os.mkdir(element) return 0 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Compile Python script # Call sample: ToolsBox.init_compile(sInputPyScript = __file__) # @param sInputPyScript: Python Script file name # @return: int @staticmethod def init_compile(sInputPyScript = ''): try: if os.path.exists(sInputPyScript): py_compile.compile(sInputPyScript) return 0 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Init error log file # Call sample: ToolsBox.init_error_log() # @return: int @staticmethod def init_error_log(): try: if not os.path.exists('log'): os.makedirs('log') fileSocketError = open(os.getcwd() + "\\log\\" + 'error.log', 'w') sys.stderr = fileSocketError return 0 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Return current date, convert date string to datetime object # Call sample: ToolsBox.get_current_date('02', '2012') # @param sMonthName: Month MM format # @param sYearName: Year YYYY format # @return: mixed (datetime/int) @staticmethod def get_current_datetime_by_string(sMonthName, sYearName): try: sDate = sYearName + '-' + sMonthName + '-' + time.strftime('%d') return datetime.strptime(sDate, '%Y-%m-%d') except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Get first day of month # Call sample: ToolsBox.get_first_day_of_month(date.today(), '-')) # @param oTodayDate: Current datetime object # @param sFormat: Current format, default / # @return: mixed (string/int) @staticmethod def get_first_day_of_month(oTodayDate, sFormat = '/'): try: return date(oTodayDate.year, oTodayDate.month, 1).strftime('%Y' + sFormat + '%m' + sFormat + '%d') except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Get end day of month # Call sample: ToolsBox.get_end_day_of_month(date.today(), '-')) # @param oTodayDate: Current datetime object # @param sFormat: Current format, default / # @return: mixed (string/int) @staticmethod def get_end_day_of_month(oTodayDate, sFormat = '/'): try: iDaysNumberInMonth = calendar.monthrange(oTodayDate.year, oTodayDate.month)[1] return date(oTodayDate.year, oTodayDate.month, iDaysNumberInMonth).strftime('%Y' + sFormat + '%m' + sFormat + '%d') except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Check for null element in input array # Call sample: ToolsBox.check_empty_element_in_array(aInputArray, 6) # @param aInputArray: Input array # @param iNbElement: Number of element in array # @return: int @staticmethod def check_empty_element_in_array(aInputArray, iNbElement): try: if len(filter(bool, aInputArray)) == iNbElement: return 0 else: sys.stderr.write('ERROR: %s\n' % 'One key element cannot be empty (you should have ' + str(iNbElement) + ' element(s)), in this array : ' + str(aInputArray)) sys.exit() except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Check if file exist regarding his pattern name # Call sample: ToolsBox.check_input_file(sInputFolder, sInputFile) # @param sInputFolder: Input folder # @param sInputFile: Input file # @return: mixed (string/int) @staticmethod def check_input_file(sInputFolder = '', sInputFile = ''): try: if sInputFolder <> '' and sInputFile <> '': i = 0 for sFileName in os.listdir(sInputFolder): if sInputFile[:5] in sFileName: i += 1 sRealFileName = sFileName if i <> 1: sys.stderr.write('ERROR: %s\n' % 'The input file seems to have a wrong name, or does not exist, or multiple existence') sys.exit() else: return sRealFileName else: sys.exit() except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: XML validation # Call sample: ToolsBox.check_xml_format(sOutputFile) # @param sOutputFile: XML output file # @return: boolean @staticmethod def check_xml_format(sOutputFile = ''): try: if sOutputFile <> '': parser = xml.parsers.expat.ParserCreate() parser.ParseFile(open(sOutputFile, "r")) return True except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return False # Description: Return current datetime # Call sample: ToolsBox.get_current_datetime('%Y-%m-%dT%H:%M:%S') # @param sFormat: Format type # @return: mixed (string/int) @staticmethod def get_current_datetime(sFormat = ''): try: return time.strftime(sFormat) except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Return files by folder # Call sample: ToolsBox.get_files_by_folder('/dev/data/', 'full') # @param sFolder: Folder # @param sFullPath: (optional) If we need full path # @return: mixed (array/int) @staticmethod def get_files_by_folder(sFolder = '', sFullPath = ''): try: if sFolder: aFileName = [] aFileNameFullPath = [] for sPath, sFolder, sFiles in os.walk(sFolder): for sFileName in sFiles: if ToolsBox.check_empty_file(os.path.join(sPath, sFileName)): aFileNameFullPath.append(os.path.join(sPath, sFileName)) aFileName.append(sFileName) if sFullPath: return aFileNameFullPath else: return aFileName else: sys.stderr.write('ERROR: %s\n' % 'The input folder is empty') return 1 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Return matched files list by search pattern # Call sample: ToolsBox.get_files_by_matched_pattern(aFilesList, 'FRA000000123', 'full') # @param aFilesList: Array files # @param sSearchedPattern: String to search # @param sPath: If we need full path, 'full' # @return: mixed (array/int) @staticmethod def get_files_by_matched_pattern(aFilesList, sSearchedPattern = '', sPath = ''): try: if aFilesList: aMatchedFilesList = [] for sFileName in aFilesList: for line in enumerate(open(sFileName)): sFile = sFileName if sPath: sFile = os.path.basename(sFileName) if sSearchedPattern: if re.search(sSearchedPattern, str(line), re.IGNORECASE): aMatchedFilesList.append(sFile) break return aMatchedFilesList else: sys.stderr.write('ERROR: %s\n' % 'The files list is empty') return 1 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Create XML node # Call sample: ToolsBox.set_xml_node(document, "node_name", parent_node, ["node_content"], ["attribute_key"], ["attribute_content"]) # @param oDoc: Current xml.dom.minidom.Document # @param sNodeName: XML node name # @param oParentNode: XML parent node # @param sNodeContent: (Optional) XML node content # @param sXMLAttributeKey: (Optional) XML attribute key name # @param sXMLAttributeContent: (Optional) XML attribute content # @return: mixed (object/int) @staticmethod def set_xml_node(oDoc, sNodeName = '', oParentNode = '', sNodeContent = '', sXMLAttributeKey = '', sXMLAttributeContent = ''): try: oXMLNode = oDoc.createElement(sNodeName) if sXMLAttributeKey <> '': oXMLNode.setAttribute(sXMLAttributeKey, sXMLAttributeContent) oParentNode.appendChild(oXMLNode) if sNodeContent <> '': sXMLContent = oDoc.createTextNode(sNodeContent) oXMLNode.appendChild(sXMLContent) oParentNode.appendChild(oXMLNode) return oXMLNode except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return 1 # Description: Check for empty file # Call sample: ToolsBox.check_empty_file(sInputFile) # @param sInputFile: Input file to check # @return: boolean @staticmethod def check_empty_file(sInputFile = ''): try: if os.stat(sInputFile).st_size <> 0: return True except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) return False # Description: Get first subelement by tree element by match tag # Call sample: ToolsBox.get_xml_node_value(oTree, 'ERS/VES', 'DATI', sNodeType = 'attrib') # @param oTree: Input element tree object # @param sXMLPath: Path to tree # @param sMatch: What tag we should match # @param sNodeType: What node type we should match # @return: mixed(string/int) @staticmethod def get_xml_node_value(oTree, sXMLPath, sMatch, sNodeType = 'text'): try: if sNodeType == 'text': # For text value for node in oTree.find(sXMLPath): if node.tag == sMatch: return node.text else: # For attrib value for node in oTree.findall(sXMLPath): if node.tag == sXMLPath.split('/')[-1]: return node.attrib[sMatch] except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit() return 1 # Description: Get first subelement by tree element # Call sample: ToolsBox.get_first_subelement_tag_name(oTree, 'ERS/VES') # @param oTree: Input element tree object # @param sXMLPath: XML Path to search for # @return: mixed(string/int) @staticmethod def get_first_subelement_tag_name(oTree, sXMLPath): try: for node in oTree.find(sXMLPath): return node.tag except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit() return 1 # Description: Rename input file # Call sample: ToolsBox.set_filename(sInputFile, 'FRA000735220', sFromDate = '20110822', sToDate = '20150822'): # @param sInputFile: Input file name # @param sCFR: CFR name # @param sFromDate: From date # @param sToDate: To date # @return: mixed (string/int) @staticmethod def set_filename(sInputFile, sCFR, sFromDate = '', sToDate = ''): try: sPattern = sCFR.upper() if sFromDate: sPattern += '_FROM_' + sFromDate if sToDate: sPattern += '_TO_' + sToDate newFileName = sInputFile.replace('%pattern%', sPattern) if os.path.exists(newFileName): os.remove(newFileName) # Remove first os.rename(sInputFile, newFileName) return newFileName except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit() return 1 # Description: Return current monday and current sunday from given year, week number # Call sample: ToolsBox.get_start_end_weekday(year, week_number) # @param year: Current year # @param week_number: Current weeknumber # @return: datetime(monday, sunday) @staticmethod def get_start_end_weekday(year, week_number): try: if year and week_number: jan = datetime(year, 1, 1) if jan.isocalendar()[1] == 1: week1 = jan # week1 contains jan else: # Var jan is in the last year, so add 7 days to get the next week which should be week 1 week1 = jan + timedelta(7) # Now adjust week1 so we'll get the start of that week week1 = week1 - timedelta(week1.weekday()) # Now we have the start date of week_number 1 # Calculate the start date of the week we want weekday_start = week1 + timedelta(7 * (week_number - 1)) # Just add 6 days to have sunday datetime weekday_end = weekday_start + timedelta(days=6) return weekday_start, weekday_end except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit() """End ToolsBox class""" """Begin ToolsValidator class""" class ToolsValidator(object): # Description: Constructor # Init validator # @param self: Constructor parameter # @param cfr: CFR # @param sFromDate: From date # @param sToDate: To date # @return: void def __init__(self, cfr = '', sFromDate = '', sToDate = ''): self.cfr = cfr self.sFromDate = sFromDate self.sToDate = sToDate # Description: CFR validation # # @param self: Constructor parameter # @param string: Input string to valid # @return: int def valid_cfr(self, sCFR = ''): try: if not sCFR: raise Exception('%s' % 'CFR cannot be empty') elif len(sCFR) <> 12: raise Exception('%s' % 'Wrong CFR length : ' + sCFR) elif not sCFR.isalnum(): raise Exception('%s' % 'Wrong CFR format, should be alphanumeric : ' + sCFR) return 0 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit() return 1 # Description: DATE validation # # @param self: Constructor parameter # @param string: Input string date to valid # @return: int def valid_date(self, sInputDate = ''): try: if not sInputDate: raise Exception('%s' % 'DATE cannot be empty') elif len(sInputDate) <> 8: raise Exception('%s' % 'Wrong DATE length' + sInputDate) elif not sInputDate.isdigit(): raise Exception('%s' % 'Wrong DATE type, should be only numeric : ' + sInputDate) try: datetime.strptime(sInputDate, '%Y%m%d') except ValueError: raise ValueError('%s' % 'Incorrect DATE format, should be YYYYMMDD, or wrong DATE : ' + sInputDate) return 0 except Exception: sys.stderr.write('ERROR: %s\n' % traceback.format_exc()) sys.exit() return 1 """End ToolsValidator class"""
La classe LogStats est pratique si vous souhaitez rediriger les logs vers un fichier et la console en même temps, les méthodes statiques sont disponibles en vrac, il vous faudra les modifier en fonction de vos besoins.