Exemple #1
0
    def oea(self, **kw):
        """login user via GECOERP Account provider"""
        dbname = kw.pop('db', None)
        if not dbname:
            dbname = db_monodb()
        if not dbname:
            return BadRequest()
        if not http.db_filter([dbname]):
            return BadRequest()

        registry = registry_get(dbname)
        with registry.cursor() as cr:
            try:
                env = api.Environment(cr, SUPERUSER_ID, {})
                provider = env.ref('auth_oauth.provider_openerp')
            except ValueError:
                return set_cookie_and_redirect('/web?db=%s' % dbname)
            assert provider._name == 'auth.oauth.provider'

        state = {
            'd': dbname,
            'p': provider.id,
            'c': {
                'no_user_creation': True
            },
        }

        kw['state'] = json.dumps(state)
        return self.signin(**kw)
Exemple #2
0
def environment():
    """ Return an environment with a new cursor for the current database; the
        cursor is committed and closed after the context block.
    """
    reg = registry(common.get_db_name())
    with reg.cursor() as cr:
        yield api.Environment(cr, SUPERUSER_ID, {})
        cr.commit()
Exemple #3
0
    def poll(self, dbname, channels, last, options=None, timeout=TIMEOUT):
        if options is None:
            options = {}
        # Dont hang ctrl-c for a poll request, we need to bypass private
        # attribute access because we dont know before starting the thread that
        # it will handle a longpolling request
        if not gecoerp.evented:
            current = threading.current_thread()
            current._Thread__daemonic = True  # PY2
            current._daemonic = True  # PY3
            # rename the thread to avoid tests waiting for a longpolling
            current.setName("openerp.longpolling.request.%s" % current.ident)

        registry = gecoerp.registry(dbname)

        # immediatly returns if past notifications exist
        with registry.cursor() as cr:
            env = api.Environment(cr, SUPERUSER_ID, {})
            notifications = env['bus.bus'].poll(channels, last, options)

        # immediatly returns in peek mode
        if options.get('peek'):
            return dict(notifications=notifications, channels=channels)

        # or wait for future ones
        if not notifications:
            if not self.started:
                # Lazy start of events listener
                self.start()

            event = self.Event()
            for channel in channels:
                self.channels.setdefault(hashable(channel), []).append(event)
            try:
                event.wait(timeout=timeout)
                with registry.cursor() as cr:
                    env = api.Environment(cr, SUPERUSER_ID, {})
                    notifications = env['bus.bus'].poll(channels,
                                                        last,
                                                        options,
                                                        force_status=True)
            except Exception:
                # timeout
                pass
        return notifications
Exemple #4
0
def _setup_inalterability(cr, registry):
    env = api.Environment(cr, SUPERUSER_ID, {})
    # enable ping for this module
    env['publisher_warranty.contract'].update_notification(cron_mode=True)

    fr_companies = env['res.company'].search([('partner_id.country_id.code', 'in', UNALTERABLE_COUNTRIES)])
    if fr_companies:
        # create the securisation sequence per company
        fr_companies._create_secure_sequence(['l10n_fr_pos_cert_sequence_id'])
Exemple #5
0
 def to_python(self, value):
     matching = re.match(self.regex, value)
     _uid = RequestUID(value=value, match=matching, converter=self)
     record_id = int(matching.group(2))
     env = api.Environment(request.cr, _uid, request.context)
     if record_id < 0:
         # limited support for negative IDs due to our slug pattern, assume abs() if not found
         if not env[self.model].browse(record_id).exists():
             record_id = abs(record_id)
     return env[self.model].browse(record_id)
Exemple #6
0
    def signin(self, **kw):
        state = json.loads(kw['state'])
        dbname = state['d']
        if not http.db_filter([dbname]):
            return BadRequest()
        provider = state['p']
        context = state.get('c', {})
        registry = registry_get(dbname)
        with registry.cursor() as cr:
            try:
                env = api.Environment(cr, SUPERUSER_ID, context)
                credentials = env['res.users'].sudo().auth_oauth(provider, kw)
                cr.commit()
                action = state.get('a')
                menu = state.get('m')
                redirect = werkzeug.url_unquote_plus(
                    state['r']) if state.get('r') else False
                url = '/web'
                if redirect:
                    url = redirect
                elif action:
                    url = '/web#action=%s' % action
                elif menu:
                    url = '/web#menu_id=%s' % menu
                resp = login_and_redirect(*credentials, redirect_url=url)
                # Since /web is hardcoded, verify user has right to land on it
                if werkzeug.urls.url_parse(
                        resp.location
                ).path == '/web' and not request.env.user.has_group(
                        'base.group_user'):
                    resp.location = '/'
                return resp
            except AttributeError:
                # auth_signup is not installed
                _logger.error(
                    "auth_signup not installed on database %s: oauth sign up cancelled."
                    % (dbname, ))
                url = "/web/login?oauth_error=1"
            except AccessDenied:
                # oauth credentials not valid, user could be on a temporary session
                _logger.info(
                    'OAuth2: access denied, redirect to main page in case a valid session exists, without setting cookies'
                )
                url = "/web/login?oauth_error=3"
                redirect = werkzeug.utils.redirect(url, 303)
                redirect.autocorrect_location_header = False
                return redirect
            except Exception as e:
                # signup error
                _logger.exception("OAuth2: %s" % str(e))
                url = "/web/login?oauth_error=2"

        return set_cookie_and_redirect(url)
Exemple #7
0
 def _auth_method_public(cls):
     """ If no user logged, set the public user of current website, or default
         public user as request uid.
         After this method `request.env` can be called, since the `request.uid` is
         set. The `env` lazy property of `request` will be correct.
     """
     if not request.session.uid:
         env = api.Environment(request.cr, SUPERUSER_ID, request.context)
         website = env['website'].get_current_website()
         if website and website.user_id:
             request.uid = website.user_id.id
     if not request.uid:
         super(Http, cls)._auth_method_public()
Exemple #8
0
def _setup_inalterability(cr, registry):
    env = api.Environment(cr, SUPERUSER_ID, {})
    # enable ping for this module
    env['publisher_warranty.contract'].update_notification(cron_mode=True)

    fr_companies = env['res.company'].search([('partner_id.country_id.code', 'in', UNALTERABLE_COUNTRIES)])
    if fr_companies:
        # create the securisation sequence per company
        fr_companies._create_secure_sequence(['l10n_fr_secure_sequence_id'])

        #reset the update_posted field on journals
        journals = env['account.journal'].search([('company_id', 'in', fr_companies.ids)])
        journals.write({'update_posted': False})
Exemple #9
0
def _set_accounts(cr, registry):
    #write the default debit account on salary rule having xml_id like 'l10n_be_hr_payroll.1' up to 'l10n_be_hr_payroll.1409'
    env = api.Environment(cr, SUPERUSER_ID, {})
    names = [str(x) for x in range(1, 1410)]
    data = env['ir.model.data'].search([('model', '=', 'hr.salary.rule'),
                                        ('module', '=', 'l10n_be_hr_payroll'),
                                        ('name', 'in', names)])
    account = env['account.account'].search([('code', 'like', '4530%')],
                                            limit=1)
    if account and data:
        rule_ids = [x['res_id'] for x in data.read(['res_id'])]
        env['hr.salary.rule'].browse(rule_ids).write(
            {'account_debit': account.id})
Exemple #10
0
 def receive(self, req):
     """ End-point to receive mail from an external SMTP server. """
     dbs = req.jsonrequest.get('databases')
     for db in dbs:
         message = base64.b64decode(dbs[db])
         try:
             db_registry = registry(db)
             with db_registry.cursor() as cr:
                 env = api.Environment(cr, SUPERUSER_ID, {})
                 env['mail.thread'].message_process(None, message)
         except psycopg2.Error:
             pass
     return True
Exemple #11
0
def post_init(cr, registry):
    """ Set the timesheet project and task on existing leave type. Do it in post_init to
        be sure the internal project/task of res.company are set. (Since timesheet_generate field
        is true by default, those 2 fields are required on the leave type).
    """
    from gecoerp import api, SUPERUSER_ID

    env = api.Environment(cr, SUPERUSER_ID, {})
    for leave_type in env['hr.holidays.status'].search([('timesheet_generate', '=', True), ('timesheet_project_id', '=', False)]):
        company = leave_type.company_id or env.user.company_id
        leave_type.write({
            'timesheet_project_id': company.leave_timesheet_project_id.id,
            'timesheet_task_id': company.leave_timesheet_task_id.id,
        })
Exemple #12
0
 def check(cls, db, uid, passwd):
     """Verifies that the given (uid, password) is authorized for the database ``db`` and
        raise an exception if it is not."""
     if not passwd:
         # empty passwords disallowed for obvious security reasons
         raise AccessDenied()
     db = cls.pool.db_name
     if cls.__uid_cache[db].get(uid) == passwd:
         return
     cr = cls.pool.cursor()
     try:
         self = api.Environment(cr, uid, {})[cls._name]
         self.check_credentials(passwd)
         cls.__uid_cache[db][uid] = passwd
     finally:
         cr.close()
Exemple #13
0
def _auto_install_l10n(cr, registry):
    #check the country of the main company (only) and eventually load some module needed in that country
    env = api.Environment(cr, SUPERUSER_ID, {})
    country_code = env.user.company_id.country_id.code
    if country_code:
        #auto install localization module(s) if available
        module_list = []
        if country_code in SYSCOHADA_LIST:
            #countries using OHADA Chart of Accounts
            module_list.append('l10n_syscohada')
        elif country_code == 'GB':
            module_list.append('l10n_uk')
        elif country_code == 'DE':
            module_list.append('l10n_de_skr03')
            module_list.append('l10n_de_skr04')
        else:
            if env['ir.module.module'].search([
                ('name', '=', 'l10n_' + country_code.lower())
            ]):
                module_list.append('l10n_' + country_code.lower())
            else:
                module_list.append('l10n_generic_coa')
        if country_code == 'US':
            module_list.append('account_plaid')
            module_list.append('account_check_printing')
        if country_code in [
                'US', 'AU', 'NZ', 'CA', 'CO', 'EC', 'ES', 'FR', 'IN', 'MX',
                'UK'
        ]:
            module_list.append('account_yodlee')
        if country_code in SYSCOHADA_LIST + [
                'AT', 'BE', 'CA', 'CO', 'DE', 'EC', 'ES', 'ET', 'FR', 'GR',
                'IT', 'LU', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'SI', 'TR',
                'UK', 'VE', 'VN'
        ]:
            module_list.append('base_vat')

        #european countries will be using SEPA
        europe = env.ref('base.europe', raise_if_not_found=False)
        if europe:
            europe_country_codes = [x.code for x in europe.country_ids]
            if country_code in europe_country_codes:
                module_list.append('account_sepa')
        module_ids = env['ir.module.module'].search([
            ('name', 'in', module_list), ('state', '=', 'uninstalled')
        ])
        module_ids.sudo().button_install()
Exemple #14
0
    def setUp(self):
        self.registry = gecoerp.registry(get_db_name())
        #: current transaction's cursor
        self.cr = self.cursor()
        self.uid = gecoerp.SUPERUSER_ID
        #: :class:`~gecoerp.api.Environment` for the current test case
        self.env = api.Environment(self.cr, self.uid, {})

        @self.addCleanup
        def reset():
            # rollback and close the cursor, and reset the environments
            self.registry.clear_caches()
            self.registry.reset_changes()
            self.env.reset()
            self.cr.rollback()
            self.cr.close()

        self.patch(type(self.env['res.partner']), '_get_gravatar_image',
                   lambda *a: False)
Exemple #15
0
    def _process_job(cls, job_cr, job, cron_cr):
        """ Run a given job taking care of the repetition.

        :param job_cr: cursor to use to execute the job, safe to commit/rollback
        :param job: job to be run (as a dictionary).
        :param cron_cr: cursor holding lock on the cron job row, to use to update the next exec date,
            must not be committed/rolled back!
        """
        try:
            with api.Environment.manage():
                cron = api.Environment(job_cr, job['user_id'], {})[cls._name]
                # Use the user's timezone to compare and compute datetimes,
                # otherwise unexpected results may appear. For instance, adding
                # 1 month in UTC to July 1st at midnight in GMT+2 gives July 30
                # instead of August 1st!
                now = fields.Datetime.context_timestamp(cron, datetime.now())
                nextcall = fields.Datetime.context_timestamp(
                    cron, fields.Datetime.from_string(job['nextcall']))
                numbercall = job['numbercall']

                ok = False
                while nextcall < now and numbercall:
                    if numbercall > 0:
                        numbercall -= 1
                    if not ok or job['doall']:
                        cron._callback(job['cron_name'],
                                       job['ir_actions_server_id'], job['id'])
                    if numbercall:
                        nextcall += _intervalTypes[job['interval_type']](
                            job['interval_number'])
                    ok = True
                addsql = ''
                if not numbercall:
                    addsql = ', active=False'
                cron_cr.execute(
                    "UPDATE ir_cron SET nextcall=%s, numbercall=%s" + addsql +
                    " WHERE id=%s", (fields.Datetime.to_string(
                        nextcall.astimezone(pytz.UTC)), numbercall, job['id']))
                cron.invalidate_cache()

        finally:
            job_cr.commit()
            cron_cr.commit()
Exemple #16
0
 def _login(cls, db, login, password):
     user_id = super(Users, cls)._login(db, login, password)
     if user_id:
         return user_id
     with registry(db).cursor() as cr:
         cr.execute("SELECT id FROM res_users WHERE lower(login)=%s",
                    (login, ))
         res = cr.fetchone()
         if res:
             return False
         env = api.Environment(cr, SUPERUSER_ID, {})
         Ldap = env['res.company.ldap']
         for conf in Ldap.get_ldap_dicts():
             entry = Ldap.authenticate(conf, login, password)
             if entry:
                 user_id = Ldap.get_or_create_user(conf, login, entry)
                 if user_id:
                     break
         return user_id
Exemple #17
0
    def _login(cls, db, login, password):
        if not password:
            return False
        user_id = False
        try:
            with cls.pool.cursor() as cr:
                self = api.Environment(cr, SUPERUSER_ID, {})[cls._name]
                user = self.search([('login', '=', login)])
                if user:
                    user_id = user.id
                    user.sudo(user_id).check_credentials(password)
                    user.sudo(user_id)._update_last_login()
        except AccessDenied:
            user_id = False

        status = "successful" if user_id else "failed"
        ip = request.httprequest.environ['REMOTE_ADDR'] if request else 'n/a'
        _logger.info("Login %s for db:%s login:%s from %s", status, db, login, ip)

        return user_id
Exemple #18
0
    def log_xml(self, xml_string, func):
        self.ensure_one()

        if self.debug_logging:
            db_name = self._cr.dbname

            # Use a new cursor to avoid rollback that could be caused by an upper method
            try:
                db_registry = registry(db_name)
                with db_registry.cursor() as cr:
                    env = api.Environment(cr, SUPERUSER_ID, {})
                    IrLogging = env['ir.logging']
                    IrLogging.sudo().create({
                        'name': 'delivery.carrier',
                        'type': 'server',
                        'dbname': db_name,
                        'level': 'DEBUG',
                        'message': xml_string,
                        'path': self.delivery_type,
                        'func': func,
                        'line': 1
                    })
            except psycopg2.Error:
                pass
Exemple #19
0
    def _serve_attachment(cls):
        env = api.Environment(request.cr, SUPERUSER_ID, request.context)
        domain = [('type', '=', 'binary'),
                  ('url', '=', request.httprequest.path)]
        fields = ['__last_update', 'datas', 'name', 'mimetype', 'checksum']
        attach = env['ir.attachment'].search_read(domain, fields)
        if attach:
            wdate = attach[0]['__last_update']
            datas = attach[0]['datas'] or b''
            name = attach[0]['name']
            checksum = attach[0]['checksum'] or hashlib.sha1(datas).hexdigest()

            if (not datas and name != request.httprequest.path
                    and name.startswith(('http://', 'https://', '/'))):
                return werkzeug.utils.redirect(name, 301)

            response = werkzeug.wrappers.Response()
            server_format = tools.DEFAULT_SERVER_DATETIME_FORMAT
            try:
                response.last_modified = datetime.datetime.strptime(
                    wdate, server_format + '.%f')
            except ValueError:
                # just in case we have a timestamp without microseconds
                response.last_modified = datetime.datetime.strptime(
                    wdate, server_format)

            response.set_etag(checksum)
            response.make_conditional(request.httprequest)

            if response.status_code == 304:
                return response

            response.mimetype = attach[0][
                'mimetype'] or 'application/octet-stream'
            response.data = base64.b64decode(datas)
            return response
Exemple #20
0
    def authenticate(self, user, password):
        # stay non-authenticated
        if user is None:
            return

        db = get_db_name()
        uid = self.registry['res.users'].authenticate(db, user, password, None)
        env = api.Environment(self.cr, uid, {})

        # self.session.authenticate(db, user, password, uid=uid)
        # OpenERPSession.authenticate accesses the current request, which we
        # don't have, so reimplement it manually...
        session = self.session

        session.db = db
        session.uid = uid
        session.login = user
        session.session_token = uid and security.compute_session_token(
            session, env)
        session.context = env['res.users'].context_get() or {}
        session.context['uid'] = uid
        session._fix_lang(session.context)

        gecoerp.http.root.session_store.save(session)
Exemple #21
0
 def authenticate(cls, db, login, password, user_agent_env):
     """Verifies and returns the user ID corresponding to the given
       ``login`` and ``password`` combination, or False if there was
       no matching user.
        :param str db: the database on which user is trying to authenticate
        :param str login: username
        :param str password: user password
        :param dict user_agent_env: environment dictionary describing any
            relevant environment attributes
     """
     uid = cls._login(db, login, password)
     if uid == SUPERUSER_ID:
         # Successfully logged in as admin!
         # Attempt to guess the web base url...
         if user_agent_env and user_agent_env.get('base_location'):
             try:
                 with cls.pool.cursor() as cr:
                     base = user_agent_env['base_location']
                     ICP = api.Environment(cr, uid, {})['ir.config_parameter']
                     if not ICP.get_param('web.base.url.freeze'):
                         ICP.set_param('web.base.url', base)
             except Exception:
                 _logger.exception("Failed to update web.base.url configuration parameter")
     return uid
Exemple #22
0
def uninstall_hook(cr, registry):
    env = api.Environment(cr, SUPERUSER_ID, {})
    env['product.template'].search([('service_type', '=', 'timesheet')
                                    ]).write({'service_type': 'manual'})
    env['product.product'].search([('service_type', '=', 'timesheet')
                                   ]).write({'service_type': 'manual'})
Exemple #23
0
def load_translations(cr, registry):
    env = api.Environment(cr, SUPERUSER_ID, {})
    env.ref('l10n_sa.account_arabic_coa_general').process_coa_translations()
Exemple #24
0
    def finish(self):
        """ Transfer the data from the temp table to ir.translation """
        cr = self._cr
        if self._debug:
            cr.execute("SELECT count(*) FROM %s" % self._table)
            count = cr.fetchone()[0]
            _logger.debug(
                "ir.translation.cursor: We have %d entries to process", count)

        # Step 1: resolve ir.model.data references to res_ids
        cr.execute(""" UPDATE %s AS ti
                          SET res_id = imd.res_id,
                              noupdate = imd.noupdate
                       FROM ir_model_data AS imd
                       WHERE ti.res_id IS NULL
                       AND ti.module IS NOT NULL AND ti.imd_name IS NOT NULL
                       AND ti.module = imd.module AND ti.imd_name = imd.name
                       AND ti.imd_model = imd.model; """ % self._table)

        if self._debug:
            cr.execute(""" SELECT module, imd_name, imd_model FROM %s
                           WHERE res_id IS NULL AND module IS NOT NULL """ %
                       self._table)
            for row in cr.fetchall():
                _logger.info(
                    "ir.translation.cursor: missing res_id for %s.%s <%s> ",
                    *row)

        # Records w/o res_id must _not_ be inserted into our db, because they are
        # referencing non-existent data.
        cr.execute(
            "DELETE FROM %s WHERE res_id IS NULL AND module IS NOT NULL" %
            self._table)

        # detect the xml_translate fields, where the src must be the same
        env = api.Environment(cr, SUPERUSER_ID, {})
        src_relevant_fields = []
        for model in env:
            for field_name, field in env[model]._fields.items():
                if hasattr(field, 'translate') and callable(field.translate):
                    src_relevant_fields.append("%s,%s" % (model, field_name))

        find_expr = """
                irt.lang = ti.lang
            AND irt.type = ti.type
            AND irt.name = ti.name
            AND (
                    (ti.type = 'model' AND ti.res_id = irt.res_id AND ti.name IN %s AND irt.src = ti.src)
                 OR (ti.type = 'model' AND ti.res_id = irt.res_id AND ti.name NOT IN %s)
                 OR (ti.type = 'view' AND (irt.res_id IS NULL OR ti.res_id = irt.res_id) AND irt.src = ti.src)
                 OR (ti.type = 'field')
                 OR (ti.type = 'help')
                 OR (ti.type NOT IN ('model', 'view', 'field', 'help') AND irt.src = ti.src)
            )
        """

        # Step 2: update existing (matching) translations
        if self._overwrite:
            cr.execute(
                """ UPDATE ONLY %s AS irt
                           SET value = ti.value,
                               src = ti.src,
                               state = 'translated'
                           FROM %s AS ti
                          WHERE %s
                            AND ti.value IS NOT NULL
                            AND ti.value != ''
                            AND noupdate IS NOT TRUE
                       """ % (self._model_table, self._table, find_expr),
                (tuple(src_relevant_fields), tuple(src_relevant_fields)))

        # Step 3: insert new translations
        cr.execute(
            """ INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments)
                       SELECT name, lang, res_id, src, type, value, module, state, comments
                       FROM %s AS ti
                       WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s);
                   """ %
            (self._model_table, self._table, self._model_table, find_expr),
            (tuple(src_relevant_fields), tuple(src_relevant_fields)))

        if self._debug:
            cr.execute("SELECT COUNT(*) FROM ONLY %s" % self._model_table)
            total = cr.fetchone()[0]
            cr.execute("SELECT COUNT(*) FROM ONLY %s AS irt, %s AS ti WHERE %s" % \
                       (self._model_table, self._table, find_expr),
                       (tuple(src_relevant_fields), tuple(src_relevant_fields)))
            count = cr.fetchone()[0]
            _logger.debug(
                "ir.translation.cursor: %d entries now in ir.translation, %d common entries with tmp",
                total, count)

        # Step 4: cleanup
        cr.execute("DROP TABLE %s" % self._table)
        return True
Exemple #25
0
 def change_digit(cr):
     env = api.Environment(cr, SUPERUSER_ID, {})
     precision = env['decimal.precision'].precision_get(application)
     return 16, precision
Exemple #26
0
def load_module_graph(cr, graph, status=None, perform_checks=True,
                      skip_modules=None, report=None, models_to_check=None):
    """Migrates+Updates or Installs all module nodes from ``graph``
       :param graph: graph of module nodes to load
       :param status: deprecated parameter, unused, left to avoid changing signature in 8.0
       :param perform_checks: whether module descriptors should be checked for validity (prints warnings
                              for same cases)
       :param skip_modules: optional list of module names (packages) which have previously been loaded and can be skipped
       :return: list of modules that were installed or updated
    """
    def load_test(module_name, idref, mode):
        cr.commit()
        try:
            _load_data(cr, module_name, idref, mode, 'test')
            return True
        except Exception:
            _test_logger.exception(
                'module %s: an exception occurred in a test', module_name)
            return False
        finally:
            if tools.config.options['test_commit']:
                cr.commit()
            else:
                cr.rollback()
                # avoid keeping stale xml_id, etc. in cache
                gecoerp.registry(cr.dbname).clear_caches()


    def _get_files_of_kind(kind):
        if kind == 'demo':
            kind = ['demo_xml', 'demo']
        elif kind == 'data':
            kind = ['init_xml', 'update_xml', 'data']
        if isinstance(kind, str):
            kind = [kind]
        files = []
        for k in kind:
            for f in package.data[k]:
                files.append(f)
                if k.endswith('_xml') and not (k == 'init_xml' and not f.endswith('.xml')):
                    # init_xml, update_xml and demo_xml are deprecated except
                    # for the case of init_xml with yaml, csv and sql files as
                    # we can't specify noupdate for those file.
                    correct_key = 'demo' if k.count('demo') else 'data'
                    _logger.warning(
                        "module %s: key '%s' is deprecated in favor of '%s' for file '%s'.",
                        package.name, k, correct_key, f
                    )
        return files

    def _load_data(cr, module_name, idref, mode, kind):
        """

        kind: data, demo, test, init_xml, update_xml, demo_xml.

        noupdate is False, unless it is demo data or it is csv data in
        init mode.

        """
        try:
            if kind in ('demo', 'test'):
                threading.currentThread().testing = True
            for filename in _get_files_of_kind(kind):
                _logger.info("loading %s/%s", module_name, filename)
                noupdate = False
                if kind in ('demo', 'demo_xml') or (filename.endswith('.csv') and kind in ('init', 'init_xml')):
                    noupdate = True
                tools.convert_file(cr, module_name, filename, idref, mode, noupdate, kind, report)
        finally:
            if kind in ('demo', 'test'):
                threading.currentThread().testing = False

    if models_to_check is None:
        models_to_check = set()

    processed_modules = []
    loaded_modules = []
    registry = gecoerp.registry(cr.dbname)
    migrations = gecoerp.modules.migration.MigrationManager(cr, graph)
    module_count = len(graph)
    _logger.info('loading %d modules...', module_count)

    registry.clear_caches()

    # register, instantiate and initialize models for each modules
    t0 = time.time()
    t0_sql = gecoerp.sql_db.sql_counter

    models_updated = set()

    for index, package in enumerate(graph, 1):
        module_name = package.name
        module_id = package.id

        if skip_modules and module_name in skip_modules:
            continue

        _logger.debug('loading module %s (%d/%d)', module_name, index, module_count)

        needs_update = (
            hasattr(package, "init")
            or hasattr(package, "update")
            or package.state in ("to install", "to upgrade")
        )
        if needs_update:
            if package.name != 'base':
                registry.setup_models(cr)
            migrations.migrate_module(package, 'pre')

        load_openerp_module(package.name)

        new_install = package.state == 'to install'
        if new_install:
            py_module = sys.modules['gecoerp.addons.%s' % (module_name,)]
            pre_init = package.info.get('pre_init_hook')
            if pre_init:
                getattr(py_module, pre_init)(cr)

        model_names = registry.load(cr, package)

        loaded_modules.append(package.name)
        if needs_update:
            models_updated |= set(model_names)
            models_to_check -= set(model_names)
            registry.setup_models(cr)
            registry.init_models(cr, model_names, {'module': package.name})
            cr.commit()
        elif package.state != 'to remove':
            # The current module has simply been loaded. The models extended by this module
            # and for which we updated the schema, must have their schema checked again.
            # This is because the extension may have changed the model,
            # e.g. adding required=True to an existing field, but the schema has not been
            # updated by this module because it's not marked as 'to upgrade/to install'.
            models_to_check |= set(model_names) & models_updated

        idref = {}

        mode = 'update'
        if hasattr(package, 'init') or package.state == 'to install':
            mode = 'init'

        if needs_update:
            env = api.Environment(cr, SUPERUSER_ID, {})
            # Can't put this line out of the loop: ir.module.module will be
            # registered by init_models() above.
            module = env['ir.module.module'].browse(module_id)

            if perform_checks:
                module._check()

            if package.state=='to upgrade':
                # upgrading the module information
                module.write(module.get_values_from_terp(package.data))
            _load_data(cr, module_name, idref, mode, kind='data')
            has_demo = hasattr(package, 'demo') or (package.dbdemo and package.state != 'installed')
            if has_demo:
                _load_data(cr, module_name, idref, mode, kind='demo')
                cr.execute('update ir_module_module set demo=%s where id=%s', (True, module_id))
                module.invalidate_cache(['demo'])

            migrations.migrate_module(package, 'post')

            # Update translations for all installed languages
            overwrite = gecoerp.tools.config["overwrite_existing_translations"]
            module.with_context(overwrite=overwrite)._update_translations()

            if package.name is not None:
                registry._init_modules.add(package.name)

            if new_install:
                post_init = package.info.get('post_init_hook')
                if post_init:
                    getattr(py_module, post_init)(cr, registry)

            # validate all the views at a whole
            env['ir.ui.view']._validate_module_views(module_name)

            if has_demo:
                # launch tests only in demo mode, allowing tests to use demo data.
                if tools.config.options['test_enable']:
                    # Yamel test
                    report.record_result(load_test(module_name, idref, mode))
                    # Python tests
                    env['ir.http']._clear_routing_map()     # force routing map to be rebuilt
                    report.record_result(gecoerp.modules.module.run_unit_tests(module_name, cr.dbname))
                    # tests may have reset the environment
                    env = api.Environment(cr, SUPERUSER_ID, {})
                    module = env['ir.module.module'].browse(module_id)

            processed_modules.append(package.name)

            ver = adapt_version(package.data['version'])
            # Set new modules and dependencies
            module.write({'state': 'installed', 'latest_version': ver})

            package.load_state = package.state
            package.load_version = package.installed_version
            package.state = 'installed'
            for kind in ('init', 'demo', 'update'):
                if hasattr(package, kind):
                    delattr(package, kind)

        if package.name is not None:
            registry._init_modules.add(package.name)
        cr.commit()

    _logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, gecoerp.sql_db.sql_counter - t0_sql)

    registry.clear_caches()

    cr.commit()

    return loaded_modules, processed_modules
Exemple #27
0
def load_modules(db, force_demo=False, status=None, update_module=False):
    initialize_sys_path()

    force = []
    if force_demo:
        force.append('demo')

    models_to_check = set()

    cr = db.cursor()
    try:
        if not gecoerp.modules.db.is_initialized(cr):
            _logger.info("init db")
            gecoerp.modules.db.initialize(cr)
            update_module = True # process auto-installed modules
            tools.config["init"]["all"] = 1
            tools.config['update']['all'] = 1
            if not tools.config['without_demo']:
                tools.config["demo"]['all'] = 1

        # This is a brand new registry, just created in
        # gecoerp.modules.registry.Registry.new().
        registry = gecoerp.registry(cr.dbname)

        if 'base' in tools.config['update'] or 'all' in tools.config['update']:
            cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))

        # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
        graph = gecoerp.modules.graph.Graph()
        graph.add_module(cr, 'base', force)
        if not graph:
            _logger.critical('module base cannot be loaded! (hint: verify addons-path)')
            raise ImportError('Module `base` cannot be loaded! (hint: verify addons-path)')

        # processed_modules: for cleanup step after install
        # loaded_modules: to avoid double loading
        report = registry._assertion_report
        loaded_modules, processed_modules = load_module_graph(
            cr, graph, status, perform_checks=update_module,
            report=report, models_to_check=models_to_check)

        load_lang = tools.config.pop('load_language')
        if load_lang or update_module:
            # some base models are used below, so make sure they are set up
            registry.setup_models(cr)

        if load_lang:
            for lang in load_lang.split(','):
                tools.load_language(cr, lang)

        # STEP 2: Mark other modules to be loaded/updated
        if update_module:
            env = api.Environment(cr, SUPERUSER_ID, {})
            Module = env['ir.module.module']
            _logger.info('updating modules list')
            Module.update_list()

            _check_module_names(cr, itertools.chain(tools.config['init'], tools.config['update']))

            module_names = [k for k, v in tools.config['init'].items() if v]
            if module_names:
                modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)])
                if modules:
                    modules.button_install()

            module_names = [k for k, v in tools.config['update'].items() if v]
            if module_names:
                modules = Module.search([('state', '=', 'installed'), ('name', 'in', module_names)])
                if modules:
                    modules.button_upgrade()

            cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
            Module.invalidate_cache(['state'])


        # STEP 3: Load marked modules (skipping base which was done in STEP 1)
        # IMPORTANT: this is done in two parts, first loading all installed or
        #            partially installed modules (i.e. installed/to upgrade), to
        #            offer a consistent system to the second part: installing
        #            newly selected modules.
        #            We include the modules 'to remove' in the first step, because
        #            they are part of the "currently installed" modules. They will
        #            be dropped in STEP 6 later, before restarting the loading
        #            process.
        # IMPORTANT 2: We have to loop here until all relevant modules have been
        #              processed, because in some rare cases the dependencies have
        #              changed, and modules that depend on an uninstalled module
        #              will not be processed on the first pass.
        #              It's especially useful for migrations.
        previously_processed = -1
        while previously_processed < len(processed_modules):
            previously_processed = len(processed_modules)
            processed_modules += load_marked_modules(cr, graph,
                ['installed', 'to upgrade', 'to remove'],
                force, status, report, loaded_modules, update_module, models_to_check)
            if update_module:
                processed_modules += load_marked_modules(cr, graph,
                    ['to install'], force, status, report,
                    loaded_modules, update_module, models_to_check)

        registry.loaded = True
        registry.setup_models(cr)

        # STEP 3.5: execute migration end-scripts
        migrations = gecoerp.modules.migration.MigrationManager(cr, graph)
        for package in graph:
            migrations.migrate_module(package, 'end')

        # STEP 4: Finish and cleanup installations
        if processed_modules:
            env = api.Environment(cr, SUPERUSER_ID, {})
            cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""")
            for (model, name) in cr.fetchall():
                if model in registry and not registry[model]._abstract and not registry[model]._transient:
                    _logger.warning('The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,base.group_user,1,0,0,0',
                        model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_'))

            # Temporary warning while we remove access rights on osv_memory objects, as they have
            # been replaced by owner-only access rights
            cr.execute("""select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""")
            for (model, name) in cr.fetchall():
                if model in registry and registry[model]._transient:
                    _logger.warning('The transient model %s (%s) should not have explicit access rules!', model, name)

            cr.execute("SELECT model from ir_model")
            for (model,) in cr.fetchall():
                if model in registry:
                    env[model]._check_removed_columns(log=True)
                elif _logger.isEnabledFor(logging.INFO):    # more an info that a warning...
                    _logger.warning("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)

            # Cleanup orphan records
            env['ir.model.data']._process_end(processed_modules)

        for kind in ('init', 'demo', 'update'):
            tools.config[kind] = {}

        cr.commit()

        # STEP 5: Uninstall modules to remove
        if update_module:
            # Remove records referenced from ir_model_data for modules to be
            # removed (and removed the references from ir_model_data).
            cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
            modules_to_remove = dict(cr.fetchall())
            if modules_to_remove:
                env = api.Environment(cr, SUPERUSER_ID, {})
                pkgs = reversed([p for p in graph if p.name in modules_to_remove])
                for pkg in pkgs:
                    uninstall_hook = pkg.info.get('uninstall_hook')
                    if uninstall_hook:
                        py_module = sys.modules['gecoerp.addons.%s' % (pkg.name,)]
                        getattr(py_module, uninstall_hook)(cr, registry)

                Module = env['ir.module.module']
                Module.browse(modules_to_remove.values()).module_uninstall()
                # Recursive reload, should only happen once, because there should be no
                # modules to remove next time
                cr.commit()
                _logger.info('Reloading registry once more after uninstalling modules')
                api.Environment.reset()
                registry = gecoerp.modules.registry.Registry.new(
                    cr.dbname, force_demo, status, update_module
                )
                registry.check_tables_exist(cr)
                cr.commit()
                return registry

        # STEP 5.5: Verify extended fields on every model
        # This will fix the schema of all models in a situation such as:
        #   - module A is loaded and defines model M;
        #   - module B is installed/upgraded and extends model M;
        #   - module C is loaded and extends model M;
        #   - module B and C depend on A but not on each other;
        # The changes introduced by module C are not taken into account by the upgrade of B.
        if models_to_check:
            registry.init_models(cr, list(models_to_check), {'models_to_check': True})

        # STEP 6: verify custom views on every model
        if update_module:
            env = api.Environment(cr, SUPERUSER_ID, {})
            View = env['ir.ui.view']
            for model in registry:
                try:
                    View._validate_custom_views(model)
                except Exception as e:
                    _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e))

        if report.failures:
            _logger.error('At least one test failed when loading the modules.')
        else:
            _logger.info('Modules loaded.')

        # STEP 8: call _register_hook on every model
        env = api.Environment(cr, SUPERUSER_ID, {})
        for model in env.values():
            model._register_hook()

        # STEP 9: save installed/updated modules for post-install tests
        registry.updated_modules += processed_modules
        cr.commit()

    finally:
        cr.close()
Exemple #28
0
 def setUpClass(cls):
     cls.registry = gecoerp.registry(get_db_name())
     cls.cr = cls.registry.cursor()
     cls.uid = gecoerp.SUPERUSER_ID
     cls.env = api.Environment(cls.cr, cls.uid, {})
Exemple #29
0
def load_translations(cr, registry):
    env = api.Environment(cr, SUPERUSER_ID, {})
    env.ref('l10n_be.l10nbe_chart_template').process_coa_translations()
Exemple #30
0
def uninstall_hook(cr, registry):
    env = api.Environment(cr, SUPERUSER_ID, {})
    teams = env['crm.team'].search([('dashboard_graph_model', '=',
                                     'crm.opportunity.report')])
    teams.update({'dashboard_graph_model': None})