예제 #1
0
파일: jal.py 프로젝트: Bulat-Gumerov/ledger
def main():
    sys.excepthook = exception_logger
    os.environ['QT_MAC_WANTS_LAYER'] = '1'    # Workaround for https://bugreports.qt.io/browse/QTBUG-87014

    error = init_and_check_db(get_app_path())

    if error.code == LedgerInitError.EmptyDbInitialized:  # If DB was just created from SQL - initialize it again
        error = init_and_check_db(get_app_path())

    app = QApplication([])
    language = JalDB().get_language_code(JalSettings().getValue('Language', default=1))
    translator = QTranslator(app)
    language_file = get_app_path() + Setup.LANG_PATH + os.sep + language + '.qm'
    translator.load(language_file)
    app.installTranslator(translator)

    if error.code == LedgerInitError.OutdatedDbSchema:
        error = update_db_schema(get_app_path())
        if error.code == LedgerInitError.DbInitSuccess:
            error = init_and_check_db(get_app_path())

    if error.code != LedgerInitError.DbInitSuccess:
        window = QMessageBox()
        window.setAttribute(Qt.WA_DeleteOnClose)
        window.setWindowTitle("JAL: Start-up aborted")
        window.setIcon(QMessageBox.Critical)
        window.setText(error.message)
        window.setInformativeText(error.details)
    else:
        window = MainWindow(language)
    window.show()

    app.exec()
    app.removeTranslator(translator)
예제 #2
0
파일: reports.py 프로젝트: flmnvd/jal
 def loadReportsList(self):
     reports_folder = get_app_path() + Setup.REPORT_PATH
     report_modules = [
         filename[:-3] for filename in os.listdir(reports_folder)
         if filename.endswith(".py")
     ]
     for module_name in report_modules:
         logging.debug(f"Trying to load report module: {module_name}")
         module = importlib.import_module(f"jal.reports.{module_name}")
         try:
             report_class_name = getattr(module, "JAL_REPORT_CLASS")
         except AttributeError:
             continue
         try:
             class_instance = getattr(module, report_class_name)
         except AttributeError:
             logging.error(
                 self.tr("Report class can't be loaded: ") +
                 report_class_name)
             continue
         report = class_instance()
         self.items.append({
             'name': report.name,
             'module': module,
             'window_class': report.window_class
         })
         logging.debug(
             f"Report class '{report_class_name}' providing '{report.name}' report has been loaded"
         )
     self.items = sorted(self.items, key=lambda item: item['name'])
예제 #3
0
 def loadStatementsList(self):
     statements_folder = get_app_path() + Setup.IMPORT_PATH + os.sep + Setup.STATEMENT_PATH
     statement_modules = [filename[:-3] for filename in os.listdir(statements_folder) if filename.endswith(".py")]
     for module_name in statement_modules:
         logging.debug(f"Trying to load statement module: {module_name}")
         module = importlib.import_module(f"jal.data_import.broker_statements.{module_name}")
         try:
             statement_class_name = getattr(module, "JAL_STATEMENT_CLASS")
         except AttributeError:
             continue
         try:
             class_instance = getattr(module, statement_class_name)
         except AttributeError:
             logging.error(self.tr("Statement class can't be loaded: ") + statement_class_name)
             continue
         statement = class_instance()
         self.items.append({
             'name': statement.name,
             'module': module,
             'loader_class': statement_class_name,
             'icon': statement.icon_name,
             'filename_filter': statement.filename_filter
         })
         logging.debug(f"Class '{statement_class_name}' providing '{statement.name}' statement has been loaded")
     self.items = sorted(self.items, key=lambda item: item['name'])
예제 #4
0
파일: xlsx.py 프로젝트: flmnvd/jal
 def load_template(self, file):
     template = None
     file_path = get_app_path() + Setup.EXPORT_PATH + os.sep + Setup.TEMPLATE_PATH + os.sep + file
     try:
         with open(file_path, 'r', encoding='utf-8') as json_file:
             template = json.load(json_file)
     except Exception as e:
         logging.error(self.tr("Can't load report template from file ") + f"'{file_path}' ({type(e).__name__} {e})")
     return template
예제 #5
0
    def createLanguageMenu(self):
        langPath = get_app_path() + Setup.LANG_PATH + os.sep

        langDirectory = QDir(langPath)
        for language_file in langDirectory.entryList(['*.qm']):
            language_code = language_file.split('.')[0]
            language = QLocale.languageToString(QLocale(language_code).language())
            language_icon = QIcon(langPath + language_code + '.png')
            action = QAction(language_icon, language, self)
            action.setCheckable(True)
            action.setData(language_code)
            self.menuLanguage.addAction(action)
            self.langGroup.addAction(action)
예제 #6
0
파일: statement.py 프로젝트: flmnvd/jal
 def validate_format(self):
     schema_name = get_app_path() + Setup.IMPORT_PATH + os.sep + Setup.IMPORT_SCHEMA_NAME
     try:
         with open(schema_name, 'r') as schema_file:
             try:
                 statement_schema = json.load(schema_file)
             except json.JSONDecodeError:
                 raise Statement_ImportError(self.tr("Failed to read JSON schema from: ") + schema_name)
     except Exception as err:
         raise Statement_ImportError(self.tr("Failed to read file: ") + str(err))
     try:
         validate(instance=self._data, schema=statement_schema)
     except ValidationError:
         raise Statement_ImportError(self.tr("Statement validation failed"))
예제 #7
0
    def __init__(self, language):
        QMainWindow.__init__(self, None)
        self.running = False
        self.setupUi(self)
        self.restoreGeometry(base64.decodebytes(JalSettings().getValue('WindowGeometry', '').encode('utf-8')))
        self.restoreState(base64.decodebytes(JalSettings().getValue('WindowState', '').encode('utf-8')))

        self.ledger = Ledger()

        # Customize Status bar and logs
        self.ProgressBar = QProgressBar(self)
        self.StatusBar.addPermanentWidget(self.ProgressBar)
        self.ProgressBar.setVisible(False)
        self.ledger.setProgressBar(self, self.ProgressBar)
        self.Logs.setStatusBar(self.StatusBar)
        self.logger = logging.getLogger()
        self.logger.addHandler(self.Logs)
        log_level = os.environ.get('LOGLEVEL', 'INFO').upper()
        self.logger.setLevel(log_level)

        self.currentLanguage = language

        self.downloader = QuoteDownloader()
        self.statements = Statements(self)
        self.reports = Reports(self, self.mdiArea)
        self.backup = JalBackup(self, get_dbfilename(get_app_path()))
        self.estimator = None
        self.price_chart = None

        self.actionImportSlipRU.setEnabled(dependency_present(['pyzbar', 'PIL']))

        self.actionAbout = QAction(text=self.tr("About"), parent=self)
        self.MainMenu.addAction(self.actionAbout)

        self.langGroup = QActionGroup(self.menuLanguage)
        self.createLanguageMenu()

        self.statementGroup = QActionGroup(self.menuStatement)
        self.createStatementsImportMenu()

        self.reportsGroup = QActionGroup(self.menuReports)
        self.createReportsMenu()

        self.setWindowIcon(load_icon("jal.png"))

        self.connect_signals_and_slots()

        self.actionOperations.trigger()
예제 #8
0
    def __init__(self, language):
        QMainWindow.__init__(self, None)
        self.setupUi(self)

        self.currentLanguage = language
        self.current_index = None  # this is used in onOperationContextMenu() to track item for menu

        self.ledger = Ledger()
        self.downloader = QuoteDownloader()
        self.taxes = TaxesRus()
        self.statements = StatementLoader()
        self.backup = JalBackup(self, get_dbfilename(get_app_path()))
        self.estimator = None
        self.price_chart = None

        self.actionImportSlipRU.setEnabled(
            dependency_present(['pyzbar', 'PIL']))

        self.actionAbout = QAction(text=self.tr("About"), parent=self)
        self.MainMenu.addAction(self.actionAbout)

        self.langGroup = QActionGroup(self.menuLanguage)
        self.createLanguageMenu()

        self.statementGroup = QActionGroup(self.menuStatement)
        self.createStatementsImportMenu()

        # Set icons
        self.setWindowIcon(load_icon("jal.png"))
        self.NewOperationBtn.setIcon(load_icon("new.png"))
        self.CopyOperationBtn.setIcon(load_icon("copy.png"))
        self.DeleteOperationBtn.setIcon(load_icon("delete.png"))

        # Operations view context menu
        self.contextMenu = QMenu(self.OperationsTableView)
        self.actionReconcile = QAction(load_icon("reconcile.png"),
                                       self.tr("Reconcile"), self)
        self.actionCopy = QAction(load_icon("copy.png"), self.tr("Copy"), self)
        self.actionDelete = QAction(load_icon("delete.png"), self.tr("Delete"),
                                    self)
        self.contextMenu.addAction(self.actionReconcile)
        self.contextMenu.addSeparator()
        self.contextMenu.addAction(self.actionCopy)
        self.contextMenu.addAction(self.actionDelete)

        # Customize Status bar and logs
        self.ProgressBar = QProgressBar(self)
        self.StatusBar.addWidget(self.ProgressBar)
        self.ProgressBar.setVisible(False)
        self.ledger.setProgressBar(self, self.ProgressBar)
        self.NewLogEventLbl = QLabel(self)
        self.StatusBar.addWidget(self.NewLogEventLbl)
        self.Logs.setNotificationLabel(self.NewLogEventLbl)
        self.Logs.setFormatter(
            logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
        self.logger = logging.getLogger()
        self.logger.addHandler(self.Logs)
        log_level = os.environ.get('LOGLEVEL', 'INFO').upper()
        self.logger.setLevel(log_level)

        # Setup reports tab
        self.reports = Reports(self.ReportTableView, self.ReportTreeView)

        # Customize UI configuration
        self.balances_model = BalancesModel(self.BalancesTableView)
        self.BalancesTableView.setModel(self.balances_model)
        self.balances_model.configureView()

        self.holdings_model = HoldingsModel(self.HoldingsTableView)
        self.HoldingsTableView.setModel(self.holdings_model)
        self.holdings_model.configureView()
        self.HoldingsTableView.setContextMenuPolicy(Qt.CustomContextMenu)

        self.operations_model = OperationsModel(self.OperationsTableView)
        self.OperationsTableView.setModel(self.operations_model)
        self.operations_model.configureView()
        self.OperationsTableView.setContextMenuPolicy(Qt.CustomContextMenu)

        self.connect_signals_and_slots()

        self.NewOperationMenu = QMenu()
        for i in range(self.OperationsTabs.count()):
            if hasattr(self.OperationsTabs.widget(i), "isCustom"):
                self.OperationsTabs.widget(i).dbUpdated.connect(
                    self.ledger.rebuild)
                self.OperationsTabs.widget(i).dbUpdated.connect(
                    self.operations_model.refresh)
                self.NewOperationMenu.addAction(
                    self.OperationsTabs.widget(i).name,
                    partial(self.createOperation, i))
        self.NewOperationBtn.setMenu(self.NewOperationMenu)

        # Setup balance and holdings parameters
        current_time = QDateTime.currentDateTime()
        current_time.setTimeSpec(
            Qt.UTC)  # We use UTC everywhere so need to force TZ info
        self.BalanceDate.setDateTime(current_time)
        self.BalancesCurrencyCombo.setIndex(
            JalSettings().getValue('BaseCurrency'))
        self.HoldingsDate.setDateTime(current_time)
        self.HoldingsCurrencyCombo.setIndex(
            JalSettings().getValue('BaseCurrency'))

        self.OperationsTabs.setCurrentIndex(TransactionType.NA)
        self.OperationsTableView.selectRow(0)
        self.OnOperationsRangeChange(0)