-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #141 from DagmawitGT/17.0-develop
Registry - Profile Photo
- Loading branch information
Showing
13 changed files
with
731 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
===================== | ||
OpenG2P Profile Image | ||
===================== | ||
|
||
.. | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! source digest: sha256:7bdf68b1fba30669d416a0928115edd95a9cfb1ee7091d4b593a0506ac530e20 | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png | ||
:target: https://odoo-community.org/page/development-status | ||
:alt: Beta | ||
.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--registry-lightgray.png?logo=github | ||
:target: https://github.com/OpenG2P/openg2p-registry/tree/17.0-develop/g2p_profile_image | ||
:alt: OpenG2P/openg2p-registry | ||
|
||
|badge1| |badge2| | ||
|
||
G2P Profile Image | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OpenG2P/openg2p-registry/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us to smash it by providing a detailed and welcomed | ||
`feedback <https://github.com/OpenG2P/openg2p-registry/issues/new?body=module:%20g2p_profile_image%0Aversion:%2017.0-develop%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Authors | ||
~~~~~~~ | ||
|
||
* OpenG2P | ||
|
||
Maintainers | ||
~~~~~~~~~~~ | ||
|
||
This module is part of the `OpenG2P/openg2p-registry <https://github.com/OpenG2P/openg2p-registry/tree/17.0-develop/g2p_profile_image>`_ project on GitHub. | ||
|
||
You are welcome to contribute. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Part of OpenG2P Social Registry. See LICENSE file for full copyright and licensing details. | ||
{ | ||
"name": "OpenG2P Profile Image", | ||
"category": "G2P", | ||
"version": "17.0.1.0.0", | ||
"sequence": 1, | ||
"author": "OpenG2P", | ||
"website": "https://openg2p.org", | ||
"license": "Other OSI approved licence", | ||
"depends": [ | ||
"g2p_registry_base", | ||
"g2p_registry_documents", | ||
], | ||
"external_dependencies": { | ||
"python": ["pillow==9.0.1"], | ||
}, | ||
"data": [], | ||
"assets": {}, | ||
"demo": [], | ||
"images": [], | ||
"application": True, | ||
"installable": True, | ||
"auto_install": False, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import profile_image, document_file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import logging | ||
|
||
from odoo import _, models | ||
from odoo.exceptions import UserError | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class G2PDocumentFile(models.Model): | ||
_inherit = "storage.file" | ||
|
||
def create(self, vals): | ||
_logger.info("Creating storage file with values: %s", vals) | ||
if isinstance(vals, dict): | ||
self._check_profile_tag(vals) | ||
elif isinstance(vals, list): | ||
for i in range(len(vals)): | ||
vals_obj = vals[i] | ||
self._check_profile_tag(vals_obj) | ||
|
||
return super().create(vals) | ||
|
||
def _check_profile_tag(self, vals_obj): | ||
_logger.info("Checking profile tag for values: %s", vals_obj) | ||
profile_tag = self.env["g2p.document.tag"].get_tag_by_name("Profile Image") | ||
profile_tag_id = profile_tag.id | ||
tags_ids = vals_obj.get("tags_ids", []) | ||
has_profile_tag = any(tag[1] == profile_tag_id for tag in tags_ids) | ||
|
||
if has_profile_tag: | ||
existing_file = self.search( | ||
[("registrant_id", "=", vals_obj.get("registrant_id")), ("tags_ids", "in", [profile_tag.id])], | ||
limit=1, | ||
) | ||
|
||
if existing_file: | ||
raise UserError( | ||
_( | ||
"Profile image already exists. To change your profile picture," | ||
"hover over your current image and click the edit button." | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import base64 | ||
import io | ||
|
||
from PIL import Image | ||
|
||
from odoo import api, models | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class G2PImageStorage(models.Model): | ||
_inherit = "res.partner" | ||
|
||
def _process_profile_image(self, values): | ||
profile_tag = self.env["g2p.document.tag"].get_tag_by_name("Profile Image") | ||
|
||
if not profile_tag: | ||
profile_tag = self.env["g2p.document.tag"].create({"name": "Profile Image"}) | ||
|
||
storage_file = self.env["storage.file"].search( | ||
[("registrant_id", "=", self.id), ("tags_ids", "in", [profile_tag.id])], limit=1 | ||
) | ||
|
||
backend_id = self.env["storage.backend"].search([("name", "=", "Default S3 Document Store")], limit=1) | ||
|
||
if values and values.get("image_1920") is not False: | ||
img = values.get("image_1920", False) | ||
if img: | ||
binary_image = base64.b64decode(img) | ||
image_size = len(binary_image) | ||
|
||
if image_size > 1 * 1024 * 1024: # Image is > 1 MB | ||
try: | ||
# Scale down the image to be less than 1 MB | ||
scaled_down_image = self._resize_image(binary_image) | ||
values["image_1920"] = scaled_down_image | ||
|
||
except Exception as e: | ||
raise ValidationError(f"Error: {e}") from e | ||
|
||
storage_file_vals = { | ||
"data": img, | ||
"file_size": image_size, | ||
"name": "Profile Image", | ||
"tags_ids": [(4, profile_tag.id)], | ||
"registrant_id": self.id, | ||
"backend_id": backend_id.id, | ||
} | ||
|
||
if storage_file: | ||
storage_file.unlink() | ||
self.env["storage.file"].create(storage_file_vals) | ||
else: | ||
if storage_file: | ||
storage_file.unlink() | ||
values["image_1920"] = img | ||
|
||
else: | ||
if values and storage_file: | ||
storage_file.unlink() | ||
|
||
def write(self, values): | ||
self._process_profile_image(values) | ||
result = super().write(values) | ||
return result | ||
|
||
@api.model | ||
def create(self, values): | ||
new_record = super().create(values) | ||
new_record._process_profile_image(values) | ||
return new_record | ||
|
||
def _resize_image(self, binary_image): | ||
image_stream = io.BytesIO(binary_image) | ||
image = Image.open(image_stream) | ||
image_format = image.format | ||
max_size = 1 * 1024 * 1024 # 1 MB | ||
|
||
# resizing with thumbnail | ||
image.thumbnail((1024, 1024), Image.ANTIALIAS) | ||
|
||
buffered = io.BytesIO() | ||
image.save(buffered, format=image_format, optimize=True, quality=85) | ||
|
||
# size of the buffered image | ||
if buffered.tell() <= max_size: | ||
return base64.b64encode(buffered.getvalue()) | ||
|
||
for quality in range(80, 20, -10): | ||
buffered = io.BytesIO() | ||
image.save(buffered, format=image_format, optimize=True, quality=quality) | ||
if buffered.tell() <= max_size: | ||
return base64.b64encode(buffered.getvalue()) | ||
|
||
# If quality reduction is not enough, reduce dimensions further | ||
new_width = image.size[0] | ||
new_height = image.size[1] | ||
while buffered.tell() > max_size and (new_width > 100 and new_height > 100): | ||
new_width = int(new_width * 0.9) | ||
new_height = int(new_height * 0.9) | ||
image = image.resize((new_width, new_height), Image.ANTIALIAS) | ||
buffered = io.BytesIO() | ||
image.save(buffered, format=image_format, optimize=True, quality=85) | ||
if buffered.tell() <= max_size: | ||
break | ||
|
||
return base64.b64encode(buffered.getvalue()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[build-system] | ||
requires = ["whool"] | ||
build-backend = "whool.buildapi" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
G2P Profile Image |
Oops, something went wrong.