88 lines
3.6 KiB
Python
88 lines
3.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import base64
|
|
import binascii
|
|
import hmac
|
|
|
|
import requests
|
|
import werkzeug.urls
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class ResPartner(models.Model):
|
|
_inherit = 'res.partner'
|
|
|
|
event_count = fields.Integer(
|
|
'# Events', compute='_compute_event_count', groups='event.group_event_registration_desk')
|
|
static_map_url = fields.Char(compute="_compute_static_map_url")
|
|
static_map_url_is_valid = fields.Boolean(compute="_compute_static_map_url_is_valid")
|
|
|
|
def _compute_event_count(self):
|
|
self.event_count = 0
|
|
for partner in self:
|
|
partner.event_count = self.env['event.event'].search_count([('registration_ids.partner_id', 'child_of', partner.ids)])
|
|
|
|
@api.depends('zip', 'city', 'country_id', 'street')
|
|
def _compute_static_map_url(self):
|
|
for partner in self:
|
|
partner.static_map_url = partner._google_map_signed_img(zoom=13, width=598, height=200)
|
|
|
|
@api.depends('static_map_url')
|
|
def _compute_static_map_url_is_valid(self):
|
|
"""Compute whether the link is valid.
|
|
|
|
This should only remain valid for a relatively short time.
|
|
Here, for the duration it is in cache.
|
|
"""
|
|
session = requests.Session()
|
|
for partner in self:
|
|
url = partner.static_map_url
|
|
if not url:
|
|
partner.static_map_url_is_valid = False
|
|
continue
|
|
|
|
is_valid = False
|
|
# If the response isn't strictly successful, assume invalid url
|
|
try:
|
|
res = session.get(url, timeout=2)
|
|
if res.ok and not res.headers.get('X-Staticmap-API-Warning'):
|
|
is_valid = True
|
|
except requests.exceptions.RequestException:
|
|
pass
|
|
|
|
partner.static_map_url_is_valid = is_valid
|
|
|
|
def action_event_view(self):
|
|
action = self.env["ir.actions.actions"]._for_xml_id("event.action_event_view")
|
|
action['context'] = {}
|
|
action['domain'] = [('registration_ids.partner_id', 'child_of', self.ids)]
|
|
return action
|
|
|
|
def _google_map_signed_img(self, zoom=13, width=298, height=298):
|
|
"""Create a signed static image URL for the location of this partner."""
|
|
GOOGLE_MAPS_STATIC_API_KEY = self.env['ir.config_parameter'].sudo().get_param('google_maps.signed_static_api_key')
|
|
GOOGLE_MAPS_STATIC_API_SECRET = self.env['ir.config_parameter'].sudo().get_param('google_maps.signed_static_api_secret')
|
|
if not GOOGLE_MAPS_STATIC_API_KEY or not GOOGLE_MAPS_STATIC_API_SECRET:
|
|
return None
|
|
# generate signature as per https://developers.google.com/maps/documentation/maps-static/digital-signature#server-side-signing
|
|
location_string = f"{self.street}, {self.city} {self.zip}, {self.country_id and self.country_id.display_name or ''}"
|
|
params = {
|
|
'center': location_string,
|
|
'markers': f'size:mid|{location_string}',
|
|
'size': f"{width}x{height}",
|
|
'zoom': zoom,
|
|
'sensor': "false",
|
|
'key': GOOGLE_MAPS_STATIC_API_KEY,
|
|
}
|
|
unsigned_path = '/maps/api/staticmap?' + werkzeug.urls.url_encode(params)
|
|
try:
|
|
api_secret_bytes = base64.urlsafe_b64decode(GOOGLE_MAPS_STATIC_API_SECRET + "====")
|
|
except binascii.Error:
|
|
return None
|
|
url_signature_bytes = hmac.digest(api_secret_bytes, unsigned_path.encode(), 'sha1')
|
|
params['signature'] = base64.urlsafe_b64encode(url_signature_bytes)
|
|
|
|
return 'https://maps.googleapis.com/maps/api/staticmap?' + werkzeug.urls.url_encode(params)
|