-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsnotparser.py
executable file
·147 lines (120 loc) · 5.29 KB
/
snotparser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
import subprocess
import string
import re
from string import Template
ADMINISTRATIVE_START_MARKER = "XXXXXXXXXXXXXXXXXX Administrative Information Follows XXXXXXXXXXXXXXXXXXXXXX"
TICKET_ERROR_MARKER = "::::::::::::::"
def parseTicket(number, command='snot'):
process = subprocess.Popen([command, '-sr', str(number)], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
bodyStartLine = 0
administrativeStartLine = 0
ticketDictionary = {}
rawTicket = process.stdout.readlines()
#print rawTicket[0]
if TICKET_ERROR_MARKER in rawTicket[0]:
return None
#print "Finding bodyStartLine"
enumeratedRawTicket = enumerate(rawTicket)
for index, line in enumeratedRawTicket:
if len(line) == 1:
bodyStartLine = index
break
#print "Finding administrativeStartLine"
for index, line in enumeratedRawTicket:
if ADMINISTRATIVE_START_MARKER in line:
administrativeStartLine = index
break
# Usually the second line, which contains both the date and a from address, which may or
# may not be different from the "From:" line
for line in rawTicket[0:bodyStartLine]:
match = re.match(r"^From\s*(?P<summary_line>.+)$", line)
if match:
summary_email = re.search(r"(?P<email>\S*@\S*)", match.group("summary_line"))
if summary_email:
ticketDictionary["summary_email"] = summary_email.group("email")
break
#print "Searching for from field"
for line in rawTicket[0:bodyStartLine]:
match = re.match(r"^From:\s*(?P<from_line>.*)$", line)
if match:
ticketDictionary["from_line"] = match.group("from_line")
break
for line in rawTicket[administrativeStartLine:]:
kvMatch = re.match("^(?P<key>.+?):\s+(?P<value>.*)$", line)
if kvMatch:
ticketDictionary[kvMatch.group("key").lower().replace(" ", "_")] = kvMatch.group("value")
# if "assigned to" not in ticketDictionary:
# ticketDictionary["assigned_to"] = "unassigned"
ticketDictionary['number'] = number
if ticketDictionary['priority'].startswith('+'):
ticketDictionary['status'] = 'completed'
elif ticketDictionary.get('closed_by') is not None:
ticketDictionary['status'] = 'completed'
else:
ticketDictionary['status'] = 'open'
return ticketDictionary
def formatTicket(number, formatString, command='snot'):
ticketDictionary = parseTicket(number, command)
if ticketDictionary:
return Template(formatString).safe_substitute(ticketDictionary)
else:
return str(number) + ": No ticket found"
# Formats a ticket dict using the newer formatting system
def formatTicketDictSmart(ticketDict, formatString):
# formatString will be in the form of "assigned_to,from_line,subject" csv
if not ticketDict:
return "No such ticket"
formatKeys = formatString.split(',')
formattedItems = []
for key in formatKeys:
key = key.strip()
if key == "from":
from_line = ticketDict["from_line"]
emailRegex = '\s?(?P<email>(?P<username>\S+?)@(?P<domain>\S+?))\s?'
m = re.match(r"^%s(\s.*)?$" % emailRegex, from_line) or re.match(r'^\s*?"?(?P<name>.+?)"? \<%s\>' % emailRegex, from_line)
if m:
md = m.groupdict()
emailFormatted = md["email"]
if re.match("(cat|cecs|ece|ee|cs|etm|me|mme|cee|ce)\.pdx\.edu", md["domain"]):
emailFormatted = md["username"]
itemText = ""
if "name" in md:
formattedItems.append("%s (%s)" % (md["name"], emailFormatted))
else:
formattedItems.append(emailFormatted)
else:
formattedItems.append("ERROR (yell at Wren)")
elif key == "url":
formattedItems.append("https://snot.cat.pdx.edu/snot.cgi?command=View&ticket=%s" % ticketDict["number"])
else:
if key in ticketDict and ticketDict[key].strip():
value = ticketDict[key].strip()
if key == "assigned_to":
assignmentMatch = re.match(r"(?P<username>[^@]+)@?(?P<domain>\S*)", value)
if (assignmentMatch):
formattedItems.append(assignmentMatch.groupdict()["username"])
else:
formattedItems.append(ticketDict[key])
return string.join(formattedItems, " | ")
#return (bodyStartLine, administrativeStartLine)
#return bodyStartLine
def formatTicketSmart(number, formatString, command='snot'):
ticketDictionary = parseTicket(number, command)
if ticketDictionary:
return formatTicketDictSmart(ticketDictionary, formatString)
else:
return str(number) + ": No ticket found"
def getTicketHistory(number):
try:
number = int(number)
process = subprocess.Popen(['grep', "TKT: %d" % number, "/u/snot/logs/log"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return process.stdout.readlines()
except ValueError as e:
return str(e)
if __name__ == "__main__":
import sys
import os
snot_cmd = os.environ.get('SNOT_CMD', 'snot')
ticket_num = sys.argv[1]
print ticket_num, parseTicket(ticket_num, snot_cmd)