def setTestingComponent(self, component): """ Set testing component. :param component: Testing component. :return: """ self.testing_component = component log_func.info(u'Testing component <%s>' % (self.testing_component.getName() if self.testing_component is not None else None)) tab_datasource = component.getTabDataSource() if component else None if tab_datasource is None: msg = u'The table datasource object is not set in the transform datasource results view window\nResult is empty' log_func.warning(msg) dlg_func.openWarningBox(title=u'WARNING', prompt_text=msg) elif isinstance(tab_datasource, data_query.COMPONENT): sql_query = tab_datasource.getSQLText() if txtgen_func.isGenered(sql_query): var_names = txtgen_func.getReplaceNames(sql_query) self.variables = dict([(name, u'') for name in var_names]) self.setVariables(self.variables) else: log_func.warning(u'Type error table datasource for testing <%s>' % tab_datasource.__class__.__name__)
def openOffice(self, xls_filename): """ Open XLS report in Office. :param xls_filename: Report XLS filename. """ if xls_filename and os.path.exists(xls_filename): if sys_func.isLinuxPlatform(): cmd = '%s %s&' % (report_gen_system.UNIX_OFFICE_OPEN, xls_filename) log_func.info('Execute command <%s>' % cmd) os.system(cmd) return True elif sys_func.isWindowsPlatform(): win_office_open = iq.KERNEL.settings.THIS.SETTINGS.win_libreoffice_run.get( ) cmd = '%s %s&' % (win_office_open if win_office_open else report_gen_system.WIN_OFFICE_OPEN, xls_filename) log_func.info(u'Execute command <%s>' % cmd) os.system(cmd) return True else: log_func.warning(u'Unsupported platform <%s>' % sys_func.getPlatform()) else: log_func.warning(u'Open. Report file <%s> not exists' % xls_filename) return False
def getReportDir(self): """ Get report folder path. :return: Report folder path. """ if self._report_dir is None: prj_dir = file_func.getProjectPath() prj_dir = prj_dir if prj_dir else DEFAULT_REPORTS_PATH self._report_dir = os.path.join(prj_dir, DEFAULT_REPORT_DIRNAME) if not os.path.exists(self._report_dir): try: os.makedirs(self._report_dir) log_func.info(u'Create folder <%s>' % self._report_dir) description_filename = os.path.join( self._report_dir, 'descript.ion') prj_name = os.path.basename(prj_dir) txtfile_func.saveTextFile( description_filename, u'<%s> project reports' % prj_name) init_filename = os.path.join(self._report_dir, '__init__.py') txtfile_func.saveTextFile(init_filename, DEFAULT_INIT_PY_FMT % prj_name) except IOError: log_func.warning(u'Error create folder <%s>' % self._report_dir) return self._report_dir
def openReportBrowser(parent_form=None, report_dir='', mode=REPORT_EDITOR_MODE): """ Launch report browser. :param parent_form: The parent form, if not specified, creates a new application. :param report_dir: Directory where reports are stored. :return: True/False. """ app = wx.GetApp() if app is None: app = wx.App() log_func.info(u'wxPython version: %s' % wx.VERSION_STRING) dlg = None try: dlg = iqReportBrowserDialog(parent=parent_form, mode=mode, report_dir=report_dir) dlg.ShowModal() dlg.Destroy() return True except: if dlg: dlg.Destroy() log_func.fatal(u'Error starting report browser') return False
def edit(self, rep_filename=None): """ Edit report. :param rep_filename: Report template filename. """ # Set *.xls filename xls_filename = os.path.abspath( os.path.splitext(rep_filename)[0] + XLS_FILENAME_EXT) if sys_func.isLinuxPlatform(): cmd = '%s \"%s\"&' % (report_gen_system.UNIX_OFFICE_OPEN, xls_filename) log_func.info('Execute command <%s>' % cmd) os.system(cmd) return True elif sys_func.isWindowsPlatform(): win_office_open = iq.KERNEL.settings.THIS.SETTINGS.win_libreoffice_run.get( ) cmd = '%s \"%s\"&' % (win_office_open if win_office_open else report_gen_system.WIN_OFFICE_OPEN, xls_filename) log_func.info(u'Execute command <%s>' % cmd) os.system(cmd) return True else: log_func.warning(u'Unsupported platform <%s>' % sys_func.getPlatform()) return False
def setScanOptions(self, **options): """ Set Scan Options :param options: Options. :return: True/False. """ try: global SCAN_OPTIONS_ORDER for option_name in SCAN_OPTIONS_ORDER: if option_name in options: option_val = options[option_name] try: setattr(self.scan_device_obj, option_name, option_val) log_func.info(u'Set scan option <%s>. Value <%s>' % (option_name, option_val)) # Remember the option values set. # It may be that we install the options in the device, # but for some reason they are not set :-( self.options[option_name] = option_val except: log_func.warning( u'Error setting scan option <%s>. Value <%s>' % (option_name, option_val)) return True except: log_func.fatal(u'Error setting scan options') return False
def runMainForm(): """ Start application. """ app = global_func.getApplication() if app is None: log_func.info(u'Create WX application') app = global_func.createApplication() if mainform_manager.showMainForm(iqMainForm): app.MainLoop()
def runCommands(self): """ Start generating. Another name for the method is generate :return: True/False. """ cmd = self.getRunCommand() log_func.info(u'Command execution <%s>' % cmd) os.system(cmd) return True
def runExtScan(self): """ Launch an external scan tool. :return: True/False. """ if self.ext_scan_cmd: log_func.info(u'Run command <%s>' % self.ext_scan_cmd) os.system(self.ext_scan_cmd) return True return False
def edit(self, rep_filename=None): """ Edit report. :param rep_filename: Report template filename. """ # Set *.rtf filename rtf_file = os.path.abspath( os.path.splitext(rep_filename)[0] + RTF_FILENAME_EXT) cmd = 'start word.exe \'%s\'' % rtf_file log_func.info(u'Execute command <%s>' % cmd) # Run MSWord os.system(cmd)
def previewOffice(self, xls_filename): """ Open preview in Office. :param xls_filename: Report XLS filename. """ if not os.path.exists(xls_filename): log_func.warning(u'Preview. Report file <%s> not exists' % xls_filename) return False pdf_filename = os.path.splitext(xls_filename)[0] + PDF_FILENAME_EXT if os.path.exists(pdf_filename): try: os.remove(pdf_filename) except: log_func.fatal(u'Error delete file <%s>' % pdf_filename) if sys_func.isLinuxPlatform(): cmd = report_gen_system.UNIX_CONV_TO_PDF_FMT % xls_filename log_func.info(u'Convert to PDF. Execute command <%s>' % cmd) os.system(cmd) if os.path.exists(pdf_filename): cmd = report_gen_system.UNIX_OPEN_PDF_FMT % pdf_filename log_func.info(u'Open PDF. Execute command <%s>' % cmd) os.system(cmd) return True else: log_func.warning(u'Open PDF. PDF file <%s> not found' % pdf_filename) elif sys_func.isWindowsPlatform(): win_conv_to_pdf_fmt = iq.KERNEL.settings.THIS.SETTINGS.win_conv_to_pdf_fmt.get( ) if not win_conv_to_pdf_fmt: win_conv_to_pdf_fmt = report_gen_system.WIN_CONV_TO_PDF_FMT cmd = win_conv_to_pdf_fmt % (xls_filename, os.path.dirname(xls_filename)) log_func.info(u'Convert to PDF. Execute command <%s>' % cmd) os.system(cmd) if os.path.exists(pdf_filename): win_open_pdf_fmt = iq.KERNEL.settings.THIS.SETTINGS.win_open_pdf_fmt.get( ) if not win_open_pdf_fmt: win_open_pdf_fmt = report_gen_system.WIN_OPEN_PDF_FMT cmd = win_open_pdf_fmt % pdf_filename log_func.info(u'Open PDF. Execute command <%s>' % cmd) os.system(cmd) return True else: log_func.warning(u'Open PDF. PDF file <%s> not found' % pdf_filename) else: log_func.warning(u'Unsupported <%s> platform' % sys_func.getPlatform()) return False
def _getSQLQueryTable(self, report, db_url=None, sql=None): """ Get query table. :param report: Report template data. :param db_url: Connection string as url. For example: postgresql+psycopg2://postgres:[email protected]:5432/realization. :param sql: SQL query text. :return: Query table dictionary: {'__fields__': field_name_list, '__data__': table_data} """ result = None db_connection = None try: if not db_url: data_source = report['data_source'] if not data_source: log_func.warning(u'Report data source not defined') return {'__fields__': list(), '__data__': list()} signature = data_source[:4].upper() if signature != DB_URL_SIGNATURE: log_func.warning('Not support DB type <%s>' % signature) return result # DB is set using standard DB URL db_url = data_source[4:].lower().strip() log_func.info(u'DB URL <%s>' % db_url) db_connection = sqlalchemy.create_engine(db_url) log_func.info(u'SQL <%s>' % str_func.toUnicode(sql, 'utf-8')) sql_result = db_connection.execute(sql) rows = sql_result.fetchall() cols = rows[0].keys() if rows else [] db_connection.dispose() db_connection = None result = {'__fields__': cols, '__data__': list(rows)} return result except: if db_connection: db_connection.dispose() log_func.fatal(u'Error defining SQL query table <%s>.' % sql) return None
def setOptions(self, **options): """ Set scan options in the dialog box. :param options: Options. :return: True/False. """ for option_name, option_value in options.items(): if hasattr(self, option_name): try: setattr(self, option_name, option_value) log_func.info(u'Set option <%s>. Value <%s>' % (option_name, option_value)) except: log_func.warning(u'Error set option <%s>. Value <%s>' % (option_name, option_value)) # After setting the attributes, display them in the dialog box self.showOptions()
def _update(self, tmpl_filename=None): """ Обновить шаблон отчета в системе генератора отчетов. :param tmpl_filename: Report template filename. If None then select this file. :return: Report template filename or None if error. """ if tmpl_filename is None: filename = dlg_func.getFileDlg(parent=self._parent_window, title=u'Select report template:', wildcard_filter=u'Open document spreadsheet ODF (*.ods)|*.ods|Microsoft Excel 2003 XML (*.xml)|*.xml', default_path=self.getReportDir()) else: filename = os.path.abspath(os.path.normpath(tmpl_filename)) if os.path.isfile(filename): log_func.info(u'Start convert <%s>' % filename) tmpl_filename = None template = None if os.path.exists(os.path.splitext(filename)[0] + DEFAULT_TEMPLATE_EXT): tmpl_filename = os.path.splitext(filename)[0] + DEFAULT_TEMPLATE_EXT template = report_template.iqODSReportTemplate() elif os.path.exists(os.path.splitext(filename)[0] + ODS_TEMPLATE_EXT): tmpl_filename = os.path.splitext(filename)[0] + ODS_TEMPLATE_EXT template = report_template.iqODSReportTemplate() elif os.path.exists(os.path.splitext(filename)[0] + XLS_TEMPLATE_EXT): tmpl_filename = os.path.splitext(filename)[0] + XLS_TEMPLATE_EXT template = report_template.iqXLSReportTemplate() elif os.path.exists(os.path.splitext(filename)[0] + XML_TEMPLATE_EXT): tmpl_filename = os.path.splitext(filename)[0] + XML_TEMPLATE_EXT template = report_template.iqlXMLSpreadSheetReportTemplate() else: log_func.warning(u'Report template not found <%s>' % filename) new_filename = None if template: rep_template = template.read(tmpl_filename) new_filename = os.path.splitext(filename)[0]+DEFAULT_REPORT_TEMPLATE_EXT res_func.saveResourcePickle(new_filename, rep_template) log_func.info(u'End convert') return new_filename else: log_func.warning(u'Report template file not found <%s>' % filename) return None
def _genXMLReport(self, report): """ Generate a report and save it in an XML file. :param report: Report template data. :return: XML filename or None if error. """ if report is None: report = self._report_template data_rep = self.generateReport(report) if data_rep: rep_file = report_file.iqXMLSpreadSheetReportFile() rep_file_name = os.path.join(self.getReportDir(), '%s_report_result.xml' % str(data_rep['name'])) rep_file.write(rep_file_name, data_rep) log_func.info(u'Save report file <%s>' % rep_file_name) return rep_file_name return None
def getDBFFieldNames(dbf_filename): """ Get DBF field names. :param dbf_filename: DBF filename. :return: DBF field name list. """ tab_dbf = None field_names = list() try: log_func.info(u'Open DBF file <%s>' % dbf_filename) tab_dbf = dbfpy3.dbf.Dbf(dbf_filename, new=False) field_names = tab_dbf.fieldNames tab_dbf.close() except: if tab_dbf: tab_dbf.close() log_func.fatal(u'Error get DBF field names in <%s>' % dbf_filename) return field_names
def selectReport(parent_form=None, report_filename='', report_dir='', db_url=None, sql=None, command=None, stylelib_filename=None, variables=None): """ The function starts the report generator with the subsequent choice of action. :param parent_form: The parent form, if not specified, creates a new application. :param report_filename: Report filename. :param report_dir: Directory where reports are stored. :param db_url: URL Connection string. For example: postgresql+psycopg2://postgres:[email protected]:5432/realization. :param sql: SQL query text. :param command: After generation command. print/preview/export. :param stylelib_filename: Style library filename. :param variables: A dictionary of variables to populate the report. :return: True/False. """ report_filename = getReportResourceFilename(report_filename, report_dir) try: if not report_filename: return openReportViewer(parent_form, report_dir) else: stylelib = loadStyleLib(stylelib_filename) repgen_system = report_gen_func.getReportGeneratorSystem( report_filename, parent_form) log_func.info(u'Use report generate system <%s>' % repgen_system.__class__.__name__) return repgen_system.selectAction( res_func.loadResource(report_filename), stylelib=stylelib, variables=variables) except: log_func.fatal(u'Error generating report with action selection <%s>' % report_filename) return False
def createApplication(): """ Create application object. :return: Application object. """ app = global_data.getGlobal('APPLICATION') if app is None: if isWXEngine(): import wx from iq.util import log_func log_func.info(u'wxPython version: %s' % wx.VERSION_STRING) app = wx.App() elif isQTEngine(): app = None elif isCUIEngine(): app = None if app: global_data.setGlobal('APPLICATION', app) return app
def _genRTFReport(self, report): """ Generate report and save it in RTF file. :param report: Report template data. :return: Report RTF filename or None if error. """ if report is None: report = self._report_template data_rep = self.generateReport(report) if data_rep: rep_file_name = os.path.join( self.getReportDir(), '%s_report_result.rtf' % data_rep['name']) template_file_name = os.path.abspath(data_rep['generator']) log_func.info(u'Save report <%s> to file <%s>' % (template_file_name, rep_file_name)) data = self._prevGenerateAllVar(data_rep['__data__']) rtf_report.genRTFReport(data, rep_file_name, template_file_name) return rep_file_name return None
def createMap(self, geo_latitude, geo_longitude, zoom=DEFAULT_ZOOM, html_filename=None, rewrite=False, auto_save=True): """ Create map object. :param geo_latitude: Geographic latitude. :param geo_longitude: Geographic longitude. :param zoom: The default scale factor. :param html_filename: The name of the file to be saved. If not specified, it is generated. :param rewrite: Overwrite existing file? :param auto_save: Save file automatically? :return: Map object, or None on error. """ if geo_latitude in (None, 0) or geo_longitude in (None, 0): log_func.warning( u'Incomplete definition of geolocation <%s : %s>' % (geo_latitude, geo_longitude)) return None try: self._geo_map = self._rendering.Map( location=[geo_latitude, geo_longitude], zoom_start=zoom) log_func.info(u'Map object created. Geolocation [%s x %s]' % (geo_latitude, geo_longitude)) if auto_save: self.saveMapBrowserFile(geo_latitude, geo_longitude, zoom=zoom, html_filename=html_filename, rewrite=rewrite) except: log_func.fatal(u'Error creating map object') self._geo_map = None return self._geo_map
def createReportResourceFile(template_filename): """ Create a resource file for the template by the name of the requested. :param template_filename: The name of the requested template file. :return: Corrected name of created template file or None in case of error. """ dir_name = os.path.dirname(template_filename) base_filename = os.path.basename(template_filename).replace(' ', '_') base_filename = str_func.rus2lat(base_filename) if str_func.isRUSText( base_filename) else base_filename norm_tmpl_filename = os.path.join(dir_name, base_filename) log_func.info(u'Create new template file <%s>' % norm_tmpl_filename) # We consistently check which file can be taken as the basis for the template for ext in report_gen_func.SRC_REPORT_EXT: src_filename = os.path.splitext(template_filename)[0] + ext unicode_src_filename = str_func.toUnicode(src_filename) if os.path.exists(src_filename): # Yes, there is such a file and it can act as a source for the template log_func.info(u'Report template source found <%s>' % unicode_src_filename) try: rep_generator = report_gen_func.createReportGeneratorSystem( ext) return rep_generator.update(src_filename) except: log_func.fatal( u'Error converting report template <%s> -> <%s>' % (unicode_src_filename, norm_tmpl_filename)) return None log_func.warning( u'Report template sources not found in folder <%s> for <%s>' % (dir_name, str_func.toUnicode(os.path.basename(template_filename)))) return None
def copyToScanDir(self, scan_filename=None, scan_dir=None, bDoRemove=True): """ Copy file - the result of scanning to a folder. :param scan_filename: The resulting scan file. If not specified, then the default file is taken. :param scan_dir: Folder scan. :param bDoRemove: Transfer file? :return: True/False """ if scan_filename is None: scan_filename = config.DEFAULT_SCAN_FILENAME if scan_dir is None: scan_dir = self.scan_dir if not os.path.exists(scan_filename): log_func.warning(u'Scan file does not exist <%s>' % scan_filename) return False if scan_dir: if not os.path.exists(scan_dir): try: os.makedirs(scan_dir) log_func.info(u'Scan folder created <%s>' % scan_dir) except OSError: log_func.fatal(u'Error creating scan folder <%s>' % scan_dir) return False new_filename = os.path.join(scan_dir, os.path.basename(scan_filename)) if scan_filename != new_filename: shutil.copyfile(scan_filename, new_filename) log_func.info(u'Copy file <%s> to folder <%s>' % (scan_filename, scan_dir)) if bDoRemove: try: os.remove(scan_filename) log_func.info(u'Delete file <%s>' % scan_filename) except: log_func.fatal(u'Error delete file <%s>' % scan_filename) return True else: log_func.warning(u'Scan folder not defined') return False
def save(self, report_data=None, to_virtual_spreadsheet=True): """ Save generated report to file. :param report_data: Generated report data. :param to_virtual_spreadsheet: Save by Virtual SpreadSheet? True - yes, False - Save by UNOCONV convertation. When converting using UNOCONV, the cells are not dimensioned. Cell sizes remain by default. UNOCONV does not translate all cell styles and attributes. :return: Destination report filename or None if error. """ if report_data: rep_file = report_file.iqXMLSpreadSheetReportFile() save_dir = self.getProfileDir() if not save_dir: save_dir = report_gen_system.DEFAULT_REPORT_DIR xml_rep_file_name = os.path.join( save_dir, '%s_report_result.xml' % report_data['name']) rep_file_name = os.path.join( save_dir, '%s_report_result.ods' % report_data['name']) rep_file.write(xml_rep_file_name, report_data) if to_virtual_spreadsheet: log_func.info(u'Convert report <%s> to file <%s>' % (str_func.toUnicode(xml_rep_file_name), str_func.toUnicode(rep_file_name))) spreadsheet = v_spreadsheet.iqVSpreadsheet() spreadsheet.load(xml_rep_file_name) spreadsheet.saveAs(rep_file_name) else: cmd = 'unoconv --format=ods %s' % xml_rep_file_name log_func.info(u'UNOCONV. Convert report <%s> to file <%s>' % (str_func.toUnicode(xml_rep_file_name), str_func.toUnicode(rep_file_name))) log_func.info(u'Execute command <%s>' % cmd) os.system(cmd) return rep_file_name return None
def runScanPack(self, *scan_filenames): """ Start the scanning process in batch mode, according to the parameters set. :param scan_filenames: Scan file names with the number of sheets and a sign of 2-sided scanning. For example: (scan001, 3, True), (scan002, 1, False), (scn003, 2, True), ... :return: True/False """ if self.scan_manager is None: log_func.warning(u'Scan Manager not defined') return False if self.scanner is None: log_func.warning(u'Undefined scan device') return False self.scan_manager.init() self.scan_manager.open(self.scanner) options = dict() if self.scan_source: options['source'] = self.scan_source if self.scan_mode: options['mode'] = self.scan_mode if self.depth: options['depth'] = self.depth if self.page_size: options['page_width'] = self.page_size[0] options['page_height'] = self.page_size[1] else: options['page_width'] = 210.0 options['page_height'] = 297.0 if self.scan_area: options['tl_x'] = self.scan_area[0] options['tl_y'] = self.scan_area[1] if self.scan_area and self.page_size: options['br_x'] = self.page_size[0] - self.scan_area[2] options['br_y'] = self.page_size[1] - self.scan_area[3] else: options['br_x'] = 210.0 options['br_y'] = 297.0 self.scan_manager.setScanOptions(**options) scans = [(os.path.join(file_func.getHomePath(), global_func.getProjectName(), scan_filename + '.' + self.scan_filetype) if scan_filename else config.DEFAULT_SCAN_FILENAME, int(n_pages), bool(is_duplex)) for scan_filename, n_pages, is_duplex in scan_filenames] for scan_filename, n_pages, is_duplex in scans: full_scan_filename = os.path.join(os.environ.get('HOME', '/home/user'), global_func.getProjectName(), scan_filename) if os.path.exists(full_scan_filename): try: os.remove(full_scan_filename) log_func.info(u'Previously scanned file deleted <%s>' % full_scan_filename) except OSError: log_func.fatal(u'Error delete file <%s>' % full_scan_filename) try: scan_filenames = self.scan_manager.scanPack(scan_filenames=scans) # Transfer scanned files to the resulting folder if self.scan_dir and os.path.exists(self.scan_dir): for scan_filename in scan_filenames: if scan_filename and os.path.exists(scan_filename): log_func.debug(u'File transfer <%s> to the resulting folder <%s>' % (scan_filename, self.scan_dir)) self.copyToScanDir(scan_filename, self.scan_dir) else: log_func.warning(u'Result scan file not defined') else: log_func.warning(u'Result scan folder not defined') return True except: log_func.fatal(u'Scan Error in Batch Processing') return False
def _runScan(self): """ Start the scanning process according to the set parameters. :return: True/False """ if self.scan_manager is None: log_func.warning(u'Scan manager not defined') return False if self.scanner is None: log_func.warning(u'Undefined scan device') return False self.scan_manager.init() self.scan_manager.open(self.scanner) # Set options options = dict() if self.scan_source: options['source'] = self.scan_source if self.scan_mode: options['mode'] = self.scan_mode if self.depth: options['depth'] = self.depth if self.page_size: options['page_width'] = self.page_size[0] options['page_height'] = self.page_size[1] else: # If you do not determine the page size, # the edge of the scan will be cropped. # Default A4 portrait orientation options['page_width'] = 210.0 options['page_height'] = 297.0 if self.scan_area: options['tl_x'] = self.scan_area[0] options['tl_y'] = self.scan_area[1] if self.scan_area and self.page_size: options['br_x'] = self.page_size[0] - self.scan_area[2] options['br_y'] = self.page_size[1] - self.scan_area[3] else: # If you do not determine the page size, # the edge of the scan will be cropped. # Default A4 portrait orientation options['br_x'] = 210.0 options['br_y'] = 297.0 self.scan_manager.setScanOptions(**options) # Defining a scan file name scan_filename = os.path.join(file_func.getHomePath(), global_func.getProjectName(), self.scan_filename + '.' + self.scan_filetype) if self.scan_filename else config.DEFAULT_SCAN_FILENAME if os.path.exists(scan_filename): # Delete old scan file try: os.remove(scan_filename) log_func.info(u'Delete file <%s>' % scan_filename) except OSError: log_func.fatal(u'Error delete file <%s>' % scan_filename) log_func.debug(u'Scan to file <%s>' % scan_filename) try: if not self.is_multi_scan: result = self.scan_manager.scanSingle(scan_filename) else: result = self.scan_manager.scanMulti(scan_filename) if not result: dlg_func.openErrBox(u'ERROR', u'Scan error. Check the sheets in the scanner tray') return False if self.scan_dir: self.copyToScanDir(scan_filename, self.scan_dir) if self.is_preview: self.previewScanFile(scan_filename) return True except: log_func.fatal(u'Scan error') return False
def main(*argv): """ Main function triggered. :param argv: Command line parameters. """ # Parse command line arguments try: options, args = getopt.getopt(argv, 'h?vdl', ['help', 'version', 'debug', 'log', 'mode=', 'engine=', 'prj=', 'username='******'password='******'res_filename=']) except getopt.error as msg: log_func.warning(str(msg), is_force_print=True) log_func.printColourText(global_data.FRAMEWORK_LOGO_TXT, color=log_func.GREEN_COLOR_TEXT) log_func.printColourText(__doc__, color=log_func.GREEN_COLOR_TEXT) sys.exit(2) mode = None runtime_mode = False engine = global_data.DEFAULT_ENGINE_TYPE project = None username = None password = None res_filename = None for option, arg in options: if option in ('-h', '--help', '-?'): log_func.printColourText(global_data.FRAMEWORK_LOGO_TXT, color=log_func.GREEN_COLOR_TEXT) log_func.printColourText(__doc__, color=log_func.GREEN_COLOR_TEXT) sys.exit(0) elif option in ('-v', '--version'): str_version = 'iqFramework %s' % '.'.join([str(sign) for sign in global_data.VERSION]) log_func.printColourText(global_data.FRAMEWORK_LOGO_TXT, color=log_func.GREEN_COLOR_TEXT) log_func.printColourText(str_version, color=log_func.GREEN_COLOR_TEXT) sys.exit(0) elif option in ('-d', '--debug'): global_func.setDebugMode() elif option in ('-l', '--log'): global_func.setLogMode() log_func.init() elif option in ('--mode',): mode = arg.lower() runtime_mode = mode == iq.RUNTIME_MODE_STATE global_func.setRuntimeMode(runtime_mode) elif option in ('--engine',): engine = arg global_func.setEngineType(engine) elif option in ('--prj',): project = arg elif option in ('--username',): username = arg elif option in ('--password',): password = arg elif option in ('--res_filename',): res_filename = arg else: log_func.warning(u'Not supported parameter <%s>' % option) start_time = time.time() log_func.info(u'iqFramework <Engine: %s / Mode: %s / Path: %s>... START' % (engine, mode, file_func.getFrameworkPath())) # Set system locale cur_locale = locale.getlocale() locale.setlocale(locale.LC_ALL, cur_locale) log_func.info(u'Set locale <%s.%s>' % tuple(cur_locale)) try: if runtime_mode: kernel = iq.createKernel() kernel.start(mode=mode, project_name=project, username=username, password=password) kernel.stop() elif mode == iq.EDITOR_MODE_STATE and os.path.basename(__file__) == os.path.basename(res_filename): editor.openFrameworkEditor() elif mode == iq.EDITOR_MODE_STATE: # kernel = iq.createKernel() editor.openResourceEditor(res_filename=res_filename) else: log_func.warning(u'Engine type <%s : %s> not support' % (engine, mode)) except: log_func.fatal(u'Run iqFramework error') log_func.info(u'iqFramework <Engine: %s / Mode: %s / Total time: %s>... STOP' % (engine, mode, str(time.time() - start_time)))
def generate(self, rep_template, query_table, name_space=None, coord_fill=None): """ Generate report. :param rep_template: Report template data. :param query_table: Query table: { '__name__': query table name, '__fields__': [field names], '__data__': [query table data], '__sub__': {sub report data}, }. :param name_space: Report name space. { 'variable name': variable value, }. This dictionary can be transmitted in the query table key __variables__. :param coord_fill: Coordinate filling in cell values. Format: { (row, col): 'value', }. This dictionary can be transmitted in the query table key __coord_fill__. :return: Generated report data. """ try: # Coordinate filling in cell values self._CoordFill = coord_fill if query_table and '__coord_fill__' in query_table: if self._CoordFill is None: self._CoordFill = dict() self._CoordFill.update(query_table['__coord_fill__']) # Group list self._RepGrp = list() # I. Define all bands in the template and amount cells if isinstance(rep_template, dict): self._Template = rep_template else: log_func.warning(u'Error report template type <%s>.' % type(rep_template)) return None # Init report name if 'name' in query_table and query_table['name']: # If the query table is named, then this is the name of the finished report self._RepName = str(query_table['name']) elif 'name' in self._Template: self._RepName = self._Template['name'] # Init name space self._NameSpace = name_space if self._NameSpace is None: self._NameSpace = dict() self._NameSpace.update(self._Template['variables']) if query_table and '__variables__' in query_table: self._NameSpace.update(query_table['__variables__']) if self._NameSpace: log_func.debug(u'Report variables: %s' % str(list(self._NameSpace.keys()))) # Style library self._StyleLib = None if 'style_lib' in self._Template: self._StyleLib = self._Template['style_lib'] self._TemplateSheet = self._Template['sheet'] self._TemplateSheet = self._initSumCells(self._TemplateSheet) # II. Init query table self._QueryTbl = query_table # Determine the number of records in the query table self._QueryTblRecCount = 0 if self._QueryTbl and '__data__' in self._QueryTbl: self._QueryTblRecCount = len(self._QueryTbl['__data__']) # Init group band for grp in self._Template['groups']: grp['old_rec'] = None time_start = time.time() log_func.info(u'Report <%s>. Generate start' % str_func.toUnicode(self._RepName)) # III. Fill report # Create report self._Rep = copy.deepcopy(REPORT_TEMPLATE) self._Rep['name'] = self._RepName # Init variables field_idx = dict() # Field indexes i = 0 i_rec = 0 # Iterate through the fields of a query table if self._QueryTbl and '__fields__' in self._QueryTbl: for cur_field in self._QueryTbl['__fields__']: field_idx[cur_field] = i i += 1 if self._QueryTblRecCount: # Init current record rec = self._QueryTbl['__data__'][i_rec] for field_name in field_idx.keys(): val = rec[field_idx[field_name]] self._CurRec[field_name] = val # Current record index self._CurRec['sys_num_rec_idx'] = i_rec # Upper if self._Template['upper']: self._genUpper(self._Template['upper']) # Header self._genHeader(self._Template['header']) # Main loop while i_rec < self._QueryTblRecCount: # Group # Check group change and find the index of the most common change group i_grp_out = -1 # Start generate flag start_gen = False for i_grp in range(len(self._Template['groups'])): grp = self._Template['groups'][i_grp] if grp['old_rec']: # Check group note output condition if self._CurRec[grp['field']] != grp['old_rec'][grp['field']]: i_grp_out = i_grp break else: i_grp_out = 0 start_gen = True break if i_grp_out != -1: # Display notes if start_gen is False: for i_grp in range(len(self._Template['groups'])-1, i_grp_out-1, -1): grp = self._Template['groups'][i_grp] self._genGrpFooter(grp) # Show headers for i_grp in range(i_grp_out, len(self._Template['groups'])): grp = self._Template['groups'][i_grp] grp['old_rec'] = copy.deepcopy(self._CurRec) self._genGrpHeader(grp) # Data area self._genDetail(self._Template['detail']) # Increase the sum of summing cells self._sumIterate(self._TemplateSheet, self._CurRec) # Next record i_rec += 1 # Set current record if i_rec < self._QueryTblRecCount: rec = self._QueryTbl['__data__'][i_rec] for field_name in field_idx.keys(): val = rec[field_idx[field_name]] self._CurRec[field_name] = val # Set current record index self._CurRec['sys_num_rec_idx'] = i_rec # Footer for i_grp in range(len(self._Template['groups'])-1, -1, -1): grp = self._Template['groups'][i_grp] if grp['old_rec']: self._genGrpFooter(grp) else: break self._genFooter(self._Template['footer']) # Under if self._Template['under']: self._genUnder(self._Template['under']) # Page setup self._Rep['page_setup'] = self._Template['page_setup'] log_func.info(u'Report <%s>. Generate end. Time: %d sec.' % (str_func.toUnicode(self._RepName), time.time()-time_start)) return self._Rep except: log_func.fatal(u'Error report generate') return None
def main(argv): """ Main function. :param argv: A list of command line options. """ # Parse command line options try: options, args = getopt.getopt(argv, 'h?vdVEDpPES', [ 'help', 'version', 'debug', 'log', 'viewer', 'editor', 'postprint', 'postpreview', 'postexport', 'print=', 'preview=', 'export=', 'select=', 'gen=', 'db=', 'sql=', 'stylelib=', 'var=', 'path=', 'no_gui' ]) except getopt.error as err: log_func.warning(err.msg, is_force_print=True) log_func.info(__doc__, is_force_print=True) sys.exit(2) report_filename = None db = None sql = None do_cmd = None stylelib = None variables = dict() path = None mode = 'default' mode_arg = None for option, arg in options: if option in ('-h', '--help', '-?'): log_func.info(__doc__, is_force_print=True) sys.exit(0) elif option in ('-v', '--version'): version_txt = 'iqReport version: %s' % '.'.join( [str(ver) for ver in __version__]) log_func.info(version_txt, is_force_print=True) sys.exit(0) elif option in ('-d', '--debug'): global_func.setDebugMode() elif option in ('-l', '--log'): global_func.setLogMode() elif option in ('-V', '--viewer'): mode = 'view' elif option in ('-E', '--editor'): mode = 'edit' elif option in ('-p', '--print'): mode = 'print' mode_arg = arg elif option in ('-P', '--preview'): mode = 'preview' mode_arg = arg elif option in ('-E', '--export'): mode = 'export' mode_arg = arg elif option in ('-S', '--select'): mode = 'select' mode_arg = arg elif option in ('--gen', ): report_filename = arg elif option in ('--db', ): db = arg elif option in ('--sql', ): sql = arg elif option in ('--postprint', ): do_cmd = do_report.DO_COMMAND_PRINT elif option in ('--postpreview', ): do_cmd = do_report.DO_COMMAND_PREVIEW elif option in ('--postexport', ): do_cmd = do_report.DO_COMMAND_EXPORT elif option in ('--stylelib', ): stylelib = arg elif option in ('--var', ): var_name = arg.split('=')[0].strip() var_value = arg.split('=')[-1].strip() variables[var_name] = var_value log_func.debug(u'External variable <%s>. Value [%s]' % (str(var_name), str(var_value))) elif option in ('--path', ): path = arg elif option in ('--no_gui', ): global_func.setEngineType(global_data.CUI_ENGINE_TYPE) log_func.init(LOG_FILENAME) # You must add the path to the report folder so that import of report modules if path is None: path = DEFAULT_REPORTS_PATH if os.path.exists(path) and os.path.isdir(path) and path not in sys.path: sys.path.append(path) app = wx.App() # locale = wx.Locale() # locale.Init(wx.LANGUAGE_RUSSIAN) if mode == 'default': if report_filename: # Run report generation from the command line do_report.doReport(report_filename=report_filename, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=variables) elif mode == 'view': do_report.openReportViewer(report_dir=path) elif mode == 'edit': do_report.openReportEditor(report_dir=path) elif mode == 'print': do_report.printReport(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=variables) elif mode == 'preview': do_report.previewReport(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=variables) elif mode == 'export': do_report.exportReport(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=variables) elif mode == 'select': do_report.selectReport(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=variables) app.MainLoop()