Ejemplo n.º 1
0
 def _all_ids_(self):
     # type: () -> t.List[int]
     """Get all record IDs in the database."""
     self._ensure_real()
     return util.sql(
         self._env,
         "SELECT id FROM {}".format(self._env[self._path]._table))
Ejemplo n.º 2
0
 def __dir__(self):
     # type: () -> t.List[t.Text]
     if self._model not in self._env.registry:
         raise TypeError("Model '{}' is not installed".format(self._model))
     listing = [u"_model", u"_field", u"_listing", u"_abbrev", u"fzf_"]
     listing.extend(filter(util.is_name, util.sql(self._env,
                                                  self._listing)))
     return listing
Ejemplo n.º 3
0
 def fzf_(self):
     # type: () -> t.Optional[BaseModel]
     all_ids = util.sql(self._env,
                        "SELECT module || '.' || name FROM ir_model_data")
     res = fzf.fzf_single(all_ids)
     if not res:
         return None
     return self._env.ref(res)
Ejemplo n.º 4
0
 def __getattr__(self, attr):
     # type: (t.Text) -> Addon
     if not util.sql(self._env,
                     "SELECT name FROM ir_module_module WHERE name = %s",
                     attr):
         raise AttributeError("No module '{}'".format(attr))
     addon = Addon(self._env, attr)
     setattr(self, attr, addon)
     return addon
Ejemplo n.º 5
0
 def do_sql(self, arg):
     # type: (str) -> None
     if self.env is None:
         raise TypeError("Uninitialized debugger")
     try:
         pprint.pprint(util.sql(self.env, arg))
     except Exception as err:
         # TODO: this might also be printed by the logging
         print(err)
Ejemplo n.º 6
0
 def __getitem__(self, ind):
     # type: (t.Union[t.Iterable[int], t.Text, int, slice]) -> t.Any
     if self._real is None:
         raise KeyError("Model '{}' does not exist".format(self._path))
     if not ind:
         return self._real
     ignore_missing = False
     if isinstance(ind, slice) or isinstance(ind, int) and ind < 0:
         max_id = util.sql(
             self._env,
             'SELECT id FROM "{}" ORDER BY id DESC LIMIT 1'.format(
                 self._real._table),
         )[0]
         ind = range(max_id + 1)[ind]
         ignore_missing = True
     if isinstance(ind, Text):
         if ind in self._real._fields:
             return fields.FieldProxy(self._env, self._real._fields[ind])
         thing = getattr(self._real, ind)
         if callable(thing):
             return methods.MethodProxy(thing, self._real, ind)
         return thing
     if isinstance(ind, abc.Iterable):
         assert not isinstance(ind, Text)
         ind = tuple(ind)
     if not isinstance(ind, tuple):
         ind = (ind, )
     # Browsing a non-existent record can cause weird caching problems, so
     # check first
     real_ind = set(
         util.sql(
             self._env,
             'SELECT id FROM "{}" WHERE id IN %s'.format(self._real._table),
             ind,
         ))
     missing = set(ind) - real_ind
     if missing:
         if ignore_missing:
             ind = sorted(real_ind)
         else:
             raise KeyError("Records {} do not exist".format(", ".join(
                 map(str, missing))))
     return self._real.browse(ind)
Ejemplo n.º 7
0
 def __getattr__(self, attr):
     # type: (t.Text) -> DataModuleBrowser
     if not util.sql(
             self._env,
             "SELECT id FROM ir_model_data WHERE module = %s LIMIT 1",
             attr):
         raise AttributeError("No module '{}'".format(attr))
     browser = DataModuleBrowser(self._env, attr)
     setattr(self, attr, browser)
     return browser
Ejemplo n.º 8
0
 def __getitem__(self, key):
     # type: (t.Text) -> BaseModel
     try:
         return self._env.ref("{}.{}".format(self._module, key))
     except ValueError as err:
         raise KeyError(err)
     except AttributeError as err:
         if err.args == ("environments", ) and not key.startswith("_"):
             # Threading issue, try to keep autocomplete working
             # See RecordBrowser.__getattr__
             model = util.sql(
                 self._env,
                 "SELECT model FROM ir_model_data WHERE module = %s AND name = %s",
                 self._module,
                 key,
             )  # type: t.List[str]
             return self._env[model[0]]
         raise
Ejemplo n.º 9
0
def search(
        model,  # type: BaseModel
        args,  # type: t.Sequence[object]
        field_vals,  # type: t.Dict[str, t.Any]
):
    # type: (...) -> BaseModel
    # if count=True, this returns an int, but that may not be worth annotating
    # TODO:
    # - inspect fields
    # - handle 2many relations
    offset = field_vals.pop("offset", 0)  # type: int
    limit = field_vals.pop("limit", None)  # type: t.Optional[int]
    order = field_vals.pop("order", "id")  # type: t.Optional[t.Text]
    count = field_vals.pop("count", False)  # type: bool
    shuf = field_vals.pop("shuf", None)  # type: t.Optional[int]
    if not field_vals.pop("active_test", True):
        model = model.with_context(active_test=False)
    if shuf and not (args or field_vals or offset or limit or count):
        # Doing a search seeds the cache with IDs, which tanks performance
        # Odoo will compute fields on many records at once even though you
        # won't use them
        query = "SELECT id FROM {}".format(model._table)
        if "active" in model._fields and not model._fields["active"].related:
            # TODO: handle related active fields
            query += " WHERE active = true"
        all_ids = util.sql(model.env, query)
        shuf = min(shuf, len(all_ids))
        return model.browse(random.sample(all_ids, shuf))
    clauses = _parse_search_query(args, field_vals, model)
    result = model.search(clauses,
                          offset=offset,
                          limit=limit,
                          order=order,
                          count=count)
    if shuf:
        shuf = min(shuf, len(result))
        return result.browse(random.sample(result._ids, shuf))
    return result
Ejemplo n.º 10
0
    def grep_(*args, **kwargs):
        # type: (object, object) -> None
        """grep through all installed addons.

        See help(odoo_repl.grep) for more information.
        """
        argv = grep.build_grep_argv(args, kwargs, recursive=True)
        mods = util.sql(
            env,
            "SELECT name FROM ir_module_module WHERE state = 'installed'",
        )
        paths = [
            odoo.modules.module.get_module_path(mod, display_warning=False)
            for mod in mods
            # The `base` module is typically included inside the odoo module
            # and we don't want to search it twice
            # A more principled way to filter it out would be to check all
            # addons for being a subdirectory of `odoo`
            if mod != "base"
        ]
        paths.append(os.path.dirname(odoo.__file__))
        argv.extend(os.path.realpath(path) for path in paths if path)
        subprocess.Popen(argv).wait()
Ejemplo n.º 11
0
def create_namespace(
        db,  # type: t.Union[None, t.Text, odoo.sql_db.Cursor, odoo.api.Environment]
):
    # type: (...) -> t.Tuple[odoo.api.Environment, t.Dict[str, t.Any]]
    global xml_thread
    if not hasattr(odoo, "tools"):
        raise RuntimeError(
            "Odoo is not imported. You should run this from an Odoo shell.")
    if db is None or isinstance(db, Text):
        db_name = db or odoo.tools.config["db_name"]
        if not db_name:
            raise ValueError(
                "Can't determine database name. Run with `-- -d dbname` "
                "or pass it as the first argument to odoo_repl.enable().")
        cursor = odoo.sql_db.db_connect(db_name).cursor()
        atexit.register(cursor.close)
        if not hasattr(odoo.api.Environment._local, "environments"):
            odoo.api.Environment._local.environments = odoo.api.Environments()
        env = odoo.api.Environment(cursor, odoo.SUPERUSER_ID, {})
    elif isinstance(db, odoo.sql_db.Cursor):
        env = odoo.api.Environment(db, odoo.SUPERUSER_ID, {})
    elif isinstance(db, odoo.api.Environment):
        env = db
    else:
        raise TypeError(db)

    envproxy = EnvProxy(env)
    util.env = env

    def grep_(*args, **kwargs):
        # type: (object, object) -> None
        """grep through all installed addons.

        See help(odoo_repl.grep) for more information.
        """
        argv = grep.build_grep_argv(args, kwargs, recursive=True)
        mods = util.sql(
            env,
            "SELECT name FROM ir_module_module WHERE state = 'installed'",
        )
        paths = [
            odoo.modules.module.get_module_path(mod, display_warning=False)
            for mod in mods
            # The `base` module is typically included inside the odoo module
            # and we don't want to search it twice
            # A more principled way to filter it out would be to check all
            # addons for being a subdirectory of `odoo`
            if mod != "base"
        ]
        paths.append(os.path.dirname(odoo.__file__))
        argv.extend(os.path.realpath(path) for path in paths if path)
        subprocess.Popen(argv).wait()

    def translate(text):
        # type: (t.Text) -> None
        translations = env["ir.translation"].search(
            ["|", ("src", "=", text), ("value", "=", text)])
        if not translations:
            text = "%" + text + "%"
            translations = env["ir.translation"].search(
                ["|", ("src", "ilike", text), ("value", "ilike", text)])
        odoo_print(translations)

    def open_():
        # type: () -> None
        util.open_browser(util.generate_url())

    namespace = {
        "self": env.user,
        "odoo": odoo,
        "openerp": odoo,
        "sql": functools.partial(util.sql, env),
        "grep_": grep_,
        "open_": open_,
        "translate": translate,
        "env": envproxy,
        "u": shorthand.UserBrowser(env),
        "emp": shorthand.EmployeeBrowser(env),
        "ref": shorthand.DataBrowser(env),
        "addons": addons.AddonBrowser(env),
    }  # type: t.Dict[str, t.Any]
    namespace.update({
        part: models.ModelProxy(env, part)
        for part in envproxy._base_parts() if not hasattr(builtins, part)
    })

    if not sources.xml_records:
        modules = util.sql(
            env,
            "SELECT name, demo FROM ir_module_module WHERE state = 'installed'",
        )
        xml_thread = threading.Thread(
            target=lambda: sources.populate_xml_records(modules))
        xml_thread.daemon = True
        xml_thread.start()

    return env, namespace
Ejemplo n.º 12
0
 def __iter__(self):
     # type: () -> t.Iterator[Addon]
     for name in util.sql(self._env, "SELECT name FROM ir_module_module"):
         yield Addon(self._env, name)
Ejemplo n.º 13
0
 def __dir__(self):
     # type: () -> t.List[t.Text]
     return util.sql(self._env, "SELECT name FROM ir_module_module")
Ejemplo n.º 14
0
 def _ipython_key_completions_(self):
     # type: () -> t.List[t.Text]
     if self._model not in self._env.registry:
         raise TypeError("Model '{}' is not installed".format(self._model))
     return util.sql(self._env, self._listing)
Ejemplo n.º 15
0
 def __dir__(self):
     # type: () -> t.List[t.Text]
     return util.sql(self._env,
                     "SELECT name FROM ir_model_data WHERE module = %s",
                     self._module)
Ejemplo n.º 16
0
 def __dir__(self):
     # type: () -> t.List[t.Text]
     return util.sql(self._env, "SELECT DISTINCT module FROM ir_model_data")