def _pasteStyleIntoWorkbook(self, Style_, WorkbookData_): """ Вставить стиль в готовую структуру книги. @param Style_: Данные вставляемого стиля. @param WorkbookData_: Данные книги. @return: Возвращает идентификатор стиля или None в случае ошибки. """ try: workbook_styles = [ data for data in WorkbookData_['children'] if data['name'] == 'Styles' ][0] if Style_ not in workbook_styles['children']: workbook_styles_id = [ data['ID'] for data in workbook_styles['children'] if data['name'] == 'Style' ] new_style_id = self._genNewStyleID(Style_['ID'], workbook_styles_id) Style_['ID'] = new_style_id workbook_styles['children'].append(Style_) return new_style_id else: # Точно такой стиль уже есть и поэтому добавлять его не надо return Style_['ID'] except: log.error('_pasteStyleIntoWorkbook function') raise return None
def getFilesByExt(Path_, Ext_): """ Функция возвращает список всех файлов в директории с указанным расширением. @param Path_: Путь. @param Ext_: Расширение, например '.pro'. @return: В случае ошибки возвращает None. """ try: Path_ = os.path.abspath(os.path.normpath(Path_)) # Приведение расширения к надлежащему виду if Ext_[0] != '.': Ext_ = '.' + Ext_ Ext_ = Ext_.lower() file_list = None file_list = [ os.path.normpath(Path_ + '/' + path) for path in os.listdir(Path_) ] file_list = [ path for path in file_list if os.path.isfile(path) and os.path.splitext(path)[1].lower() == Ext_ ] return file_list except: log.error( 'Read folder file list error. ext: <%s>, path: <%s>, list: <%s>' % (Ext_, Path_, file_list)) return None
def exec_cmd_script(self, CmdScript_=None, AutoSave_=True): """ Выполнить скрипт - список команд. @param CmdScript_: Список команд формата [ ('ИмяКоманды',(кортеж не именованных аргуметов),{словарь именованных аргументов}), ... ] @param AutoSave_: Автоматически по завершению работы сохранить. """ if CmdScript_: for cmd in CmdScript_: try: args = () len_cmd = len(cmd) if len_cmd >= 2: args = cmd[1] kwargs = {} if len_cmd >= 3: kwargs = cmd[2] # Непосредственный вызов функции getattr(self, cmd[0])(*args, **kwargs) except: log.error('Execute command <%s>' % cmd) raise if AutoSave_: self.Save()
def startSheet(self, RepName_, Rep_): """ Теги начала страницы. @param RepName_: Имя отчета. @param Rep_: Тело отчета. """ rep_name = unicode(str(RepName_), self._encoding) self.startElementLevel('Worksheet', {'ss:Name': rep_name}) # Диапазон ячеек верхнего колонтитула try: if Rep_['upper']: refers_to = self._getUpperRangeStr(Rep_['upper']) self.startElementLevel('Names', {}) self.startElementLevel('NamedRange', { 'ss:Name': 'Print_Titles', 'ss:RefersTo': refers_to }) self.endElementLevel('NamedRange') self.endElementLevel('Names') except: log.error('Names SAVE <%s>' % Rep_['upper']) raise # Начало таблицы self.startElementLevel('Table', {})
def _clearSum(self, Sheet_, RowStart_, RowStop_): """ Обнуление сумм. @param Sheet_: Описание листа отчета. @param RowStart_: Начало бэнда обнуления. @param RowStop_: Конец бэнда обнуления. @return: Возвращает описание листа с корректным описанием ячеек с суммами. В результате ошибки возвращает старое описание листа. """ try: sheet = Sheet_ # Просмотр и коррекция каждой ячейки листа for row in range(RowStart_, RowStop_): for col in range(len(sheet[row])): # Если ячейка определена, то ... if sheet[row][col]: # Если ячейка суммирующая, то выполнить операцию обнуления if sheet[row][col]['sum'] is not None and sheet[row][ col]['sum'] is not []: for cur_sum in sheet[row][col]['sum']: cur_sum['value'] = 0 return sheet except: # Вывести сообщение об ошибке в лог log.error( u'Ошибка обнуления сумм суммирующих ячеек шаблона <%s>.' % self._RepName) return Sheet_
def saveResourceText(FileName_, Resource_): """ Сохранить ресурс в файле в текстовом формате. @param FileName_: Полное имя ресурсного файла. @param Resource_: Словарно-списковая структура спецификации. @return: Возвращает результат выполнения операции True/False. """ try: f = None # Если необходимые папки не созданы, то создать их dir_name = os.path.dirname(FileName_) try: os.makedirs(dir_name) except: pass f = open(FileName_, 'w') text = textfunc.StructToTxt(Resource_) f.write(text) f.close() log.info(u'Файл <%s> сохранен в текстовом формате.' % FileName_) return True except: if f: f.close() log.error(u'Ошибка сохраненения файла <%s> в текстовом формате.' % FileName_) return False
def show_scan_error_msg(self, err_msg=u''): """ Функция отображения ошибок сканирования. @param err_msg: Сообщение об ошибке. """ log.error(u'ОШИБКА СКАНИРОВАНИЯ. %s' % err_msg) try: import wx from ic.std.dlg import dlg app = wx.GetApp() if not app: app = wx.PySimpleApp() dlg.getErrBox(u'ОШИБКА СКАНИРОВАНИЯ', err_msg, parent=None) app.MainLoop() else: dlg.getErrBox(u'ОШИБКА СКАНИРОВАНИЯ', err_msg, parent=app.GetTopWindow()) except: # Если не отобразим сообщение об ошибке, то процесс # сканирования не должен остановиться log.fatal( u'Ошибка в функиции <show_scan_error_msg> менеджера сканирования' )
def _findWorkbookData(self, XMLFileName_=None): """ Найти данные указанной книги. @param XMLFileName_: Имя XML файла книги. Если не определено, то имеется ввиду активная книга. """ # Определить книгу if XMLFileName_ is None: workbook_data = self._data else: xml_file_name = os.path.abspath(XMLFileName_) try: workbook_data = self._workbooks[xml_file_name] except KeyError: log.error('Workbook <%s> not registered in <%s>' % (xml_file_name, self._workbooks.keys())) raise workbook_data = [ data for data in workbook_data['children'] if 'name' in data and data['name'] == 'Workbook' ] if workbook_data: workbook_data = workbook_data[0] else: log.warning('Workbook in <%s> not defined' % XMLFileName_) return None return workbook_data
def convertXLS2XML(self, XLSFileName_=None): """ Сконвертировать XLS файл в XML. Конвертация будет происходить только при установленном Excel. @return: True - все нормально сконвертировалось, False - ошибка. """ try: import win32com.client xlXMLSpreadsheet = 46 # 0x2e # from enum XlFileFormat except ImportError: print('import win32com error!') return False try: # Установить связь с Excel excel_app = win32com.client.Dispatch('Excel.Application') # Сделать приложение невидимым # Закрыть все книги excel_app.Workbooks.Close() # Открыть XLS wrkbook = excel_app.Workbooks.Open(XLSFileName_) # Сохранить как XML xml_file_name = os.path.splitext(XLSFileName_)[0] + '.xml' wrkbook.SaveAs(xml_file_name, FileFormat=xlXMLSpreadsheet, ReadOnlyRecommended=False, CreateBackup=False) excel_app.Workbooks.Close() return True except: log.error('convertXLS2XML function') return False
def exec_code(sCode='', bReImport=False, name_space=None, kwargs=None): """ Выполнить блок кода. @type sCode: C{string} @param sCode: Блок кода. Блок кода - строка в формате: ИмяПакета.ИмяМодуля.ИмяФункции(аргументы). @type bReImport: C{bool} @param bReImport: Переимпортировать модуль функции? @type name_space: C{dictionary} @param name_space: Пространство имен. @type kwargs: C{dictionary} @param kwargs: Дополнительные аргументы функции. """ result = None # Подготовить пространство имен if name_space is None or not isinstance(name_space, dict): name_space = {} func_import = sCode.split('(')[0].split('.') func_mod = '.'.join(func_import[:-1]) if bReImport: unLoadSource(func_mod) # Импортирование модуля if func_mod: import_str = 'import ' + func_mod try: exec import_str except: log.error(u'Import module error <%s>' % import_str) raise # Добавить локальное пространство имен name_space.update(locals()) if kwargs: if isinstance(kwargs, dict): name_space.update(kwargs) else: log.warning( u'Не поддерживаемый тип <%s> дополнительных аргументов функции <%s>' % (type(kwargs), sCode)) # Выполнение функции try: result = eval(sCode, globals(), name_space) except: log.error(u'Execute function error <%s>' % sCode) raise return result
def write(self, RepFileName_, RepData_): """ Сохранить заполненный отчет в файле. @param RepFileName_: Имя файла отчета XML. @param RepData_: Данные отчета. @return: Функция возвращает имя созданного xml файла, или None в случае ошибки. """ xml_file = None try: # Начать запись xml_file = open(RepFileName_, 'w') xml_gen = icXMLSSGenerator(xml_file) xml_gen.startDocument() xml_gen.startBook() # Параметры страницы # xml_gen.savePageSetup(RepName_,Rep_) # Стили xml_gen.scanStyles(RepData_['sheet']) xml_gen.saveStyles() # Данные xml_gen.startSheet(RepData_['name'], RepData_) xml_gen.saveColumns(RepData_['sheet']) for i_row in xrange(len(RepData_['sheet'])): xml_gen.startRow(RepData_['sheet'][i_row]) # Сбросить индекс ячейки xml_gen.cell_idx = 1 for i_col in range(len(RepData_['sheet'][i_row])): cell = RepData_['sheet'][i_row][i_col] xml_gen.saveCell(i_row + 1, i_col + 1, cell, RepData_['sheet']) xml_gen.endRow() xml_gen.endSheet(RepData_) # Закончить запись xml_gen.endBook() xml_gen.endDocument() xml_file.close() return RepFileName_ except: if xml_file: xml_file.close() log.error(u'Ошибка сохранения отчета <%s>.' % textfunc.toUnicode(RepFileName_)) raise return None
def write_book(self, RepFileName_, *RepSheetData_): """ Сохранить список листов заполненного отчета в файле. @param RepFileName_: Имя файла отчета XML. @param RepSheetData_: Данные отчета, разобранные по листам. @return: Функция возвращает имя созданного xml файла, или None в случае ошибки. """ try: # Начать запись xml_file = None xml_file = open(RepFileName_, 'w') xml_gen = icXMLSSGenerator(xml_file) xml_gen.startDocument() xml_gen.startBook() for rep_sheet_data in RepSheetData_: # Стили xml_gen.scanStyles(rep_sheet_data['sheet']) xml_gen.saveStyles() for rep_sheet_data in RepSheetData_: # Данные xml_gen.startSheet(rep_sheet_data['name'], rep_sheet_data) xml_gen.saveColumns(rep_sheet_data['sheet']) for i_row in xrange(len(rep_sheet_data['sheet'])): xml_gen.startRow(rep_sheet_data['sheet'][i_row]) # Сбросить индекс ячейки xml_gen.cell_idx = 1 for i_col in range(len(rep_sheet_data['sheet'][i_row])): cell = rep_sheet_data['sheet'][i_row][i_col] xml_gen.saveCell(i_row + 1, i_col + 1, cell, rep_sheet_data['sheet']) xml_gen.endRow() xml_gen.endSheet(rep_sheet_data) #Закончить запись xml_gen.endBook() xml_gen.endDocument() xml_file.close() return RepFileName_ except: if xml_file: xml_file.close() log.error(u'Ошибка сохранения отчета %s.' % RepFileName_) raise return None
def activeWorkbook(self, XMLFileName_=None): """ Сделать книгу активной. """ try: xml_file_name = os.path.abspath(XMLFileName_) if os.path.exists(xml_file_name): self.SpreadsheetFileName = xml_file_name self._data = self._workbooks[xml_file_name] else: log.warning('Workbook file <%s> not exists!' % xml_file_name) except KeyError: log.error('Workbook <%s> not registered in <%s>' % (xml_file_name, self._workbooks.keys())) raise
def getSubDirsFilter(Path_, Filter_=DEFAULT_DIR_FILTER): """ Функция возвращает список поддиректорий с отфильтрованными папками. @param Path_: Дeрикторий. @param Filter_: Список недопустимых имен папок. @return: В случае ошибки возвращает None. """ try: dir_list = [ os.path.normpath(Path_ + '/' + path) for path in os.listdir(Path_) ] dir_list = [path for path in dir_list if os.path.isdir(path)] dir_list = [dir for dir in dir_list if _pathFilter(dir, Filter_)] return dir_list except: log.error('Read subfolder list error <%s>' % Path_) return None
def get_absolute_path(path, cur_dir=None): """ Абсолютный путь. Путь приводится к виду Unix. @param path: Путь. @param cur_dir: Текущий путь. """ try: if not path: log.error(u'Не определен путь для приведения к абсолютному виду') return None # Нормализация текущего пути cur_dir = getCurDirPrj(cur_dir) # Коррекция самого пути path = os.path.abspath(path.replace('./', cur_dir).strip()) except: log.fatal(u'Ошибка определения абсолютног пути <%s>. Текущая директория <%s>' % (path, cur_dir)) return path
def getReportGeneratorSystem(RepFileName_, ParentForm_=None, bRefresh=True): """ Получить объект системы генерации отчетов. @param RepFileName_: Имя файла шаблона отчета. @param ParentForm_: Родительская форма, необходима для вывода сообщений. @param bRefresh: Указание обновления данных шаблона отчета в генераторе. @return: Функция возвращает объект-наследник класса icReportGeneratorSystem. None - в случае ошибки. """ try: # Прочитать шаблон отчета rep = res.loadResourceFile(RepFileName_, bRefresh=True) global REP_GEN_SYS # Создание системы ренерации отчетов if REP_GEN_SYS is None: REP_GEN_SYS = createReportGeneratorSystem(rep['generator'], rep, ParentForm_) REP_GEN_SYS.RepTmplFileName = RepFileName_ elif not REP_GEN_SYS.sameGeneratorType(rep['generator']): REP_GEN_SYS = createReportGeneratorSystem(rep['generator'], rep, ParentForm_) REP_GEN_SYS.RepTmplFileName = RepFileName_ else: if bRefresh: # Просто установить обновление REP_GEN_SYS.setRepData(rep) REP_GEN_SYS.RepTmplFileName = RepFileName_ # Если родительская форма не определена у системы генерации, # то установить ее if REP_GEN_SYS and REP_GEN_SYS.getParentForm() is None: REP_GEN_SYS.setParentForm(ParentForm_) return REP_GEN_SYS except: log.error( u'Ошибка определения объекта системы генерации отчетов. Отчет <%s>.' % RepFileName_) raise return None
def loadResourceText(FileName_): """ Получить ресурс из ресурсного файла в текстовом формате. @param FileName_: Полное имя ресурсного файла. """ if os.path.isfile(FileName_): try: f = None f = open(FileName_) txt = f.read().replace('\r\n', '\n') f.close() return eval(txt) except: if f: f.close() log.error(u'Ошибка чтения файла <%s>.' % FileName_) return None else: log.warning(u'Файл <%s> не найден.' % FileName_) return None
def loadResourcePickle(FileName_): """ Получить ресурс из ресурсного файла в формате Pickle. @param FileName_: Полное имя ресурсного файла. """ if os.path.isfile(FileName_): try: f = None f = open(FileName_) struct = cPickle.load(f) f.close() return struct except: if f: f.close() log.error(u'Ошибка чтения файла <%s>.' % FileName_) return None else: log.warning(u'Файл <%s> не найден.' % FileName_) return None
def data_convert(self, Data_): """ Преобразование данных из одного представления в другое. """ try: style_lib = {} # Определение основных структур workbook = Data_['children'][0] # Стили (в виде словаря) styles = {} styles_lst = [ element for element in workbook['children'] if element['name'] == 'Styles' ] if styles_lst: styles = dict([(style['ID'], style) for style in styles_lst[0]['children']]) worksheets = [ element for element in workbook['children'] if element['name'] == 'Worksheet' ] rep_worksheet = worksheets[0] rep_data_tab = rep_worksheet['children'][0] # Список строк rep_data_rows = [ element for element in rep_data_tab['children'] if element['name'] == 'Row' ] # Заполнение style_lib = self._getStyles(rep_data_rows, styles) return style_lib except: # Вывести сообщение об ошибке в лог log.error( u'Ошибка преобразования данных библиотеки стилей отчета.') return None
def createEmptyBitmap(width, height, colour): """ Создать пустой битмап. @param width, height: Размер битмапа. @param colour: Цвет фона. """ try: # Пустой квадратик bmp = wx.EmptyBitmap(width, height) # Создать объект контекста устройства dc = wx.MemoryDC() # Выбрать объект для контекста dc.SelectObject(bmp) # Изменить фон dc.SetBackground(wx.Brush(colour)) dc.Clear() # Освободить объект dc.SelectObject(wx.NullBitmap) return bmp except: log.error('Create empty bitmap SIZE: <%s, %s> COLOUR: <%s>' % (wodth, height, colour)) return None
def PreviewOffice(self, ODSFileName_): """ Открыть отчет в режиме предварительного просмотра. @param ODSFileName_: Имя ods файла, содержащего сгенерированный отчет. """ if not os.path.exists(ODSFileName_): log.warning(u'Предварительный просмотр. Файл <%s> не найден' % ODSFileName_) return pdf_filename = os.path.splitext(ODSFileName_)[0] + '.pdf' if os.path.exists(pdf_filename): try: os.remove(pdf_filename) except: log.error(u'Delete file <%s>' % pdf_filename) cmd = 'unoconv --format=pdf %s' % ODSFileName_ log.info(u'UNOCONV. Command <%s>' % cmd) os.system(cmd) cmd = 'evince %s&' % pdf_filename log.info(u'EVINCE. Command <%s>' % cmd) os.system(cmd)
def getImageFileType(img_filename): """ Определить тип файла образа по его расширению ( .jpg, ... ). @param img_filename: Полное имя файла. """ if img_filename == '' or not os.path.exists(img_filename): log.warning('File <%s> not found' % img_filename) return None try: name, ext = os.path.splitext(img_filename) ext = ext[1:].upper() if ext == 'BMP': return wx.BITMAP_TYPE_BMP elif ext == 'GIF': return wx.BITMAP_TYPE_GIF elif ext == 'JPG' or ext == 'JPEG': return wx.BITMAP_TYPE_JPEG elif ext == 'PCX': return wx.BITMAP_TYPE_PCX elif ext == 'PNG': return wx.BITMAP_TYPE_PNG elif ext == 'PNM': return wx.BITMAP_TYPE_PNM elif ext == 'TIF' or ext == 'TIFF': return wx.BITMAP_TYPE_TIF elif ext == 'XBM': return wx.BITMAP_TYPE_XBM elif ext == 'XPM': return wx.BITMAP_TYPE_XPM else: log.warning('Not support image file type <%s>' % ext) except: log.error('Get image file type') return None
def createBitmap(img_filename, bMakeMask=False): """ Создать объект Bitmap из файла ImgFileName_. @param img_filename: Имя файла. @param bMakeMask: Флаг создания маски по изображению. Фон д.б. CYAN (0, 255, 255) @return: Возвращает созданный объект или None в случае ошибки. """ try: # Преобразовать относительные пути в абсолютные img_filename = os.path.abspath(os.path.normpath(img_filename)) if not img_filename or not os.path.exists(img_filename): log.warning('File <%s> not found' % img_filename) return None bmp = wx.Bitmap(img_filename, getImageFileType(img_filename)) if bMakeMask: # Создать маску и присоединить ее к битмапу phone_colour = wx.CYAN bmp.SetMask(wx.MaskColour(bmp, phone_colour)) return bmp except: log.error(u'Ошибка создания образа файла <%s>' % img_filename) return None
def main(argv): """ Основная запускающая функция. @param argv: Список параметров коммандной строки. """ # Разбираем аргументы командной строки try: options, args = getopt.getopt(argv, 'h?vdl', [ 'help', 'version', 'debug', 'log', 'scanner=', 'source=', 'mode=', 'multi_scan', 'preview', 'page_size=', 'area=', 'scan_dir=', 'file_name=', 'file_type=', 'ext_cmd=', 'pack_mode', 'pack_pages=', 'glue', 'max_sheets=' ]) except getopt.error as msg: log.error(str(msg), bForcePrint=True) log.info(__doc__) sys.exit(2) # Инициализоция системы журналирования log.init(config) txt_version = '.'.join([str(ver) for ver in __version__]) cmd_options = dict() for option, arg in options: if option in ('-h', '--help', '-?'): print(__doc__) sys.exit(0) elif option in ('-v', '--version'): print('icScanner version: %s' % txt_version) sys.exit(0) elif option in ('-d', '--debug'): config.set_glob_var('DEBUG_MODE', True) elif option in ('-l', '--log'): config.set_glob_var('LOG_MODE', True) elif option in ('--scanner', ): cmd_options['scanner'] = arg elif option in ('--source', ): cmd_options['scan_source'] = arg elif option in ('--mode', ): cmd_options['scan_mode'] = arg elif option in ('--multi_scan', ): cmd_options['is_multi_scan'] = True elif option in ('--preview', ): cmd_options['is_preview'] = True elif option in ('--page_size', ): if arg in ('A4', 'a4'): cmd_options['page_size'] = scan_manager.A4_PORTRAIT_PAGE_SIZE elif arg in ('A3', 'a3'): cmd_options['page_size'] = scan_manager.A3_PORTRAIT_PAGE_SIZE else: log.warning(u'Не обрабатываемый размер страницы <%s>' % arg) elif option in ('--area', ): try: area = tuple([float(x.strip()) for x in arg.split(',')]) cmd_options['scan_area'] = area except: log.fatal( u'Ошибка парсинга параметра области сканирования <%s>' % arg) elif option in ('--scan_dir', ): cmd_options['scan_dir'] = arg elif option in ('--file_name', ): cmd_options['scan_filename'] = arg elif option in ('--file_type', ): cmd_options['scan_filetype'] = arg.lower() elif option in ('--depth', ): cmd_options['depth'] = int(arg) elif option in ('--ext_cmd', ): cmd_options['ext_scan_cmd'] = arg elif option in ('--pack_mode', ): cmd_options['pack_mode'] = True elif option in ('--pack_pages', ): cmd_options['pack_pages'] = arg elif option in ('--max_sheets', ): config.set_glob_var('DEFAULT_SCANNER_MAX_SHEETS', int(arg)) else: log.warning(u'Не обрабатываемый параметр коммандной строки <%s>' % option) # По умолчанию пакетный режим отключен+ # v if not cmd_options.get('pack_mode', False): # Внимание! Приложение создается для # управления диалоговыми окнами app = wx.PySimpleApp() # ВНИМАНИЕ! Выставить русскую локаль # Это необходимо для корректного отображения календарей, # форматов дат, времени, данных и т.п. locale = wx.Locale() locale.Init(wx.LANGUAGE_RUSSIAN) scanner_dlg.do_scan_dlg(options=cmd_options, title=u'Сканирование. icScanner ' + txt_version) app.MainLoop() else: # В пакетном режиме не используем диалоговое окно # Но в случае режима склеивания документа по частям диалоговые окна используются filenames = cmd_options.get('scan_filename', u'').split(';') pack_page_list = cmd_options.get('pack_pages', u'').split(';') n_pages = [ int(pack_page.split('/')[0]) if '/' in pack_page else int(pack_page) for pack_page in pack_page_list ] duplexes = [ bool(int(pack_page.split('/')[1])) if '/' in pack_page else False for pack_page in pack_page_list ] scan_filenames = [(filename, n_pages[i] if i < len(n_pages) else 1, duplexes[i] if i < len(duplexes) else False) for i, filename in enumerate(filenames)] scan_admin = scanner_dlg.icScanAdministrator() # Установить дополнительные опции из коммандной строки scan_admin.setExtOptions(scan_dir=cmd_options['scan_dir']) scan_admin.runScanPack(*scan_filenames)
def main(argv): """ Основная запускающая функция. @param argv: Список параметров коммандной строки. """ # Инициализоция системы журналирования log.init(config) # Разбираем аргументы командной строки 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.error(err.msg, bForcePrint=True) log.warning('For help use --help option', bForcePrint=True) sys.exit(2) # Параметры запуска генерации отчета из коммандной строки report_filename = None db = None sql = None do_cmd = None stylelib = None vars = dict() path = None mode = 'default' mode_arg = None for option, arg in options: if option in ('-h', '--help', '-?'): print(__doc__) sys.exit(0) elif option in ('-v', '--version'): print('icReport version: %s' % '.'.join([str(ver) for ver in __version__])) sys.exit(0) elif option in ('-d', '--debug'): config.set_glob_var('DEBUG_MODE', True) elif option in ('-l', '--log'): config.set_glob_var('LOG_MODE', True) 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() vars[var_name] = var_value log.debug(u'Дополнительная переменная <%s>. Значение [%s]' % (unicode(var_name, config.DEFAULT_ENCODING), unicode(var_value, config.DEFAULT_ENCODING))) elif option in ('--path', ): path = arg elif option in ('--no_gui', ): config.set_glob_var('NO_GUI_MODE', True) # ВНИМАНИЕ! Небходимо добавить путь к папке отчетов, # чтобы проходили импорты модулей отчетов 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.PySimpleApp() # ВНИМАНИЕ! Выставить русскую локаль # Это необходимо для корректного отображения календарей, # форматов дат, времени, данных и т.п. locale = wx.Locale() locale.Init(wx.LANGUAGE_RUSSIAN) if mode == 'default': if report_filename: # Запустить генерацию отчета из комадной строки do_report.doReport(report_filename=report_filename, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=vars) elif mode == 'view': do_report.ReportViewer(report_dir=path) elif mode == 'edit': do_report.ReportEditor(report_dir=path) elif mode == 'print': do_report.ReportPrint(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=vars) elif mode == 'preview': do_report.ReportPreview(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=vars) elif mode == 'export': do_report.ReportExport(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=vars) elif mode == 'select': do_report.ReportSelect(report_filename=mode_arg, report_dir=path, db_url=db, sql=sql, command=do_cmd, stylelib_filename=stylelib, variables=vars) app.MainLoop()
def loadResourceFile(filename, dictRpl={}, bRefresh=False, *arg, **kwarg): """ Загрузить ресурс из файла. Функция читает файл и выполняет его. @type filename: C{string} @param filename: Имя ресурсного файла. @type dictRpl: C{dictionary} @param dictRpl: Словарь замен. @type bRefresh: C{bool} @param bRefresh: Признак того, что файл надо перечитать даже если он буферезирован. """ obj = None filename = filename.strip() try: # Проверяем есть ли в буфферном файле такой объект, если есть, то его и возвращаем if not bRefresh and filename in Buff_readAndEvalFile: log.debug(' ' * 3 + '[b] ' + 'Return from buffer file: <%s>' % filename) return Buff_readAndEvalFile[filename] nm = os.path.basename(filename) pt = nm.find('.') if pt >= 0: filepcl = os.path.dirname( filename) + '/' + nm[:pt] + '_pkl' + nm[pt:] else: filepcl = os.path.dirname(filename) + '/' + nm + '_pkl' # Проверяем нужно ли компилировать данную структуру по следующим признакам: # наличие скомпилированного файла, по времени последней модификации. try: if (os.path.isfile(filepcl) and not os.path.isfile(filename)) or \ (os.path.getmtime(filename) < os.path.getmtime(filepcl)): # Пытаеся прочитать сохраненную структуру если время последней # модификации текстового представления меньше, времени # последней модификации транслированного варианта. fpcl = None try: fpcl = open(filepcl) obj = cPickle.load(fpcl) fpcl.close() # Сохраняем объект в буфере Buff_readAndEvalFile[filename] = obj log.debug(' [+] Load from: %s' % filepcl) return obj except IOError: log.error(' [-] readAndEvalFile: Open file <%s> error.' % filepcl) except: if fpcl: fpcl.close() except: pass # Пытаемся прочитать cPickle, если не удается считаем, что в файле # хранится текст. Читаем его, выполняем, полученный объект сохраняем # на диске для последующего использования if os.path.isfile(filename): try: fpcl = open(filename) obj = cPickle.load(fpcl) fpcl.close() # Сохраняем объект в буфере Buff_readAndEvalFile[filename] = obj log.debug(' [+] Load file <%s> cPickle Format.' % filename) return obj except Exception, msg: log.error( ' [*] Non cPickle Format file <%s>. Try to compile text' % filename) # Открываем текстовое представление, если его нет, то создаем его f = open(filename, 'rb') txt = f.read().replace('\r\n', '\n') f.close() for key in dictRpl: txt = txt.replace(key, dictRpl[key]) # Выполняем obj = eval(txt) # Сохраняем объект в буфере Buff_readAndEvalFile[filename] = obj # Сохраняем транслированный вариант fpcl = open(filepcl, 'w') log.debug('Create cPickle <%s>' % filepcl) cPickle.dump(obj, fpcl, PICKLE_PROTOCOL) fpcl.close()
# --- Подключение библиотек --- import sys import os import os.path import inspect import wx from encodings.aliases import aliases from ic.std.log import log try: import win32api import win32con import regutil except ImportError: log.error(u'ImportError: PyWin32') try: import DevId except: log.error(u'ImportError: Recompiled DevId module') __version__ = (0, 0, 1, 2) # --- Функции --- def IsSubClass(Class1_, Class2_): """ Функция определяет является ли Class1_ базовым для Class2_. Проверка производится рекурсивно. @param Class1_: Объект класса.
def parse(self, TemplateData_, template_name=None): """ Разобрать/преобразовать прочитанную структуру. @param TemplateData_: Словарь описания шаблона. @param template_name: Имя шаблона(листа), если None то первый лист. """ try: # Создать первоначальный шаблон rep = copy.deepcopy(icrepgen.IC_REP_TMPL) # 0. Определение основных структур workbook = TemplateData_['children'][0] # Стили (в виде словаря) styles = dict([(style['ID'], style) for style in [element for element in workbook['children'] if element['name'] == 'Styles'][0]['children']]) worksheets = [element for element in workbook['children'] if element['name'] == 'Worksheet'] # I. Определить все бэнды в шаблоне # Если имя шаблона не определено, тогда взять первый лист if template_name is None: template_name = worksheets[0]['Name'] self._rep_worksheet = worksheets[0] else: # Установить активной страницу выбранного шаблона отчета self._rep_worksheet = [sheet for sheet in worksheets if sheet['Name'] == template_name][0] # Прописать имя отчета rep['name'] = template_name # Взять таблицу rep_template_tabs = [rep_obj for rep_obj in self._rep_worksheet['children'] if rep_obj['name'] == 'Table'] self._setDefaultCellSize(rep_template_tabs[0]) # Привести таблицу к нормальному виду rep_template_tab = self._normTable(rep_template_tabs[0]) # Взять описания колонок rep_template_cols = [element for element in rep_template_tab['children'] if element['name'] == 'Column'] rep_template_cols = self._defineSpan(rep_template_cols) # Взять описания строк rep_template_rows = [element for element in rep_template_tab['children'] if element['name'] == 'Row'] rep_template_rows = self._defineSpan(rep_template_rows) # Количество колонок без колонки тегов бендов col_count = self._getColumnCount(rep_template_rows) log.debug(u'Количество колонок: %d' % col_count) # II. Определить все ячейки листа used_rows = range(len(rep_template_rows)) used_cols = range(col_count) self.__cur_band = None # Тег текущего бенда # Перебор по строкам for cur_row in used_rows: if not self._isTitleBand(rep_template_rows, cur_row): # Не колонтитулы, добавить ячейки в общий лист rep['sheet'].append([]) for cur_col in used_cols: cell_attr = self._getCellAttr(rep_template_rows, rep_template_cols, styles, cur_row, cur_col) if not self._isTag(cell_attr['value']): rep['sheet'][-1].append(cell_attr) else: rep['sheet'][-1].append(None) # III. Определить бэнды в шаблоне # Перебрать все ячейки первой колонки self.__cur_band = None # Тег текущего бенда title_row = 0 # Счетчик строк колонтитулов/заголовочных бендов # Перебор всех строк в шаблоне for cur_row in range(len(rep_template_rows)): tag = self._getTagBandRow(rep_template_rows, cur_row) # Если это ячейка с определенным тегом, значит новый бенд if tag: # Определить текущий бэнд self.__cur_band = tag if tag in TITLE_TAGS: # Обработка строк заголовочных тегов parse_func = self._TitleTagParse.setdefault(tag, None) try: parse_func(self, rep, rep_template_rows[cur_row]['children']) except: log.fatal(u'Ошибка парсинга функции <%s>' % textfunc.toUnicode(parse_func)) title_row += 1 else: # Определить бэнд внутри объекта rep = self._defBand(self.__cur_band, cur_row, col_count, title_row, rep) else: log.error(u'Не корректный тег строки [%d]' % cur_row) # Прочитать в шаблон параметры страницы rep['page_setup'] = copy.deepcopy(icrepgen.IC_REP_PAGESETUP) sheet_options = [rep_obj for rep_obj in self._rep_worksheet['children'] if rep_obj['name'] == 'WorksheetOptions'] page_setup = [rep_obj for rep_obj in sheet_options[0]['children'] if rep_obj['name'] == 'PageSetup'][0] rep['page_setup'].update(self._getPageSetup(page_setup)) print_setup = [rep_obj for rep_obj in sheet_options[0]['children'] if rep_obj['name'] == 'Print'] if print_setup: rep['page_setup'].update(self._getPrintSetup(print_setup[0])) # Проверить заполнение генератора отчета if not rep['generator']: tmpl_filename = self.getTemplateFilename() rep['generator'] = os.path.splitext(tmpl_filename)[1].upper() if tmpl_filename else '.ODS' return rep except: log.fatal(u'Ошибка парсинга шаблона отчета <%s>' % textfunc.toUnicode(template_name)) return None
#!/usr/bin/env python # -*- coding: utf-8 -*- import time import random import md5 try: from ic.std.log import log except ImportError: from ic.log import log try: import pythoncom except ImportError: log.error(u'Import Error pythoncom') __version__ = (0, 0, 2, 1) def get_uuid(*args): """ Generates a universally unique ID. Any arguments only create more randomness. """ t = long(time.time() * 1000) r = long(random.random()*100000000000000000L) a = random.random()*100000000000000000L data = str(t)+' '+str(r)+' '+str(a)+' '+str(args) data = md5.md5(data).hexdigest()
f.close() for key in dictRpl: txt = txt.replace(key, dictRpl[key]) # Выполняем obj = eval(txt) # Сохраняем объект в буфере Buff_readAndEvalFile[filename] = obj # Сохраняем транслированный вариант fpcl = open(filepcl, 'w') log.debug('Create cPickle <%s>' % filepcl) cPickle.dump(obj, fpcl, PICKLE_PROTOCOL) fpcl.close() except IOError: log.error(' [*] Open file <%s> error.' % filename) obj = None except: log.error(' [*] Translation file <%s> error.' % filename) obj = None return obj def loadResource(FileName_): """ Получить ресурс в ресурсном файле. @param FileName_: Полное имя ресурсного файла. """ # Сначала предположим что файл в формате Pickle. struct = loadResourcePickle(FileName_)