Source code for stoqlib.api

# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4

##
## Copyright (C) 2011-2012 Async Open Source
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., or visit: http://www.gnu.org/.
##
##
## Author(s): Stoq Team <stoq-devel@async.com.br>
##
##

"""Stoqlib API

Singleton object which makes it easier to common stoqlib APIs without
having to import their symbols.
"""
import operator
import sys

from kiwi.component import get_utility

from stoqlib.database.runtime import (new_store,
                                      get_default_store)
from stoqlib.database.runtime import (get_current_branch,
                                      get_current_station, get_current_user)
from stoqlib.database.settings import db_settings
from stoqlib.domain.person import Branch
from stoqlib.gui.events import CanSeeAllBranches
from stoqlib.lib.environment import is_developer_mode
from stoqlib.lib.interfaces import IStoqConfig
from stoqlib.lib.parameters import sysparam
from stoqlib.lib.settings import get_settings
from stoqlib.lib.translation import locale_sorted, stoqlib_gettext as _
from stoqlib.l10n.l10n import get_l10n_field


[docs]class safe_str(str): pass
[docs]class safe_unicode(unicode): pass
[docs]class StoqAPI(object):
[docs] def get_default_store(self): return get_default_store()
[docs] def new_store(self): return new_store()
[docs] def get_current_branch(self, store): return get_current_branch(store)
[docs] def get_current_station(self, store): return get_current_station(store)
[docs] def get_current_user(self, store): return get_current_user(store)
@property def config(self): return get_utility(IStoqConfig) @property def db_settings(self): return db_settings @property def user_settings(self): return get_settings()
[docs] def is_developer_mode(self): return is_developer_mode()
[docs] def get_l10n_field(self, field_name, country=None): return get_l10n_field(field_name, country=country)
[docs] def for_combo(self, resultset, attr=None, empty=None, sorted=True): """ Prepares the result of a table for inserting into a combo. Formats the item and sorts them according to the current locale :param resultset: a resultset :param attr: attribute to use instead of :py:class:`~stoqlib.domain.interfaces.IDescribable` :param empty: if set, add an initial None item with this parameter as a label Example:: categories = self.store.find(SellableCategory) self.category_combo.prefill(api.for_combo(categories, attr='full_description')) """ if attr is not None: items = [(getattr(obj, attr), obj) for obj in resultset] else: # If attr is not specified, the objects in the resultset must # implement IDescribable items = [(obj.get_description(), obj) for obj in resultset] if sorted: items = locale_sorted(items, key=operator.itemgetter(0)) if empty is not None: items.insert(0, (empty, None)) return items
[docs] def for_person_combo(self, resultset): """ This is similar to :py:func:`~stoqlib.api.StoqAPI.for_combo` but takes a class that references a :py:class:`~stoqlib.domain.person.Person`, such as a :py:class:`~stoqlib.domain.person.Client`, :py:class:`~stoqlib.domain.person.Company`, :py:class:`~stoqlib.domain.person.Supplier` etc. :param resultset: a resultset Example:: suppliers = Supplier.get_active_suppliers(self.store) self.supplier.prefill(api.for_person_combo(suppliers)) """ from stoqlib.domain.person import Person from storm import Undef from storm.expr import Eq store = resultset._store facet = resultset._find_spec.default_cls where = resultset._where # This is fetching all persons to cache the objects and avoid extra # queries when constructing the combo strings. resultset = store.find((Person, facet), Person.id == facet.person_id, Eq(Person.merged_with_id, None)) if where is not Undef: resultset = resultset.find(where) items = [(obj[1].get_description(), obj[1]) for obj in resultset] # FIXME: A combo only changes to data mode (the one that it # returns an object insted of the label) when prefilled with # objects. Prefilling with this fake data will prevent the problem # from happening. We should fix this on kiwi later if not items: return [('', None)] return locale_sorted(items, key=operator.itemgetter(0))
[docs] def can_see_all_branches(self): can_see = CanSeeAllBranches.emit() if can_see is not None: return can_see user = self.get_current_user(self.get_default_store()) if user.profile.check_app_permission(u'admin'): return True return not api.sysparam.get_bool('SYNCHRONIZED_MODE')
[docs] def get_branches_for_filter(self, store, use_id=False): """Returns a list of branches to be used in a combo. :param use_id: If True, we will return the options using the object id instead of the real object. """ if not api.can_see_all_branches(): current = self.get_current_branch(store) if use_id: value = current.id else: value = current items = [(current.get_description(), value)] else: branches = Branch.get_active_branches(store) if use_id: items = [(b.get_description(), b.id) for b in branches] else: items = [(b.get_description(), b) for b in branches] items.insert(0, (_("Any"), None)) return items
[docs] def escape(self, string): """Escapes the text and makes it suitable for use with a PangoMarkup, usually via Label.set_markup()""" import glib if string is None: string = '' if isinstance(string, (safe_str, safe_unicode)): return string return unicode(glib.markup_escape_text(string))
[docs] def prepare_test(self): """Prepares to run a standalone test. This initializes Stoq and creates a store and returns an example creator. :returns: an :py:class:`~stoqlib.domain.exampledata.ExampleCreator` """ # FIXME: We need to move this into stoqlib from stoq.gui.shell.bootstrap import boot_shell from stoq.lib.options import get_option_parser parser = get_option_parser() options = parser.parse_args(sys.argv[1:])[0] options.wizard = False options.splashscreen = False options.autoreload = False options.login_username = u'admin' options.non_fatal_warnings = False shell = boot_shell(options, initial=False) shell._dbconn.connect() shell._do_login() from stoqlib.domain.exampledata import ExampleCreator ec = ExampleCreator() store = self.new_store() ec.set_store(store) return ec
api = StoqAPI() api.sysparam = sysparam