185 lines
6.3 KiB
Python
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}')
|