275 lines
16 KiB
Python
Executable File
275 lines
16 KiB
Python
Executable File
import ast
|
|
import datetime
|
|
import json
|
|
import re
|
|
import uuid
|
|
import logging
|
|
import base64
|
|
import subprocess
|
|
import tempfile
|
|
import easywebdav
|
|
import os
|
|
import os.path
|
|
import requests
|
|
import hashlib
|
|
|
|
|
|
from odoo import api, fields, models, _
|
|
from odoo import tools
|
|
from odoo.exceptions import ValidationError
|
|
from datetime import date
|
|
from datetime import datetime
|
|
from dateutil.relativedelta import relativedelta
|
|
from pyffmpeg import FFmpeg
|
|
from tuya_iot import TuyaOpenAPI, TUYA_LOGGER
|
|
from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
|
|
import sys
|
|
|
|
TUYA_LOGGER.setLevel(logging.DEBUG)
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class dssadvertisefields(models.Model):
|
|
|
|
@api.model
|
|
def create(self,vals):
|
|
result = super().create(vals)
|
|
result.issaved = True
|
|
return result
|
|
|
|
_name = "dss.advertisefields"
|
|
_description = "DigitalSignage Werbefelder"
|
|
_inherit = ['mail.thread','mail.activity.mixin']
|
|
_rec_name = "auto_feldname"
|
|
# _inherit = ['mail.thread', 'mail.activity.mixin']
|
|
uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID')
|
|
date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date())
|
|
date_lastedit = fields.Date('Änderungsdatum')
|
|
user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user())
|
|
user_lastedit = fields.Char('Änderungsuser')
|
|
issaved = fields.Boolean('ist gespeichert')
|
|
isblocked = fields.Boolean('Nach Nutzung sperren',tracking=True, default=True)
|
|
|
|
# uuid = fields.Char('UUID', required=True, translate=True)
|
|
auto_feldname = fields.Char('Projekt_Feldname', default=lambda self: self._default_projektfeld(), required=True)
|
|
display = fields.Char('Designname',tracking=True)
|
|
feldname = fields.Char('Feldname', required=True,tracking=True)
|
|
project = fields.Many2one('dss.projects' , string='Project', store=True,tracking=True)
|
|
project_id = fields.Integer(related='project.projectid', string='Project ID',tracking=True)
|
|
contract = fields.Many2many('dss.contracts' , string='Vertrag', store=True,tracking=True)
|
|
contract_save = fields.Many2one('dss.contracts' , string='Vertrag', store=True,tracking=True)
|
|
contract_project_id = fields.Integer(related='contract.project_id', string='Project ID',tracking=True)
|
|
color_used = fields.Char(string='Color Index',tracking=True)
|
|
color_unused = fields.Char(string='Color Index',tracking=True)
|
|
mediastructure = fields.Many2one('dss.adstructures',string='Feldaufbau',tracking=True)
|
|
mediastructure_medias = fields.Many2many(related='mediastructure.medias',string='Inhalt')
|
|
mediarelations = fields.One2many('dss.mediarelations','relname',tracking=True)
|
|
is_btn = fields.Boolean('Feld ist Button',help="Feld hat einen Button auf eineen TSS System ?",tracking=True, default=True)
|
|
|
|
|
|
btn_displaytemplate = fields.Many2one('dss.display.templates',string="Bildschirmvorlage",tracking=True)
|
|
btn_fromtemplate = fields.Many2one('dss.advertisefields.templates',string="Buttonvorlage",tracking=True)
|
|
btn_pos_x = fields.Integer('Position im Display X (px)', tracking=True)
|
|
btn_pos_y = fields.Integer('Position im Display Y (px)', tracking=True)
|
|
btn_pos_w = fields.Integer('Breite des Feldes (px)', tracking=True)
|
|
btn_pos_h = fields.Integer('Höhe des Feldes (px)', tracking=True)
|
|
btn_name = fields.Char('Button name',tracking=True)
|
|
btn_image = fields.Char('Button Bild Pfad',tracking=True)
|
|
btn_image_hash = fields.Char('Button Bild Hash',tracking=True)
|
|
btn_image_bin = fields.Binary('Button Bild Binary',tracking=True)
|
|
btn_image_bin_base64 = fields.Char('Button Bild Base64',tracking=True,compute='_compute_base64', store=True)
|
|
btn_fieldname = fields.Char('Feldname',tracking=True)
|
|
btn_visible = fields.Boolean('Feld wird angezeigt',tracking=True, default=True)
|
|
btn_active = fields.Boolean('Feld ist bedienbar/aktiv',tracking=True, default=True)
|
|
btn_action_inactive = fields.Integer('Inaktiv Klickaktion',help='Aktion die ausgeführt wird bei click auf inaktiven Button - >0 und nicht activ = Baustellenbild bringen', tracking=True)
|
|
btn_action_active = fields.Selection([('9','Spezialfenster'),('16','Internetfenster'),('3','Storry ausführen'),('2','Gallerie anzeigen'),('5','normales Verhalten'),('12','im Specialfenster das Fenster schliessen'),('14','im Specialfenster ein Bild anzeigen')],string='Aktive Klickaktion',help='Aktion die ausgeführt wird bei click auf Aktiven Button', tracking=True)
|
|
btn_playlist_filename = fields.Char('Playlistendatei',help='Bei Aktion-Story = Storrydatei', tracking=True)
|
|
btn_playlist_zuordnung = fields.Selection([('1','Standard Zuordnung - Pfad+SchemaID+File'),('20','Kunden Zuordnung - Pfad+KundenID+File'),('50','Gallerie Zuordnung - Pfad+GallerieID+File')], tracking=True)
|
|
btn_gallery_filename = fields.Char('Galleriedatei',help="Gallerie Datei - Ohne Pfad, und Ohne .GAL",tracking=True)
|
|
btn_gallery_id = fields.Char('Gallerie ID', tracking=True)
|
|
btn_gallery_rows = fields.Integer('Zeilen der Gallery', tracking=True)
|
|
btn_gallery_cols = fields.Integer('Spalten der Gallery', tracking=True)
|
|
btn_gallery_prv_w = fields.Integer('Gallery Bildpreview Breite', tracking=True)
|
|
btn_gallery_prv_h = fields.Integer('Gallery Bildpreview Höhe', tracking=True)
|
|
btn_has_timer = fields.Boolean('Button Timeout',tracking=True, default=True)
|
|
btn_has_timer_time = fields.Integer('Button Timer-Zeit', tracking=True)
|
|
btn_editable = fields.Boolean('Button Editierbar',tracking=True, default=True)
|
|
btn_special_actionimage = fields.Char('Anzeigebild Spezialform ', tracking=True)
|
|
btn_special_actionimage_x = fields.Integer('X-Position Anzeigebild', tracking=True)
|
|
btn_special_actionimage_y = fields.Integer('Y-Position Anzeigebild', tracking=True)
|
|
btn_special_actionimage_w = fields.Integer('Breite Anzeigebild', tracking=True)
|
|
btn_special_actionimage_h = fields.Integer('Hoehe Anzeigebild', tracking=True)
|
|
btn_special_actionimage_time = fields.Integer('Anzeigezeit Anzeigebild', tracking=True)
|
|
btn_center_video_1 = fields.Char('Zentralvideo 1', tracking=True)
|
|
btn_center_video_2 = fields.Char('Zentralvideo 1', tracking=True)
|
|
btn_center_video_3 = fields.Char('Zentralvideo 1', tracking=True)
|
|
btn_center_video_4 = fields.Char('Zentralvideo 1', tracking=True)
|
|
btn_text_1 = fields.Char('Textzeile 1', tracking=True)
|
|
btn_text_2 = fields.Char('Textzeile 2', tracking=True)
|
|
btn_text_3 = fields.Char('Textzeile 3', tracking=True)
|
|
btn_text_4 = fields.Char('Textzeile 4', tracking=True)
|
|
btn_text_1_visible = fields.Boolean('Textzeile 1 anzeigen',tracking=True, default=False)
|
|
btn_text_2_visible = fields.Boolean('Textzeile 1 anzeigen',tracking=True, default=False)
|
|
btn_text_3_visible = fields.Boolean('Textzeile 1 anzeigen',tracking=True, default=False)
|
|
btn_text_4_visible = fields.Boolean('Textzeile 1 anzeigen',tracking=True, default=False)
|
|
btn_text_1_pos_x = fields.Integer('Textzeile 1 X-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_1_pos_y = fields.Integer('Textzeile 1 Y-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_2_pos_x = fields.Integer('Textzeile 2 X-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_2_pos_y = fields.Integer('Textzeile 2 Y-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_3_pos_x = fields.Integer('Textzeile 3 X-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_3_pos_y = fields.Integer('Textzeile 3 Y-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_4_pos_x = fields.Integer('Textzeile 4 X-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_4_pos_y = fields.Integer('Textzeile 4 Y-Pos',help="xxxx direkter Zahlenwert , +/-xxxx relativ zu Button",tracking=True)
|
|
btn_text_1_font = fields.Char('Textzeile 1 Schriftart', tracking=True)
|
|
btn_text_2_font = fields.Char('Textzeile 2 Schriftart', tracking=True)
|
|
btn_text_3_font = fields.Char('Textzeile 3 Schriftart', tracking=True)
|
|
btn_text_4_font = fields.Char('Textzeile 4 Schriftart', tracking=True)
|
|
|
|
loopfiles = fields.Char('Durchlaufdateien', tracking=True)
|
|
|
|
|
|
def _default_projektfeld(self):
|
|
return "000_unbekannt"
|
|
|
|
def _default_create_date(self):
|
|
return str(date.today())
|
|
|
|
def _default_create_user(self):
|
|
self.issaved = True
|
|
return str(self.env.user.name)
|
|
|
|
|
|
@api.onchange('project')
|
|
def _onchange_project(self):
|
|
autoid = ""
|
|
autoid = str(self.project_id)+"_"+str(self.feldname)
|
|
self.auto_feldname = autoid
|
|
|
|
@api.onchange('contract')
|
|
def _onchange_contract(self):
|
|
autoid = ""
|
|
_logger.info('Contract Änderung prüfe Projekte !' + str(self.project_id) + ' / ' + str(self.contract_project_id))
|
|
if not self.project_id == self.contract_project_id:
|
|
_logger.info('Contract Änderung unterschiedliche Projekte !'+str(self.project_id)+' / '+str(self.contract_project_id))
|
|
raise ValidationError(_("Gewähltes Projekt und Projekt des Vertrages sind unterschiedlich !"))
|
|
else:
|
|
autoid = str(self.project_id)+"_"+str(self.feldname)
|
|
self.auto_feldname =autoid
|
|
|
|
@api.onchange('mediastructure')
|
|
def _onchange_mediastructure_id(self):
|
|
restr = 'keine'
|
|
for record in self :
|
|
resstr = record.mediastructure.uuid
|
|
mtyp = self.env['dss.adstructures'].search([("uuid","=",str(record.mediastructure.uuid))])
|
|
_logger.info(resstr)
|
|
if mtyp:
|
|
resstr = mtyp.structurename
|
|
_logger.info(resstr + ' uuid : '+record.mediastructure.uuid)
|
|
foundused = self.env['dss.mediarelations'].search_count(["&",('field_uuid','=',record.uuid),'|',('secured_ro','=',True),('used_ro','=',True)])
|
|
if foundused != 0 :
|
|
_logger.info('change - Canceled !')
|
|
raise ValidationError(_("Datensatz kann nicht gewechselt werden ! Es sind benutzt Medien in der Kampagne ! Bitte erst diese freigeben !"))
|
|
self.date_lastedit = str(date.today())
|
|
self.mediastructure = mtyp
|
|
|
|
@api.model
|
|
def _default_uuid(self):
|
|
return str(uuid.uuid4())
|
|
|
|
def check_contract_multi_Values(self):
|
|
for record in self:
|
|
if not record.contract:
|
|
record.contract = record.contract_save
|
|
|
|
def pyactiontaketemplate(self):
|
|
action = (self.env["confirmation.wizard"].confirm_message(_("Das Template wirklich übernehmen ?"),title="Bitte bestätigen",method="taketemplate",records=self,callback_params={"template":self.id})
|
|
)
|
|
if action:
|
|
return action
|
|
|
|
def taketemplate(self,template):
|
|
self.btn_pos_x = self.btn_fromtemplate.btn_pos_x
|
|
self.btn_pos_y = self.btn_fromtemplate.btn_pos_y
|
|
self.btn_pos_w = self.btn_fromtemplate.btn_pos_w
|
|
self.btn_pos_h = self.btn_fromtemplate.btn_pos_h
|
|
self.btn_name = self.btn_fromtemplate.btn_name
|
|
self.btn_fieldname = self.btn_fromtemplate.btn_fieldname
|
|
self.btn_visible = self.btn_fromtemplate.btn_visible
|
|
self.btn_active = self.btn_fromtemplate.btn_active
|
|
self.btn_action_inactive = self.btn_fromtemplate.btn_action_inactive
|
|
self.btn_action_active = self.btn_fromtemplate.btn_action_active
|
|
self.btn_playlist_zuordnung = self.btn_fromtemplate.btn_playlist_zuordnung
|
|
self.btn_gallery_rows = self.btn_fromtemplate.btn_gallery_rows
|
|
self.btn_gallery_cols = self.btn_fromtemplate.btn_gallery_cols
|
|
self.btn_gallery_prv_w = self.btn_fromtemplate.btn_gallery_prv_w
|
|
self.btn_gallery_prv_h = self.btn_fromtemplate.btn_gallery_prv_h
|
|
self.btn_has_timer = self.btn_fromtemplate.btn_has_timer
|
|
self.btn_has_timer_time = self.btn_fromtemplate.btn_has_timer_time
|
|
self.btn_editable = self.btn_fromtemplate.btn_editable
|
|
self.btn_special_actionimage = self.btn_fromtemplate.btn_special_actionimage
|
|
self.btn_special_actionimage_x = self.btn_fromtemplate.btn_special_actionimage_x
|
|
self.btn_special_actionimage_y = self.btn_fromtemplate.btn_special_actionimage_y
|
|
self.btn_special_actionimage_w = self.btn_fromtemplate.btn_special_actionimage_w
|
|
self.btn_special_actionimage_h = self.btn_fromtemplate.btn_special_actionimage_h
|
|
self.btn_special_actionimage_time = self.btn_fromtemplate.btn_special_actionimage_time
|
|
self.btn_text_1_visible = self.btn_fromtemplate.btn_text_1_visible
|
|
self.btn_text_2_visible = self.btn_fromtemplate.btn_text_2_visible
|
|
self.btn_text_3_visible = self.btn_fromtemplate.btn_text_3_visible
|
|
self.btn_text_4_visible = self.btn_fromtemplate.btn_text_4_visible
|
|
self.btn_text_1_pos_x = self.btn_fromtemplate.btn_text_1_pos_x
|
|
self.btn_text_1_pos_y = self.btn_fromtemplate.btn_text_1_pos_y
|
|
self.btn_text_2_pos_x = self.btn_fromtemplate.btn_text_2_pos_x
|
|
self.btn_text_2_pos_y = self.btn_fromtemplate.btn_text_2_pos_y
|
|
self.btn_text_3_pos_x = self.btn_fromtemplate.btn_text_3_pos_x
|
|
self.btn_text_3_pos_y = self.btn_fromtemplate.btn_text_3_pos_y
|
|
self.btn_text_4_pos_x = self.btn_fromtemplate.btn_text_4_pos_x
|
|
self.btn_text_4_pos_y = self.btn_fromtemplate.btn_text_4_pos_y
|
|
self.btn_text_1_font = self.btn_fromtemplate.btn_text_1_font
|
|
self.btn_text_2_font = self.btn_fromtemplate.btn_text_2_font
|
|
self.btn_text_3_font = self.btn_fromtemplate.btn_text_3_font
|
|
self.btn_text_4_font = self.btn_fromtemplate.btn_text_4_font
|
|
|
|
def py_openadvfield(self):
|
|
action = self.env["ir.actions.actions"]._for_xml_id("DigitalSignage.action_dss_advertisefields_fill")
|
|
action['context']='{"active_id":'+str(self.id)+'}'
|
|
action['res_id']=self.id
|
|
return action
|
|
|
|
def btn_image_import(self):
|
|
action = self.env["confirmation.wizard"].confirm_message(_("Das Bild wirklich importieren ?"),title="Bitte bestätigen",method="btn_image_import_do",records=self,callback_params={"template":self.id})
|
|
if action:
|
|
return action
|
|
|
|
def btn_image_import_do(self,template):
|
|
try:
|
|
response = requests.get(self.btn_image, stream=True)
|
|
if response.status_code == 200:
|
|
# Encode the image content to base64
|
|
image_data = base64.b64encode(response.content)
|
|
# Save the image to the Binary field
|
|
self.btn_image_bin = image_data
|
|
|
|
# Calculate the hash of the image
|
|
image_hash = hashlib.sha256(response.content).hexdigest()
|
|
# Save the hash to the hash field
|
|
self.btn_image_hash = image_hash
|
|
else:
|
|
raise ValidationError(_("Failed to download the image. HTTP Status: %s") % response.status_code)
|
|
except requests.exceptions.RequestException as e:
|
|
raise ValidationError(_("An error occurred while downloading the image: %s") % str(e))
|
|
|
|
|
|
def btn_image_import_local(self):
|
|
action = self.env["confirmation.wizard"].confirm_message(_("Das Bild wirklich importieren ?"),title="Bitte bestätigen",method="btn_image_import_do_local",records=self,callback_params={"template":self.id})
|
|
if action:
|
|
return action
|
|
|
|
|
|
@api.depends('btn_image_bin')
|
|
def _compute_base64(self):
|
|
for record in self:
|
|
if record.btn_image_bin:
|
|
record.btn_image_bin_base64 = 'data:image/png;base64,'+str(record.btn_image_bin)
|
|
else:
|
|
record.btn_image_bin_base64 = False |