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'Sysaid ticket #{issue_id}'
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