DigitalSignage/models/dss_projects.py

373 lines
20 KiB
Python
Executable File

import ast
import datetime
import json
import re
import uuid
import logging
import base64
import subprocess
import tempfile
import requests
#from symbol import return_stmt
import json
from types import SimpleNamespace
import easywebdav
import os
import os.path
from odoo import api, fields, models, _
from odoo import tools
from odoo.exceptions import ValidationError
from . import dss_settings
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 dssprojects(models.Model):
_name = "dss.projects"
_description = "DigitalSignage Projekte"
_rec_name = "projektname"
_inherit = ['mail.thread','mail.activity.mixin','dss.triggermodel']
projektname = fields.Char('Projektname', required=True)
uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID')
projectid = fields.Integer('Projekt ID',tracking=True)
color = fields.Char('Color Index',tracking=True)
active = fields.Boolean('Active', default=True,tracking=True)
invisible = fields.Boolean('Ausgeblendet', default=False,tracking=True)
name = fields.Char('Interner Name', required=True,tracking=True)
aktstatus = fields.Many2one('dss.projectstate',string='Aktueller Status:',tracking=True)
aktstatus_typ = fields.Selection(related='aktstatus.typ')
aktstatus_color = fields.Char(related='aktstatus.color')
aktstatus_icon = fields.Image(related='aktstatus.icon')
description = fields.Text('Beschreibung',tracking=True)
short_partner_description = fields.Char('Kurz-Beschreibung für Kunden',tracking=True)
partner_description = fields.Text('Beschreibung für Kunden',tracking=True)
systemname = fields.Many2one('dss.systems',tracking=True)
grundsystemname = fields.Many2one('dss.systemtypen',group_expand='_read_group_system_ids',tracking=True)
grundsystem_typ = fields.Char(related='grundsystemname.kennung',tracking=True)
grundsystemnameuuid = fields.Char(related='grundsystemname.uuid',tracking=True)
grundsystemicon = fields.Image(related='grundsystemname.icon',tracking=True)
grundsystem_default_adstructure = fields.Many2one(related='grundsystemname.default_adstructure',tracking=True)
grundsystemicon5050 = fields.Image(related='grundsystemname.icon_5050')
grundsystem_ordner = fields.Char(related='grundsystemname.default_cloud_path')
grundsystem_showonlinestate = fields.Boolean(related='grundsystemname.showonlinestate')
grundsystem_showonlinestate_type = fields.Selection(related='grundsystemname.showonlinestate_type')
standort = fields.Char('Beschreibung des Standortes')
standort_strasse = fields.Char('Strasse des Projektes',tracking=True)
standort_plz = fields.Char('PLZ des Projektes',tracking=True)
standort_ort = fields.Char('Ort des Projektes',tracking=True)
standort_bundesland = fields.Many2one('res.country.state',string='Bundesland des Projektes',tracking=True)
standort_land = fields.Many2one('res.country',string='Land des Projektes',tracking=True)
standort_long = fields.Char('Standort Longitude',tracking=True)
standort_lati = fields.Char('Standort Latitude',tracking=True)
standort_visible = fields.Boolean('Auf Projekt-Karte sichtbar',tracking=True)
zahlungsvorlauf = fields.Integer('Wochen Zahlungsvorlauf', tracking=True)
maps_name = fields.Char('Name in Google',tracking=True)
maps_type = fields.Char('Type in Google',tracking=True)
maps_marker = fields.Selection([('m1.png','Marker 1'),('m2.png','Marker 2'),('m3.png','Marker 3'),('m4.png','Marker 4'),('m5.png','Marker 5'),('pin.png','Marker Pin'),('pin2.png','3D Marker Pin'),('pin_display.png','Displpay Pin'),('pin_display_touch.png','TouchDisplpay Pin'),('pin_led.png','LEDWand Pin')],'Marker in Google',tracking=True)
maps_image = fields.Binary('Google Bild',tracking=True)
maps_image_2 = fields.Binary('Google Bild 2',tracking=True)
maps_image_3 = fields.Binary('Google Bild 3',tracking=True)
maps_text = fields.Html('Google Beschreibung',tracking=True)
maps_typ_interactive = fields.Boolean('Ist Interactive ?', tracking=True)
maps_visitors = fields.Integer('Besucher pro Tag', tracking=True)
maps_displaytyp = fields.Char('Anzeigetyp in Google', tracking=True)
maps_displaysize = fields.Char('Anzeigegroesse in Google',tracking=True)
maps_werbeflaechen_a_free = fields.Boolean('Werbeflächen 1 Frei', tracking=True)
maps_werbeflaechen_a = fields.Char('Werbeflächenbeschreibung 1',tracking=True)
maps_werbeflaechen_b_free = fields.Boolean('Werbeflächen 2 Frei', tracking=True)
maps_werbeflaechen_b = fields.Char('Werbeflächenbeschreibung 2',tracking=True)
maps_werbemedien = fields.Char('Werbeflächen-Dateien',tracking=True)
maps_freespaces_b_show = fields.Boolean('Freie Flächen zeigen ?', tracking=True)
maps_freespaces_b = fields.Char('Freie Werbeflächen',tracking=True)
vertragsschreiber = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]",tracking=True)
standortpartner = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_standort','=',True)]",tracking=True)
vertriebspartner = fields.Many2many('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]",tracking=True)
project_grafiker = fields.Many2one('res.partner',domain="['&',('dssinternpartner','=',True),('dssinternpartner_grafik','=',True)]",tracking=True)
zeiten_on = fields.Datetime('veraltet',tracking=True)
zeiten_off = fields.Datetime('veraltet',tracking=True)
zeitenf_on = fields.Float('Einschaltzeit',tracking=True)
zeitenf_off = fields.Float('Ausschaltzeit',tracking=True)
zeiten_notiz = fields.Char('Schaltzeiten Notizen', tracking=True)
errichtet_am = fields.Date('Errichtungstag',tracking=True)
standort_inout = fields.Selection([('indoor','im Gebäude'), ('outdoor','Aussenbereich'), ('semiindoor','Überdachter Aussenbereich'),('Divers','Andere Art')],tracking=True)
date_start_compute = fields.Date('Kalender Start intern',compute='_compute_calendar_start')
cloudlink = fields.Char('Cloud Verzeichnis',help='Verzeichnis für das Project innerhalb des Cloud Struktur')
maintains = fields.Many2many('dss.maintaintask',string="Einsätze am Projekt")
marker_list = fields.Many2many('dss.marker', string='vorhandene Marker', tracking=True)
onlinestate_1 = fields.Char('OnlineColor_1')
playername_1 = fields.Char('Name des Players_1', tracking=True)
onlinestate_2 = fields.Char('OnlineColor_2')
playername_2 = fields.Char('Name des Players_2', tracking=True)
onlinestate_3 = fields.Char('OnlineColor_3')
playername_3 = fields.Char('Name des Players_3', tracking=True)
Rportid_1 = fields.Char('RPort ID 1', tracking=True)
Rportid_2 = fields.Char('RPort ID 2', tracking=True)
Rportid_3 = fields.Char('RPort ID 3', tracking=True)
issim = fields.Boolean('Sim Karte genutzt ?', tracking=True)
simid_1 = fields.Char('Simkarte Nr 1', tracking=True)
simstart_1 = fields.Char('Simkarte 1 Vertr.start', tracking=True)
simstart_DVEmpty_1 = fields.Boolean('Simkarte 1 DV leer', tracking=True)
simstart_DVEmpty_1_lastdate = fields.Date('Simkarte 1 Leerdatum', tracking=True)
simid_2 = fields.Char('Simkarte Nr 2', tracking=True)
simstart_2 = fields.Char('Simkarte 2 Vertr.start', tracking=True)
simstart_DVEmpty_2 = fields.Boolean('Simkarte 2 DV leer', tracking=True)
simstart_DVEmpty_2_lastdate = fields.Date('Simkarte 2 Leerdatum', tracking=True)
simid_3 = fields.Char('Simkarte Nr 3', tracking=True)
simstart_3 = fields.Char('Simkarte 3 Vertr.start', tracking=True)
simstart_DVEmpty_3 = fields.Boolean('Simkarte 3 DV leer', tracking=True)
simstart_DVEmpty_3_lastdate = fields.Date('Simkarte 3 Leerdatum', tracking=True)
@api.model
def _read_group_system_ids(self, stages, domain, order):
project_system_ids = self.env['dss.systemtypen'].search([('open_close_standard_state','=',False)], order='order')
return project_system_ids
def jumpcloud(self):
urlbase=str(self.env['dss.settings'].search([], limit=1).def_cloud_url_base)
_logger.info("Cloud Open Link Urlbase DB " + str(urlbase))
if not urlbase:
urlbase = 'https://cloud.logumedia.de/index.php/apps/files/?dir=';
_logger.info("Cloud Open Link Urlbase Used " + str(urlbase))
url=str(urlbase)+str(dss_settings.dssSettings._get_path_converted(self,self.cloudlink,self))
_logger.info("Cloud Open Link " + str(url))
return {
'type': 'ir.actions.act_url',
'url': str(url),
'target': 'new',
}
@api.model
def _compute_calendar_start(self):
for record in self:
if record.errichtet_am:
record.date_start_compute=record.errichtet_am
else:
record.date_start_compute=date.today()
@api.model
def _default_uuid(self):
return str(uuid.uuid4())
def _track_template(self, changes):
res = super()._track_template(changes)
if self.run_trigger:
self.trigger_track_template(changes, self)
return res
def pyaction_view_contracts(self):
# action = self.env['ir.actions.act_window'].with_context({'default_project': self.id})._for_xml_id('DigitalSignage.action_dss_project_contracts')
# action['display_name'] = self.projektname
# context = action['context'].replace('active_id', str(self.id))
# domain = action['domain'].replace('active_id', str(self.id))
# _logger.info('Vertraege fuer : '+str(self.id))
return {
'type': 'ir.actions.act_window',
'view_type':'kanban',
'view_mode':'kanban,tree',
'res_model':'dss.contracts',
'target':'current',
'context':'{"default_project":'+str(self.id)+',"show_project_update":True}',
'res_id':self.id,
'display_name' : self.name,
'domain':'[("project","=",'+str(self.id)+')]'
}
# context = ast.literal_eval(context)
# context = "{
# 'create': self.active,
# 'active_test': self.active
# }7
# action['context'] = context
# action['domain'] = domain
# return action
@api.onchange('cloudlink')
def _onchange_cloudlink(self):
_logger.info("Project "+str(self.id)+" Cloudpath changed")
if (self.cloudlink == ''):
if (self._origin.cloudlink != ''):
_logger.info("Project " + str(self.id) + " deleted - using standard path")
self.cloudlink = dss_settings.dssSettings._get_path_converted(self,self.env['dss.settings'].search([],limit=1).def_project_cloudpath,self)
def switch_invislbe(self):
return {
'type': 'ir.actions.act_window',
'view_type':'kanban',
'view_mode':'kanban,tree',
'res_model':'dss.contracts',
'target':'current',
'context':'{"default_project":'+str(self.id)+',"show_project_update":True}',
'res_id':self.id,
'display_name' : self.projektname,
'domain':'[("project","=",'+str(self.id)+')]'
}
@api.model
def _geo_localize(self, street='', zip='', city='', state='', country=''):
geo_obj = self.env['base.geocoder']
search = geo_obj.geo_query_address(street=street, zip=zip, city=city, state=state, country=country)
result = geo_obj.geo_find(search, force_country=country)
if result is None:
search = geo_obj.geo_query_address(city=city, state=state, country=country)
result = geo_obj.geo_find(search, force_country=country)
return result
def dss_geo_localize(self):
# We need country names in English below
result = self._geo_localize(self.standort_strasse,
self.standort_plz,
self.standort_ort,
self.standort_bundesland.name,
self.standort_land.name)
if result:
self.write({
'standort_lati': result[0],
'standort_long': result[1]
})
else:
partners_not_geo_localized |= partner
return True
def pyaction_dss_project_set_def_cloud(self):
self.cloudlink = str(self.env['dss.settings'].search([], limit=1).def_project_cloudpath)
return True
@api.model
def _compute_getonlinestate(self):
colorval = "#a0a0a0"
self.onlinestate = colorval
@api.model
def compute_getonlinestate2(self,project):
projekte = self.env['dss.projects'].search([('grundsystem_showonlinestate','=',True)])
for pro in projekte:
self.compute_getonlinestate_single(pro)
def compute_getonlinestate_single(self,project):
#proj = self.env['dss.projects'].search([('id',"=",project.id)])
proj = project
colorOn = str(self.env['dss.settings'].search([], limit=1).systemonline_color)
colorOff = str(self.env['dss.settings'].search([], limit=1).systemoffline_color)
_logger.info("Projekt Online Settings Check "+str(proj.grundsystem_showonlinestate_type)+' '+str(self)+' '+str(project))
if (proj.grundsystem_showonlinestate_type == 'RPORT'):
playername = proj["Rportid_1"]
_logger.info("Projekt RPORT Settings "+str(playername) )
if playername!=False:
rporturl = str(self.env['dss.settings'].search([], limit=1).rporturl)+'/api/v1/clients/'
rportusername = str(self.env['dss.settings'].search([], limit=1).rportusername)
rporttoken = str(self.env['dss.settings'].search([], limit=1).rporttoken)
auth = (rportusername, rporttoken)
for plnr in range(1,4):
playername = proj["Rportid_"+str(plnr)]
if playername:
_logger.info("RPORT request :"+str(rporturl)+str(playername))
r = requests.get(str(rporturl)+str(playername), auth=auth, verify=False)
_logger.info("RPORT answere :"+str(r.status_code)+' - '+str(r.content))
if (str(r.status_code) == "200"):
content = str(r.json())
index = content.find("connection_state")
content = content[index+20:]
index = content.find("',")
token = content[:index]
if (self.env['dss.onlinestate'].search([("project","=",proj.id),("number","=",plnr)], order="date_create desc", limit=1) == False):
self.env['dss.onlinestate'].create({'project':proj.id,'number':plnr,'online':False})
laststate = self.env['dss.onlinestate'].search([("project","=",proj.id),("number","=",plnr)], order="date_create desc", limit=1).online
_logger.info("RPORT answere :"+str(token)+"/"+str(laststate))
if token == 'connected':
colorval = colorOn
if not laststate:
self.env['dss.onlinestate'].create({'project':proj.id,'number':plnr,'online':True})
else:
colorval = colorOff
if laststate:
self.env['dss.onlinestate'].create({'project':proj.id,'number':plnr,'online':False})
else:
colorval = colorOff
else:
colorval = 0
proj['onlinestate_'+str(plnr)]=colorval
else:
colorval = 0
proj['onlinestate_1']=colorval
elif (proj.grundsystem_showonlinestate_type == 'VNNOX'):
vnurl = str(self.env['dss.settings'].search([], limit=1).vnnoxurl)+'/Rest/Logon'
vnusername = str(self.env['dss.settings'].search([], limit=1).vnnoxusername)
vnpassword = str(self.env['dss.settings'].search([], limit=1).vnnoxpassword)
# _logger.info("Projekt VNNOX Settings " + str(vnurl))
r = requests.post(vnurl, json={"password": vnpassword,"username": vnusername})
if (str(r.status_code) == "200"):
content = str(r.json())
index = content.find("token")
content = content[index+9:]
index = content.find("',")
token = content[:index]
for plnr in range(1,4):
playername = proj["playername_"+str(plnr)]
if playername!=False:
# _logger.info("Projekt VNNOX Settings Token : /" + str(token)+"/")
vnurl_getPlayer = str(self.env['dss.settings'].search([], limit=1).vnnoxurl)+'/Rest/Player?offset=0&limit=10&sort=name&sortType=asc&search='+str(playername)
headers = {'token': token}
r = requests.get(vnurl_getPlayer, headers=headers)
if (str(r.status_code) == "200"):
_logger.info("Projekt VNNOX Settings Data : /" + str(r.content)+"/")
resj = json.loads(r.content)
if resj["data"]["count"] == "1":
if (self.env['dss.onlinestate'].search([("project","=",proj.id),("number","=",plnr)], order="date_create desc", limit=1) == False):
self.env['dss.onlinestate'].create({'project':proj.id,'number':plnr,'online':False})
laststate = self.env['dss.onlinestate'].search([("project","=",proj.id),("number","=",plnr)], order="date_create desc", limit=1).online
_logger.info("Projekt VNNOX Settings Data : /" + str(resj["data"]["playerInfo"][0]["online"])+"/"+str(laststate))
if resj["data"]["playerInfo"][0]["online"] == "1":
colorval = colorOn
if not laststate:
self.env['dss.onlinestate'].create({'project':proj.id,'number':plnr,'online':True})
else:
colorval = colorOff
if laststate:
self.env['dss.onlinestate'].create({'project':proj.id,'number':plnr,'online':False})
else:
colorval = "#a0a0a0"
else:
colorval = "#a0a0a0"
proj['onlinestate_'+str(plnr)]=colorval
else:
colorval = "0"
proj['onlinestate_'+str(plnr)]=colorval
else:
colorval = "#a0a0a0"
proj['onlinestate_1']=colorval
else:
colorval = "#a0a0a0"
proj['onlinestate_1']=colorval
def method(self):
return (
self.env["confirmation.wizard"]
.with_context(hide_cancel=True)
.confirm_no_action_message(
message="Message",
title="Notification"
)
)