Initial import from Docker volume

This commit is contained in:
root
2025-12-26 13:11:43 +00:00
commit 4998dc066a
13336 changed files with 1767801 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import Pool
from . import product, routes
__all__ = ['register', 'routes']
def register():
Pool.register(
product.Template,
product.Product,
product.Image,
product.ImageCache,
product.Category,
product.CategoryImage,
product.CategoryImageCache,
module='product_image', type_='model')
Pool.register(
module='product_image', type_='wizard')
Pool.register(
module='product_image', type_='report')

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "URL imatge"
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Imatges"
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr "Memòria cau"
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr "Categoria"
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Imatge"
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "ID de la imatge"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr "Categoria Imatge"
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr "Altura"
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Imatge"
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "ID de la imatge"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr "Amplada"
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr "Memòria cau"
msgctxt "field:product.image,image:"
msgid "Image"
msgstr "Imatge"
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr "ID de la imatge"
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr "Variant"
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Producte"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr "Altura"
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr "Imatge"
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr "ID de la imatge"
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Imatge del producte"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr "Amplada"
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr "URL de la imatge"
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Imatges"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr "URL de la imatge"
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Imatges"
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr "La mida d'una imatge en cache ha de ser única."
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr "Imatge Categoria"
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr "Cache imatge categoría"
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr "Imatge del producte"
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr "Memòria cau de la imatge del producte"

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,124 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "Bild-URL"
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Bilder"
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr "Cache"
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr "Kategorie"
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Bild"
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "Bild-ID"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr "Kategoriebild"
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr "Höhe"
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Bild"
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "Bild-ID"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr "Breite"
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr "Cache"
msgctxt "field:product.image,image:"
msgid "Image"
msgstr "Bild"
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr "Bild ID"
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Artikel"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr "Höhe"
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr "Bild"
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr "Bild ID"
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Artikelbild"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr "Breite"
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr "Bild-URL"
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Bilder"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr "Bild-URL"
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Bilder"
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
"Die Größe für zwischengespeicherte Bilder kann nur einmal vergeben werden."
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr "Kategoriebild"
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr "Kategoriebild Cache"
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr "Artikelbild"
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr "Artikelbild Cache"

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "URL Imagen"
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Imágenes"
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr "Caché"
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr "Categoría"
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Imagen"
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "ID de la Imagen"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr "Imagen Categoría"
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr "Alto"
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Imagen"
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "ID de la Imagen"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr "Ancho"
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr "Caché"
msgctxt "field:product.image,image:"
msgid "Image"
msgstr "Imagen"
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr "ID Imagen"
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Producto"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr "Alto"
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr "Imagen"
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr "ID Imagen"
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Imagen producto"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr "Ancho"
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr "URL Imagen"
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Imágenes"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr "URL Imagen"
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Imágenes"
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr "El tamaño de una imagen en cache debe ser único."
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr "Imagen Categoría"
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr "Caché imagen categoría"
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr "Imagen producto"
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr "Caché imagen producto"

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "URL de l'image"
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Images"
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr "Cache"
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr "Catégorie"
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Image"
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "ID de l'image"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr "Image de catégorie"
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr "Hauteur"
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Image"
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "ID de l'image"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr "Largeur"
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr "Cache"
msgctxt "field:product.image,image:"
msgid "Image"
msgstr "Image"
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr "ID de l'image"
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr "Variante"
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Produit"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr "Hauteur"
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr "Image"
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr "ID de l'image"
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Image du produit"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr "Largeur"
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr "URL de l'image"
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Images"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr "URL de l'image"
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Images"
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr "La taille de l'image mise en cache doit être unique."
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr "Image de catégorie"
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr "Cache d'images de catégorie"
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr "Image du produit"
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr "Cache de l'image du produit"

View File

@@ -0,0 +1,129 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
#, fuzzy
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "Képek"
#, fuzzy
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Képek"
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
#, fuzzy
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Képek"
#, fuzzy
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "Képek"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
#, fuzzy
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Képek"
#, fuzzy
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "Képek"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Termék"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Termékkép"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Képek"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Képek"
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Prodotto"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "Afbeelding URL"
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Afbeeldingen"
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr "Cache"
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr "Categorie"
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Afbeelding"
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "Afbeelding ID"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr "Categorie afbeelding"
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr "Hoogte"
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Afbeelding"
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "Afbeelding ID"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr "Breedte"
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr "Cache"
msgctxt "field:product.image,image:"
msgid "Image"
msgstr "Afbeelding"
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr "Afbeeldings-ID"
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr "Variant"
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Product"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr "Hoogte"
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr "Afbeelding"
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr "Afbeeldings-ID"
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Product afbeelding"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr "Breedte"
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr "Afbeelding URL"
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Afbeeldingen"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr "Afbeelding URL"
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Afbeeldingen"
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr "De grootte van de in de cache opgeslagen afbeelding moet uniek zijn."
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr "Categorie afbeelding"
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr "Cache van categorie afbeelding"
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr "Product afbeelding"
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr "Cache van productafbeeldingen"

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,132 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
#, fuzzy
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr "URL podobe"
#, fuzzy
msgctxt "field:product.category,images:"
msgid "Images"
msgstr "Podobe"
#, fuzzy
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr "Predpomnilnik"
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
#, fuzzy
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr "Podoba"
#, fuzzy
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr "ID podobe"
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
#, fuzzy
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr "Podoba"
#, fuzzy
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr "ID podobe"
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr "Predpomnilnik"
msgctxt "field:product.image,image:"
msgid "Image"
msgstr "Podoba"
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr "ID podobe"
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr "Različica"
msgctxt "field:product.image,template:"
msgid "Product"
msgstr "Izdelek"
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr "Podoba"
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr "ID podobe"
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr "Podoba produkta"
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr "URL podobe"
msgctxt "field:product.product,images:"
msgid "Images"
msgstr "Podobe"
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr "URL podobe"
msgctxt "field:product.template,images:"
msgid "Images"
msgstr "Podobe"
#, fuzzy
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr "Velikost podobe izdelka mora biti edinstvena."
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
#, fuzzy
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr "Predpomnilnik podobe izdelka"
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr "Podoba izdelka"
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr "Predpomnilnik podobe izdelka"

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,123 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:product.category,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.category,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.category.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.category.image,category:"
msgid "Category"
msgstr ""
msgctxt "field:product.category.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,category_image:"
msgid "Category Image"
msgstr ""
msgctxt "field:product.category.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.category.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.category.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.category.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.image,cache:"
msgid "Cache"
msgstr ""
msgctxt "field:product.image,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image,product:"
msgid "Variant"
msgstr ""
msgctxt "field:product.image,template:"
msgid "Product"
msgstr ""
msgctxt "field:product.image.cache,height:"
msgid "Height"
msgstr ""
msgctxt "field:product.image.cache,image:"
msgid "Image"
msgstr ""
msgctxt "field:product.image.cache,image_id:"
msgid "Image ID"
msgstr ""
msgctxt "field:product.image.cache,product_image:"
msgid "Product Image"
msgstr ""
msgctxt "field:product.image.cache,width:"
msgid "Width"
msgstr ""
msgctxt "field:product.product,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.product,images:"
msgid "Images"
msgstr ""
msgctxt "field:product.template,image_url:"
msgid "Image URL"
msgstr ""
msgctxt "field:product.template,images:"
msgid "Images"
msgstr ""
msgctxt "model:ir.message,text:msg_image_cache_size_unique"
msgid "The size of cached image must be unique."
msgstr ""
msgctxt "model:product.category.image,name:"
msgid "Category Image"
msgstr ""
msgctxt "model:product.category.image.cache,name:"
msgid "Category Image Cache"
msgstr ""
msgctxt "model:product.image,name:"
msgid "Product Image"
msgstr ""
msgctxt "model:product.image.cache,name:"
msgid "Product Image Cache"
msgstr ""

View File

@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.message" id="msg_image_cache_size_unique">
<field name="text">The size of cached image must be unique.</field>
</record>
</data>
</tryton>

331
modules/product_image/product.py Executable file
View File

@@ -0,0 +1,331 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import io
import math
from urllib.parse import quote, urlencode, urljoin
import PIL.Image
from trytond.config import config
from trytond.model import (
MatchMixin, ModelSQL, ModelView, Unique, fields, sequence_ordered)
from trytond.pool import PoolMeta
from trytond.pyson import Bool, Eval, If
from trytond.tools import slugify
from trytond.transaction import Transaction
from trytond.url import http_host
from trytond.wsgi import Base64Converter
if config.getboolean('product', 'image_filestore', default=False):
file_id = 'image_id'
store_prefix = config.get('product', 'image_prefix', default=None)
else:
file_id = None
store_prefix = None
SIZE_MAX = config.getint('product', 'image_size_max', default=2048)
URL_BASE = config.get('product', 'image_base', default='')
URL_EXTERNAL_BASE = config.get('product', 'image_base', default=http_host())
class ImageURLMixin:
__slots__ = ()
__image_url__ = None
images = None
image_url = fields.Function(fields.Char("Image URL"), '_get_image_url')
def _get_image_url(self, name):
return self.get_image_url(s=64)
def _image_url(self, base, **args):
if self.code and list(self.images_used):
url = urljoin(
base, quote('%(prefix)s/%(code)s/%(database)s/%(name)s' % {
'prefix': self.__image_url__,
'database': Base64Converter(None).to_url(
Transaction().database.name),
'code': quote(self.code, ''),
'name': slugify(self.name),
}))
if args:
size = args.pop('s', None)
width = args.pop('w', None)
height = args.pop('h', None)
index = args.pop('i', None)
args = {k: int(bool(v)) for k, v in args.items()}
if size:
args['s'] = size
if width:
args['w'] = width
if height:
args['h'] = height
if index is not None:
args['i'] = index
url += '?' + urlencode(args)
return url
def get_image_url(self, _external=False, **args):
return self._image_url(
URL_EXTERNAL_BASE if _external else URL_BASE, **args)
@property
def images_used(self):
yield from self.images
def get_images(self, pattern):
Image = self.__class__.images.get_target()
pattern = pattern.copy()
for key in set(pattern.keys()) - Image.allowed_match_keys():
del pattern[key]
pattern = {k: bool(int(v)) for k, v in pattern.items()}
for image in self.images_used:
if image.match(pattern, match_none=True):
yield image
class Template(ImageURLMixin, metaclass=PoolMeta):
__name__ = 'product.template'
__image_url__ = '/product/image'
images = fields.One2Many('product.image', 'template', "Images")
class Product(ImageURLMixin, metaclass=PoolMeta):
__name__ = 'product.product'
__image_url__ = '/product/variant/image'
images = fields.One2Many(
'product.image', 'product', "Images",
domain=[
('template', '=', Eval('template', -1)),
])
@property
def images_used(self):
yield from super().images_used
for image in self.template.images_used:
if not image.product:
yield image
class _ImageMixin:
__slots__ = ()
image = fields.Binary(
"Image", file_id=file_id, store_prefix=store_prefix, required=True)
image_id = fields.Char("Image ID", readonly=True)
class ImageMixin(_ImageMixin):
__slots__ = ()
cache = None
@classmethod
def allowed_match_keys(cls):
return set()
@classmethod
def create(cls, vlist):
vlist = [v.copy() for v in vlist]
for values in vlist:
if values.get('image'):
values['image'] = cls.convert(values['image'])
return super().create(vlist)
@classmethod
def write(cls, *args):
actions = iter(args)
args = []
for images, values in zip(actions, actions):
if values.get('image'):
values = values.copy()
values['image'] = cls.convert(values['image'])
args.append(images)
args.append(values)
super().write(*args)
cls.clear_cache(sum(args[0:None:2], []))
@classmethod
def _round_size(cls, size):
return min((
2 ** math.ceil(math.log2(size)),
10 * math.ceil(size / 10) if size <= 100
else 50 * math.ceil(size / 50)))
def get(self, size=400):
if isinstance(size, int):
size = (size, size)
size = tuple(map(self._round_size, size))
if not all(0 < s <= SIZE_MAX for s in size):
raise ValueError(f"Invalid size {size}")
for cache in self.cache:
if (cache.width, cache.height) == size:
return cache.image
with Transaction().new_transaction():
cache = self._store_cache(size, self._resize(size))
# Save cache only if record is already committed
if self.__class__.search([('id', '=', self.id)]):
cache.save()
return cache.image
@classmethod
def convert(cls, image, **_params):
data = io.BytesIO()
img = PIL.Image.open(io.BytesIO(image))
img.thumbnail((SIZE_MAX, SIZE_MAX))
if img.mode in {'RGBA', 'P'}:
img.convert('RGBA')
background = PIL.Image.new('RGBA', img.size, (255, 255, 255))
background.alpha_composite(img)
img = background.convert('RGB')
img.save(data, format='jpeg', optimize=True, **_params)
return data.getvalue()
def _resize(self, size=64, **_params):
data = io.BytesIO()
img = PIL.Image.open(io.BytesIO(self.image))
if isinstance(size, int):
size = (size, size)
img.thumbnail(size)
img.save(data, format='jpeg', optimize=True, **_params)
return data.getvalue()
def _store_cache(self, size, image):
Cache = self.__class__.cache.get_target()
if isinstance(size, int):
width = height = size
else:
width, height = size
return Cache(
image=image,
width=width,
height=height)
@classmethod
def clear_cache(cls, images):
Cache = cls.cache.get_target()
caches = [c for i in images for c in i.cache]
Cache.delete(caches)
class Image(ImageMixin, sequence_ordered(), ModelSQL, ModelView, MatchMixin):
"Product Image"
__name__ = 'product.image'
template = fields.Many2One(
'product.template', "Product",
required=True, ondelete='CASCADE',
domain=[
If(Bool(Eval('product')),
('products', '=', Eval('product')),
()),
])
product = fields.Many2One(
'product.product', "Variant",
domain=[
If(Bool(Eval('template')),
('template', '=', Eval('template')),
()),
])
cache = fields.One2Many(
'product.image.cache', 'product_image', "Cache", readonly=True)
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.update(['product', 'template'])
def _store_cache(self, size, image):
cache = super()._store_cache(size, image)
cache.product_image = self
return cache
class ImageCacheMixin(_ImageMixin):
__slots__ = ()
width = fields.Integer(
"Width", required=True,
domain=[
('width', '>', 0),
('width', '<=', SIZE_MAX),
])
height = fields.Integer(
"Height", required=True,
domain=[
('height', '>', 0),
('height', '<=', SIZE_MAX),
])
class ImageCache(ImageCacheMixin, ModelSQL):
"Product Image Cache"
__name__ = 'product.image.cache'
product_image = fields.Many2One(
'product.image', "Product Image", required=True, ondelete='CASCADE')
@classmethod
def __setup__(cls):
super().__setup__()
t = cls.__table__()
cls._sql_constraints += [
('dimension_unique', Unique(t, t.product_image, t.width, t.height),
'product_image.msg_image_cache_size_unique'),
]
@classmethod
def __register__(cls, module):
cursor = Transaction().connection.cursor()
table = cls.__table__()
table_h = cls.__table_handler__(module)
super().__register__(module)
# Migration from 7.0: split size into width and height
table_h.drop_constraint('size_unique')
if table_h.column_exist('size'):
cursor.execute(*table.update(
[table.width, table.height],
[table.size, table.size]))
table_h.drop_column('size')
class Category(ImageURLMixin, metaclass=PoolMeta):
__name__ = 'product.category'
__image_url__ = '/product-category/image'
images = fields.One2Many('product.category.image', 'category', "Images")
class CategoryImage(
ImageMixin, sequence_ordered(), ModelSQL, ModelView, MatchMixin):
"Category Image"
__name__ = 'product.category.image'
category = fields.Many2One(
'product.category', "Category",
required=True, ondelete='CASCADE')
cache = fields.One2Many(
'product.category.image.cache', 'category_image', "Cache",
readonly=True)
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.add('category')
def _store_cache(self, size, image):
cache = super()._store_cache(size, image)
cache.category_image = self
return cache
class CategoryImageCache(ImageCacheMixin, ModelSQL):
"Category Image Cache"
__name__ = 'product.category.image.cache'
category_image = fields.Many2One(
'product.category.image', "Category Image", required=True,
ondelete='CASCADE')
@classmethod
def __setup__(cls):
super().__setup__()
t = cls.__table__()
cls._sql_constraints += [
('dimension_unique',
Unique(t, t.category_image, t.width, t.height),
'product_image.msg_image_cache_size_unique'),
]

View File

@@ -0,0 +1,66 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="template_view_list">
<field name="model">product.template</field>
<field name="inherit" ref="product.template_view_tree"/>
<field name="name">template_list</field>
</record>
<record model="ir.ui.view" id="template_view_form">
<field name="model">product.template</field>
<field name="inherit" ref="product.template_view_form"/>
<field name="name">template_form</field>
</record>
<record model="ir.ui.view" id="image_view_list">
<field name="model">product.image</field>
<field name="type">tree</field>
<field name="name">image_list</field>
</record>
<record model="ir.ui.view" id="image_view_form">
<field name="model">product.image</field>
<field name="type">form</field>
<field name="name">image_form</field>
</record>
<record model="ir.ui.view" id="image_view_list_form">
<field name="model">product.image</field>
<field name="type">list-form</field>
<field name="name">image_form</field>
</record>
<record model="ir.ui.view" id="category_view_list">
<field name="model">product.category</field>
<field name="inherit" ref="product.category_view_list"/>
<field name="name">category_list</field>
</record>
<record model="ir.ui.view" id="category_view_form">
<field name="model">product.category</field>
<field name="inherit" ref="product.category_view_form"/>
<field name="name">category_form</field>
</record>
<record model="ir.ui.view" id="category_image_view_list">
<field name="model">product.category.image</field>
<field name="type">tree</field>
<field name="name">category_image_list</field>
</record>
<record model="ir.ui.view" id="category_image_view_form">
<field name="model">product.category.image</field>
<field name="type">form</field>
<field name="name">category_image_form</field>
</record>
<record model="ir.ui.view" id="category_image_view_list_form">
<field name="model">product.category.image</field>
<field name="type">list-form</field>
<field name="name">category_image_form</field>
</record>
</data>
</tryton>

97
modules/product_image/routes.py Executable file
View File

@@ -0,0 +1,97 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from urllib.parse import unquote
from trytond.config import config
from trytond.protocols.wrappers import (
HTTPStatus, Response, abort, with_pool, with_transaction)
from trytond.wsgi import app
TIMEOUT = config.getint('product', 'image_timeout', default=365 * 24 * 60 * 60)
@app.route(
'/product/image/<code>/<base64:database_name>',
methods={'GET'})
@app.route(
'/product/image/<code>/<base64:database_name>/<name>',
methods={'GET'})
@with_pool
@with_transaction()
def product_image(request, pool, code, name=None):
Template = pool.get('product.template')
try:
template, = Template.search([
('code', '=', unquote(code)),
])
except ValueError:
abort(HTTPStatus.NOT_FOUND)
return _image(request, pool, template)
@app.route(
'/product/variant/image/<code>/<base64:database_name>',
methods={'GET'})
@app.route(
'/product/variant/image/<code>/<base64:database_name>/<name>',
methods={'GET'})
@with_pool
@with_transaction()
def variant_image(request, pool, code, name=None):
Product = pool.get('product.product')
try:
product, = Product.search([
('code', '=', unquote(code)),
])
except ValueError:
abort(HTTPStatus.NOT_FOUND)
return _image(request, pool, product)
@app.route(
'/product-category/image/<code>/<base64:database_name>',
methods={'GET'})
@app.route(
'/product-category/image/<code>/<base64:database_name>/<name>',
methods={'GET'})
@with_pool
@with_transaction()
def category_image(request, pool, code, name=None):
Category = pool.get('product.category')
try:
category, = Category.search([
('code', '=', unquote(code)),
])
except ValueError:
abort(HTTPStatus.NOT_FOUND)
return _image(request, pool, category)
def _image(request, pool, record):
images = record.get_images(request.args)
if not images:
abort(HTTPStatus.NOT_FOUND)
try:
image = list(images)[int(request.args.get('i', 0))]
except IndexError:
abort(HTTPStatus.NOT_FOUND)
except ValueError:
abort(HTTPStatus.BAD_REQUEST)
try:
size = int(request.args.get('s', 400))
except ValueError:
abort(HTTPStatus.BAD_REQUEST)
try:
width = int(request.args.get('w', size))
except ValueError:
abort(HTTPStatus.BAD_REQUEST)
try:
height = int(request.args.get('h', size))
except ValueError:
abort(HTTPStatus.BAD_REQUEST)
response = Response(image.get((width, height)), mimetype='image/jpeg')
response.headers['Cache-Control'] = (
'max-age=%s, public' % TIMEOUT)
response.add_etag()
return response

View File

@@ -0,0 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

View File

@@ -0,0 +1,118 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import io
import urllib.request
import PIL.Image
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
class ProductImageTestCase(ModuleTestCase):
'Test Product Image module'
module = 'product_image'
@with_transaction()
def test_image_square(self):
"Test image square"
pool = Pool()
Image = pool.get('product.image')
Template = pool.get('product.template')
Uom = pool.get('product.uom')
template = Template(name="Template")
template.default_uom, = Uom.search([], limit=1)
template.save()
image = Image(template=template)
image.image = urllib.request.urlopen(
'https://picsum.photos/200').read()
image.save()
self.assertEqual(template.image_url, None)
template.code = "CODE"
template.save()
self.assertRegex(
template.image_url,
r'/product/image/CODE/.*/Template\?s=64')
img = PIL.Image.open(io.BytesIO(image.get(size=100)))
self.assertEqual(img.size, (100, 100))
img = PIL.Image.open(io.BytesIO(image.get(size=(150, 200))))
self.assertEqual(img.size, (150, 150))
@with_transaction()
def test_image_non_square(self):
"Test image non square"
pool = Pool()
Image = pool.get('product.image')
Template = pool.get('product.template')
Uom = pool.get('product.uom')
template = Template(name="Template")
template.default_uom, = Uom.search([], limit=1)
template.save()
image = Image(template=template)
image.image = urllib.request.urlopen(
'https://picsum.photos/200/400').read()
image.save()
self.assertEqual(template.image_url, None)
template.code = "CODE"
template.save()
self.assertRegex(
template.image_url,
r'/product/image/CODE/.*/Template\?s=64')
img = PIL.Image.open(io.BytesIO(image.get(size=100)))
self.assertEqual(img.size, (50, 100))
img = PIL.Image.open(io.BytesIO(image.get(size=(100, 200))))
self.assertEqual(img.size, (100, 200))
@with_transaction()
def test_round_size(self):
"Test round size"
pool = Pool()
Image = pool.get('product.image')
for size, result in [
(1, 1),
(2, 2),
(19, 20),
(45, 50),
(101, 128),
(129, 150),
]:
with self.subTest(size=size):
self.assertEqual(Image._round_size(size), result)
@with_transaction()
def test_get_image_url(self):
"Test get_image_url"
pool = Pool()
Image = pool.get('product.image')
Template = pool.get('product.template')
Uom = pool.get('product.uom')
template = Template(name="Template", code="CODE")
template.default_uom, = Uom.search([], limit=1)
template.save()
for _ in range(3):
image = Image(template=template)
image.image = urllib.request.urlopen(
'https://picsum.photos/200').read()
image.save()
self.assertRegex(
template.get_image_url(i=2),
r'/product/image/CODE/.*/Template\?i=2')
self.assertRegex(
template.get_image_url(s=400),
r'/product/image/CODE/.*/Template\?s=400')
del ModuleTestCase

View File

@@ -0,0 +1,8 @@
[tryton]
version=7.2.2
depends:
ir
product
xml:
product.xml
message.xml

View File

@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//notebook" position="inside">
<page name="images">
<field name="images" colspan="4" mode="list-form,tree,form"/>
</page>
</xpath>
</data>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form>
<field name="image" widget="image" height="200" width="200" xexpand="0" colspan="2"/>
<group id="category" col="2" colspan="2" yalign="0" yexpand="0">
<label name="sequence"/>
<field name="sequence"/>
<group colspan="2" col="-1" id="checkboxes">
<!-- Add checkboxes here -->
</group>
<label name="category"/>
<field name="category"/>
</group>
</form>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree sequence="sequence">
<field name="category" expand="1"/>
<field name="image" expand="2"/>
</tree>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//field[@name='code']" position="inside">
<prefix id="image" icon="image_url" icon_type="url" url_size="s"/>
</xpath>
</data>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form>
<field name="image" widget="image" height="200" width="200" xexpand="0" colspan="2"/>
<group id="product" col="2" colspan="2" yalign="0" yexpand="0">
<label name="sequence"/>
<field name="sequence"/>
<group colspan="2" col="-1" id="checkboxes">
<!-- Add checkboxes here -->
</group>
<label name="template"/>
<field name="template"/>
<label name="product"/>
<field name="product"/>
</group>
</form>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree sequence="sequence">
<field name="template" expand="1"/>
<field name="product" expand="1"/>
<field name="image" expand="2"/>
</tree>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//notebook" position="inside">
<page name="images">
<field name="images" colspan="4" mode="list-form,tree,form"/>
</page>
</xpath>
</data>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="//field[@name='code']" position="inside">
<prefix id="image" icon="image_url" icon_type="url" url_size="s"/>
</xpath>
</data>