Skip to content

Commit

Permalink
Merge PR #276 into 16.0
Browse files Browse the repository at this point in the history
Signed-off-by lmignon
  • Loading branch information
OCA-git-bot committed Sep 24, 2023
2 parents 782c33e + ee99393 commit af3ccf7
Show file tree
Hide file tree
Showing 57 changed files with 1,415 additions and 0 deletions.
35 changes: 35 additions & 0 deletions fs_base_multi_image/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
**This file is going to be generated by oca-gen-addon-readme.**

*Manual changes will be overwritten.*

Please provide content in the ``readme`` directory:

* **DESCRIPTION.rst** (required)
* INSTALL.rst (optional)
* CONFIGURE.rst (optional)
* **USAGE.rst** (optional, highly recommended)
* DEVELOP.rst (optional)
* ROADMAP.rst (optional)
* HISTORY.rst (optional, recommended)
* **CONTRIBUTORS.rst** (optional, highly recommended)
* CREDITS.rst (optional)

Content of this README will also be drawn from the addon manifest,
from keys such as name, authors, maintainers, development_status,
and license.

A good, one sentence summary in the manifest is also highly recommended.


Automatic changelog generation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`HISTORY.rst` can be auto generated using `towncrier <https://pypi.org/project/towncrier>`_.

Just put towncrier compatible changelog fragments into `readme/newsfragments`
and the changelog file will be automatically generated and updated when a new fragment is added.

Please refer to `towncrier` documentation to know more.

NOTE: the changelog will be automatically generated when using `/ocabot merge $option`.
If you need to run it manually, refer to `OCA/maintainer-tools README <https://github.com/OCA/maintainer-tools>`_.
1 change: 1 addition & 0 deletions fs_base_multi_image/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
24 changes: 24 additions & 0 deletions fs_base_multi_image/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Fs Base Multi Image",
"summary": """
Mulitple Images from External File System""",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/storage",
"depends": [
"fs_image",
],
"data": [
"security/res_groups.xml",
"security/fs_image.xml",
"views/fs_image.xml",
"views/fs_image_relation_mixin.xml",
],
"demo": [],
"maintainers": ["lmignon"],
"development_status": "Alpha",
}
2 changes: 2 additions & 0 deletions fs_base_multi_image/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import fs_image
from . import fs_image_relation_mixin
29 changes: 29 additions & 0 deletions fs_base_multi_image/models/fs_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models

from odoo.addons.fs_image import fields as fs_fields


class FsImage(models.Model):

_name = "fs.image"
_inherit = "fs.image.mixin"
_description = "Image"
_order = "name, id"
_rec_name = "name"

image = fs_fields.FSImage(required=True) # makes field required
name = fields.Char(compute="_compute_name", store=True, index=True)
mimetype = fields.Char(compute="_compute_mimetype", store=True)

@api.depends("image")
def _compute_name(self):
for record in self:
record.name = record.image.name if record.image else None

@api.depends("image")
def _compute_mimetypes(self):
for record in self:
record.mimetype = record.image.mimetype if record.image else None
101 changes: 101 additions & 0 deletions fs_base_multi_image/models/fs_image_relation_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError

from odoo.addons.fs_image import fields as fs_fields


class FsImageRelationMixin(models.AbstractModel):

_name = "fs.image.relation.mixin"
_description = "Image Relation"
_order = "sequence, name"
_rec_name = "name"

sequence = fields.Integer()
image_id = fields.Many2one(
comodel_name="fs.image",
string="Linked image",
)
specific_image = fs_fields.FSImage("Specific Image")
# resized fields stored (as attachment) for performance
specific_image_medium = fs_fields.FSImage(
"Specific Image 128",
related="specific_image",
max_width=128,
max_height=128,
store=True,
)
link_existing = fields.Boolean(default=False)

image = fs_fields.FSImage(
"Image", compute="_compute_image", inverse="_inverse_image", store=False
)
# resized fields stored (as attachment) for performance
image_medium = fs_fields.FSImage(
"Image 128", compute="_compute_image_medium", store=False
)

name = fields.Char(compute="_compute_name", store=True, index=True)
mimetype = fields.Char(compute="_compute_mimetype", store=True)

@api.constrains("specific_image", "image_id")
def _check_image(self):
for record in self:
if not record.image_id and not record.specific_image:
raise ValidationError(_("You must set an image"))

@api.depends("image")
def _compute_name(self):
for record in self:
record.name = record.image.name if record.image else None

@api.depends("image")
def _compute_mimetypes(self):
for record in self:
record.mimetype = record.image.mimetype if record.image else None

@api.depends("image_id", "specific_image", "link_existing")
def _compute_image(self):
for record in self:
if record.link_existing:
record.image = record.image_id.image
else:
record.image = record.specific_image

@api.depends("image_id", "specific_image", "link_existing")
def _compute_image_medium(self):
for record in self:
if record.link_existing:
record.image_medium = record.image_id.image_medium
else:
record.image_medium = record.specific_image_medium

def _inverse_image(self):
for record in self:
if record.link_existing:
raise ValueError(_("Cannot set image on a linked image"))
else:
record.specific_image = record.image

@api.model
def _cleanup_vals(self, vals):
if (
"link_existing" in vals
and vals["link_existing"]
and "specific_image" in vals
):
vals["specific_image"] = False
return vals

@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
self._cleanup_vals(vals)
return super().create(vals_list)

def write(self, vals):
self._cleanup_vals(vals)
return super().write(vals)
1 change: 1 addition & 0 deletions fs_base_multi_image/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Laurent Mignon <laurent.mignon@acsone.eu>
14 changes: 14 additions & 0 deletions fs_base_multi_image/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
This addon is a technical addon providing a set of models to ease the
creation of other models that need to be linked to multiple images stored
into external filesystems.

The models provided by this addon are:

* ``fs.image``: a model that stores a reference to an image stored into
an external filesystem.
* ``fs.image.relation.mixin``: an abstract model that can be used to
as base class for models created to store an image linked to a model.
This abstract model defines fields and methods to transparently handle
2 cases:
* the image is specific to the model.
* the image is shared between multiple models and therefore is a ``fs.image`` instance linked to the mixin.
2 changes: 2 additions & 0 deletions fs_base_multi_image/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Add dedicated widget to ease the addition of new images to a model linked to
multiple images. (As it's the case in the *storage_image_product* addon)
3 changes: 3 additions & 0 deletions fs_base_multi_image/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To be able to create and or manages shared images, you must have the ``Image Manager``
role. If you do not have this role, as an authenticated user, you can
only view the shared images.
26 changes: 26 additions & 0 deletions fs_base_multi_image/security/fs_image.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>

<record model="ir.model.access" id="fs_image_access_read">
<field name="name">fs.image access read</field>
<field name="model_id" ref="model_fs_image" />
<field name="group_id" ref="base.group_user" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
</record>

<record model="ir.model.access" id="fs_image_access_manage">
<field name="name">fs.image access manage</field>
<field name="model_id" ref="model_fs_image" />
<field name="group_id" ref="group_image_manager" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_unlink" eval="1" />
</record>

</odoo>
10 changes: 10 additions & 0 deletions fs_base_multi_image/security/res_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="res.groups" id="group_image_manager">
<field name="name">Image Manager</field>
<field
name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
/>
</record>
</odoo>
Binary file added fs_base_multi_image/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions fs_base_multi_image/views/fs_image.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>

<record model="ir.ui.view" id="fs_image_form_view">
<field name="name">fs.image.form (in fs_base_multi_image)</field>
<field name="model">fs.image</field>
<field name="arch" type="xml">
<form>
<sheet>
<label for="name" />
<h1>
<field name="name" />
</h1>
<group>
<group>
<field name="image" />
</group>
</group>
</sheet>
</form>
</field>
</record>

<record model="ir.ui.view" id="fs_image_search_view">
<field name="name">fs.image.search (in fs_base_multi_image)</field>
<field name="model">fs.image</field>
<field name="arch" type="xml">
<search>
<field
name="name"
filter_domain="[('name','ilike',self)]"
string="Name"
/>
<separator />
<field name="create_uid" string="Created by" />
<field name="mimetype" />
<group expand="0" string="Group By">
<filter
string="MimeType"
name="mimetype"
domain="[]"
context="{'group_by':'mimetype'}"
/>
</group>
</search>
</field>
</record>

<record model="ir.ui.view" id="fs_image_tree_view">
<field name="name">fs.image.tree (in fs_base_multi_image)</field>
<field name="model">fs.image</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="create_uid" />
<field name="create_date" />
</tree>
</field>
</record>

<record model="ir.actions.act_window" id="fs_image_act_window">
<field name="name">Fs Image</field>
<field name="res_model">fs.image</field>
<field name="view_mode">tree,form</field>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>

<record model="ir.ui.menu" id="fs_image_menu">
<field name="name">Fs Images</field>
<field name="parent_id" ref="fs_storage.menu_storage" />
<field name="action" ref="fs_image_act_window" />
</record>

</odoo>
42 changes: 42 additions & 0 deletions fs_base_multi_image/views/fs_image_relation_mixin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>

<record model="ir.ui.view" id="fs_image_relation_mixin_form_view">
<field name="name">fs.image.relation.mixin.form</field>
<field name="model">fs.image.relation.mixin</field>
<field name="arch" type="xml">
<form>
<sheet>
<field
name="image"
class="oe_avatar"
options="{'preview_image': 'image_medium', 'zoom': true}"
readonly="1"
attrs="{'invisible': [('link_existing', '=', False)]}"
/>
<field
name="specific_image"
class="oe_avatar"
options="{'preview_image': 'image_medium', 'zoom': true}"
attrs="{'invisible': [('link_existing', '=', True)]}"
/>
<group>
<field name="link_existing" />
<field name="name" />
<field name="sequence" />
<field
name="image_id"
attrs="{'invisible': [('link_existing', '=', False)]}"
/>
</group>
<group name="extra">
<!-- Add here custom relation fields -->
</group>
</sheet>
</form>
</field>
</record>

</odoo>
Loading

0 comments on commit af3ccf7

Please sign in to comment.