Exemple #1
0
def getDateRangeDlg(parent=None, is_concrete_date=False):
    """
    Select date range in dialog.

    :param parent: Parent window.
        If None then get wx.GetApp().GetTopWindow()
    :param is_concrete_date: Select concrete date?
    :return: Date range tuple (as datetime) or None if press <Cancel>.
    """
    selected_range = None

    if parent is None:
        parent = wx.GetApp().GetTopWindow()

    dlg = daterange_dlg.iqDateRangeDialog(parent)
    dlg.setConcreteDateCheck(is_concrete_date)

    dlg.Centre()

    if dlg.ShowModal() == wx.ID_OK:
        selected_range = dlg.getSelectedDateRangeAsDatetime()
    dlg.Destroy()

    if selected_range:
        try:
            log_func.debug(u'Selected date range: <%s> - <%s>' % selected_range)
        except:
            pass
    return selected_range
def editIndicatorConstructorDlg(parent=None, indicator=None):
    """
    Start editing the filter indicator.

    :param parent: Parent window.
    :param indicator: Indicator state.
    :return: Edited indicator list or None if CANCEL is pressed.
    """
    try:
        if parent is None:
            parent = iq.getMainWin()

        dlg = iqIndicatorConstructorDlg(parent)
        dlg.init()
        dlg.setIndicator(indicator=indicator, refresh_ctrl=True)
        result = dlg.ShowModal()
        if result == wx.ID_OK:
            indicator = dlg.getIndicator()
            dlg.Destroy()
            log_func.debug(u'List of edited filter indicator %s' %
                           str(indicator))
            return indicator
    except:
        log_func.fatal(u'Filter indicator editing error')
    return None
    def edit(self, rep_filename=None):
        """
        Edit report.

        :param rep_filename: Report template filename.
        """
        rprt_file_name = os.path.abspath(rep_filename)
        rep = res_func.loadResource(rprt_file_name)
        report_dir = os.path.abspath(self.getReportDir())
        rep_file = os.path.join(report_dir, rep['generator'])

        reportman_designer_key = utilfunc.getRegValue(
            'Software\\Classes\\Report Manager Designer\\shell\\open\\command',
            None)
        if reportman_designer_key:
            reportman_designer_run = reportman_designer_key.replace(
                '\'%1\'', '\'%s\'') % rep_file
            cmd = 'start %s' % reportman_designer_run
            log_func.debug(u'Execute command <%s>' % cmd)
            # Run Report Manager Designer
            os.system(cmd)
        else:
            msg = u'Not define Report Manager Designer <%s>' % reportman_designer_key
            log_func.warning(msg)
            dlg_func.openWarningBox(u'WARNING', msg)

        xml_file = os.path.normpath(
            os.path.abspath(os.path.splitext(rep_filename)[0] + '.xml'))
        cmd = 'start excel.exe \'%s\'' % xml_file
        log_func.debug(u'Execute command <%s>' % cmd)
        os.system(cmd)
    def _execCodeBlock(self, cur_func, locals, globals):
        """
        Execute code block.
        In the code block, new_cell and record objects are available.
        If you need to display information, then it must be displayed in the variable value.
        For example:
            [=value = '-' if record['name']=='My name' else ''=]

        :param cur_func: Code block text.
        :param locals: Local name space.
        :param globals: Global name space.
        :return: The calculated value as a string or an empty string in case of an error.
        """
        value = u''
        exec_func = cur_func[2:-2].strip()
        try:
            exec(exec_func, globals, locals)
            # When the code block is executed, the value of the variable is located in the locals namespace.
            # Therefore, after executing the code block, it is necessary
            # to return the variable back to the current function
            value = locals.get('value', u'')
            log_func.debug(u'Execute code block <%s>. Value [%s]' % (exec_func, value))
        except:
            log_func.fatal(u'Error code block execute <%s>' % str_func.toUnicode(exec_func))
        return str(value)
    def createNewByOffice(self, dst_path=None):
        """
        Create a new report using LibreOffice Calc.

        :param dst_path: Destination report folder path.
        """
        try:
            src_filename = DEFAULT_REP_TMPL_FILE
            new_filename = dlg_func.getTextEntryDlg(self._parent_window,
                                                    u'Create new',
                                                    u'Enter a file name for the report template')
            if os.path.splitext(new_filename)[1] != '.ods':
                new_filename += '.ods'

            if dst_path is None:
                # It is necessary to determine the resulting path
                dst_path = dlg_func.getDirDlg(self._parent_window,
                                              u'Report folder')
                if not dst_path:
                    dst_path = os.getcwd()

            dst_filename = os.path.join(dst_path, new_filename)
            if os.path.exists(dst_filename):
                if dlg_func.openAskBox(u'Rewrite existing file?'):
                    shutil.copyfile(src_filename, dst_filename)
            else:
                shutil.copyfile(src_filename, dst_filename)

            cmd = '%s %s' % (UNIX_OFFICE_OPEN, dst_filename)
            log_func.debug(u'Command <%s>' % str_func.toUnicode(cmd))
            os.system(cmd)

            return True
        except:
            log_func.fatal(u'Error create new report template by LibreOffice Calc')
Exemple #6
0
    def setExtOptions(self, **options):
        """
        Set advanced options.

        :param options: Dictionary of options.
        """
        log_func.debug(u'Scan options: %s' % options)
        if options:
            if 'scanner' in options:
                self.scanner = options.get('scanner', None)
            if 'source' in options:
                self.scan_source = options.get('source', None)
            if 'mode' in options:
                self.scan_mode = options.get('mode', None)
            if 'is_multi_scan' in options:
                self.is_multi_scan = options.get('is_multi_scan', None)
            if 'is_preview' in options:
                self.is_preview = options.get('is_preview', None)
            if 'page_size' in options:
                self.page_size = options.get('page_size', None)
            if 'area' in options:
                self.scan_area = options.get('area', None)
            if 'scan_dir' in options:
                self.scan_dir = options.get('scan_dir', None)
            if 'file_name' in options:
                self.scan_filename = options.get('file_name', None)
            if 'file_type' in options:
                self.scan_filetype = options.get('file_type', None)
            if 'depth' in options:
                self.depth = options.get('depth', None)
            if 'ext_scan_cmd' in options:
                self.ext_scan_cmd = options.get('ext_scan_cmd', None)
        else:
            log_func.warning(u'Undefined scan options for set')
Exemple #7
0
    def showOptions(self):
        """
        Set scan parameters in window controls.
        """
        if self.scanner:
            self.scanner_comboBox.SetStringSelection(self.scanner)

        if self.scan_source:
            i = 0
            try:
                log_func.debug(u'Setting the scan source <%s>' % self.scan_source)
                i = scan_manager.SCAN_SOURCES.index(self.scan_source)
            except ValueError:
                log_func.warning(u'Scan source not found <%s>' % self.scan_source)
            self.source_comboBox.Select(i)

        if self.scan_mode:
            i = 0
            try:
                i = scan_manager.SCAN_MODES.index(self.scan_mode)
            except ValueError:
                log_func.warning(u'Scan mode not found <%s>' % self.scan_mode)
            self.mode_comboBox.Select(i)

        self.multiscan_checkBox.SetValue(bool(self.is_multi_scan))
        self.preview_checkBox.SetValue(bool(self.is_preview))

        if self.page_size:
            i = 0
            try:
                i = scan_manager.SCAN_PAGE_SIZES.index(self.page_size)
            except ValueError:
                log_func.warning(u'Scan page size not found <%s>' % self.page_size)
            self.pagesize_comboBox.Select(i)

        if self.scan_area:
            self.left_spinCtrl.SetValue(self.scan_area[0])
            self.top_spinCtrl.SetValue(self.scan_area[1])
            self.right_spinCtrl.SetValue(self.scan_area[2])
            self.bottom_spinCtrl.SetValue(self.scan_area[3])

        if self.scan_dir:
            self.scan_dirPicker.SetPath(self.scan_dir)

        if self.scan_filename:
            self.filename_textCtrl.SetValue(self.scan_filename)

        if self.scan_filetype:
            i = 0
            try:
                i = scan_manager.SCAN_FILE_TYPES.index(self.scan_filetype)
            except ValueError:
                log_func.warning(u'Scan file type not found <%s>' % self.scan_filetype)
            self.fileext_comboBox.Select(i)

        if self.depth:
            self.depth_spinCtrl.SetValue(self.depth)

        if self.ext_scan_cmd:
            self.extern_cmd_textCtrl.SetValue(self.ext_scan_cmd)
Exemple #8
0
def appendDBFNewField(dbf_filename,
                      new_fieldname,
                      field_type,
                      field_length,
                      default=None):
    """
    Append new field inDBF table.

    :param dbf_filename: DBF filename.
    :param new_fieldname: New field name.
    :param field_type: Field type (C-string and etc).
    :param field_length: Field length.
    :param default: Default value.
    :return: DBF table object.
    """
    dbf_filename = os.path.abspath(dbf_filename)
    if not os.path.exists(dbf_filename):
        log_func.warning(u'DBF file <%s> not found' % dbf_filename)
        return None

    dbf_connection = None
    try:
        dbf_url = DBF_DB_URL_FMT % (os.path.dirname(dbf_filename),
                                    DEFAULT_DBF_ENCODING)
        dbf_connection = jaydebeapi.connect('com.hxtt.sql.dbf.DBFDriver',
                                            [dbf_url], JDBC_DBF_DRIVER)

        if field_type == 'C':
            db_cursor = dbf_connection.cursor()
            sql = 'ALTER TABLE %s ADD %s VARCHAR(%d)' % (os.path.splitext(
                os.path.basename(dbf_filename))[0], new_fieldname,
                                                         field_length)
            if default is not None:
                sql += ' DEFAULT \'%s\'' % str(default)
            log_func.debug(u'Execute SQL <%s>' % sql)
            db_cursor.execute(sql)
        elif field_type == 'L':
            db_cursor = dbf_connection.cursor()
            sql = 'ALTER TABLE %s ADD %s BOOLEAN' % (os.path.splitext(
                os.path.basename(dbf_filename))[0], new_fieldname)
            if default is not None:
                sql += ' DEFAULT %s' % str(default)
            db_cursor.execute(sql)
        elif field_type == 'D':
            db_cursor = dbf_connection.cursor()
            sql = 'ALTER TABLE %s ADD %s DATE' % (os.path.splitext(
                os.path.basename(dbf_filename))[0], new_fieldname)
            if default is not None:
                sql += ' DEFAULT \'%s\'' % str(default)
            db_cursor.execute(sql)
        else:
            log_func.warning(u'Unsupported field type <%s>' % field_type)
        dbf_connection.close()
    except:
        if dbf_connection:
            dbf_connection.close()
        log_func.fatal(u'Error append new field DBF file <%s>' % dbf_filename)
    return None
    def scanPack(self, scan_filenames=()):
        """
        Scan documents in batch mode and save them to files.

        :param scan_filenames: Scan file names with the number of sheets
            and a sign of 2-sided scanning.
            For example:
                ('D:/tmp/scan001', 3, True), ('D:/tmp/scan002', 1, False), ('D:/tmp/scn003', 2, True), ...
        :return: List of scan file names. None - in case of an error.
        """
        result = list()
        # Scanned Sheet Counter
        tray_sheet_count = 0
        # Tray volume in sheets
        max_sheets = self.getMaxSheets()

        # In batch mode, do not use the dialog box
        # But in the case of gluing the document in parts, the dialog boxes are used
        # Dialog Box Application Object
        wx_app = None

        for scan_filename, n_pages, is_duplex in scan_filenames:
            tray_sheet_count += n_pages if not is_duplex else n_pages / 2

            if tray_sheet_count <= max_sheets:
                # Until the scan counter has exceeded the tray size limit,
                # then continue the usual scan
                scan_result = self.scanPackPart(scan_filename, n_pages,
                                                is_duplex)
                result.append(scan_filename if scan_result
                              and os.path.exists(scan_filename) else None)
            else:
                log_func.debug(
                    u'Enabling document scan mode <%s> piecemeal. Number of pages [%d] Current counter %d. '
                    % (scan_filename, n_pages, tray_sheet_count))
                if wx_app is None:
                    wx_app = wx.PySimpleApp()

                    locale = wx.Locale()
                    locale.Init(wx.LANGUAGE_RUSSIAN)

                # If the tray runs out of paper, you need to start the process of gluing the last document
                glue_result = self.scanGlue(scan_filename, n_pages, is_duplex)
                result.append(scan_filename if glue_result
                              and os.path.exists(scan_filename) else None)

                # ATTENTION! After a successfully scanned large document,
                # reset the counter of scanned sheets
                tray_sheet_count = 0

        # ATTENTION! Because Since the interaction is built on modal dialogs,
        # MainLoop does not need to be done otherwise
        # the main application freezes
        # if wx_app:
        #    wx_app.MainLoop()

        return result
    def onIndicatorListItemSelected(self, event):
        """
        Handler for selecting an indicator state from the list.
        """
        idx = event.GetIndex()
        state_indicator = self._indicator[idx]
        log_func.debug(u'Edit indicator: %s' % str(state_indicator))
        self.setStateCtrlValue(state_indicator=state_indicator)

        self.ctrl_toolBar.EnableTool(self.save_tool.GetId(), True)

        event.Skip()
    def _execQueryFunc(self, query, vars=None):
        """
        Get a request from a function.

        :param query: Query text.
        :param vars: External variables.
        :return: Query in internal format.
        """
        # Clear signature
        func = query.replace(PY_SIGNATURE, '').strip()
        var_names = vars.keys() if vars else None
        log_func.debug(u'Execute function: <%s>. External variables %s' % (func, var_names))
        return exec_func.execTxtFunction(func, context=vars, show_debug=True)
    def _getVariable(self, cur_func, locals, globals):
        """
        Get variable from report name space.

        :param cur_func: Get variable text.
        :param locals: Local name space.
        :param globals: Global name space.
        :return: The variable value as a string or an empty string in case of an error.
        """
        var_name = cur_func[2:-2]
        if var_name in self._NameSpace:
            log_func.debug(u'Get variable <%s>' % var_name)
        else:
            log_func.warning(u'Variable <%s> not found in report name space' % var_name)
        value = str(self._NameSpace.setdefault(var_name, u''))
        return value
Exemple #13
0
    def setCircleMarker(self,
                        geo_latitude,
                        geo_longitude,
                        radius=100,
                        color='blue',
                        is_fill=True,
                        fill_color='blue',
                        popup_text=u'',
                        tooltip_text=u''):
        """
        Adding a circle marker to the map.

        :param geo_latitude: Geographic latitude.
        :param geo_longitude: Geographic longitude.
        :param radius: Circle radius.
        :param color: Circle color.
        :param is_fill: Fill the inner area of the circle?
        :param fill_color: The fill color of the circle.
        :param popup_text: Marker pop-up text.
            A tooltip appears by clicking on the marker.
        :param tooltip_text: Marker tooltip text.
            A tooltip appears when you hover the mouse over the marker.
        :return: True/False.
        """
        if self._geo_map is not None:
            try:
                color = wxcolour_func.wxColour2StrRGB(color) if color else None
                fill_color = wxcolour_func.wxColour2StrRGB(
                    color) if fill_color else None

                marker = self._rendering.CircleMarker(
                    location=[geo_latitude, geo_longitude],
                    radius=radius,
                    popup=popup_text if popup_text else None,
                    color=color if color else None,
                    fill=is_fill,
                    fill_color=fill_color if fill_color else None,
                    tooltip=tooltip_text if tooltip_text else None)
                marker.add_to(self._geo_map)
                log_func.debug(
                    u'Circle marker created. Geolocation [%s x %s]' %
                    (geo_latitude, geo_longitude))
            except:
                log_func.fatal(u'Error adding a circle marker to the map')
        else:
            log_func.warning(u'Map object not defined to add a circle marker')
        return False
 def onPrintRepButton(self, event):
     """
     Print button click handler.
     """
     item = self.rep_tree.GetSelection()
     item_data = self.rep_tree.GetItemData(item)
     log_func.debug(u'Print <%s>' %
                    item_data[REP_FILE_IDX] if item_data else u'-')
     if item_data is not None and item_data[REP_ITEMS_IDX] is None:
         report_gen_func.getReportGeneratorSystem(item_data[REP_FILE_IDX],
                                                  parent=self,
                                                  refresh=True).print()
     else:
         dlg_func.openWarningBox(title=_(u'WARNING'),
                                 message=_(u'You must select a report'),
                                 parent=self)
     event.Skip()
Exemple #15
0
    def onLastDateChanged(self, event):
        """
        Change last date handler.
        """
        first_date = self.firstDatePicker.GetValue()
        last_date = event.GetDate()

        try:
            log_func.debug(u'Correct last date <%d.%d.%d>' %
                           (last_date.GetDay(), last_date.GetMonth(),
                            last_date.GetYear()))
        except:
            pass
        if first_date > last_date and len(str(last_date.GetYear())) == 4:
            self.lastDatePicker.SetValue(first_date)

        event.Skip()
    def onUpdateRepButton(self, event):
        """
        Update button click handler.
        """
        item = self.rep_tree.GetSelection()
        item_data = self.rep_tree.GetItemData(item)
        if item_data is not None and item_data[REP_ITEMS_IDX] is None:
            log_func.debug(u'Update report <%s>' % item_data[0])
            report_gen_func.getReportGeneratorSystem(item_data[REP_FILE_IDX],
                                                     parent=self).update(
                                                         item_data[0])
        else:
            report_gen_func.getCurReportGeneratorSystem(self).update()

        self.buildReportTree(self._report_dirname)

        event.Skip()
Exemple #17
0
def getSputnikGeolocations(address_query):
    """
    Get all geolocation data for the requested address
    by service http://api.sputnik.ru/maps/geocoder/.

    :param address_query: Address.
        For example:
            Moscow, Gagarin street, 10.
    :return: [(latitude, longitude),...] Geolocation data list or empty list in case of error.
    """
    try:
        address = urllib.parse.quote(address_query)
        url = SPUTNIK_GEO_LOCATOR_URL_FMT % address
        log_func.debug(u'Geodata retrieval URL <%s>' % url)
        response = urllib.request.urlopen(url)
        data = response.read()
        # ERROR: JSON object must be str not bytes
        #                                      V
        geo_location_data = json.loads(data.decode('utf-8'))

        find_address = geo_location_data.get('result',
                                             dict()).get('address', list())
        find_features = list(
            itertools.chain(
                *[item.get('features', list()) for item in find_address]))
        find_geometries = list(
            itertools.chain(*[
                item.get('geometry', dict()).get('geometries', list())
                for item in find_features
            ]))
        find_coordinates = [
            item.get('coordinates', list()) for item in find_geometries
        ]
        find_coordinates = [
            list(reversed(item))
            for item, _ in itertools.groupby(find_coordinates)
        ]

        # log_func.debug(u'Sputnik. Get geo locations %s' % str(find_coordinates))
        return find_coordinates
    except Exception as e:
        log_func.fatal(
            u'Sputnik. Error retrieving geolocation data by address <%s>' %
            address_query)
    return list()
Exemple #18
0
def getYandexMapsGeolocations(address_query, geo_key=None):
    """
    Get all geolocation data for the requested address by yandex maps.

    :param address_query: Address.
        For example:
            Moscow, Gagarin street, 10.
    :param geo_key: Geolocator API key.
    :return: [(latitude, longitude),...] Geolocation data list or empty list in case of error.
    """
    if geo_key is None:
        geo_key = txtfile_func.loadTextFile(API_KEY_YANDEX_FILENAME).strip()

    try:
        address = urllib.parse.quote(address_query)
        url = YANDEX_GEO_LACATOR_URL_FMT % (address, geo_key)
        log_func.debug(u'Geodata retrieval URL <%s>' % url)
        response = urllib.request.urlopen(url)
        data = response.read()
        # ERROR: JSON object must be str not bytes
        #                                      V
        geo_location_data = json.loads(data.decode('utf-8'))

        find_geo = geo_location_data.get('response', dict()).get(
            'GeoObjectCollection', dict()).get('featureMember', list())
        str_geo_locations = [
            item.get('GeoObject', dict()).get('Point',
                                              dict()).get('pos', None)
            for item in find_geo
        ]
        # [NOTE] In API Yandex Maps longitude first, then latitude,
        #                                                V
        geo_locations = [
            tuple([float(pos) for pos in reversed(location.split(' '))])
            if location is not None else (None, None)
            for location in str_geo_locations
        ]
        # log_func.debug(u'Yandexmaps. Get geo locations %s' % str(geo_locations))
        return geo_locations
    except Exception as e:
        log_func.fatal(
            u'Yandex default. Error retrieving geolocation data by address <%s>'
            % address_query)
    return list()
    def _execExpression(self, cur_func, locals, globals):
        """
        Execute expression.
        For example:
            [#record["dt"].strftime("%B")#]

        :param cur_func: Expression text.
        :param locals: Local name space.
        :param globals: Global name space.
        :return: The calculated value as a string or an empty string in case of an error.
        """
        value = u''
        exp_body = cur_func[2:-2]
        try:
            value = eval(exp_body, globals, locals)
        except:
            log_func.fatal(u'Error expression execute <%s>' % exp_body)
        log_func.debug(u'Execute expression <%s>. Value <%s>' % (exp_body, str(value)))
        return value
    def scanSingle(self, scan_filename=None):
        """
        Single Page Scan
        If incl. DUPLEX and off-page scanning,
        then you need to scan 1 sheet from 2 sides.

        :param scan_filename: The name of the scan file.
            If the file name is not specified, then scanning and
            returns the PIL.Image object.
        :return: True/False
        """
        if self.isDuplexOption():
            # If on DUPLEX and multi-page scanning is turned off,
            # then you need to scan 1 sheet from 2 sides
            log_func.debug(u'Duplex scan')
            return self.scanMulti(scan_filename, 2)

        log_func.debug(u'Single-sided scanning')
        self.startScan()
        scan_obj = self.scan(scan_filename)
        return scan_obj is not None
Exemple #21
0
def getReportResourceFilename(report_filename='', report_dir=''):
    """
    Get the full file name of the report template.

    :param report_filename:The name of the report file in short form.
    :param report_dir: Report folder.
    :return: The full name of the report file.
    """
    # Check extension
    if not report_filename.endswith(DEFAULT_REPORT_FILE_EXT):
        report_filename = os.path.splitext(
            report_filename)[0] + XML_REPORT_FILE_EXT

    rprt_filename = report_filename
    if not rprt_filename.endswith(DEFAULT_REPORT_FILE_EXT):
        rprt_filename = os.path.splitext(
            rprt_filename)[0] + DEFAULT_REPORT_FILE_EXT

    # Check the relevance of the template
    full_src_filename = getPathFilename(report_filename, report_dir)
    full_rprt_filename = getPathFilename(rprt_filename, report_dir)
    if isNewReportTemplateFile(full_src_filename, full_rprt_filename):
        # If the original template is changed later than the working
        # template file <rprt> then you need to make changes
        updateReportTemplateFile(full_src_filename, full_rprt_filename)

    if os.path.exists(rprt_filename):
        # Check can be given an absolute file name
        filename = rprt_filename
    else:
        # The relative file name relative to the report
        # folder is most likely set
        filename = full_rprt_filename
        if not os.path.exists(filename):
            log_func.warning(u'Report template file <%s> not found' %
                             str(filename))
            filename = createReportResourceFile(filename)
    log_func.debug(u'Report template filename <%s>' % str(filename))
    return filename
Exemple #22
0
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()
Exemple #23
0
    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
Exemple #24
0
    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
Exemple #25
0
def getDaDataGeolocation(address_query,
                         api_key=None,
                         secret_key=None,
                         cache=True):
    """
    Get geolocation data for the requested address.
    Library used https://github.com/hflabs/dadata-py.
    Ubuntu installation: pip3 install dadata

    :param address_query: Address.
        For example:
            Moscow, Gagarin street, 10.
    :param api_key: Geolocator API key.
    :param secret_key: Secret key.
    :param cache: Use internal cache?
    :return: (latitude, longitude) of geolocation data or (None, None) in case of error.
    """
    if api_key is None:
        api_key = txtfile_func.loadTextFile(API_KEY_DADATA_FILENAME).strip()
    if secret_key is None:
        secret_key = txtfile_func.loadTextFile(
            SECRET_KEY_DADATA_FILENAME).strip()

    global GEO_LOCATOR_CACHE
    if cache:
        if GEO_LOCATOR_CACHE is None:
            GEO_LOCATOR_CACHE = dict()
        if address_query in GEO_LOCATOR_CACHE:
            # If such an address is in the cache, then we take it from the cache
            return GEO_LOCATOR_CACHE[address_query]

    dadata_client = None
    try:
        if not dadata:
            log_func.warning(
                u'DaData library not installed. Ubuntu installation: pip3 install dadata'
            )
            return None, None
        dadata_client = dadata.Dadata(token=api_key, secret=secret_key)
        geo_data = dadata_client.clean(name='address', source=address_query)
        dadata_client.close()
        dadata_client = None

        geo_latitude = geo_data.get('geo_lat', None)
        geo_latitude = float(geo_latitude.replace(',', '.')) if isinstance(
            geo_latitude, str) else geo_latitude
        geo_longitude = geo_data.get('geo_lon', None)
        geo_longitude = float(geo_longitude.replace(',', '.')) if isinstance(
            geo_longitude, str) else geo_longitude
        log_func.debug(u'Address <%s>. Geo position [%f x %f]' %
                       (address_query, geo_latitude, geo_longitude))
        if cache:
            # Save in the cache
            GEO_LOCATOR_CACHE[address_query] = (geo_latitude, geo_longitude)
        # log_func.debug(u'DaData. Get geo locations (%s x %s)' % (str(geo_latitude), str(geo_longitude)))
        return geo_latitude, geo_longitude
    except Exception as e:
        if dadata_client:
            dadata_client.close()
        log_func.fatal(
            u'DaData. Error retrieving geolocation data by address <%s>' %
            address_query)
    return None, None
def scan_glue_mode(scan_manager, scan_filename, n_sheets, is_duplex=False, max_tray_sheets=60):
    """
    Starting the document gluing mode in parts.

    :param scan_manager: Scan manager.
    :param scan_filename: The name of the resulting scan file.
    :param n_sheets: Number of sheets.
    :param is_duplex: Duplex scanning?
    :param max_tray_sheets: The maximum number of sheets in the scanner tray.
    :return: True/False.
    """
    # The main cycle of scanning a document in parts and subsequent gluing
    n_part = 1
    scan_file_path, scan_file_ext = os.path.splitext(scan_filename)
    part_suffix = '_part%03d' % n_part
    new_scan_filename = scan_file_path + part_suffix + scan_file_ext
    sheets = scan_glue_load_sheets(None, min(max_tray_sheets, n_sheets))
    scan_sheet_count = sheets
    is_cancel = scan_sheet_count <= 0

    while (0 < scan_sheet_count <= n_sheets) or is_cancel:
        log_func.debug(u'Scan File <%s> Scan Sheets [%d]' % (new_scan_filename, sheets))
        # If duplex is used, then it is necessary to increase the number of pages
        scan_n_pages = sheets * 2 if is_duplex else sheets
        # Starting the scanning process
        scan_result = scan_manager.scanMulti(new_scan_filename, scan_n_pages)
        if scan_result and os.path.exists(new_scan_filename):
            verify_result = scan_glue_verify(None, new_scan_filename)
            if verify_result:
                n_part += 1
                part_suffix = '_part%03d' % n_part
                new_scan_filename = scan_file_path + part_suffix + scan_file_ext
                do_scan_sheet_count = min(max_tray_sheets, n_sheets-scan_sheet_count)
                if do_scan_sheet_count <= 0:
                    # All sheets are scanned.
                    break
                sheets = scan_glue_load_sheets(None, do_scan_sheet_count)
                if sheets <= 0:
                    # Clicked <Cancel>
                    is_cancel = True
                    break
                scan_sheet_count += sheets
            elif verify_result is None:
                scan_sheet_count -= sheets
                sheets = scan_glue_load_sheets(None, min(max_tray_sheets, n_sheets))
                if sheets <= 0:
                    # Clicked <Cancel>
                    is_cancel = True
                    break
                scan_sheet_count += sheets
            else:
                is_cancel = True
                log_func.warning(u'Scan to parts of file <%s> canceled' % new_scan_filename)
                break
        else:
            is_cancel = True
            log_func.warning(u'Error scanning file <%s>' % new_scan_filename)

    # Glue the scanned parts of the document
    if not is_cancel:
        part_pdf_filenames = [scan_file_path + ('_part%03d' % i_part) + scan_file_ext for i_part in range(1, n_part)]
        log_func.debug(u'Merge %d parts of scan %s to PDF file% s' % (n_part-1, part_pdf_filenames, scan_filename))
        glue_result = pdf_func.glue_pdf_files(scan_filename, *part_pdf_filenames)
        
        dlg_func.openMsgBox(u'SCAN',
                            u'Load documents in the scanner tray for later scanning')
        return glue_result
    else:
        log_func.warning(u'The mode of combining a scanned document in parts is canceled')

    return False
    def getQueryTbl(self, report, db_url=None, sql=None, *args, **kwargs):
        """
        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.
            At the beginning of the SQL query should be a signature:
            <SQL:> - SQL query text
            <PY:> -  SQL query text returned Python function.
            <PRG:> - SQL query text returned Python function.
        :return: Query table dictionary:
            {'__fields__': field_name_list, '__data__': table_data}
        """
        query = None
        try:
            if sql:
                query = sql
            else:
                # Case when a query function returns a table
                if isinstance(report['query'], dict):
                    return report['query']
                elif self._isQueryFunc(report['query']):
                    variables = kwargs.get('variables', None)
                    query = self._execQueryFunc(report['query'], vars=variables)
                    log_func.debug(u'Execute query func <%s>' % str(query))

                    if isinstance(query, dict):
                        if '__sql__' in query:
                            dataset_dict = self._getSQLQueryTable(report=report,
                                                                  db_url=db_url,
                                                                  sql=query['__sql__'])
                            if isinstance(dataset_dict, dict):
                                query.update(dataset_dict)
                        return query
                    else:
                        log_func.warning(u'Error query result type <%s>' % query.__class__.__name__)
                else:
                    query = report['query']
                # Query not defined
                if query is None:
                    log_func.warning(u'Query not defined')
                    return None

                if query.startswith(SQL_SIGNATURE):
                    # SQL expression
                    query = query.replace(SQL_SIGNATURE, u'').strip()
                elif query.startswith(CODE_SIGNATURE):
                    # Python function
                    query = exec_func.execTxtFunction(query.replace(CODE_SIGNATURE, u'').strip())
                elif query.startswith(PY_SIGNATURE):
                    # Python
                    query = exec_func.execTxtFunction(query.replace(PY_SIGNATURE, u'').strip())
                else:
                    log_func.warning(u'Not defined query signature <%s>' % query)
                    return None
                # The request can be parameterized by variables passed explicitly.
                # Therefore, it is necessary to generate
                if kwargs:
                    try:
                        # For replacements, use another generator
                        query_txt = query.replace(u'[&', u'{{ ').replace(u'&]', u' }}')
                        query = txtgen_func.generate(query_txt, kwargs)
                    except:
                        log_func.fatal(u'Error transform query\n<%s>\nfor report query table' % str(query))

            query_tbl = None
            if not self._query_table:
                # SQL expression
                query_tbl = self._getSQLQueryTable(report, db_url=db_url, sql=query)
            else:
                if isinstance(self._query_table, str):
                    if self._query_table[:4].upper() == SQL_SIGNATURE:
                        query_tbl = self._getSQLQueryTable(report, sql=self._query_table[4:].strip())
                    else:
                        log_func.warning(u'Unsupported query type <%s>' % self._query_table)

                elif isinstance(self._query_table, dict):
                    query_tbl = self._query_table
                else:
                    log_func.warning(u'Unsupported query type <%s>' % type(self._query_table))
            return query_tbl
        except:
            log_func.fatal(u'Error query table <%s>.' % query)
        return None
    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 getReportList(report_dir, is_sort=True):
    """
    Get report template list.

    :param report_dir: Report directory.
    :type is_sort: bool.
    :param is_sort: Sort list by name?
    :return: Format list:
        [
            [
            full file name / report directory,
            report name / directory,
            report description / directory,
            None / Nested Objects,
            image index
            ],
        .
        .
        .
        ]
        The description of the directory is taken from the descript.ion file,
        which should be in the same directory.
        If such a file is not found, then the directory description is empty.
        Nested objects is a list whose elements have the same structure.
    """
    try:
        report_dir = os.path.abspath(os.path.normpath(report_dir))
        log_func.debug(u'Report folder scan <%s>' % report_dir)

        dir_list = list()
        rep_list = list()

        sub_dirs = file_func.getSubDirs(report_dir)

        img_idx = 0
        for sub_dir in sub_dirs:
            # Exclude not processed folders
            if os.path.basename(sub_dir) in NOT_WORK_DIRNAMES:
                continue

            description_file = None
            try:
                description_file = open(os.path.join(sub_dir, 'descript.ion'),
                                        'rt')
                dir_description = description_file.read()
                description_file.close()
            except:
                if description_file:
                    description_file.close()
                dir_description = sub_dir

            data = [
                sub_dir,
                os.path.basename(sub_dir), dir_description,
                getReportList(sub_dir, is_sort), img_idx
            ]
            dir_list.append(data)

        if is_sort:
            dir_list.sort(key=lambda i: i[2])

        filename_mask = os.path.join(report_dir, '*%s' % REPORT_FILENAME_EXT)
        file_rep_list = [
            filename for filename in file_func.getFilesByMask(filename_mask)
        ]

        for rep_file_name in file_rep_list:
            rep_struct = res_func.loadResourcePickle(rep_file_name)
            img_idx = 2
            try:
                if rep_struct['generator'][-3:].lower() == 'xml':
                    img_idx = 1
            except:
                log_func.warning(u'Report type definition error')

            try:
                data = [
                    rep_file_name, rep_struct['name'],
                    rep_struct['description'], None, img_idx
                ]
                rep_list.append(data)
            except:
                log_func.fatal(u'Error reading report template <%s>' %
                               rep_file_name)

        if is_sort:
            rep_list.sort(key=lambda i: i[2])

        return dir_list + rep_list
    except:
        log_func.fatal(
            u'Error filling out information about report files <%s>.' %
            report_dir)
    return list()