示例#1
0
def sentry_report(exctype, value, tb, **tags):
    tags.update({
        'version': stoqserver.version_str,
        'stoq_version': stoq.version,
        'architecture': platform.architecture(),
        'distribution': platform.dist(),
        'python_version': tuple(sys.version_info),
        'system': platform.system(),
        'uname': platform.uname(),
    })
    # Those are inside a try/except because thy require database access.
    # If the database access is not working, we won't be able to get them
    try:
        default_store = api.get_default_store()
        tags['user_hash'] = api.sysparam.get_string('USER_HASH')
        tags['demo'] = api.sysparam.get_bool('DEMO_MODE')
        tags['postgresql_version'] = get_database_version(default_store)
        tags['plugins'] = InstalledPlugin.get_plugin_names(default_store)
        tags['cnpj'] = get_main_cnpj(default_store)
    except Exception:
        pass

    # Disable send sentry log if we are on developer mode.
    developer_mode = stoqserver.library.uninstalled
    if raven_client is not None and not developer_mode:
        if hasattr(raven_client, 'user_context'):
            raven_client.user_context({'id': tags.get('hash', None),
                                       'username': tags.get('cnpj', None)})
        raven_client.captureException((exctype, value, tb), tags=tags)
示例#2
0
    def __init__(self, parent=None, store=None, orientation=None,
                 reuse_store=False):
        """
        Create a new ModelListDialog object.
        :param store: a store connection
        """
        if orientation is None:
            orientation = gtk.ORIENTATION_VERTICAL
        if self.columns is None:
            fmt = "%s needs to set it's columns attribute"
            raise TypeError(fmt % (self.__class__.__name__, ))
        if self.model_type is None:
            fmt = "%s needs to set it's model_type attribute"
            raise TypeError(fmt % (self.__class__.__name__, ))

        if not store:
            store = api.get_default_store()
            assert not reuse_store

        self.store = store

        self.parent = parent
        self.reuse_store = reuse_store
        columns = self.columns or self.get_columns()
        ListSlave.__init__(self, columns, orientation)
        self._setup_permission()
示例#3
0
    def __init__(self, resource, manager, compact=False):
        self._resource = resource
        self._compact = compact
        self._manager = manager
        user = api.get_current_user(api.get_default_store())
        self._is_admin = user.profile.check_app_permission(u'admin')

        super(ResourceStatusBox, self).__init__(spacing=6)
        if compact:
            self.props.margin = 6
        else:
            self.props.margin = 12

        self.img = Gtk.Image()
        self.pack_start(self.img, False, True, 0)
        self.lbl = Gtk.Label()
        self.lbl.set_xalign(0)
        self.lbl.set_line_wrap(True)
        self.pack_start(self.lbl, False, True, 0)

        self.buttonbox = Gtk.Box()
        self.buttonbox.set_valign(Gtk.Align.CENTER)
        self.buttonbox.get_style_context().add_class('linked')
        if not compact:
            self.pack_end(self.buttonbox, False, True, 0)
示例#4
0
文件: shell.py 项目: romaia/stoq
    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
示例#5
0
文件: login.py 项目: Guillon88/stoq
    def _check_user(self, username, pw_hash):
        username = unicode(username)
        pw_hash = unicode(pw_hash)
        # This function is really just a post-validation item.
        default_store = api.get_default_store()
        current_branch = api.get_current_branch(default_store)

        user = LoginUser.authenticate(default_store, username, pw_hash,
                                      current_branch)

        # Dont know why, but some users have this empty. Prevent user from
        # login in, since it will break later
        if not user.profile:
            msg = (_("User '%s' has no profile set, "
                     "but this should not happen.") % user.username + '\n\n' +
                   _("Please contact your system administrator or Stoq team."))
            warning(msg)
            raise LoginError(_("User does not have a profile"))

        user.login()

        # ICurrentUser might already be provided which is the case when
        # creating a new database, thus we need to replace it.
        provide_utility(ICurrentUser, user, replace=True)
        return user
示例#6
0
    def _check_user(self, username, password):
        username = unicode(username)
        password = unicode(password)
        # This function is really just a post-validation item.
        default_store = api.get_default_store()
        user = default_store.find(LoginUser, username=username).one()
        if not user:
            raise LoginError(_("Invalid user or password"))

        if not user.is_active:
            raise LoginError(_('This user is inactive'))

        branch = api.get_current_branch(default_store)
        # current_branch may not be set if we are registering a new station
        if branch and not user.has_access_to(branch):
            raise LoginError(_('This user does not have access to this branch'))

        if user.pw_hash != password:
            raise LoginError(_("Invalid user or password"))

        # Dont know why, but some users have this empty. Prevent user from
        # login in, since it will break later
        if not user.profile:
            msg = (_("User '%s' has no profile set, "
                     "but this should not happen.") % user.username + '\n\n' +
                   _("Please contact your system administrator or Stoq team."))
            warning(msg)
            raise LoginError(_("User does not have a profile"))

        user.login()

        # ICurrentUser might already be provided which is the case when
        # creating a new database, thus we need to replace it.
        provide_utility(ICurrentUser, user, replace=True)
        return user
示例#7
0
    def cookie_login(self):
        if api.sysparam(api.get_default_store()).DISABLE_COOKIES:
            log.info("Cookies disable by parameter")
            return

        cookie_file = get_utility(ICookieFile)
        try:
            username, password = cookie_file.get()
        except CookieError:
            log.info("Not using cookie based login")
            return

        def is_md5(password):
            # This breaks for passwords that are 32 characters long,
            # uses only digits and lowercase a-f, pretty unlikely as
            # real-world password
            if len(password) != 32:
                return False
            for c in '1234567890abcdef':
                password = password.replace(c, '')
            return password == ''

        # Migrate old passwords to md5 hashes.
        if not is_md5(password):
            password = _encrypt_password(password)
            cookie_file.store(username, password)

        try:
            user = self._check_user(username, password)
        except (LoginError, UserProfileError, DatabaseError) as e:
            log.info("Cookie login failed: %r" % e)
            return

        log.info("Logging in using cookie credentials")
        return user
示例#8
0
 def _check_new_person(self):
     self.is_new_person = False
     # If this person is not in the default store, then it was created
     # inside another transaction that was not commited yet.
     default_store = api.get_default_store()
     if default_store.find(Person, id=self.model.id).is_empty():
         self.is_new_person = True
示例#9
0
 def get_uri(self):
     if locale.getlocale()[0] == 'pt_BR' or platform.system() == 'Windows':
         content = environ.find_resource('html', 'welcome-pt_BR.html')
     else:
         content = environ.find_resource('html', 'welcome.html')
     if api.sysparam(api.get_default_store()).DEMO_MODE:
         content += '?demo-mode'
     return 'file:///' + content
示例#10
0
文件: search.py 项目: romaia/stoq
    def __init__(self, columns, tree=False, restore_name=None):
        self._restore_name = restore_name
        self._settings_key = 'search-columns-%s' % (
            api.get_current_user(api.get_default_store()).username, )
        self._columns = self.restore_columns(columns)

        SearchSlaveDelegate.__init__(self, self._columns, tree=tree)
        self.search.connect("search-completed",
                            self._on_search__search_completed)
示例#11
0
    def on_RemoveSettingsCache__activate(self, action):
        keys = ["app-ui", "launcher-geometry"]
        keys.append("search-columns-%s" % (api.get_current_user(api.get_default_store()).username,))

        for key in keys:
            try:
                api.user_settings.remove(key)
            except KeyError:
                pass
示例#12
0
def restore(restore_dir, user_hash, time=None):
    global _user_hash
    _user_hash = user_hash

    with _mock_environ():
        config = get_config()

        backup_key = config.get('Backup', 'key')
        if not backup_key:
            raise ValueError("No backup key set on configuration file")
        os.environ.setdefault('PASSPHRASE', backup_key)

        # Close the main store so the database can be dropped after this
        api.get_default_store().rollback(close=True)
        sys.argv.extend([_duplicity_bin, 'restore',
                         _webservice_url, restore_dir])
        if time is not None:
            sys.argv.extend(['--time', time])

        _duplicity_main.main()
示例#13
0
 def validate_confirm(self):
     if not self.edit_mode:
         settings = DeviceSettings.get_by_station_and_type(
             store=api.get_default_store(), station=self.model.station.id, type=self.model.type
         )
         if settings:
             self.station.set_invalid(
                 _(u'A %s already exists for station "%s"')
                 % (self.model.get_device_type_name(), self.model.station.name)
             )
             return False
     return True
示例#14
0
文件: search.py 项目: romaia/stoq
 def _migrate_from_pickle(self):
     username = api.get_current_user(api.get_default_store()).username
     filename = os.path.join(get_application_dir(), 'columns-%s' % username,
                             self._restore_name + '.pickle')
     log.info("Migrating columns from pickle: %s" % (filename, ))
     try:
         with open(filename) as fd:
             import cPickle
             return cPickle.load(fd)
     except Exception, e:
         log.info("Exception while migrating: %r" % (e, ))
         return {}
示例#15
0
    def setup_widgets(self):
        self.get_toplevel().set_size_request(*self.size)
        self.notification_label.set_text('')
        self.notification_label.set_color('black')

        if api.sysparam(api.get_default_store()).DISABLE_COOKIES:
            self.remember.hide()
            self.remember.set_active(False)

        gtkimage = gtk.Image()
        gtkimage.set_from_pixbuf(render_logo_pixbuf('login'))
        self.logo_container.add(gtkimage)
        self.logo_container.show_all()
示例#16
0
    def validate_confirm(self):
        settings = DeviceSettings.get_by_station_and_type(
            store=api.get_default_store(),
            station=self.model.station.id,
            type=self.model.type,
            exclude=self.model)
        if settings and self.is_active_button.get_active():
            warning(_(u"An active %s already exists for station \"%s\"") % (
                    self.model.device_type_name,
                    self.model.station_name))
            return False

        return True
示例#17
0
    def _get_proxy(self):
        if self._proxy is None:
            config = get_config()
            if not config:
                raise ServerError(_('Configuration not found'))

            address = config.get('General', 'serveraddress')
            if not address:
                query = ("SELECT client_addr FROM pg_stat_activity "
                         "WHERE application_name LIKE ? AND "
                         "      datname = ? "
                         "LIMIT 1")
                params = [u'stoqserver%', str(db_settings.dbname)]
                res = api.get_default_store().execute(query, params=params).get_one()

                if res:
                    # When stoqserver is located in another machine
                    if res[0] not in ['127.0.0.1', '::1', '', None]:
                        address = res[0]
                    else:
                        # XXX: For now we only support ipv4
                        # XXX: If the client_addr is NULL, then stoqserver is
                        # connected using the unix socket, which means that he
                        # is in the same ip as the postgresql
                        address = db_settings.address
                        if not address:
                            address = 'localhost'
                else:
                    address = None

            if not address:
                raise ServerError(_("Stoq server not found"))

            port = config.get('General', 'serverport') or 6970
            url = 'http://%s:%s/XMLRPC' % (address, port)

            default_timeout = socket.getdefaulttimeout()
            socket.setdefaulttimeout(self._timeout)
            self._proxy = xmlrpc.client.ServerProxy(url, allow_none=True)
            socket.setdefaulttimeout(default_timeout)

        try:
            retval = self._proxy.ping()
        except (Exception, AttributeError):
            self._proxy = None
            raise

        if not retval:
            raise ServerError(_("Server not responding to pings"))

        return self._proxy
示例#18
0
def register_payment_slaves():
    dsm = get_utility(IDomainSlaveMapper)
    default_store = api.get_default_store()
    for method_name, slave_class in [
        (u'money', MoneyMethodSlave),
        (u'bill', BillMethodSlave),
        (u'check', CheckMethodSlave),
        (u'card', CardMethodSlave),
        (u'store_credit', StoreCreditMethodSlave),
        (u'multiple', MultipleMethodSlave),
        (u'deposit', DepositMethodSlave)]:

        method = PaymentMethod.get_by_name(default_store, method_name)
        dsm.register(method, slave_class)
示例#19
0
 def get_pixbuf(self, model):
     kind = model.kind
     if kind == 'payable':
         pixbuf = self._pixbuf_payable
     elif kind == 'receivable':
         pixbuf = self._pixbuf_receivable
     elif kind == 'account':
         till_account_id = sysparam(api.get_default_store()).TILLS_ACCOUNT.id
         if model.matches(till_account_id):
             pixbuf = self._pixbuf_till
         else:
             pixbuf = self._pixbuf_money
     else:
         return None
     return pixbuf
示例#20
0
def setup_stoq(register_station=False, name='stoqserver', version=stoqserver.version_str):
    info = AppInfo()
    info.set('name', name)
    info.set('version', version)
    info.set('ver', version)
    provide_utility(IAppInfo, info, replace=True)

    # FIXME: Maybe we should check_schema and load plugins here?
    setup(config=get_config(), options=None, register_station=register_station,
          check_schema=False, load_plugins=True)

    # This is needed for api calls that requires the current branch set,
    # e.g. Sale.confirm
    main_company = api.sysparam.get_object(
        api.get_default_store(), 'MAIN_COMPANY')
    provide_utility(ICurrentBranch, main_company, replace=True)
示例#21
0
    def __init__(self, window, store=None):
        if store is None:
            store = api.get_default_store()
        self.store = store
        self.window = window

        self._sensitive_group = dict()
        self.help_ui = None
        self.uimanager = self.window.uimanager

        # FIXME: These two should probably post-__init__, but
        #        that breaks date_label in the calender app
        self._create_search()
        self.create_actions()
        GladeDelegate.__init__(self, gladefile=self.gladefile, toplevel_name=self.toplevel_name)
        self._attach_search()
        self.create_ui()
示例#22
0
文件: tilleditor.py 项目: romaia/stoq
    def on_confirm(self):
        till = self.model.till
        # Using api.get_default_store instead of self.store
        # or it will return self.model.till
        last_opened = Till.get_last_opened(api.get_default_store())
        if (last_opened and
            last_opened.opening_date.date() == till.opening_date.date()):
            warning(_("A till was opened earlier this day."))
            self.retval = False
            return

        try:
            TillOpenEvent.emit(till=till)
        except (TillError, DeviceError), e:
            warning(str(e))
            self.retval = False
            return
示例#23
0
文件: shellapp.py 项目: sarkis89/stoq
    def __init__(self, window, store=None):
        if store is None:
            store = api.get_default_store()
        self.store = store
        self.window = window

        self._sensitive_group = dict()
        self.help_ui = None
        self.uimanager = self.window.uimanager

        # FIXME: These two should probably post-__init__, but
        #        that breaks date_label in the calender app
        self._create_search()
        self.create_actions()
        GladeDelegate.__init__(self,
                               gladefile=self.gladefile,
                               toplevel_name=self.toplevel_name)
        self._attach_search()
        self.create_ui()
示例#24
0
def setup_stoq(register_station=False, name='stoqserver'):
    info = AppInfo()
    info.set('name', name)
    info.set('version', stoqserver.version_str)
    info.set('ver', stoqserver.version_str)
    provide_utility(IAppInfo, info, replace=True)

    # FIXME: Maybe we should check_schema and load plugins here?
    setup(config=get_config(),
          options=None,
          register_station=register_station,
          check_schema=False,
          load_plugins=True)

    # This is needed for api calls that requires the current branch set,
    # e.g. Sale.confirm
    main_company = api.sysparam.get_object(api.get_default_store(),
                                           'MAIN_COMPANY')
    provide_utility(ICurrentBranch, main_company, replace=True)
示例#25
0
    def render_GET(self, resource):
        if not 'type' in resource.args:
            raise TypeError

        chart_type = resource.args['type'][0]
        chart_class = get_chart_class(chart_type)
        if chart_class is None:
            raise TypeError("chart_class")

        if (not 'start' in resource.args or
            not 'end' in resource.args):
            raise TypeError
        start_str = resource.args['start'][0]
        end_str = resource.args['end'][0]

        args = dict(start=_iso_to_datetime(start_str),
                    end=_iso_to_datetime(end_str))

        chart = chart_class(api.get_default_store())
        response = chart.run(args)
        return json.dumps(response)
示例#26
0
    def __init__(self, columns=None, tree=False, restore_name=None, chars=25):
        """
        Create a new SearchContainer object.
        :param columns: a list of :class:`kiwi.ui.objectlist.Column`
        :param tree: if we should list the results as a tree
        :param chars: maximum number of chars used by the search entry
        :param restore_name:
        """
        if tree:
            self.result_view_class = SearchResultTreeView

        self._auto_search = True
        self._columns = columns
        self._lazy_search = False
        self._last_results = None
        self._model = None
        self._query_executer = None
        self._restore_name = restore_name
        self._search_filters = []
        self._selected_item = None
        self._summary_label = None
        self.menu = None
        self.result_view = None
        self._settings_key = 'search-columns-%s' % (api.get_current_user(
            api.get_default_store()).username, )
        self._columns = self.restore_columns(columns)

        self.vbox = gtk.VBox()
        SlaveDelegate.__init__(self, toplevel=self.vbox)
        self.vbox.show()

        search_filter = StringSearchFilter(_('Search:'),
                                           chars=chars,
                                           container=self)
        search_filter.connect('changed', self._on_search_filter__changed)
        self._search_filters.append(search_filter)
        self._primary_filter = search_filter

        self._create_ui()
示例#27
0
    def __init__(self, parent=None, store=None, orientation=None):
        """
        Create a new ModelListDialog object.
        :param store: a store connection
        """
        if orientation is None:
            orientation = gtk.ORIENTATION_VERTICAL
        if self.columns is None:
            fmt = "%s needs to set it's columns attribute"
            raise TypeError(fmt % (self.__class__.__name__, ))
        if self.model_type is None:
            fmt = "%s needs to set it's model_type attribute"
            raise TypeError(fmt % (self.__class__.__name__, ))

        if not store:
            store = api.get_default_store()
        self.store = store

        self.parent = parent
        self._reuse_store = False
        columns = self.columns or self.get_columns()
        ListSlave.__init__(self, columns, orientation)
示例#28
0
    def on_confirm(self):
        till = self.model.till
        # Using api.get_default_store instead of self.store
        # or it will return self.model.till
        last_opened = Till.get_last_opened(api.get_default_store())
        if last_opened and last_opened.opening_date.date() == till.opening_date.date():
            warning(_("A till was opened earlier this day."))
            self.retval = False
            return

        try:
            TillOpenEvent.emit(till=till)
        except (TillError, DeviceError) as e:
            warning(str(e))
            self.retval = False
            return

        value = self.proxy.model.value
        if value:
            TillAddCashEvent.emit(till=till, value=value)
            till_entry = till.add_credit_entry(value, _(u"Initial Cash amount"))
            _create_transaction(self.store, till_entry)
示例#29
0
    def __init__(self, store, model, expanded_edition=False):
        """An editor for a loan item. If the expaned_edition is True, the
        editor will enable the sale_quantity and return_quantity fields to be
        edited and will lock the quantity and price fields.
        :param store: a store.
        :param model: a loan item.
        :param expanded_edition: whether or not we should enable sale_quantity
                                 and return_quantity fields to be edited.
        """
        self._expanded_edition = expanded_edition
        self._branch = model.loan.branch

        default_store = api.get_default_store()
        orig_model = default_store.find(LoanItem, id=model.id).one()
        if orig_model:
            self._original_sale_qty = orig_model.sale_quantity
            self._original_return_qty = orig_model.return_quantity
        else:
            self._original_sale_qty = 0
            self._original_return_qty = 0

        BaseEditor.__init__(self, store, model)
示例#30
0
    def insert_initial(self, store, edited_account=None):
        """ Insert accounts and parent accounts in a ObjectTree.

        :param store: a store
        :param edited_account: If not None, this is the account being edited.
          In this case, this acount (and its decendents) will not be shown in
          the account tree.
        """
        till_id = sysparam(api.get_default_store()).TILLS_ACCOUNT.id

        if self.create_mode and edited_account:
            accounts = list(store.find(AccountView,
                                       AccountView.id != edited_account.id))
        else:
            accounts = list(store.find(AccountView))
        accounts = self._orderaccounts(accounts)

        for account in accounts:
            account.total = self._calculate_total(accounts, account)
            if self.create_mode and account.matches(till_id):
                account.selectable = False
            self.add_account(account.parent_id, account)

        selectable = not self.create_mode

        # Tabs cache requires unique ids
        self.append(None, Settable(description=_("Accounts Payable"),
                                   id=-1,
                                   parent=None,
                                   kind='payable',
                                   selectable=selectable,
                                   total=None))
        self.append(None, Settable(description=_("Accounts Receivable"),
                                   id=-2,
                                   parent=None,
                                   kind='receivable',
                                   selectable=selectable,
                                   total=None))
        self.flush()
示例#31
0
    def __init__(self, store, model, expanded_edition=False):
        """An editor for a loan item. If the expaned_edition is True, the
        editor will enable the sale_quantity and return_quantity fields to be
        edited and will lock the quantity and price fields.
        :param store: a store.
        :param model: a loan item.
        :param expanded_edition: whether or not we should enable sale_quantity
                                 and return_quantity fields to be edited.
        """
        self._expanded_edition = expanded_edition
        self._branch = model.loan.branch

        default_store = api.get_default_store()
        orig_model = default_store.find(LoanItem, id=model.id).one()
        if orig_model:
            self._original_sale_qty = orig_model.sale_quantity
            self._original_return_qty = orig_model.return_quantity
        else:
            self._original_sale_qty = 0
            self._original_return_qty = 0

        BaseEditor.__init__(self, store, model)
示例#32
0
    def get(self):
        stream = Queue()
        station = self.get_current_station(api.get_default_store(),
                                           token=request.args['token'])
        log.info('Estabilished event stream for %s', station.id)
        self._streams[station.id] = stream

        # Don't replace the reply queue and waiting reply flag
        self._replies.setdefault(station.id, Queue(maxsize=1))
        self._waiting_reply.setdefault(station.id, Event())

        if self._waiting_reply[station.id].is_set():
            # There is a new stream for this station, but we were currently waiting for a reply from
            # the same station in the previous event stream. Put an invalid reply there, and clear
            # the flag so that the station can continue working
            self._replies[station.id].put(EventStreamBrokenException)
            self._waiting_reply[station.id].clear()

        # If we dont put one event, the event stream does not seem to get stabilished in the browser
        stream.put(json.dumps({}))

        EventStreamEstablishedEvent.send(station)

        # This is the best time to check if there are pending transactions, since the frontend just
        # stabilished a connection with the backend (thats us).
        has_canceled = TefCheckPendingEvent.send()
        if has_canceled and has_canceled[0][1]:
            EventStream.add_event(
                {
                    'type':
                    'TEF_WARNING_MESSAGE',
                    'message': ('Última transação TEF não foi efetuada.'
                                ' Favor reter o Cupom.')
                },
                station=station)
            EventStream.add_event({'type': 'CLEAR_SALE'}, station=station)
        return Response(self._loop(stream, station.id),
                        mimetype="text/event-stream")
示例#33
0
    def __init__(self, columns=None, tree=False, restore_name=None, chars=25):
        """
        Create a new SearchContainer object.
        :param columns: a list of :class:`kiwi.ui.objectlist.Column`
        :param tree: if we should list the results as a tree
        :param chars: maximum number of chars used by the search entry
        :param restore_name:
        """
        if tree:
            self.result_view_class = SearchResultTreeView

        self._auto_search = True
        self._columns = columns
        self._lazy_search = False
        self._last_results = None
        self._model = None
        self._query_executer = None
        self._restore_name = restore_name
        self._search_filters = []
        self._selected_item = None
        self._summary_label = None
        self.menu = None
        self.result_view = None
        self._settings_key = 'search-columns-%s' % (
            api.get_current_user(api.get_default_store()).username, )
        self._columns = self.restore_columns(columns)

        self.vbox = gtk.VBox()
        SlaveDelegate.__init__(self, toplevel=self.vbox)
        self.vbox.show()

        search_filter = StringSearchFilter(_('Search:'), chars=chars,
                                           container=self)
        search_filter.connect('changed', self._on_search_filter__changed)
        self._search_filters.append(search_filter)
        self._primary_filter = search_filter

        self._create_ui()
示例#34
0
    def on_confirm(self):
        till = self.model.till
        # Using api.get_default_store instead of self.store
        # or it will return self.model.till
        last_opened = Till.get_last_opened(api.get_default_store())
        if (last_opened and
            last_opened.opening_date.date() == till.opening_date.date()):
            warning(_("A till was opened earlier this day."))
            self.retval = False
            return

        try:
            TillOpenEvent.emit(till=till)
        except (TillError, DeviceError) as e:
            warning(str(e))
            self.retval = False
            return

        value = self.proxy.model.value
        if value:
            TillAddCashEvent.emit(till=till, value=value)
            till_entry = till.add_credit_entry(value, _(u'Initial Cash amount'))
            _create_transaction(self.store, till_entry)
示例#35
0
    def _excepthook(exctype, value, tb):
        tags = {
            'version': ".".join(str(i) for i in stoqserver.__version__),
            'stoq_version': stoq.version,
            'architecture': platform.architecture(),
            'distribution': platform.dist(),
            'python_version': tuple(sys.version_info),
            'system': platform.system(),
            'uname': platform.uname(),
        }
        # Those are inside a try/except because thy require database access.
        # If the database access is not working, we won't be able to get them
        try:
            default_store = api.get_default_store()
            tags['user_hash'] = api.sysparam.get_string('USER_HASH')
            tags['demo'] = api.sysparam.get_bool('DEMO_MODE')
            tags['postgresql_version'] = get_database_version(default_store)
            tags['plugins'] = InstalledPlugin.get_plugin_names(default_store)
            tags['cnpj'] = get_main_cnpj(default_store)
        except Exception:
            pass

        _raven_client.captureException((exctype, value, tb), tags=tags)
        traceback.print_exception(exctype, value, tb)
示例#36
0
def sentry_report(exctype, value, tb, **tags):
    developer_mode = not importlib.util.find_spec("stoqdrivers")
    if raven_client is None or developer_mode:
        # Disable send sentry log if we are on developer mode.
        return

    tags.update({
        'version': stoqserver.version_str,
        'stoq_version': stoq.version,
        'architecture': platform.architecture(),
        'python_version': tuple(sys.version_info),
        'system': platform.system(),
        'uname': platform.uname(),
    })
    # python deprecated platform.dist in python3.5 and removed it in 3.7
    if hasattr(platform, 'dist'):
        tags['distribution'] = platform.dist()

    # Those are inside a try/except because thy require database access.
    # If the database access is not working, we won't be able to get them
    try:
        default_store = api.get_default_store()
        tags['user_hash'] = api.sysparam.get_string('USER_HASH')
        tags['demo'] = api.sysparam.get_bool('DEMO_MODE')
        tags['postgresql_version'] = get_database_version(default_store)
        tags['plugins'] = InstalledPlugin.get_plugin_names(default_store)
        tags['cnpj'] = get_main_cnpj(default_store)
    except Exception:
        pass

    if hasattr(raven_client, 'user_context'):
        raven_client.user_context({
            'id': tags.get('hash', None),
            'username': tags.get('cnpj', None)
        })
    raven_client.captureException((exctype, value, tb), tags=tags)
示例#37
0
    def _excepthook(exctype, value, tb):
        tags = {
            'version': stoqserver.version_str,
            'stoq_version': stoq.version,
            'architecture': platform.architecture(),
            'distribution': platform.dist(),
            'python_version': tuple(sys.version_info),
            'system': platform.system(),
            'uname': platform.uname(),
        }
        # Those are inside a try/except because thy require database access.
        # If the database access is not working, we won't be able to get them
        try:
            default_store = api.get_default_store()
            tags['user_hash'] = api.sysparam.get_string('USER_HASH')
            tags['demo'] = api.sysparam.get_bool('DEMO_MODE')
            tags['postgresql_version'] = get_database_version(default_store)
            tags['plugins'] = InstalledPlugin.get_plugin_names(default_store)
            tags['cnpj'] = get_main_cnpj(default_store)
        except Exception:
            pass

        _raven_client.captureException((exctype, value, tb), tags=tags)
        traceback.print_exception(exctype, value, tb)
示例#38
0
    def validate_user(self):
        """ Checks if an user can log in or not.
        :returns: a user object
        """
        # If there is only one user, and that user is admin with a blank
        # password, just log the user in
        store = api.get_default_store()
        if store.find(LoginUser).count() == 1:
            try:
                return self._check_user(u'admin', LoginUser.hash(u''))
            except Exception:
                pass

        log.info("Showing login dialog")
        # Loop for logins
        retry = 0
        retry_msg = None
        dialog = None

        while retry < RETRY_NUMBER:
            username = self._force_username
            password = None

            if not dialog:
                dialog = LoginDialog(_("Stoq - Access Control"))
            if self._force_username:
                dialog.force_username(username)

            ret = dialog.run(username, password, msg=retry_msg)

            # user cancelled (escaped) the login dialog
            if not ret:
                return

            # Use credentials
            if not (isinstance(ret, (tuple, list)) and len(ret) == 2):
                raise ValueError('Invalid return value, got %s'
                                 % str(ret))

            username, password = ret

            if not username:
                retry_msg = _("specify an username")
                continue

            try:
                user = self._check_user(username, password)
            except (LoginError, UserProfileError) as e:
                # We don't hide the dialog here; it's kept open so the
                # next loop we just can call run() and display the error
                cookie = get_utility(ICookieFile, None)
                if cookie:
                    cookie.clear()
                retry += 1
                retry_msg = str(e)
            except DatabaseError as e:
                if dialog:
                    dialog.destroy()
                self._abort(str(e))
            else:
                log.info("Authenticated user %s" % username)
                self._force_username = None

                if dialog.remember.get_active():
                    get_utility(ICookieFile).store(user.username,
                                                   user.pw_hash)

                if dialog:
                    dialog.destroy()

                return user

        if dialog:
            dialog.destroy()
        raise LoginError(_("Depleted attempts of authentication"))
示例#39
0
def post_ping_request(station):
    if is_developer_mode():
        return

    from .lib.restful import PDV_VERSION
    target = 'https://app.stoq.link:9000/api/ping'
    time_format = '%d-%m-%Y %H:%M:%S%Z'
    store = api.get_default_store()
    plugin_manager = get_plugin_manager()
    boot_time = datetime.datetime.fromtimestamp(
        psutil.boot_time()).strftime(time_format)

    def get_stoq_conf():
        with open(get_config().get_filename(), 'r') as fh:
            return fh.read().encode()

    def get_clisitef_ini():
        try:
            with open('CliSiTef.ini', 'r') as fh:
                return fh.read().encode()
        except FileNotFoundError:
            return ''.encode()

    while True:
        try:
            dpkg_list = subprocess.check_output('dpkg -l \\*stoq\\*',
                                                shell=True).decode()
        except subprocess.CalledProcessError:
            dpkg_list = ""
        stoq_packages = re.findall(r'ii\s*(\S*)\s*(\S*)', dpkg_list)
        if PDV_VERSION:
            logger.info('Running stoq_pdv {}'.format(PDV_VERSION))
        logger.info('Running stoq {}'.format(stoq_version))
        logger.info('Running stoq-server {}'.format(stoqserver_version))
        logger.info('Running stoqdrivers {}'.format(stoqdrivers_version))
        local_time = tzlocal.get_localzone().localize(datetime.datetime.now())

        response = requests.post(
            target,
            headers={
                'Stoq-Backend':
                '{}-portal'.format(api.sysparam.get_string('USER_HASH'))
            },
            data={
                'station_id':
                station.id,
                'data':
                json.dumps({
                    'platform': {
                        'architecture': platform.architecture(),
                        'distribution': platform.dist(),
                        'system': platform.system(),
                        'uname': platform.uname(),
                        'python_version': platform.python_version_tuple(),
                        'postgresql_version': get_database_version(store)
                    },
                    'system': {
                        'boot_time': boot_time,
                        'cpu_times': psutil.cpu_times(),
                        'load_average': os.getloadavg(),
                        'disk_usage': psutil.disk_usage('/'),
                        'virtual_memory': psutil.virtual_memory(),
                        'swap_memory': psutil.swap_memory()
                    },
                    'plugins': {
                        'available':
                        plugin_manager.available_plugins_names,
                        'installed':
                        plugin_manager.installed_plugins_names,
                        'active':
                        plugin_manager.active_plugins_names,
                        'versions':
                        getattr(plugin_manager, 'available_plugins_versions',
                                None)
                    },
                    'running_versions': {
                        'pdv': PDV_VERSION,
                        'stoq': stoq_version,
                        'stoqserver': stoqserver_version,
                        'stoqdrivers': stoqdrivers_version
                    },
                    'stoq_packages':
                    dict(stoq_packages),
                    'local_time':
                    local_time.strftime(time_format),
                    'stoq_conf_md5':
                    md5(get_stoq_conf()).hexdigest(),
                    'clisitef_ini_md5':
                    md5(get_clisitef_ini()).hexdigest()
                })
            })

        logger.info("POST {} {} {}".format(target, response.status_code,
                                           response.elapsed.total_seconds()))
        gevent.sleep(3600)
示例#40
0
文件: financial.py 项目: tmaxter/stoq
        # Bottom, rightmost: yearly total
        formula = 'SUM(%s:%s)' % (xlwt.Utils.rowcol_to_cell(
            first_data_row, n_columns +
            2), xlwt.Utils.rowcol_to_cell(last_data_row, n_columns + 2))
        sheet.write(n_rows + 3, n_columns + 2, xlwt.Formula(formula),
                    SUM_STYLE)

    def _write_account_cells(self, sheet, cells):
        for y, cell in enumerate(cells):
            sheet.write(2 + y, 0, cell, HEADER_LEFT_STYLE)

        n_rows = len(cells)
        sheet.write(n_rows + 2, 0, _(u'Average'), HEADER_LEFT_STYLE)
        sheet.write(n_rows + 3, 0, _(u'Total'), HEADER_LEFT_STYLE)

    def write(self, temporary):
        self._wb.save(temporary.name)


if __name__ == '__main__':
    import os
    import tempfile
    ec = api.prepare_test()
    store = api.get_default_store()
    fir = FinancialIntervalReport(store, year=2012)
    with tempfile.NamedTemporaryFile(suffix='.xls', delete=False) as temporary:
        if fir.run():
            fir.write(temporary)
        os.system("soffice %s" % (temporary.name, ))
示例#41
0
 def __init__(self, application_screen=None):
     # FIXME: BaseEditor expects a store, so we are passing one here, even
     # though it won't be used. We should be inheriting from BaseDialog.
     BaseEditor.__init__(self, api.get_default_store())
     self.main_dialog.set_title(self.model_name)
     self.application_screen = application_screen
示例#42
0
def run_flaskserver(port, debug=False, multiclient=False):
    from stoqlib.lib.environment import configure_locale
    # Force pt_BR for now.
    configure_locale('pt_BR')

    global is_multiclient
    is_multiclient = multiclient

    from .workers import WORKERS
    # For now we're disabling workers when stoqserver is serving multiple clients (multiclient mode)
    # FIXME: a proper solution would be to modify the workflow so that the clients ask the server
    # about devices health, the till status, etc. instead of the other way around.
    if not is_multiclient:
        for function in WORKERS:
            gevent.spawn(function,
                         get_current_station(api.get_default_store()))

    try:
        from stoqserver.lib import stacktracer
        stacktracer.start_trace("/tmp/trace-stoqserver-flask.txt",
                                interval=5,
                                auto=True)
    except ImportError:
        pass

    app = bootstrap_app()
    app.debug = debug
    if not is_developer_mode():
        sentry.raven_client = Sentry(app, dsn=SENTRY_URL, client=raven_client)

    @app.after_request
    def after_request(response):
        # Add all the CORS headers the POS needs to have its ajax requests
        # accepted by the browser
        origin = request.headers.get('origin')
        if not origin:
            origin = request.args.get('origin',
                                      request.form.get('origin', '*'))
        response.headers['Access-Control-Allow-Origin'] = origin
        response.headers[
            'Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, DELETE'
        response.headers[
            'Access-Control-Allow-Headers'] = 'Authorization, Content-Type'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        return response

    from stoqserver.lib.restful import has_sat, has_nfe
    logger.info('Starting wsgi server (has_sat=%s, has_nfe=%s)', has_sat,
                has_nfe)
    http_server = WSGIServer(('0.0.0.0', port),
                             app,
                             spawn=gevent.spawn_raw,
                             log=logger,
                             error_log=logger)

    if is_developer_mode():
        if debug:
            gevent.spawn(_gtk_main_loop)

        @run_with_reloader
        def run_server():
            http_server.serve_forever()

        run_server()
    else:
        http_server.serve_forever()