/
ShorthandParser.py
154 lines (123 loc) · 5.6 KB
/
ShorthandParser.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
148
149
150
151
152
153
154
import re
import datetime
import random
from random import randint
from DateUtils import DateUtils
from Flight import Flight
from Glider import Glider, GliderSearch
from Location import Location
class ShorthandParseException(Exception):
def __init__(self, expr, msg):
self.expr = expr
self.msg = msg
def __str__(self):
return self.msg + " (" + self.expr + ")"
class ShorthandParser():
def __init__(self, shorthand, db):
self.shorthand = shorthand
self.db = db
@staticmethod
def generateRandomEntry(db):
shorthand = "A"
randomDate = DateUtils.randomDate(datetime.date(2013, 6, 1), datetime.date.today())
shorthand += "D" + randomDate.strftime("%d%m%y")
shorthand += "G" + Glider.getRandomTrigraphOrCompNo(db)
shorthand += "L" + Location.getRandomLocation(db)[:3]
nFlights = randint(1,4);
shorthand += "N" + str(nFlights)
shorthand += "P" + str(randint(1,2))
shorthand += "T"
for i in range(nFlights):
shorthand += "%02d" % randint(3, 20)
shorthand += random.choice("WA")
shorthand = shorthand.upper()
shorthand += "NRandom Notes " if random.choice([True, False]) else ""
return shorthand
def getFlights(self):
print self.shorthand
"""Create a flight object from a shorthand command"""
regexp = """
A
(D[0-9]{6})?
(G[A-Z0-9]{2,3})
(L[A-Z]{3})
(N[0-9]{1,2})
(P1|P2)
T([0-9]*)
(W|A)?
(N.*)?
"""
regexp = ''.join(regexp.split())
try:
matches = re.match(regexp, self.shorthand).groups()
except AttributeError:
raise ShorthandParseException(self.shorthand, "Failed to parse shorthand")
expectedMatches = [
"Date",
"Identifier",
"Location",
"Number Of Flights",
"Capacity",
"Times",
"Launch Type",
"Notes"
]
successfulParseCount = 0
for idx, expectedMatch in enumerate(expectedMatches):
if matches[idx] is not None:
match = matches[idx][1:]
if expectedMatch == "Identifier":
gliders = GliderSearch.find(self.db, GliderSearch.TRIGRAPH, match)
if len(gliders) == 0:
gliders = GliderSearch.find(self.db, GliderSearch.COMPNO, match)
if len(gliders) == 0:
raise ShorthandParseException(matches[idx], "Could not parse this %s" % expectedMatch )
gliderID = random.choice(gliders).Get('ID')
elif expectedMatch == "Date":
try:
flightDate = datetime.datetime.strptime(match, "%d%m%y")
except:
raise ShorthandParseException(matches[idx], "Could not parse this %s" % expectedMatch )
elif expectedMatch == "Location":
location_name = Location.findByName(self.db, match).Get('name')
if location_name is None:
raise ShorthandParseException(matches[idx], "Could not parse this %s" % expectedMatch)
elif expectedMatch == "Number Of Flights":
try:
number_of_flights = int(match)
except:
raise ShorthandParseException(matches[idx], "Could not parse this %s" % expectedMatch)
elif expectedMatch == "Capacity":
capacity = "P" + match
elif expectedMatch == "Times":
times = self.__parseQuickEntryTimes(matches[idx])
if times is None:
raise ShorthandParseException(matches[idx], "Could not parse this as %s" % expectedMatch)
elif expectedMatch == "Launch Type":
launchtype = match
elif expectedMatch == "Notes":
notes = match
else:
## Date, launch type and notes are not required
if expectedMatch == "Launch Type":
launchtype = "W" # Default to winch type
elif expectedMatch == "Notes":
notes = ""
elif expectedMatch == "Date":
flightDate = date.today()
else:
raise ShorthandParseException(self.shorthand, "Expected entry %s was not found" % expectedMatch)
if len(times) != number_of_flights:
raise ShorthandParseException(self.shorthand, "Number of flights (%d) and provided times (%d) do not match." % (number_of_flights, len(times)))
flights = [Flight(self.db, self.db.flights, flightDate, gliderID, location_name, capacity, t, launchtype, 0, notes) for t in times]
return flights
@staticmethod
def __parseQuickEntryTimes(times):
""" Parses a numeric string in the form "99999999..." where each 99
represents a flight time in minutes """
try:
# Split and convert to integers
integerTimes = [int(times[i:i+2]) for i in range(0, len(times), 2)]
except ValueError:
raise
return integerTimes