summaryrefslogtreecommitdiff
path: root/addons/web_unsplash/controllers/main.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web_unsplash/controllers/main.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web_unsplash/controllers/main.py')
-rw-r--r--addons/web_unsplash/controllers/main.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/addons/web_unsplash/controllers/main.py b/addons/web_unsplash/controllers/main.py
new file mode 100644
index 00000000..505531ed
--- /dev/null
+++ b/addons/web_unsplash/controllers/main.py
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import base64
+import logging
+import mimetypes
+import requests
+import werkzeug.utils
+
+from odoo import http, tools, _
+from odoo.http import request
+from odoo.tools.mimetypes import guess_mimetype
+from werkzeug.urls import url_encode
+
+logger = logging.getLogger(__name__)
+
+
+class Web_Unsplash(http.Controller):
+
+ def _get_access_key(self):
+ if request.env.user._has_unsplash_key_rights():
+ return request.env['ir.config_parameter'].sudo().get_param('unsplash.access_key')
+ raise werkzeug.exceptions.NotFound()
+
+ def _notify_download(self, url):
+ ''' Notifies Unsplash from an image download. (API requirement)
+ :param url: the download_url of the image to be notified
+
+ This method won't return anything. This endpoint should just be
+ pinged with a simple GET request for Unsplash to increment the image
+ view counter.
+ '''
+ try:
+ if not url.startswith('https://api.unsplash.com/photos/'):
+ raise Exception(_("ERROR: Unknown Unsplash notify URL!"))
+ access_key = self._get_access_key()
+ requests.get(url, params=url_encode({'client_id': access_key}))
+ except Exception as e:
+ logger.exception("Unsplash download notification failed: " + str(e))
+
+ # ------------------------------------------------------
+ # add unsplash image url
+ # ------------------------------------------------------
+ @http.route('/web_unsplash/attachment/add', type='json', auth='user', methods=['POST'])
+ def save_unsplash_url(self, unsplashurls=None, **kwargs):
+ """
+ unsplashurls = {
+ image_id1: {
+ url: image_url,
+ download_url: download_url,
+ },
+ image_id2: {
+ url: image_url,
+ download_url: download_url,
+ },
+ .....
+ }
+ """
+ def slugify(s):
+ ''' Keeps only alphanumeric characters, hyphens and spaces from a string.
+ The string will also be truncated to 1024 characters max.
+ :param s: the string to be filtered
+ :return: the sanitized string
+ '''
+ return "".join([c for c in s if c.isalnum() or c in list("- ")])[:1024]
+
+ if not unsplashurls:
+ return []
+
+ uploads = []
+ Attachments = request.env['ir.attachment']
+
+ query = kwargs.get('query', '')
+ query = slugify(query)
+
+ res_model = kwargs.get('res_model', 'ir.ui.view')
+ if res_model != 'ir.ui.view' and kwargs.get('res_id'):
+ res_id = int(kwargs['res_id'])
+ else:
+ res_id = None
+
+ for key, value in unsplashurls.items():
+ url = value.get('url')
+ try:
+ if not url.startswith('https://images.unsplash.com/'):
+ logger.exception("ERROR: Unknown Unsplash URL!: " + url)
+ raise Exception(_("ERROR: Unknown Unsplash URL!"))
+ req = requests.get(url)
+ if req.status_code != requests.codes.ok:
+ continue
+
+ # get mime-type of image url because unsplash url dosn't contains mime-types in url
+ image_base64 = base64.b64encode(req.content)
+ except requests.exceptions.ConnectionError as e:
+ logger.exception("Connection Error: " + str(e))
+ continue
+ except requests.exceptions.Timeout as e:
+ logger.exception("Timeout: " + str(e))
+ continue
+
+ image_base64 = tools.image_process(image_base64, verify_resolution=True)
+ mimetype = guess_mimetype(base64.b64decode(image_base64))
+ # append image extension in name
+ query += mimetypes.guess_extension(mimetype) or ''
+
+ # /unsplash/5gR788gfd/lion
+ url_frags = ['unsplash', key, query]
+
+ attachment = Attachments.create({
+ 'name': '_'.join(url_frags),
+ 'url': '/' + '/'.join(url_frags),
+ 'mimetype': mimetype,
+ 'datas': image_base64,
+ 'public': res_model == 'ir.ui.view',
+ 'res_id': res_id,
+ 'res_model': res_model,
+ 'description': value.get('description'),
+ })
+ attachment.generate_access_token()
+ uploads.append(attachment._get_media_info())
+
+ # Notifies Unsplash from an image download. (API requirement)
+ self._notify_download(value.get('download_url'))
+
+ return uploads
+
+ @http.route("/web_unsplash/fetch_images", type='json', auth="user")
+ def fetch_unsplash_images(self, **post):
+ access_key = self._get_access_key()
+ app_id = self.get_unsplash_app_id()
+ if not access_key or not app_id:
+ return {'error': 'key_not_found'}
+ post['client_id'] = access_key
+ response = requests.get('https://api.unsplash.com/search/photos/', params=url_encode(post))
+ if response.status_code == requests.codes.ok:
+ return response.json()
+ else:
+ return {'error': response.status_code}
+
+ @http.route("/web_unsplash/get_app_id", type='json', auth="public")
+ def get_unsplash_app_id(self, **post):
+ return request.env['ir.config_parameter'].sudo().get_param('unsplash.app_id')
+
+ @http.route("/web_unsplash/save_unsplash", type='json', auth="user")
+ def save_unsplash(self, **post):
+ if request.env.user._has_unsplash_key_rights():
+ request.env['ir.config_parameter'].sudo().set_param('unsplash.app_id', post.get('appId'))
+ request.env['ir.config_parameter'].sudo().set_param('unsplash.access_key', post.get('key'))
+ return True
+ raise werkzeug.exceptions.NotFound()