def test_get_plugin_manager(self): # PluginManager should be a singleton self.assertEqual(self._manager, get_plugin_manager()) self.assertEqual(id(self._manager), id(get_plugin_manager())) # Just check if it really provides IPluginManager self.assertTrue(IPluginManager.providedBy(self._manager)) self.assertTrue(isinstance(self._manager, PluginManager))
def _enable_plugins(): manager = get_plugin_manager() for plugin in [u'nfe', u'ecf']: if not manager.is_installed(plugin): # STOQLIB_TEST_QUICK won't let dropdb on testdb run. Just a # precaution to avoid trying to install it again manager.install_plugin(plugin)
def _start_tasks(self): tasks = [ _Task(start_backup_scheduler), _Task(start_server), _Task(start_rtc), ] if start_xmlrpc_server not in [t.func for t in self._get_children()]: tasks.append(_Task(start_xmlrpc_server, self._xmlrpc_conn2)) manager = get_plugin_manager() for plugin_name in manager.installed_plugins_names: plugin = manager.get_plugin(plugin_name) if not hasattr(plugin, 'get_server_tasks'): continue # FIXME: Check that the plugin implements IPluginTask when # we Stoq 1.11 is released for plugin_task in plugin.get_server_tasks(): task_name = plugin_task.name kwargs = {} if plugin_task.handle_actions: conn1, conn2 = multiprocessing.Pipe(True) self._plugins_pipes[(plugin_name, task_name)] = conn1 kwargs['pipe_connection'] = conn2 tasks.append(_Task(plugin_task.start, **kwargs)) for t in tasks: t.start()
def checkout(self, cancel_clear=False): """Initiates the sale wizard to confirm sale. :param cancel_clear: If cancel_clear is true, the sale will be cancelled if the checkout is cancelled. """ assert len(self.sale_items) >= 1 if self._current_store: store = self._current_store savepoint = 'before_run_fiscalprinter_confirm' store.savepoint(savepoint) else: store = api.new_store() savepoint = None if self._trade: if self._get_subtotal() < self._trade.returned_total: info(_("Traded value is greater than the new sale's value. " "Please add more items or return it in Sales app, " "then make a new sale")) return sale = self._create_sale(store) self._trade.new_sale = sale self._trade.trade() else: sale = self._create_sale(store) if sysparam.get_bool('CONFIRM_SALES_ON_TILL'): sale.order() store.commit() else: assert self._coupon ordered = self._coupon.confirm(sale, store, savepoint, subtotal=self._get_subtotal()) # Dont call store.confirm() here, since coupon.confirm() # above already did it if not ordered: # FIXME: Move to TEF plugin manager = get_plugin_manager() if manager.is_active('tef') or cancel_clear: self._cancel_order(show_confirmation=False) elif not self._current_store: # Just do that if a store was created above and # if _cancel_order wasn't called (it closes the connection) store.rollback(close=True) return log.info("Checking out") self._coupon = None POSConfirmSaleEvent.emit(sale, self.sale_items[:]) # We must close the connection only after the event is emmited, since it # may use value from the sale that will become invalid after it is # closed store.close() self._clear_order()
def _check_online_plugins(self): # For each online plugin, try to download and install it. # Otherwise warn him online_plugins = InstalledPlugin.get_pre_plugin_names(self.store) if not online_plugins: return successes = [] manager = get_plugin_manager() for plugin_name in online_plugins: success, msg = manager.download_plugin(plugin_name) successes.append(success) if success: manager.install_plugin(self.store, plugin_name) online_plugins.remove(plugin_name) if all(successes): return # Title title = _('You have pending plugins.') # Description url = 'https://stoq.link/?source=stoq-plugin-alert&hash={}'.format( api.sysparam.get_string('USER_HASH')) desc = _('The following plugins need to be enabled: <b>{}</b>.\n\n' 'You can do it by registering on <a href="{}">Stoq.link</a>.' ).format(', '.join(online_plugins), url) msg = '<b>%s</b>\n%s' % (title, desc) self.add_info_bar(Gtk.MessageType.WARNING, msg)
def _setup_test_environment(request): plugin_config = _get_plugin_configs(request.config) if plugin_config['skip_env_setup']: return stoq_config = StoqConfig() stoq_config.load_default() register_config(stoq_config) quick = plugin_config['quick_mode'] or _to_falsy( os.environ.get("STOQLIB_TEST_QUICK", None)) bootstrap_suite( address=os.environ.get("STOQLIB_TEST_HOSTNAME"), dbname=os.environ.get("STOQLIB_TEST_DBNAME"), port=int(os.environ.get("STOQLIB_TEST_PORT") or 0), username=os.environ.get("STOQLIB_TEST_USERNAME"), password=os.environ.get("STOQLIB_TEST_PASSWORD"), quick=quick, ) manager = get_plugin_manager() for plugin_name in plugin_config['extra_plugins']: _register_plugin(plugin_name) with stoqlib.api.new_store() as store: manager.install_plugin(store, plugin_name) manager.activate_plugin(plugin_name) plugin_cls = plugin_config['plugin_cls'] if plugin_cls: _install_plugin(plugin_cls)
def run_command(self, options, cmd, args): func = getattr(self, 'cmd_' + cmd, None) if func is None: self._read_config(options, load_plugins=False, register_station=False) from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() if cmd in manager.installed_plugins_names: if not len(args): raise SystemExit("%s: %s requires at least 2 argument(s)" % (self.prog_name, cmd)) plugin = manager.get_plugin(cmd) return plugin.handle_dbadmin_command(args[0], options, args[1:]) else: print("%s: Invalid command: `%s' type `%s help' for usage." % (self.prog_name, cmd, self.prog_name)) return 1 nargs = func.__code__.co_argcount - 2 if len(args) < nargs: raise SystemExit("%s: %s requires at least %d argument(s)" % (self.prog_name, cmd, nargs)) self.args = args return func(options, *args)
def cmd_help(self, options): """Show available commands help""" cmds = [] max_len = 0 for attr in dir(self): if not attr.startswith('cmd_'): continue name = attr[4:] doc = getattr(self, attr).__doc__ or '' max_len = max(max_len, len(name)) cmds.append((name, doc.split(r'\n')[0])) max_len = max_len + 2 print('Usage: stoqdbadmin [plugin] <command> [<args>]') print() print('Available commands:') for name, doc in cmds: print(' %s%s' % (name.ljust(max_len), doc)) self._read_config(options, load_plugins=False, register_station=False) from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() for plugin_name in manager.installed_plugins_names: plugin = manager.get_plugin(plugin_name) for command in plugin.get_dbadmin_commands(): print(' %s %s' % (plugin_name, command)) return 0
def run_embedded(self, appdesc, app_window, params=None): app = self._load_app(appdesc, app_window) app.launcher = app_window self._current_app = app self._appname = appdesc.name if appdesc.name in self._blocked_apps: app_window.show() return app.run(params) # Possibly correct window position (livecd workaround for small # screens) from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() from stoqlib.api import api if (api.sysparam(api.get_default_store()).DEMO_MODE and manager.is_active(u'ecf')): pos = app.main_window.toplevel.get_position() if pos[0] < 220: app.main_window.toplevel.move(220, pos[1]) return app
def _setup_widgets(self): self._calc = CalculatorPopup(self.price, CalculatorPopup.MODE_SUB) self.sale.set_text(unicode(self.model.sale.identifier)) self.description.set_text(self.model.sellable.get_description()) self.original_price.update(self.model.base_price) self.price.set_adjustment(gtk.Adjustment(lower=0, upper=MAX_INT, step_incr=1, page_incr=10)) unit = self.model.sellable.unit digits = QUANTITY_PRECISION if unit and unit.allow_fraction else 0 for widget in [self.quantity, self.reserved]: widget.set_digits(digits) widget.set_adjustment(gtk.Adjustment(lower=0, upper=MAX_INT, step_incr=1, page_incr=10)) manager = get_plugin_manager() self.nfe_is_active = manager.is_active('nfe') if not self.nfe_is_active: self.cfop_label.hide() self.cfop.hide() if not self._can_reserve(): self.reserved.hide() self.reserved_lbl.hide() # We populate this even if it's hidden because we need a default value # selected to add to the sale item cfop_items = CfopData.get_for_sale(self.store) self.cfop.prefill(api.for_combo(cfop_items)) self._update_total() self.reserved.get_adjustment().set_upper(self.quantity_model.quantity)
def _start_tasks(self): tasks = [ Task('_backup', start_backup_scheduler), Task('_server', start_server), Task('_rtc', start_rtc), Task('_xmlrpc', start_xmlrpc_server, self._xmlrpc_conn2), Task('_updater', start_plugins_update_scheduler, self._updater_event), ] manager = get_plugin_manager() for plugin_name in manager.installed_plugins_names: plugin = manager.get_plugin(plugin_name) if not hasattr(plugin, 'get_server_tasks'): continue # FIXME: Check that the plugin implements IPluginTask when # we Stoq 1.11 is released for plugin_task in plugin.get_server_tasks(): task_name = plugin_task.name name = _get_plugin_task_name(plugin_name, task_name) if self._manager.is_running(name): continue kwargs = {} if plugin_task.handle_actions: conn1, conn2 = multiprocessing.Pipe(True) self._plugins_pipes[name] = conn1 kwargs['pipe_connection'] = conn2 tasks.append(Task(name, plugin_task.start, **kwargs)) for task in tasks: if not self._manager.is_running(task.name): self._manager.run_task(task)
def setUp(self): super(TestPluginManager, self).setUp() # Generate 2 instances of plugins that will be used for testing later. # '_dependent_plugin' will require 'independent_plugin' activation prior # to it's own. self._independent_plugin = _TestPlugin() self._dependent_plugin = _TestDependentPlugin() # Since the plugins are commited inside pluginmanager, try to remove # it first, or we will have problems if STOQLIB_TEST_QUICK is set. store = new_store() plugins = set(InstalledPlugin.get_plugin_names(store=self.store)) expected = set([u'ecf', u'nfe', u'optical']) self.assertTrue(expected.issubset(plugins)) ind_name = self._independent_plugin.name dep_name = self._dependent_plugin.name plugin_names = [ind_name, dep_name] test_plugins = store.find(InstalledPlugin, InstalledPlugin.plugin_name.is_in(plugin_names)) for plugin in test_plugins: store.remove(plugin) store.commit() store.close() self._manager = get_plugin_manager() self._register_test_plugin()
def _setup_widgets(self): self._calc = CalculatorPopup(self.price, CalculatorPopup.MODE_SUB) self.sale.set_text(str(self.model.sale.identifier)) self.description.set_text(self.model.sellable.get_description()) self.original_price.update(self.model.base_price) self.price.set_adjustment(Gtk.Adjustment(lower=0, upper=MAX_INT, step_increment=1, page_increment=10)) unit = self.model.sellable.unit digits = QUANTITY_PRECISION if unit and unit.allow_fraction else 0 for widget in [self.quantity, self.reserved]: widget.set_digits(digits) widget.set_adjustment(Gtk.Adjustment(lower=0, upper=MAX_INT, step_increment=1, page_increment=10)) manager = get_plugin_manager() self.nfe_is_active = manager.is_any_active(['nfe', 'nfce']) if not self.nfe_is_active: self.cfop_label.hide() self.cfop.hide() if not self._can_reserve(): self.reserved.hide() self.reserved_lbl.hide() # We populate this even if it's hidden because we need a default value # selected to add to the sale item cfop_items = CfopData.get_for_sale(self.store) self.cfop.prefill(api.for_combo(cfop_items)) self._update_total() self.reserved.get_adjustment().set_upper(self.quantity_model.quantity)
def _check_online_plugins(self): # For each online plugin, try to download and install it. # Otherwise warn him online_plugins = InstalledPlugin.get_pre_plugin_names(self.store) if not online_plugins: return successes = [] manager = get_plugin_manager() for plugin_name in online_plugins: success, msg = manager.download_plugin(plugin_name) successes.append(success) if success: manager.install_plugin(self.store, plugin_name) online_plugins.remove(plugin_name) if all(successes): return # Title title = _('You have pending plugins.') # Description url = 'https://stoq.link/?source=stoq-plugin-alert&hash={}'.format( api.sysparam.get_string('USER_HASH')) desc = _( 'The following plugins need to be enabled: <b>{}</b>.\n\n' 'You can do it by registering on <a href="{}">Stoq.link</a>.' ).format(', '.join(online_plugins), url) msg = '<b>%s</b>\n%s' % (title, desc) self.add_info_bar(gtk.MESSAGE_WARNING, msg)
def run_command(self, options, cmd, args): func = getattr(self, 'cmd_' + cmd, None) if func is None: self._read_config(options, load_plugins=False, register_station=False) from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() if cmd in manager.installed_plugins_names: if not len(args): raise SystemExit( "%s: %s requires at least 2 argument(s)" % ( self.prog_name, cmd)) plugin = manager.get_plugin(cmd) return plugin.handle_dbadmin_command(args[0], options, args[1:]) else: print("%s: Invalid command: `%s' type `%s help' for usage." % ( self.prog_name, cmd, self.prog_name)) return 1 nargs = func.func_code.co_argcount - 2 if len(args) < nargs: raise SystemExit( "%s: %s requires at least %d argument(s)" % ( self.prog_name, cmd, nargs)) self.args = args return func(options, *args)
def checkout(self, cancel_clear=False): """Initiates the sale wizard to confirm sale. :param cancel_clear: If cancel_clear is true, the sale will be cancelled if the checkout is cancelled. """ assert len(self.sale_items) >= 1 if self._current_store: store = self._current_store savepoint = 'before_run_fiscalprinter_confirm' store.savepoint(savepoint) else: store = api.new_store() savepoint = None if self._trade: if self._get_subtotal() < self._trade.returned_total: info( _("Traded value is greater than the new sale's value. " "Please add more items or return it in Sales app, " "then make a new sale")) return sale = self._create_sale(store) self._trade.new_sale = sale self._trade.trade() else: sale = self._create_sale(store) if self.param.CONFIRM_SALES_ON_TILL: sale.order() store.commit(close=True) else: assert self._coupon ordered = self._coupon.confirm(sale, store, savepoint, subtotal=self._get_subtotal()) # Dont call store.confirm() here, since coupon.confirm() # above already did it if not ordered: # FIXME: Move to TEF plugin manager = get_plugin_manager() if manager.is_active('tef') or cancel_clear: self._cancel_order(show_confirmation=False) elif not self._current_store: # Just do that if a store was created above and # if _cancel_order wasn't called (it closes the connection) store.rollback(close=True) return log.info("Checking out") store.close() self._coupon = None POSConfirmSaleEvent.emit(sale, self.sale_items[:]) self._clear_order()
def setup_widgets(self): marker('Setting up widgets') # Only quotes have expire date. self.expire_date.hide() self.expire_label.hide() # Hide client category widgets self.client_category_lbl.hide() self.client_category.hide() # if the NF-e plugin is active, the client is mandantory in this # wizard (in this situation, we have only quote sales). if self.model.status == Sale.STATUS_QUOTE: manager = get_plugin_manager() mandatory_client = manager.is_active('nfe') self.client.set_property('mandatory', mandatory_client) marker('Filling sales persons') salespersons = self.store.find(SalesPerson) self.salesperson.prefill(api.for_person_combo(salespersons)) marker('Finished filling sales persons') marker('Read parameter') change_salesperson = sysparam.get_int('ACCEPT_CHANGE_SALESPERSON') if change_salesperson == ChangeSalespersonPolicy.ALLOW: self.salesperson.grab_focus() elif change_salesperson == ChangeSalespersonPolicy.DISALLOW: self.salesperson.set_sensitive(False) elif change_salesperson == ChangeSalespersonPolicy.FORCE_CHOOSE: self.model.salesperson = None self.salesperson.grab_focus() else: raise AssertionError marker('Finished reading parameter') self._setup_clients_widget() self._fill_transporter_combo() self._fill_cost_center_combo() if sysparam.get_bool('ASK_SALES_CFOP'): self._fill_cfop_combo() else: self.cfop_lbl.hide() self.cfop.hide() self.create_cfop.hide() # the maximum number allowed for an invoice is 999999999. self.invoice_number.set_adjustment( gtk.Adjustment(lower=1, upper=999999999, step_incr=1)) if not self.model.invoice_number: new_invoice_number = Invoice.get_next_invoice_number(self.store) self.invoice_model.invoice_number = new_invoice_number else: new_invoice_number = self.model.invoice_number self.invoice_model.invoice_number = new_invoice_number self.invoice_number.set_sensitive(False) self.invoice_model.original_invoice = new_invoice_number marker('Finished setting up widgets')
def close_till(self, close_db=True, close_ecf=True): """Closes the till There are 3 possibilities for parameters combination: * *total close*: Both *close_db* and *close_ecf* are ``True``. The till on both will be closed. * *partial close*: Both *close_db* and *close_ecf* are ``False``. It's more like a till verification. The actual user will do it to check and maybe remove money from till, leaving it ready for the next one. Note that this will not emit 'till-status-changed' event, since the till will not really close. * *fix conflicting status*: *close_db* and *close_ecf* are different. Use this only if you need to fix a conflicting status, like if the DB is open but the ECF is closed, or the other way around. :param close_db: If the till in the DB should be closed :param close_ecf: If the till in the ECF should be closed :returns: True if the till was closed, otherwise False """ is_partial = not close_db and not close_ecf manager = get_plugin_manager() # This behavior is only because of ECF if not is_partial and not self._previous_day: if (manager.is_active('ecf') and not yesno(_("You can only close the till once per day. " "You won't be able to make any more sales today.\n\n" "Close the till?"), Gtk.ResponseType.NO, _("Close Till"), _("Not now"))): return elif not is_partial: # When closing from a previous day, close only what is needed. close_db = self._close_db close_ecf = self._close_ecf if close_db: till = Till.get_last_opened(self.store) assert till store = api.new_store() editor_class = TillVerifyEditor if is_partial else TillClosingEditor model = run_dialog(editor_class, self._parent, store, previous_day=self._previous_day, close_db=close_db, close_ecf=close_ecf) if not model: store.confirm(model) store.close() return # TillClosingEditor closes the till retval = store.confirm(model) store.close() if retval and not is_partial: self._till_status_changed(closed=True, blocked=False) return retval
def _on_EditorCreateEvent(self, editor, model, store, *args): from stoqlib.gui.dialogs.saledetails import SaleDetailsDialog manager = get_plugin_manager() nfe_active = manager.is_active('nfe') if not nfe_active and isinstance(editor, SaleDetailsDialog): # Only display the coupon number if the nfe is not active. editor.invoice_label.set_text(_('Coupon Number')) editor.invoice_number.update(model.coupon_id)
def _register_plugins(self, plugin_names): from stoqlib.database.runtime import new_store from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() with new_store() as store: for name in plugin_names: manager.pre_install_plugin(store, name)
def _register_plugin(plugin_name, plugin_module=None): manager = get_plugin_manager() if not plugin_module: plugin_module = importlib.import_module("stoq" + plugin_name) plugin_dir = os.path.dirname(plugin_module.__file__) desc_filename = os.path.join(plugin_dir, "{}.plugin".format(plugin_name)) manager.register_plugin_description(desc_filename)
def _on_EditorCreateEvent(self, editor, model, store, *args): from stoqlib.gui.dialogs.saledetails import SaleDetailsDialog manager = get_plugin_manager() nfe_active = any(manager.is_active(plugin) for plugin in ['nfe', 'nfce']) if not nfe_active and isinstance(editor, SaleDetailsDialog): # Only display the coupon number if the nfe is not active. editor.attach_slave('coupon_number_holder', CouponNumberSlave(editor.store, model))
def __init__(self, store, model): manager = get_plugin_manager() self.nfe_is_active = manager.is_active('nfe') self.proxy = None self.icms_slave = None self.ipi_slave = None BaseEditor.__init__(self, store, model)
def _start_tasks(self): tasks = [ Task('_xmlrpc', start_xmlrpc_server, self._xmlrpc_conn2), # This is not working nice when using NTK lib (maybe related to the multiprocess lib). # Must be executed as a separate process for now. #Task('_flask', start_flask_server), Task('_updater', start_plugins_update_scheduler, self._updater_event, self._doing_backup), Task('_backup', start_backup_scheduler, self._doing_backup), ] # TODO: Make those work on windows if not _is_windows: tasks.extend([ Task('_htsql', start_htsql, self._htsql_port), Task('_server', start_server), Task('_rtc', start_rtc), ]) manager = get_plugin_manager() for plugin_name in manager.installed_plugins_names: plugin = manager.get_plugin(plugin_name) if not hasattr(plugin, 'get_server_tasks'): continue # FIXME: Check that the plugin implements IPluginTask when # we Stoq 1.11 is released for plugin_task in plugin.get_server_tasks(): task_name = plugin_task.name name = _get_plugin_task_name(plugin_name, task_name) if self._manager.is_running(name): continue kwargs = {} if plugin_task.handle_actions: conn1, conn2 = multiprocessing.Pipe(True) self._plugins_pipes[name] = conn1 kwargs['pipe_connection'] = conn2 # Since Windows has no os.fork, multiprocessing will actually # run the process again and pass the required objects by # pickling them. For some reason, passing a plugin task will # break some places, since the it will make some objects # like PluginManager be pickled/unpicled, and when unlicking # it will run its contructor again, but it should wait # to do that until we have configured the database. func = (plugin_name, task_name) tasks.append(Task(name, func, **kwargs)) for task in tasks: if not self._manager.is_running(task.name): self._manager.run_task(task) # Close the default store because it not functioning anymore since the # forked processes closed its "clone", but open a new one later # or else Stoq will not be able to find this instance set_default_store(None) get_default_store()
def __init__(self, store): header = _(u'Select the plugin you want to activate and click in ' 'the apply button.') BasicDialog.__init__(self, hide_footer=False, size=PluginManagerDialog.size, title=PluginManagerDialog.title, header_text=header) self.store = store self._manager = get_plugin_manager() self._setup_widgets()
def _maybe_correct_demo_position(self, shell_window): # Possibly correct window position (livecd workaround for small # screens) from stoqlib.lib.parameters import sysparam from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() if (sysparam.get_bool('DEMO_MODE') and manager.is_active(u'ecf')): pos = shell_window.toplevel.get_position() if pos[0] < 220: shell_window.toplevel.move(220, pos[1])
def __init__(self, store, model): manager = get_plugin_manager() self.nfe_is_active = manager.is_any_active(['nfe', 'nfce']) self.proxy = None self.icms_slave = None self.ipi_slave = None self.pis_slave = None self.cofins_slave = None BaseEditor.__init__(self, store, model)
def setup_proxies(self): manager = get_plugin_manager() nfe_is_active = manager.is_active('nfe') self.invoice_number.set_property('mandatory', nfe_is_active) # Set an initial invoice number. if not self.model.invoice_number: new_invoice_number = Invoice.get_next_invoice_number(self.store) self.model.invoice_number = new_invoice_number self.proxy = self.add_proxy(self.model, self.proxy_widgets)
def post_init(self): self.hide_add_button() manager = get_plugin_manager() nfe_is_active = manager.is_active("nfe") if not self.wizard.create_payments and not nfe_is_active: self.cost_label.hide() self.cost.hide() self.cost.update(0) self.slave.klist.connect("cell-editing-started", self._on_klist__cell_editing_started) super(DecreaseItemStep, self).post_init()
def __init__(self, **kw): if not 'branch' in kw: kw['branch'] = get_current_branch(kw.get('store')) super(Invoice, self).__init__(**kw) # The mode and series are only set if the nfce plugin is active, since # the invoice_number will be also set by it. if get_plugin_manager().is_active('nfce'): mode = InvoiceGetModeEvent.emit() assert mode self.mode = mode # TODO Handle series number self.series = 1
def run(self): # FIXME: parent pid is not supported on windows. Maybe we should # find a way for the task to check if the parent is alive in another # way in this case? if not _is_windows: os.setpgrp() self._ppid = os.getppid() t = threading.Thread(target=self._check_parent_running) t.daemon = True t.start() else: from stoqserver.main import setup_stoq, setup_logging from stoqserver.sentry import setup_excepthook # Do this as soon as possible so we can log any early traceback setup_excepthook() # Allow .pyd files to be imported from egg files from zipextimporter import ZipExtensionImporter sys.path_hooks.append(ZipExtensionImporter) sys.path_importer_cache.clear() cacerts_path = os.path.join(_root, 'cacert.pem') requests.utils.DEFAULT_CA_BUNDLE_PATH = cacerts_path requests.adapters.DEFAULT_CA_BUNDLE_PATH = cacerts_path setup_stoq() setup_logging() if isinstance(self.func, tuple): # Windows plugin_name, task_name = self.func manager = get_plugin_manager() plugin = manager.get_plugin(plugin_name) for task in plugin.get_server_tasks(): if task.name == task_name: break else: raise AssertionError func = task.start else: func = self.func # Workaround a python issue where multiprocessing/threading will not # use the modified sys.excepthook: https://bugs.python.org/issue1230540 try: func(*self._func_args, **self._func_kwargs) except Exception: sys.excepthook(*sys.exc_info()) self._error_queue.put(self.name)
def post_init(self): self.hide_add_button() manager = get_plugin_manager() nfe_is_active = manager.is_any_active(['nfce', 'nfe']) if not self.wizard.create_payments and not nfe_is_active: self.cost_label.hide() self.cost.hide() self.cost.update(0) self.slave.klist.connect('cell-editing-started', self._on_klist__cell_editing_started) super(DecreaseItemStep, self).post_init()
def cmd_update_plugins(self, options): """Update plugins on Stoq""" self._read_config(options, register_station=False, check_schema=False, load_plugins=False) self._provide_app_info() self._setup_logging() from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() for egg_plugin in manager.egg_plugins_names: manager.download_plugin(egg_plugin)
def _uifield__cell_data_func(self, column, renderer, obj, text): if isinstance(renderer, Gtk.CellRendererText): return text manager = get_plugin_manager() if manager.is_any_active(['nfe', 'nfce']): is_editable = obj.field_name not in [u'street', u'district', u'city', u'state', u'country', u'street_number'] renderer.set_property('sensitive', is_editable) renderer.set_property('activatable', is_editable) return text
def _enable_plugins(): manager = get_plugin_manager() for plugin in [u'ecf', u'nfe', u'optical']: if not manager.is_installed(plugin): # STOQLIB_TEST_QUICK won't let dropdb on testdb run. Just a # precaution to avoid trying to install it again manager.install_plugin(plugin) else: # Make sure that the plugin is imported so sys.path is properly # setup plugin = manager.get_plugin(plugin) plugin # pylint: disable=W0104
def run(self): # FIXME: parent pid is not supported on windows. Maybe we should # find a way for the task to check if the parent is alive in another # way in this case? if not _is_windows: os.setpgrp() self._ppid = os.getppid() t = threading.Thread(target=self._check_parent_running) t.daemon = True t.start() else: from stoqserver.main import (setup_stoq, setup_logging, setup_excepthook) # Do this as soon as possible so we can log any early traceback setup_excepthook() # Allow .pyd files to be imported from egg files from zipextimporter import ZipExtensionImporter sys.path_hooks.append(ZipExtensionImporter) sys.path_importer_cache.clear() cacerts_path = os.path.join(_root, 'cacert.pem') requests.utils.DEFAULT_CA_BUNDLE_PATH = cacerts_path requests.adapters.DEFAULT_CA_BUNDLE_PATH = cacerts_path setup_stoq() setup_logging() if isinstance(self.func, tuple): # Windows plugin_name, task_name = self.func manager = get_plugin_manager() plugin = manager.get_plugin(plugin_name) for task in plugin.get_server_tasks(): if task.name == task_name: break else: raise AssertionError func = task.start else: func = self.func # Workaround a python issue where multiprocessing/threading will not # use the modified sys.excepthook: https://bugs.python.org/issue1230540 try: func(*self._func_args, **self._func_kwargs) except Exception: sys.excepthook(*sys.exc_info()) self._error_queue.put(self.name)
def __init__(self, store, person, model=None, is_main_address=True, visual_mode=False, db_form=None): self.person = person self.is_main_address = (model and model.is_main_address or is_main_address) self.db_form = db_form if model is not None: model = store.fetch(model) model = _AddressModel(model, store) plugin = get_plugin_manager() self._nfe_active = plugin.is_any_active(['nfe', 'nfce']) BaseEditorSlave.__init__(self, store, model, visual_mode=visual_mode)
def start_plugins_update_scheduler(event): _setup_signal_termination() if not api.sysparam.get_bool('ONLINE_SERVICES'): logger.info( "ONLINE_SERVICES not enabled. Not scheduling plugin updates...") return manager = get_plugin_manager() while True: last_check_str = UserSettings().get('last-plugins-update', None) last_check = (dateutil.parser.parse(last_check_str) if last_check_str else datetime.datetime.min) # Check for updates once per day if last_check.date() == datetime.date.today(): time.sleep(24 * 60 * 60) continue logger.info("Checking for plugins updates...") updated = False default_store = get_default_store() # TODO: atm we are only updating the conector plugin to avoid # problems with migrations. Let this update everything once we # find a solution for this problem for egg in default_store.find(PluginEgg, plugin_name=u'conector'): md5sum = egg.egg_md5sum manager.download_plugin(egg.plugin_name) # If download_plugin updated the plugin, autoreload will # make egg. be reloaded from the database if md5sum != egg.egg_md5sum: updated = True settings = UserSettings() settings.set('last-plugins-update', datetime.datetime.now().isoformat()) settings.flush() if updated: # Wait until any running backup is finished and restart while _doing_backup.value: time.sleep(60) logger.info("Some plugins were updated. Restarting now " "to reflect the changes...") event.set() else: logger.info("No update was found...")
def _setup_widgets(self): self.confirm_date.set_sensitive(False) self._fill_employee_combo() self._fill_branch_combo() self._fill_cfop_combo() self._fill_cost_center_combo() self._fill_person_combo() manager = get_plugin_manager() nfe_is_active = manager.is_active('nfe') self.person.set_property('mandatory', nfe_is_active) if not sysparam.get_bool('CREATE_PAYMENTS_ON_STOCK_DECREASE'): self.create_payments.hide()
def setUp(self): super(TestPluginManager, self).setUp() # Since the plugins are commited inside pluginmanager, try to remove # it first, or we will have problems if STOQLIB_TEST_QUICK is set. store = new_store() test_plugin = store.find(InstalledPlugin, plugin_name=_TestPlugin.name).one() if test_plugin: store.remove(test_plugin) store.commit() store.close() self._manager = get_plugin_manager() self._register_test_plugin()
def _setup_widgets(self): branches = Branch.get_active_remote_branches(self.store) self.destination_branch.prefill(api.for_person_combo(branches)) self.source_branch.set_text(self.branch.get_description()) employees = self.store.find(Employee) self.source_responsible.prefill(api.for_person_combo(employees)) manager = get_plugin_manager() nfe_is_active = manager.is_active('nfe') self.invoice_number.set_property('mandatory', nfe_is_active) # Set an initial invoice number to TransferOrder and Invoice if not self.model.invoice_number: new_invoice_number = Invoice.get_next_invoice_number(self.store) self.model.invoice_number = new_invoice_number
def action_install_plugin(self, plugin_name): manager = get_plugin_manager() if (plugin_name not in manager.available_plugins_names or plugin_name in manager.egg_plugins_names): rv, msg = manager.download_plugin(plugin_name) if not rv: return False, msg if plugin_name not in manager.installed_plugins_names: with api.new_store() as store: try: manager.install_plugin(store, plugin_name) except PluginError as err: return False, str(err) return True, "Plugin installed/updated sucessfully"