Newer
Older
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
import xml.etree.ElementTree as et
import requests
from cmislib.exceptions import (
ContentAlreadyExistsException,
InvalidArgumentException,
ObjectNotFoundException,
UpdateConflictException,
)
from odoo import _, exceptions, models
"""Appelle l'API alfresco et implémente les fonctions suivantes :
_name = "cgscop.alfresco"
_description = "Connecteur Alfresco"
def alfresco_get_by_url(self, url, call_type, json=None, files=None):
"""Création de la requête à Alfresco
:param url: action API Alfresco
:param call_type: post/get
:param json: data to post
:param files: byte to upload
:param data: data to post
@return response au format JSON
"""
_logger.info("Calling %s" % url)
param = self.env["cmis.backend"].sudo().search([["active", "=", True]])
raise exceptions.UserError(
_("La connexion avec Alfresco n'est pas configurée !")
)
alfresco_url = param.url
alfresco_ssl = param.ssl
basicAuthCredentials = (param.username, param.password)
if call_type == "get":

Benjamin
committed
auth=basicAuthCredentials,
verify=alfresco_ssl,
)
elif call_type == "post":
response = requests.post(
alfresco_url + url,
auth=basicAuthCredentials,

Benjamin
committed
json=json,
files=files,
verify=alfresco_ssl,
timeout=15,
)
elif call_type == "put":
response = requests.put(
alfresco_url + url,
auth=basicAuthCredentials,
data=json,
files=files,
verify=alfresco_ssl,
)
elif call_type == "delete":
response = requests.delete(
alfresco_url + url,
auth=basicAuthCredentials,

Benjamin
committed
json=json,
verify=alfresco_ssl,
except Exception as err:
_logger.warning(
"Erreur de connexion. URL: %s",
err.__str__(),
)
raise exceptions.ValidationError(err.__str__())
# Gestion erreur API
if response.status_code not in [200, 201]:
try:
message = response.json().get("message")
except Exception:
message = response.text
raise exceptions.ValidationError(
_(
"L'appel url '%s' a échoué\n"
"- Code erreur : %d\n"
"- Message : %s" % (response.url, response.status_code, message)
)
)
return response

Benjamin
committed
def alfresco_list_docs(self, node_id):
"""Liste les documents pour un organisme (raison sociale)
:param name: raison sociale de la structure
url = "/alfresco/s/erp/listedocuments?nodeId=" + node_id
return self.alfresco_get_by_url(url=url, call_type="get").json()
"""Liste le valeurs du formulaire de dépôt d'un nouveau document
@return: dict des valeurs possibles pour période, validité, type
"""
url = "/alfresco/s/api/properties?nsp=crm&n=document"
list_type = self.alfresco_get_by_url(url=url, call_type="get").json()
"periode": self.get_allowed_values(
list_type=list_type, value="crm:periode"
),
"type": self.get_allowed_values(list_type=list_type, value="crm:type"),
"""Retourne le contenu d'un document en base64
:param nodeRef: id Alfresco
url = "/alfresco/s/document/" + nodeRef
return self.alfresco_get_by_url(url=url, call_type="get").json()
def alfresco_get_ticket(self, username):
"""Liste les documents pour un organisme (raison sociale)
:param username: username de l'utilisateur
"""
url = "/alfresco/s/authentifier-entantque?compte=" + username
result = self.alfresco_get_by_url(url=url, call_type="get")
tree = et.ElementTree(et.fromstring(result.content))
root = tree.getroot()
return root[0].text
# Post Methods
def alfresco_create_organism(self, partner):
"""Création d'un dossier Organisme
:param partner: objet Odoo créé
@return: id Alfresco (nodeRef) du dossier
"""
url = "/alfresco/s/erp/createdossierorganisme"
"raisonSociale": partner.name,
"ur": partner.ur_id,
self.alfresco_get_by_url(url=url, call_type="post", json=json).json()
)

Benjamin
committed
def alfresco_update_organism(self, partner):
"""Mise à jour d'un dossier Organisme

Benjamin
committed
:param partner: objet Odoo créé
@return: id Alfresco (nodeRef) du dossier
"""
url = "/alfresco/s/erp/updatedossierorganisme/" + partner.id_alfresco

Benjamin
committed
json = {
"raisonSociale": partner.name,

Benjamin
committed
"id": partner.id,
"siret": partner.siret,
"ur": partner.ur_id,

Benjamin
committed
}
return self.get_nodeRef(
self.alfresco_get_by_url(url=url, call_type="post", json=json).json()
)
"""Supprime un document d'Alfresco
:param id_doc: id du document Alfresco
url = "/alfresco/s/document/" + nodeRef
return self.alfresco_get_by_url(url=url, call_type="delete").json()
# Others
def get_allowed_values(self, list_type, value):
"""Fonction qui itère dans l'objet retourné"""
list_selected = list(filter(lambda i: i["name"] == value, list_type))
return (
list_selected[0]
.get("constraints")[0]
.get("parameters")[0]
.get("allowedValues")
)
"""Renvoie la référence Alfresco d'un JSON contenant au premier
niveau la clé "nodeRef" puis supprime le chemin du workspace
"""
return result.get("nodeRef", "").replace("workspace://SpacesStore/", "")
def push_alfresco_file(self, file, name, metadata=None, backend=None, folder=None):
Ajoute un fichier sur la GED Alfresco
@return: fonction get_partner_files() de res.partner
if not backend:
backend = self.env["cmis.backend"].search([], limit=1)
if not folder:
raise exceptions.ValidationError(
_("Le dossier parent n'existe pas ou n'est pas renseigné !")
)

Benjamin - Le Filament
committed
cmis_rep = backend.get_cmis_repository()
cmis_obj = cmis_rep.getObject(folder)
_logger.info("Chargement document Alfresco : %s" % name)
file_upload = cmis_obj.createDocument(
name=name,
properties=metadata,
contentType="application/pdf",

Benjamin - Le Filament
committed
except UpdateConflictException:
_logger.info("Le document %s existe déjà dans le dossier spécifié" % name)
# Recherche noderef document existant
children = cmis_obj.getChildren().getResults()
old_cmis_file = list(filter(lambda f: f.name == name, children))[0]
# Création d'une copie de travail du document pour versionnage
pwc = old_cmis_file.checkout()
# Mise à jour de la version
pwc.checkin(
contentFile=file, contentType="application/pdf", properties=metadata
)
except (
ContentAlreadyExistsException,
ObjectNotFoundException,
InvalidArgumentException,
) as e:
_(
"L'appel à Alfresco à échoué :\n- Code: %s\n\n- Url\n%s\n\n- Détail\n%s"
)
except Exception as e:
raise exceptions.ValidationError(e)
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
def push_alfresco_file_api(self, file, name, metadata=None, folder=None):
"""
Ajoute un fichier sur la GED Alfresco
@return: fonction get_partner_files() de res.partner
"""
if not folder:
raise exceptions.ValidationError(
_("Le dossier parent n'existe pas ou n'est pas renseigné !")
)
# url = "/nodes/%s/children" % folder
url = (
"/alfresco/api/-default-/public/alfresco/versions/1/nodes/%s/children?majorVersion=true"
% folder
)
_logger.info("Chargement document Alfresco : %s" % name)
content_type = "multipart/form-data"
params = {
"name": name,
"nodeType": "cmis:document",
"overwrite": True,
"properties": metadata,
}
files = {"filedata": (name, file, content_type, params)}
return self.alfresco_get_by_url(url=url, call_type="post", files=files).json()