import io import logging import os import re import urllib.parse from datetime import datetime from typing import Any, Dict, Tuple import requests from django.core.cache import cache from django.utils.timezone import make_aware from .models import Department, Issue, Reciever, Status api_url = os.environ.get('DATA_ACQUISITION_URL') def is_sysaid(reciever: Reciever) -> int: sysaid_match = re.match(r'sys.?aid', reciever.name, re.IGNORECASE) return True if sysaid_match else False def parse_username(responsibility: str) -> str: string = responsibility.replace('.', ' ').title() result = string.split('\\') if result.__len__() >= 2: return result[-1] return string def url_encode(string: str) -> str: return urllib.parse.quote(string) def create_sysaid_ticket(config: Dict[str, Any], data: Dict[str, Any]) -> Tuple[bool, Dict[str, Any]]: def generate_body(data: Dict[str, Any]) -> str: template = "formID=0&reRoute=1&isLogged=1&noframe=null&type=null&subType=null&populateSR_id=182806&customFormCodeHiddenValue=&paneMessage=&paneType=&paneBtnArrayButtons=&panePreSubmitFunc=&panePreSubmitFunc2=&paneCancelFunc=&paneTextRow=¢erPopup=&parentPageName=SubmitSR.jsp&tabID=180&populateSR=&changedFields=null%5Eproblem_type%5Esubcategory%5EthirdLevelCategory%5Etitle%5Edesc&userChanged=0&requestUser={request_user}&autoAttach2ContactCiHidden=true&company={company_id}&problem_type=07.+Field_Support&subcategory=10.+FS_Ukraine&thirdLevelCategory=+&autoDescriptionTemplate=N&title={title}&desc={desc}&selectUrgency={urgency}&selectImpact=1&cust_list1={impact}&computer={hostname}&autoAttach2AssetCiHidden=true&removeAction=¬es=¬eToAdd=&verifyText=&location={location_id}&Apply=&OK=OK&Cancel=&Addtokb=&subAction=&reopenNote=&pageID=1&subPageID=1&replacePage=Y&changes=0¤tSupportLevel=0&CustomColumn150sr=2&CustomColumn170sr=Choose+Admin+group+who+will+be+informed+by+email.+If+you+don%27t+wish+to+inform+your+team+by+email%2C+Choose+Admin+group%3A+none&CustomColumn130sr=&CustomColumn175sr=&newActivities=&deletedActivities=&existingActiviteies=&changeCategory=0&resp=none&assignCounter=0&CustomColumn122sr=&followupUser=null&CustomColumn158sr=2&dueDate=&CustomColumn166sr=When+you+set+the+Security+Incident+or+MI+Flag+you+need+to+follow+Information+Security+Incident+management+procedure+or+Major+Incident+Procedure.+&autoMessages=true&custDate1=&hidden_disable_email_notifications_for_end_users=false&quick_name=null&quickSrId=182806&custDate2=&workaround=&CustomColumn162sr=&followupText=&adminGroup=none&CustomColumn180sr=&CustomColumn10sr=2&CustomColumn181sr=2&CustomColumn182sr=&CustomColumn176sr=&CustomColumn119sr=&selectPriority=1&custNotes=&CustomColumn12sr=&userManager=null&CustomColumn9sr=2&custText1=&custText2=&custInt1=0&custInt2=0&CustomColumn184sr=&projectID=0&attachedCIId=0&emailAccount=+&cc=&CustomColumn4sr=&updateUser=SEBN%5Cnuri.ramadan&CustomColumn146sr=2&CustomColumn154sr=&taskID=0&resolution=&solution=&CustomColumn5sr=&responsibleManager=null&followupPlannedDate=&CustomColumn6sr=&maxSupportLevel=0&CustomColumn138sr=2&cust_list2=0&CustomColumn174sr=&successRating=0&agreement=0&CustomColumn134sr=1&escalation=0&followupActualDate=" department = Department.objects.get(pk=data['department_id']) location_id = config['locations'][department.location.name] body = template.format(title=url_encode(data['title']), desc=url_encode(data['description']), urgency=data['urgency'], impact=data['impact'], hostname=url_encode(data['hostname']), request_user=config['request_user'], location_id=location_id, company_id=config.get('company_id', None)) return body def parse_issue_id(string: str) -> int | None: pattern = config['response_id_regex'] result = re.search(pattern, string) if (result): issue_id = result.group(1) return int(issue_id) return None server = config['server'] url = f'{server}SubmitSR.jsp' headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Connection': 'close', 'Origin': server, 'Referer': url, 'Cookie': config['cookie'] } body = generate_body(data) response = requests.post(url, data=body, headers=headers) issue_id = parse_issue_id(response.text) if issue_id: href = f'{server}index.jsp#/SREdit.jsp?id={issue_id}' text = f'<b>Sysaid ticket</b> <a href="{href}">#{issue_id}</a>' return (True, {'issue_id': issue_id, 'text': text}) return (False, { 'status_code': response.status_code, 'text': response.text }) def fetch_sysaid_ticket(id: int) -> Any: url = f'{api_url}sebn-data-acquisition/api/sebn-taskbar-manager/service-req/' response = requests.post(url, json={"id": id}) if response.status_code == 200: return response.json() logging.error(f'Error on fetch_sysaid_ticket: {response.status_code}') return None def save_sysaid_fields(issue: Issue, fields: Dict[str, str]) -> Issue: issue_status_id = fields['status'] cached_existed_status_ids = cache.get('status_ids', []) if not cached_existed_status_ids: cached_existed_status_ids = Status.objects.all().values( 'id', 'redmine_code', 'sysaid_code') cache.set('status_ids', cached_existed_status_ids) for s in cached_existed_status_ids: if s['sysaid_code'] == issue_status_id: issue.status_id = s['id'] # type: ignore ## not cached old code # status = Status.objects.filter(sysaid_code=fields['status']).first() # if status: issue.status = status if (fields['responsibility']): issue.responsibility = parse_username(fields['responsibility']) issue.comments = fields['notes'] if (fields['update_time']): issue.update_datetime = make_aware( datetime.fromisoformat(fields['update_time'])) if (fields['close_time']): issue.close_datetime = make_aware( datetime.fromisoformat(fields['close_time'])) issue.save() return issue def fetch_layout(hostname: str) -> Tuple[Any, str] | None: url = f'{api_url}sebn-material-requests-manager/api/location/' hostname_url = f'{api_url}sebn-material-requests-manager/locate/{hostname}' response = requests.post(url, json={"hostname": hostname}) if response.status_code == 200: return (io.BytesIO(response.content).read(), hostname_url) return None