summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorajay javiya (OpenERP) <aja@tinyerp.com>2014-03-28 09:58:15 +0530
committerajay javiya (OpenERP) <aja@tinyerp.com>2014-03-28 09:58:15 +0530
commite63646130e8f01ff0c8378c2316e8eaf8a47e44d (patch)
tree93e58717e8ba23e3eb5cfac56288afda681cc8f0
parentb8b562ce0a04e09b805f2f64b5631ae506801be3 (diff)
parentcf311bda60da7c6b166bdee28937fff097009508 (diff)
[MERGE] : with trunk
bzr revid: aja@tinyerp.com-20140328042815-kv5qmuh2wxdt9wwp
-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/website/models/ir_http.py32
-rw-r--r--addons/website/models/website.py15
-rw-r--r--addons/website/static/src/css/website.css6
-rw-r--r--addons/website/static/src/css/website.sass6
-rw-r--r--addons/website/static/src/js/website.editor.js3
-rw-r--r--addons/website_event/controllers/main.py41
-rw-r--r--addons/website_event/static/src/img/world_map.jpgbin0 -> 12075 bytes
-rw-r--r--addons/website_event/static/src/js/website_geolocation.js16
-rw-r--r--addons/website_event/views/website_event.xml99
20 files changed, 550 insertions, 7 deletions
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/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/css/website.css b/addons/website/static/src/css/website.css
index 7e377196030..c4cf689d8de 100644
--- a/addons/website/static/src/css/website.css
+++ b/addons/website/static/src/css/website.css
@@ -526,3 +526,9 @@ span[data-oe-type="monetary"] {
width: 400px;
margin: 40px auto;
}
+
+.oe_website_overflow_ellipsis{
+ white-space:nowrap;
+ overflow:hidden;
+ text-overflow:ellipsis;
+}
diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass
index fc3bdb6da39..67e0aa5fde2 100644
--- a/addons/website/static/src/css/website.sass
+++ b/addons/website/static/src/css/website.sass
@@ -427,3 +427,9 @@ span[data-oe-type="monetary"]
.oe_website_login_container
width: 400px
margin: 40px auto
+
+.oe_website_overflow_ellipsis
+ white-space:nowrap
+ overflow:hidden
+ text-overflow:ellipsis
+
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_event/controllers/main.py b/addons/website_event/controllers/main.py
index dad603f47ef..aae57e32a93 100644
--- a/addons/website_event/controllers/main.py
+++ b/addons/website_event/controllers/main.py
@@ -26,12 +26,21 @@ from openerp.tools.translate import _
from openerp.addons.website.controllers.main import Website as controllers
controllers = controllers()
+import logging
+_logger = logging.getLogger(__name__)
from datetime import datetime, timedelta
+import time
from dateutil.relativedelta import relativedelta
from openerp import tools
import werkzeug.urls
+try:
+ import GeoIP
+except ImportError:
+ GeoIP = None
+ _logger.warn("Please install GeoIP python module to use events localisation.")
+
class website_event(http.Controller):
@http.route(['/event', '/event/page/<int:page>'], type='http', auth="public", website=True, multilang=True)
def events(self, page=1, **searches):
@@ -203,3 +212,35 @@ class website_event(http.Controller):
}
event_id = Event.create(request.cr, request.uid, vals, context=context)
return request.redirect("/event/%s?enable_editor=1" % event_id)
+
+ def get_visitors_country(self):
+ GI = GeoIP.open('/usr/share/GeoIP/GeoIP.dat', 0)
+ return {'country_code': GI.country_code_by_addr(request.httprequest.remote_addr), 'country_name': GI.country_name_by_addr(request.httprequest.remote_addr)}
+
+ def get_formated_date(self, event):
+ start_date = datetime.strptime(event.date_begin, tools.DEFAULT_SERVER_DATETIME_FORMAT).date()
+ end_date = datetime.strptime(event.date_end, tools.DEFAULT_SERVER_DATETIME_FORMAT).date()
+ return ('%s %s%s') % (start_date.strftime("%b"), start_date.strftime("%e"), (end_date != start_date and ("-"+end_date.strftime("%e")) or ""))
+
+ @http.route('/event/get_country_event_list', type='http', auth='public', website=True)
+ def get_country_events(self ,**post):
+ if not GeoIP:
+ return ""
+ country_obj = request.registry['res.country']
+ event_obj = request.registry['event.event']
+ cr, uid, context,event_ids = request.cr, request.uid, request.context,[]
+ country_code = self.get_visitors_country()['country_code']
+ result = {'events':[],'country':False}
+ if country_code:
+ country_ids = country_obj.search(request.cr, request.uid, [('code', '=', country_code)], context=request.context)
+ event_ids = event_obj.search(request.cr, request.uid, ['|', ('address_id', '=', None),('country_id.code', '=', country_code),('date_begin','>=', time.strftime('%Y-%m-%d 00:00:00')),('state', '=', 'confirm')], order="date_begin", context=request.context)
+ if not event_ids:
+ event_ids = event_obj.search(request.cr, request.uid, [('date_begin','>=', time.strftime('%Y-%m-%d 00:00:00')),('state', '=', 'confirm')], order="date_begin", context=request.context)
+ for event in event_obj.browse(request.cr, request.uid, event_ids, context=request.context)[:6]:
+ if country_code and event.country_id.code == country_code:
+ result['country'] = country_obj.browse(request.cr, request.uid, country_ids[0], context=request.context)
+ result['events'].append({
+ "date": self.get_formated_date(event),
+ "event": event,
+ "url": event.website_url})
+ return request.website.render("website_event.country_events_list",result)
diff --git a/addons/website_event/static/src/img/world_map.jpg b/addons/website_event/static/src/img/world_map.jpg
new file mode 100644
index 00000000000..2813f53f4c3
--- /dev/null
+++ b/addons/website_event/static/src/img/world_map.jpg
Binary files differ
diff --git a/addons/website_event/static/src/js/website_geolocation.js b/addons/website_event/static/src/js/website_geolocation.js
new file mode 100644
index 00000000000..fb00edc5e64
--- /dev/null
+++ b/addons/website_event/static/src/js/website_geolocation.js
@@ -0,0 +1,16 @@
+(function() {
+ "use strict";
+ var website = openerp.website;
+
+ website.snippet.animationRegistry.visitor = website.snippet.Animation.extend({
+ selector: ".oe_country_events",
+ start: function () {
+ var self = this;
+ $.post( "/event/get_country_event_list", function( data ) {
+ if(data){
+ $( ".country_events_list" ).replaceWith( data );
+ }
+ });
+ }
+ });
+})(); \ No newline at end of file
diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml
index 3d019ba7417..1b3ce09fca6 100644
--- a/addons/website_event/views/website_event.xml
+++ b/addons/website_event/views/website_event.xml
@@ -117,6 +117,23 @@
</xpath>
</template>
+<template id="event_right_country_event" inherit_option_id="website_event.index" name="Country Events">
+ <xpath expr="//div[@id='right_column']" position="inside">
+ <div class="row">
+ <div class="col-md-12 mb16 mt16 country_events">
+ <div class="country_events_list">
+ <div class="text-muted text-center">
+ <h1>
+ <i class="fa fa-flag fa-5x"></i>
+ </h1>
+ <h1>Events from Your Country</h1>
+ </div>
+ </div>
+ </div>
+ </div>
+ </xpath>
+</template>
+
<template id="event_left_column" inherit_option_id="website_event.index" inherit_id="website_event.index" name="Filters">
<xpath expr="//div[@id='middle_column']" position="attributes">
<attribute name="class">col-md-6</attribute>
@@ -126,7 +143,7 @@
<ul class="nav nav-pills nav-stacked">
<t t-foreach="dates" t-as="date">
<li t-att-class="searches.get('date') == date[0] and 'active' or ''" t-if="date[3] or (date[0] in ('old','all'))">
- <a t-attf-href="/event/?{{ keep_query('country', 'type', date=date[0]) }}"><t t-esc="date[1]"/>
+ <a t-attf-href="/event?{{ keep_query('country', 'type', date=date[0]) }}"><t t-esc="date[1]"/>
<span t-if="date[3]" class="badge pull-right"><t t-esc="date[3]"/></span>
</a>
</li>
@@ -141,7 +158,7 @@
<ul class="nav nav-pills nav-stacked mt32">
<t t-foreach="types">
<li t-if="type" t-att-class="searches.get('type') == str(type and type[0]) and 'active' or ''">
- <a t-attf-href="/event/?{{ keep_query('country', 'date', type=type[0]) }}"><t t-esc="type[1]"/>
+ <a t-attf-href="/event?{{ keep_query('country', 'date', type=type[0]) }}"><t t-esc="type[1]"/>
<span class="badge pull-right"><t t-esc="type_count"/></span>
</a>
</li>
@@ -155,7 +172,7 @@
<ul class="nav nav-pills nav-stacked mt32">
<t t-foreach="countries">
<li t-if="country_id" t-att-class="searches.get('country') == str(country_id and country_id[0]) and 'active' or ''">
- <a t-attf-href="/event/?{{ keep_query('type', 'data', country=country_id[0]) }}"><t t-esc="country_id[1]"/>
+ <a t-attf-href="/event?{{ keep_query('type', 'data', country=country_id[0]) }}"><t t-esc="country_id[1]"/>
<span class="badge pull-right"><t t-esc="country_id_count"/></span>
</a>
</li>
@@ -335,5 +352,81 @@
</div>
</t>
</template>
+
+<template id="event_script" name="Country Events Snippet Script" inherit_id="website.layout">
+ <xpath expr="//head" position="inside">
+ <script type="text/javascript" src="/website_event/static/src/js/website_geolocation.js"></script>
+ </xpath>
+</template>
+
+<template id="country_events" name="Country Events" inherit_id="website.snippets">
+ <xpath expr="//div[@id='snippet_content']" position="inside">
+ <div>
+ <div class="oe_snippet_thumbnail">
+ <div style="background: white;box-shadow:none;-webkit-box-shadow:none;" class="oe_snippet_thumbnail_img" >
+ <i class="fa fa-flag fa-5x text-muted"></i>
+ </div>
+ <span class="oe_snippet_thumbnail_title">Local Events</span>
+ </div>
+ <div class="oe_snippet_body oe_country_events mb16 mt16">
+ <div class="country_events_list">
+ <div class="text-muted text-left">
+ <div>
+ <img style="max-height:10em;" class="img-rounded img-responsive" src="/website_event/static/src/img/world_map.jpg"></img>
+ </div>
+ <div>Events in visitor's country</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </xpath>
+ <xpath expr="//div[@id='snippet_options']" position="inside">
+ <div data-snippet-option-id='content'
+ data-selector=".oe_country_events"
+ data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel"
+ data-selector-children=".content"
+ >
+ </div>
+ </xpath>
+</template>
+
+<template id="country_events_list" name="Country">
+ <t t-ignore="true">
+ <t t-if="events">
+ <div class="country_events_list">
+ <div>
+ <t t-if="country">
+ <img style="max-height:10em;" class="img-rounded img-responsive" t-att-src="'/website/image?model=res.country&amp;field=image&amp;id='+str(country.id)"></img>
+ <h4><b>Events in <span t-esc="country.name"></span></b></h4>
+ </t>
+ <t t-if="not country">
+ <img style="max-height:10em;" class="img-rounded img-responsive" src="/website_event/static/src/img/world_map.jpg"></img>
+ <h4><b>Upcoming Events</b></h4>
+ </t>
+ <div t-foreach="events[:5]" t-as="event_dict" class="oe_website_overflow_ellipsis mb8">
+ <t t-if="not event_dict['event'].website_published">
+ <span class="label label-danger"><i class="fa fa-ban"></i></span>
+ </t>
+ <t t-if="event_dict['event'].address_id">
+ <i class="fa fa-map-marker"></i>
+ </t>
+ <t t-if="not event_dict['event'].address_id">
+ <i class="fa fa-cloud"></i>
+ </t>
+ <b><span t-esc="event_dict['date']"/>: <span><a t-att-href="event_dict['url']"><t t-esc="event_dict['event'].name"/></a></span></b>
+ </div>
+ <t t-if="len(events) > 5">
+ <div t-if="country">
+ <b><a t-att-href="'/event?country='+str(country.id)">See all events from <span t-esc="country.name"></span></a></b>
+ </div>
+ <div t-if="not country">
+ <b><a href="/event"> See all upcoming events </a></b>
+ </div>
+ </t>
+ </div>
+ </div>
+ </t>
+ </t>
+</template>
</data>
</openerp>