summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParth Gajjar (Open ERP) <pga@tinyerp.com>2014-03-28 18:48:22 +0530
committerParth Gajjar (Open ERP) <pga@tinyerp.com>2014-03-28 18:48:22 +0530
commit3de6738dbbfeb5f5dda0eae434e3ccef62aa4e8e (patch)
tree7dfdb25e57640ffdc5d12169b372bf51318dc04b
parent1ccbc213e7f39c1902d70714d0e75418155dab6d (diff)
parenta224b88d80bc5311a684a6ae59e8584a2eec9150 (diff)
merged with trunk addons
bzr revid: pga@tinyerp.com-20140328131822-0kc0f5j5qhupkhbr
-rw-r--r--addons/auth_signup/i18n/sv.po279
-rw-r--r--addons/base_import_module/__init__.py2
-rw-r--r--addons/base_import_module/__openerp__.py21
-rwxr-xr-xaddons/base_import_module/bin/oe_module_deploy.py86
-rw-r--r--addons/base_import_module/controllers/__init__.py1
-rw-r--r--addons/base_import_module/controllers/main.py73
-rw-r--r--addons/base_import_module/models/__init__.py2
-rw-r--r--addons/base_import_module/models/ir_module.py71
-rw-r--r--addons/base_import_module/tests/test_module/__openerp__.py37
-rw-r--r--addons/base_import_module/tests/test_module/static/src/img/c64.pngbin0 -> 24385 bytes
-rw-r--r--addons/base_import_module/tests/test_module/static/src/js/test.js1
-rw-r--r--addons/base_import_module/tests/test_module/test.xml45
-rw-r--r--addons/l10n_be_coda/i18n/fi.po14
-rw-r--r--addons/website/models/ir_http.py32
-rw-r--r--addons/website/models/website.py15
-rw-r--r--addons/website/static/src/js/website.editor.js3
-rw-r--r--addons/website_gengo/static/src/xml/website.gengo.xml4
17 files changed, 673 insertions, 13 deletions
diff --git a/addons/auth_signup/i18n/sv.po b/addons/auth_signup/i18n/sv.po
new file mode 100644
index 00000000000..9acedf81abc
--- /dev/null
+++ b/addons/auth_signup/i18n/sv.po
@@ -0,0 +1,279 @@
+# Swedish translation for openobject-addons
+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-12-21 17:05+0000\n"
+"PO-Revision-Date: 2014-03-27 12:30+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Swedish <sv@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2014-03-28 05:42+0000\n"
+"X-Generator: Launchpad (build 16967)\n"
+
+#. module: auth_signup
+#: field:res.partner,signup_type:0
+msgid "Signup Token Type"
+msgstr ""
+
+#. module: auth_signup
+#: field:base.config.settings,auth_signup_uninvited:0
+msgid "Allow external users to sign up"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:19
+#, python-format
+msgid "Confirm Password"
+msgstr "Bekräfta lösenord"
+
+#. module: auth_signup
+#: help:base.config.settings,auth_signup_uninvited:0
+msgid "If unchecked, only invited users may sign up."
+msgstr ""
+
+#. module: auth_signup
+#: model:ir.model,name:auth_signup.model_base_config_settings
+msgid "base.config.settings"
+msgstr "base.config.settings"
+
+#. module: auth_signup
+#: code:addons/auth_signup/res_users.py:266
+#, python-format
+msgid "Cannot send email: user has no email address."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:27
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:31
+#, python-format
+msgid "Reset password"
+msgstr "Återställ lösenord"
+
+#. module: auth_signup
+#: field:base.config.settings,auth_signup_template_user_id:0
+msgid "Template user for new users created through signup"
+msgstr ""
+
+#. module: auth_signup
+#: model:email.template,subject:auth_signup.reset_password_email
+msgid "Password reset"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:120
+#, python-format
+msgid "Please enter a password and confirm it."
+msgstr ""
+
+#. module: auth_signup
+#: view:res.users:0
+msgid "Send an email to the user to (re)set their password."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:26
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:29
+#, python-format
+msgid "Sign Up"
+msgstr ""
+
+#. module: auth_signup
+#: selection:res.users,state:0
+msgid "New"
+msgstr ""
+
+#. module: auth_signup
+#: code:addons/auth_signup/res_users.py:258
+#, python-format
+msgid "Mail sent to:"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.users,state:0
+msgid "Status"
+msgstr ""
+
+#. module: auth_signup
+#: model:email.template,body_html:auth_signup.reset_password_email
+msgid ""
+"\n"
+"<p>A password reset was requested for the OpenERP account linked to this "
+"email.</p>\n"
+"\n"
+"<p>You may change your password by following <a "
+"href=\"${object.signup_url}\">this link</a>.</p>\n"
+"\n"
+"<p>Note: If you do not expect this, you can safely ignore this email.</p>"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:114
+#, python-format
+msgid "Please enter a name."
+msgstr ""
+
+#. module: auth_signup
+#: model:ir.model,name:auth_signup.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_url:0
+msgid "Signup URL"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:117
+#, python-format
+msgid "Please enter a username."
+msgstr ""
+
+#. module: auth_signup
+#: selection:res.users,state:0
+msgid "Active"
+msgstr ""
+
+#. module: auth_signup
+#: code:addons/auth_signup/res_users.py:270
+#, python-format
+msgid ""
+"Cannot send email: no outgoing email server configured.\n"
+"You can configure it under Settings/General Settings."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:12
+#, python-format
+msgid "Username"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:8
+#, python-format
+msgid "Name"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:173
+#, python-format
+msgid "Please enter a username or email address."
+msgstr ""
+
+#. module: auth_signup
+#: selection:res.users,state:0
+msgid "Resetting Password"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:13
+#, python-format
+msgid "Username (Email)"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_expiration:0
+msgid "Signup Expiration"
+msgstr ""
+
+#. module: auth_signup
+#: help:base.config.settings,auth_signup_reset_password:0
+msgid "This allows users to trigger a password reset from the Login page."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:25
+#, python-format
+msgid "Log in"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_valid:0
+msgid "Signup Token is Valid"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:111
+#: code:addons/auth_signup/static/src/js/auth_signup.js:114
+#: code:addons/auth_signup/static/src/js/auth_signup.js:117
+#: code:addons/auth_signup/static/src/js/auth_signup.js:120
+#: code:addons/auth_signup/static/src/js/auth_signup.js:123
+#: code:addons/auth_signup/static/src/js/auth_signup.js:170
+#: code:addons/auth_signup/static/src/js/auth_signup.js:173
+#, python-format
+msgid "Login"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:97
+#, python-format
+msgid "Invalid signup token"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:123
+#, python-format
+msgid "Passwords do not match; please retype them."
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/js/auth_signup.js:111
+#: code:addons/auth_signup/static/src/js/auth_signup.js:170
+#, python-format
+msgid "No database selected !"
+msgstr ""
+
+#. module: auth_signup
+#: view:res.users:0
+msgid "Reset Password"
+msgstr ""
+
+#. module: auth_signup
+#: field:base.config.settings,auth_signup_reset_password:0
+msgid "Enable password reset from Login page"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:30
+#, python-format
+msgid "Back to Login"
+msgstr ""
+
+#. module: auth_signup
+#. openerp-web
+#: code:addons/auth_signup/static/src/xml/auth_signup.xml:22
+#, python-format
+msgid "Sign up"
+msgstr ""
+
+#. module: auth_signup
+#: model:ir.model,name:auth_signup.model_res_partner
+msgid "Partner"
+msgstr ""
+
+#. module: auth_signup
+#: field:res.partner,signup_token:0
+msgid "Signup Token"
+msgstr ""
diff --git a/addons/base_import_module/__init__.py b/addons/base_import_module/__init__.py
new file mode 100644
index 00000000000..9f86759e32b
--- /dev/null
+++ b/addons/base_import_module/__init__.py
@@ -0,0 +1,2 @@
+import controllers
+import models
diff --git a/addons/base_import_module/__openerp__.py b/addons/base_import_module/__openerp__.py
new file mode 100644
index 00000000000..ba37462642c
--- /dev/null
+++ b/addons/base_import_module/__openerp__.py
@@ -0,0 +1,21 @@
+{
+ 'name': 'Base import module',
+ 'description': """
+Import a custom data module
+===========================
+
+This module allows authorized users to import a custom data module (.xml files and static assests)
+for customization purpose.
+""",
+ 'category': 'Uncategorized',
+ 'website': 'http://www.openerp.com',
+ 'author': 'OpenERP SA',
+ 'depends': ['web'],
+ 'installable': True,
+ 'auto_install': False,
+ 'data': [],
+ 'css': [],
+ 'js': [],
+ 'qweb': [],
+ 'test': [],
+}
diff --git a/addons/base_import_module/bin/oe_module_deploy.py b/addons/base_import_module/bin/oe_module_deploy.py
new file mode 100755
index 00000000000..2412382cba5
--- /dev/null
+++ b/addons/base_import_module/bin/oe_module_deploy.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+import argparse
+import os
+import sys
+import tempfile
+import zipfile
+
+
+try:
+ import requests
+except ImportError:
+ # no multipart encoding in stdlib and this script is temporary
+ sys.exit("This script requires the 'requests' module. ( pip install requests )")
+
+session = requests.session()
+
+def deploy_module(module_path, url, login, password, db=''):
+ url = url.rstrip('/')
+ authenticate(url, login, password, db)
+ module_file = zip_module(module_path)
+ try:
+ return upload_module(url, module_file)
+ finally:
+ os.remove(module_file)
+
+def upload_module(server, module_file):
+ print("Uploading module file...")
+ url = server + '/base_import_module/upload'
+ files = dict(mod_file=open(module_file, 'rb'))
+ res = session.post(url, files=files)
+ if res.status_code != 200:
+ raise Exception("Could not authenticate on server '%s'" % server)
+ return res.text
+
+def authenticate(server, login, password, db=''):
+ print("Authenticating on server '%s' ..." % server)
+
+ # Fixate session with a given db if any
+ session.get(server + '/web/login', params=dict(db=db))
+
+ args = dict(login=login, password=password, db=db)
+ res = session.post(server + '/base_import_module/login', args)
+ if res.status_code == 404:
+ raise Exception("The server '%s' does not have the 'base_import_module' installed." % server)
+ elif res.status_code != 200:
+ raise Exception(res.text)
+
+def zip_module(path):
+ path = os.path.abspath(path)
+ if not os.path.isdir(path):
+ raise Exception("Could not find module directory '%s'" % path)
+ container, module_name = os.path.split(path)
+ temp = tempfile.mktemp(suffix='.zip')
+ try:
+ print("Zipping module directory...")
+ with zipfile.ZipFile(temp, 'w') as zfile:
+ for root, dirs, files in os.walk(path):
+ for file in files:
+ file_path = os.path.join(root, file)
+ zfile.write(file_path, file_path.split(container).pop())
+ return temp
+ except Exception:
+ os.remove(temp)
+ raise
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Deploy a module on an OpenERP server.')
+ parser.add_argument('path', help="Path of the module to deploy")
+ parser.add_argument('--url', dest='url', help='Url of the server (default=http://localhost:8069)', default="http://localhost:8069")
+ parser.add_argument('--db', dest='db', help='Database to use if server does not use db-filter.')
+ parser.add_argument('--login', dest='login', default="admin", help='Login (default=admin)')
+ parser.add_argument('--password', dest='password', default="admin", help='Password (default=admin)')
+ parser.add_argument('--no-ssl-check', dest='no_ssl_check', action='store_true', help='Do not check ssl cert')
+ if len(sys.argv) == 1:
+ sys.exit(parser.print_help())
+
+ args = parser.parse_args()
+
+ if args.no_ssl_check:
+ session.verify = False
+
+ try:
+ result = deploy_module(args.path, args.url, args.login, args.password, args.db)
+ print(result)
+ except Exception, e:
+ sys.exit("ERROR: %s" % e)
diff --git a/addons/base_import_module/controllers/__init__.py b/addons/base_import_module/controllers/__init__.py
new file mode 100644
index 00000000000..8ee9bae18d9
--- /dev/null
+++ b/addons/base_import_module/controllers/__init__.py
@@ -0,0 +1 @@
+import main
diff --git a/addons/base_import_module/controllers/main.py b/addons/base_import_module/controllers/main.py
new file mode 100644
index 00000000000..cbfbd75894b
--- /dev/null
+++ b/addons/base_import_module/controllers/main.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+import functools
+import os
+import zipfile
+from os.path import join as opj
+
+import openerp
+from openerp.http import Controller, route, request, Response
+
+MAX_FILE_SIZE = 100 * 1024 * 1024 # in megabytes
+
+def webservice(f):
+ @functools.wraps(f)
+ def wrap(*args, **kw):
+ try:
+ return f(*args, **kw)
+ except Exception, e:
+ return Response(response=str(e), status=500)
+ return wrap
+
+class ImportModule(Controller):
+
+ def check_user(self, uid=None):
+ if uid is None:
+ uid = request.uid
+ is_admin = request.registry['res.users'].has_group(request.cr, uid, 'base.group_erp_manager')
+ if not is_admin:
+ raise openerp.exceptions.AccessError("Only administrators can upload a module")
+
+ @route('/base_import_module/login', type='http', auth='none', methods=['POST'])
+ @webservice
+ def login(self, login, password, db=None):
+ if db and db != request.db:
+ raise Exception("Could not select database '%s'" % db)
+ uid = request.session.authenticate(request.db, login, password)
+ if not uid:
+ return Response(response="Wrong login/password", status=401)
+ self.check_user(uid)
+ return "ok"
+
+ @route('/base_import_module/upload', type='http', auth='user', methods=['POST'])
+ @webservice
+ def upload(self, mod_file=None, **kw):
+ self.check_user()
+ imm = request.registry['ir.module.module']
+
+ if not mod_file:
+ raise Exception("No file sent.")
+ if not zipfile.is_zipfile(mod_file):
+ raise Exception("Not a zipfile.")
+
+ success = []
+ errors = dict()
+ with zipfile.ZipFile(mod_file, "r") as z:
+ for zf in z.filelist:
+ if zf.file_size > MAX_FILE_SIZE:
+ raise Exception("File '%s' exceed maximum allowed file size" % zf.filename)
+
+ with openerp.tools.osutil.tempdir() as module_dir:
+ z.extractall(module_dir)
+ dirs = [d for d in os.listdir(module_dir) if os.path.isdir(opj(module_dir, d))]
+ for mod_name in dirs:
+ try:
+ # assert mod_name.startswith('theme_')
+ path = opj(module_dir, mod_name)
+ imm.import_module(request.cr, request.uid, mod_name, path, context=request.context)
+ success.append(mod_name)
+ except Exception, e:
+ errors[mod_name] = str(e)
+ r = ["Successfully imported module '%s'" % mod for mod in success]
+ for mod, error in errors.items():
+ r.append("Error while importing module '%s': %r" % (mod, error))
+ return '\n'.join(r)
diff --git a/addons/base_import_module/models/__init__.py b/addons/base_import_module/models/__init__.py
new file mode 100644
index 00000000000..a28c82fe5ba
--- /dev/null
+++ b/addons/base_import_module/models/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+import ir_module
diff --git a/addons/base_import_module/models/ir_module.py b/addons/base_import_module/models/ir_module.py
new file mode 100644
index 00000000000..18e60f858da
--- /dev/null
+++ b/addons/base_import_module/models/ir_module.py
@@ -0,0 +1,71 @@
+import logging
+import os
+import sys
+from os.path import join as opj
+
+import openerp
+from openerp.osv import osv
+from openerp.tools import convert_file
+
+_logger = logging.getLogger(__name__)
+
+class view(osv.osv):
+ _inherit = "ir.module.module"
+
+ def import_module(self, cr, uid, module, path, context=None):
+ known_mods = self.browse(cr, uid, self.search(cr, uid, []))
+ known_mods_names = dict([(m.name, m) for m in known_mods])
+
+ mod = known_mods_names.get(module)
+ terp = openerp.modules.load_information_from_description_file(module, mod_path=path)
+ values = self.get_values_from_terp(terp)
+
+ unmet_dependencies = set(terp['depends']).difference(known_mods_names.keys())
+ if unmet_dependencies:
+ raise Exception("Unmet module dependencies: %s" % ', '.join(unmet_dependencies))
+
+ if mod:
+ self.write(cr, uid, mod.id, values)
+ mode = 'update'
+ else:
+ assert terp.get('installable', True), "Module not installable"
+ self.create(cr, uid, dict(name=module, state='uninstalled', **values))
+ mode = 'init'
+
+ for kind in ['data', 'init_xml', 'update_xml']:
+ for filename in terp[kind]:
+ _logger.info("module %s: loading %s", module, filename)
+ noupdate = False
+ if filename.endswith('.csv') and kind in ('init', 'init_xml'):
+ noupdate = True
+ pathname = opj(path, filename)
+ idref = {}
+ convert_file(cr, module, filename, idref, mode=mode, noupdate=noupdate, kind=kind, pathname=pathname)
+
+ path_static = opj(path, 'static')
+ ir_attach = self.pool['ir.attachment']
+ if os.path.isdir(path_static):
+ for root, _, files in os.walk(path_static):
+ for static_file in files:
+ full_path = opj(root, static_file)
+ with open(full_path, 'r') as fp:
+ data = fp.read().encode('base64')
+ url_path = '/%s%s' % (module, full_path.split(path)[1].replace(os.path.sep, '/'))
+ url_path = url_path.decode(sys.getfilesystemencoding())
+ filename = os.path.split(url_path)[1]
+ values = dict(
+ name=filename,
+ datas_fname=filename,
+ url=url_path,
+ res_model='ir.ui.view',
+ type='binary',
+ datas=data,
+ )
+ att_id = ir_attach.search(cr, uid, [('url', '=', url_path), ('type', '=', 'binary'), ('res_model', '=', 'ir.ui.view')], context=context)
+ if att_id:
+ ir_attach.write(cr, uid, att_id, values, context=context)
+ else:
+ ir_attach.create(cr, uid, values, context=context)
+
+ return True
+
diff --git a/addons/base_import_module/tests/test_module/__openerp__.py b/addons/base_import_module/tests/test_module/__openerp__.py
new file mode 100644
index 00000000000..b0ecb362b3f
--- /dev/null
+++ b/addons/base_import_module/tests/test_module/__openerp__.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{
+ 'name': 'Test Module',
+ 'category': 'Website',
+ 'summary': 'Custom',
+ 'version': '1.0',
+ 'description': """
+ Test
+ """,
+ 'author': 'OpenERP SA',
+ 'depends': ['website'],
+ 'data': [
+ 'test.xml',
+ ],
+ 'installable': True,
+ 'application': True,
+}
diff --git a/addons/base_import_module/tests/test_module/static/src/img/c64.png b/addons/base_import_module/tests/test_module/static/src/img/c64.png
new file mode 100644
index 00000000000..3e8183f934f
--- /dev/null
+++ b/addons/base_import_module/tests/test_module/static/src/img/c64.png
Binary files differ
diff --git a/addons/base_import_module/tests/test_module/static/src/js/test.js b/addons/base_import_module/tests/test_module/static/src/js/test.js
new file mode 100644
index 00000000000..de803c83c34
--- /dev/null
+++ b/addons/base_import_module/tests/test_module/static/src/js/test.js
@@ -0,0 +1 @@
+console.log('test_module javascript');
diff --git a/addons/base_import_module/tests/test_module/test.xml b/addons/base_import_module/tests/test_module/test.xml
new file mode 100644
index 00000000000..489b286d975
--- /dev/null
+++ b/addons/base_import_module/tests/test_module/test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+<data>
+ <!-- TODO: make test suite -->
+ <record id="base.main_company" model="res.company">
+ <field name="name">The base company is noupdate=1</field>
+ </record>
+
+ <record id="main_company2" model="res.company">
+ <field name="name">Hagrid</field>
+ <field name="rml_header1">Your Company Tagline</field>
+ <field name="currency_id" ref="base.EUR"/>
+ </record>
+
+ <template id="test_page" name="Test Page" page="True">
+ <t t-call="website.layout">
+ <h1>
+ This page comes from an imported module!
+ </h1>
+ <p>
+ And this static image too !
+ <img src="/test_module/static/src/img/c64.png"/>
+ </p>
+ </t>
+ </template>
+
+ <template id="website.homepage">
+ <t t-call="website.layout">
+ <div id="wrap" class="oe_structure oe_empty">
+ This homepage has been overwritten by an imported module !
+ <p>
+ <a href="/page/test_module.test_page">Link to page added by imported module</a>
+ </p>
+ </div>
+ </t>
+ </template>
+
+ <template id="contactus_test" name="Contact Form" inherit_id="website.contactus">
+ <xpath expr="//h1" position="replace">
+ <h1>This contact us title has been changed by an imported module</h1>
+ </xpath>
+ </template>
+
+</data>
+</openerp>
diff --git a/addons/l10n_be_coda/i18n/fi.po b/addons/l10n_be_coda/i18n/fi.po
index e957d181fc8..4e24edcfcd3 100644
--- a/addons/l10n_be_coda/i18n/fi.po
+++ b/addons/l10n_be_coda/i18n/fi.po
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-11-24 02:53+0000\n"
-"PO-Revision-Date: 2011-06-28 09:19+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"PO-Revision-Date: 2014-03-27 20:07+0000\n"
+"Last-Translator: Päivi Kouki <paivi.kouki@uta.fi>\n"
"Language-Team: Finnish <fi@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2014-03-27 07:08+0000\n"
+"X-Launchpad-Export-Date: 2014-03-28 05:41+0000\n"
"X-Generator: Launchpad (build 16967)\n"
#. module: l10n_be_coda
@@ -292,7 +292,7 @@ msgstr "Tuontipäivä"
#. module: l10n_be_coda
#: model:account.coda.trans.category,description:l10n_be_coda.actrca_039
msgid "Telecommunications"
-msgstr ""
+msgstr "Tietoliikenne"
#. module: l10n_be_coda
#: field:coda.bank.statement.line,globalisation_id:0
@@ -344,7 +344,7 @@ msgstr ""
#. module: l10n_be_coda
#: model:account.coda.trans.code,comment:l10n_be_coda.actcc_80_27
msgid "For publications of the financial institution"
-msgstr ""
+msgstr "Taloudellisen instituution julkaisuja varten"
#. module: l10n_be_coda
#: model:account.coda.trans.code,description:l10n_be_coda.actcc_47_01
@@ -359,7 +359,7 @@ msgstr ""
#. module: l10n_be_coda
#: selection:account.coda.trans.code,type:0
msgid "Transaction Code"
-msgstr ""
+msgstr "Tapahtumakoodi"
#. module: l10n_be_coda
#: model:account.coda.trans.code,description:l10n_be_coda.actcc_47_13
@@ -389,7 +389,7 @@ msgstr "CODA-tiliotekategoria"
#. module: l10n_be_coda
#: model:account.coda.trans.category,description:l10n_be_coda.actrca_067
msgid "Fixed loan advance - extension"
-msgstr ""
+msgstr "Kiinteä lainaennakko - lisäaika"
#. module: l10n_be_coda
#: model:account.coda.trans.code,description:l10n_be_coda.actcc_13_07
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py
index c0a9e209d00..272e3480fb5 100644
--- a/addons/website/models/ir_http.py
+++ b/addons/website/models/ir_http.py
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
+import datetime
+import hashlib
import logging
import re
import traceback
-
import werkzeug
import werkzeug.routing
@@ -99,9 +100,38 @@ class ir_http(orm.AbstractModel):
path = '/' + request.lang + path
return werkzeug.utils.redirect(path)
+ def _serve_attachment(self):
+ domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)]
+ attach = self.pool['ir.attachment'].search_read(request.cr, openerp.SUPERUSER_ID, domain, ['__last_update', 'datas', 'mimetype'], context=request.context)
+ if attach:
+ wdate = attach[0]['__last_update']
+ datas = attach[0]['datas']
+ response = werkzeug.wrappers.Response()
+ server_format = openerp.tools.misc.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(hashlib.sha1(datas).hexdigest())
+ response.make_conditional(request.httprequest)
+
+ if response.status_code == 304:
+ return response
+
+ response.mimetype = attach[0]['mimetype']
+ response.set_data(datas.decode('base64'))
+ return response
+
def _handle_exception(self, exception=None, code=500):
if isinstance(exception, werkzeug.exceptions.HTTPException) and hasattr(exception, 'response') and exception.response:
return exception.response
+
+ attach = self._serve_attachment()
+ if attach:
+ return attach
+
if getattr(request, 'website_enabled', False) and request.website:
values = dict(
exception=exception,
diff --git a/addons/website/models/website.py b/addons/website/models/website.py
index 15e1a643d3d..a516f5cb96f 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -4,6 +4,7 @@ import inspect
import itertools
import logging
import math
+import mimetypes
import re
import urlparse
@@ -553,7 +554,7 @@ class ir_attachment(osv.osv):
def _website_url_get(self, cr, uid, ids, name, arg, context=None):
result = {}
for attach in self.browse(cr, uid, ids, context=context):
- if attach.type == 'url':
+ if attach.url:
result[attach.id] = attach.url
else:
result[attach.id] = urlplus('/website/image', {
@@ -574,7 +575,7 @@ class ir_attachment(osv.osv):
def _compute_checksum(self, attachment_dict):
if attachment_dict.get('res_model') == 'ir.ui.view'\
- and not attachment_dict.get('res_id')\
+ and not attachment_dict.get('res_id') and not attachment_dict.get('url')\
and attachment_dict.get('type', 'binary') == 'binary'\
and attachment_dict.get('datas'):
return hashlib.new('sha1', attachment_dict['datas']).hexdigest()
@@ -600,17 +601,27 @@ class ir_attachment(osv.osv):
'website_url': fields.function(_website_url_get, string="Attachment URL", type='char'),
'datas_big': fields.function (_datas_big, type='binary', store=True,
string="Resized file content"),
+ 'mimetype': fields.char('Mime Type', readonly=True),
}
+ def _add_mimetype_if_needed(self, values):
+ if values.get('datas_fname'):
+ values['mimetype'] = mimetypes.guess_type(values.get('datas_fname'))[0] or 'application/octet-stream'
+
def create(self, cr, uid, values, context=None):
chk = self._compute_checksum(values)
if chk:
match = self.search(cr, uid, [('datas_checksum', '=', chk)], context=context)
if match:
return match[0]
+ self._add_mimetype_if_needed(values)
return super(ir_attachment, self).create(
cr, uid, values, context=context)
+ def write(self, cr, uid, ids, values, context=None):
+ self._add_mimetype_if_needed(values)
+ return super(ir_attachment, self).write(cr, uid, ids, values, context=context)
+
def try_remove(self, cr, uid, ids, context=None):
""" Removes a web-based image attachment if it is used by no view
(template)
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js
index ae126ad16ab..c965c5ef834 100644
--- a/addons/website/static/src/js/website.editor.js
+++ b/addons/website/static/src/js/website.editor.js
@@ -1500,7 +1500,8 @@
args: [],
kwargs: {
fields: ['name', 'website_url'],
- domain: [['res_model', '=', 'ir.ui.view']],
+ domain: [['res_model', '=', 'ir.ui.view'], '|',
+ ['mimetype', '=', false], ['mimetype', '=like', 'image/%']],
order: 'id desc',
context: website.get_context(),
}
diff --git a/addons/website_gengo/static/src/xml/website.gengo.xml b/addons/website_gengo/static/src/xml/website.gengo.xml
index cdcca3a092a..294318cf24f 100644
--- a/addons/website_gengo/static/src/xml/website.gengo.xml
+++ b/addons/website_gengo/static/src/xml/website.gengo.xml
@@ -24,10 +24,10 @@
Content to translate or you can post them to <b><a href="http://gengo.com/" >Gengo</a></b> for translation.
</li>
<li class="oe_translatable_inprogress">
- Translation in Process (Gengo)
+ Translation in process (Gengo)
</li>
<li class="oe_translatable_text">
- Already Translated content
+ Already translated content
</li>
</ul>
</p>