old_console/ncircc/services/comments.py
2024-11-02 14:12:45 +03:00

185 lines
6.3 KiB
Python

import json
import logging
import uuid
from dataclasses import dataclass
from datetime import datetime, timedelta
from json import JSONDecodeError
from typing import Dict, Optional, List
from urllib.parse import urljoin
import requests
from django.contrib.auth.models import User
from django.db.utils import IntegrityError
from company.models.company import Company
from console.settings.base import NCIRCC_DOMAIN_NAME, NCIRCC_CERT_VERIFY
from ncircc.models.comments import Comment
from ncircc.models.notification import Notification
from ncircc.serializers.comments import CommentRetrieveSerializer
_log = logging.getLogger(__name__)
@dataclass
class CommentSuccessDataResponse:
"""Data for success comment created"""
id: int
incident_id: int
comment: str
user_id: int
d_comment: datetime
t_comment: str
createdAt: datetime
updatedAt: datetime
to: str
parent_id: Optional[int]
workgroup_resolved: bool
options: dict
@dataclass
class CommentGettingResponse:
id: int
incident_uuid: uuid.UUID
text: str
login: str
incident_id: str
create_time: datetime
class CommentSenderService:
"""Send comment to notification."""
path = '/api/v2/comments'
def __init__(self, message: str, notification_pk: int, user: User) -> None:
self.user = user
self.company = Company.objects.first()
self.message = message
notification = Notification.objects.get(pk=notification_pk)
self.notification_uuid = str(notification.uuid)
def get_headers(self) -> Dict[str, str]:
"""Return headers for sending."""
headers = {
'x-token': self.company.api_key,
'Content-Type': 'application/json',
}
return headers
def get_payload(self) -> dict:
data = {
'incident.uuid': self.notification_uuid,
'data': {'comment': self.message}
}
return data
def _save(self, data: CommentSuccessDataResponse) -> Comment:
comment = Comment(
text=self.message,
notification=Notification.objects.get(uuid=self.notification_uuid),
id_in_ncircc=data.id,
create_time=data.createdAt,
login=str(self.user.username),
is_read=True,
from_console=True,
)
comment.save()
return CommentRetrieveSerializer(comment).data
def send(self):
url = urljoin(NCIRCC_DOMAIN_NAME, self.path)
msg, status = 'Success', 200
headers = self.get_headers()
payload = self.get_payload()
try:
response = requests.post(url, json=payload, headers=headers, verify=NCIRCC_CERT_VERIFY)
except requests.exceptions.RequestException as err:
_log.error(f'Error: {err}')
return str(err), 400
try:
data = response.json()
except (JSONDecodeError, AttributeError) as err:
_log.error(f'Error: {err}')
return str(err), 400
if response.status_code == 200:
data = self._save(CommentSuccessDataResponse(**data.get('data', {})))
return data, status
else:
return 'Error', 400
class CommentsUpdaterService:
"""Service for getting all comments and save it in db"""
update_delta = timedelta(minutes=10) # todo после уточнения изменить
company = None
path = 'api/v2/incidents/comments'
def __init__(self) -> None:
self.company = Company.objects.first()
def get_headers(self) -> Dict[str, str]:
"""Return headers for sending."""
headers = {
'x-token': self.company.api_key,
'Content-Type': 'application/json',
}
return headers
def get_payload(self) -> tuple:
data_value = datetime.now() - self.update_delta
params = [
{"property": "create_time", "operator": "gte", "value": str(data_value.isoformat())},
{"property": "login", "operator": "endsWith", "value": "НКЦКИ"}]
return ('filter', json.dumps(params),),
def send(self):
_log.debug('start1')
url = urljoin(NCIRCC_DOMAIN_NAME, self.path)
payload = self.get_payload()
headers = self.get_headers()
try:
response = requests.get(url, headers=headers, params=payload, verify=NCIRCC_CERT_VERIFY)
except requests.exceptions.RequestException as err:
_log.error(f'Error: {err}')
return 'Error', 400
try:
data = response.json()
except (JSONDecodeError, AttributeError) as err:
_log.error(f'Error: {err}')
return 'Error', 400
if response.status_code == 200:
data = data.get('data', [])
comment_list = [CommentGettingResponse(**self.clear_comments_request(comment)) for comment in data]
self._save(comment_list)
return 'Success', 200
else:
_log.error(f'Error: {data}')
return 'Error', 400
def clear_comments_request(self, data: dict) -> dict:
"""Clear json from ncircc."""
if 'incident.uuid' in data:
data['incident_uuid'] = data.pop('incident.uuid')
if 'incident.id' in data:
data['incident_id'] = data.pop('incident.id')
return data
def _save(self, comments: List[CommentGettingResponse]) -> None:
"""bulk create comments in db"""
incidents_uuid = [comment.incident_uuid for comment in comments]
_log.debug(f'start bulk save: {incidents_uuid}')
notifications = Notification.objects.filter(uuid__in=incidents_uuid)
notifications_map = {str(notification.uuid): notification for notification in notifications}
for comment in comments:
if notifications_map.get(comment.incident_uuid):
try:
Comment.objects.create(text=comment.text, notification=notifications_map[comment.incident_uuid],
create_time=comment.create_time, login=comment.login,
id_in_ncircc=comment.id)
except IntegrityError as err:
_log.debug(f'Cannot save comment {comment.id}: {err}')
_log.debug(f'Saved: {incidents_uuid}')