source: tmcsimulator/branches/LCSv2/controllers/default.py.bak @ 641

Revision 641, 24.0 KB checked in by jdalbey, 5 years ago (diff)

LCSv2.default.py modified for #254. Changed studentnames file reading.

Line 
1# added comments for testing
2# Constants
3kLogfile = "samplelogfile.txt"
4kSimtimefile = "sim_elapsedtime.json"  #"../webapps/dynamicdata/sim_elapsed_time.json"
5hwys = ['','1','5', '22', '55', '57', '73', '74', '91', '133', '142', '241', '261', '405', '605']
6hwyDirections = ['','NB', 'SB', 'NB/SB','EB','WB','EB/WB']
7# Names to appear in the username dropdown box
8users = []
9users.append('')
10# Show the login page
11def index():
12    userfile = open('student_names.txt','r')
13    # read the file into a buffer
14    buffer = [line.strip() for line in userfile.readlines()]
15    # Append each name in the buffer to the users list, skipping blank lines
16    for item in buffer:
17        if len(item) > 0:
18            users.append(item)
19    form = FORM(LABEL('User:',_for='username', _class="label username-label"),
20                #INPUT(_name='username', _size='15', _style="font-size: 18px;"), BR(),
21                SELECT(users,_name='username',requires=IS_LENGTH(minsize=1,error_message='Must select a user from the list.')),BR(),
22                INPUT(_type='submit',_value="Log in", _class=" btn btn-primary", _style="margin-top: 3%;"))
23    if form.process().accepted:
24        # Put the username entry into the session variable
25        session.username = reverseNameFields(form.vars.username)
26        redirect(URL('home'))
27    return dict(form=form)
28def home():
29    return dict(name=session.username)
30def help():
31    return dict()
32# List all the current records in the database - remove in final application
33def list():
34    highways = db().select(db.closures.ALL, orderby=db.closures.closureid)
35    return dict(highways = highways)
36# Show details of a single record - remove in final application
37def show():
38    # Retrieve the requested log entry from the database
39    # Assumes the requested entry exists in the db (no error handling yet)
40    hwy = db(db.closures.lognum == request.args(0)).select().first()
41    return dict(hwy=hwy)
42# Display a search form
43def search():
44    form = FORM(LABEL('ClosureID/Log:',_for='closureid', _class="label"),
45                INPUT(_name='closureid',_size='7', _style="margin-right: 5px;"),
46                INPUT(_name='lognum',_size='3'),
47                XML('   '),
48                LABEL('Route: ',_for='route', _class="label"),
49                SELECT(hwys,_name='route'), XML('   '),
50                LABEL('Direction: ',_for='direction', _class="label"),
51                SELECT(hwyDirections,_name='direction'), BR(),BR(),
52                LABEL('Dates:',_for='startdate', _class="label"),
53                INPUT(_name='startdate',_class='date'),
54                XML('   '),
55                LABEL('  to:',_for='enddate', _class="label"),
56                INPUT(_name='enddate',_class='date'),BR(),
57                INPUT(_value="Search", _type='submit', _class="btn btn-primary btn-default", _style="margin:  7% 45% 2% 40%;"))
58    if form.process(onvalidation=special_validation).accepted:
59        # Put the form fields into the session variables
60        session.closureid = form.vars.closureid.strip().upper()
61        session.lognum = form.vars.lognum.strip()
62        session.startdate = form.vars.startdate.strip()
63        session.enddate = form.vars.enddate.strip()
64        session.route = form.vars.route
65        session.direction = form.vars.direction
66        redirect(URL('results'))
67    return dict(form=form)
68# Search Form: Special validation check to reject lognum without closureID
69def special_validation(form):
70    # Error if a lognum was given and no closure id
71    if (len(form.vars.lognum) > 0 and len(form.vars.closureid) == 0):
72       form.errors.lognum = 'Must provide a closureID when specifying a log number'
73# Show the item that was found in the search
74def results():
75    # query object is equivalent to the where clause in query
76    query = True
77    msg = ""
78    if (len(session.closureid) != 0):
79        query = (db.closures.closureid == session.closureid)
80        msg += " Closure ID = " + session.closureid   
81    if (len(session.lognum) != 0):
82        query = query & (db.closures.lognum == session.lognum)
83        msg += " Log number = " + session.lognum   
84    if (len(session.route) != 0):
85        query = query & (db.closures.route == session.route)
86        msg += " Route = " + session.route
87    if (len(session.direction) != 0):
88        query = query & (db.closures.direction == session.direction)
89        msg += " Route = " + session.route
90    if (len(session.startdate) != 0):
91        query = query & (db.closures.startdate >= session.startdate)
92        msg += "Start date = " + session.startdate
93    if (len(session.enddate) != 0):
94        query = query & (db.closures.enddate <= session.enddate)
95        msg += "End date = " + session.enddate
96   
97    # if no restrictions entered then get all entries
98    if query == True :
99        hwy = db().select(db.closures.ALL)
100        msg = "ALL"
101    else:
102        # get entries with the matching requirements
103        hwy = db(query).select()
104
105    count = len(hwy)
106    # Show the results in table format.  Get the radio call number from supervisor name lookup
107    header = THEAD(TR(TH(''), TH('DTM',BR(),'Area'), TH('Closure ID/',BR(),'Log No.'),TH('Route & Dir/',BR(),'Type of Closure'),TH('Start Date/',BR(),'End Date/',BR(),'Est. Delay'),TH('Facility/Lanes'),TH('Limits'),TH('Work'), TH('TMP:',BR(),'Cozeep/',BR(),'Detour'),TH('Requestor/',BR(),'Radio Call No.')))
108    multiform = []
109    # Iterates over all search results
110    for row in hwy:
111        statusfields = row.closureid +','+ row.lognum + ',1097,' + str(row.s1097user) +','+ str(row.startdate) + ',' + formatTime(row.starttime) +','+str(row.s1097date)+','+ formatTime(row.s1097time) + ',1098,' + str(row.s1098user) +','+ str(row.s1098date)+','+ formatTime(row.s1098time)+ ',1022,' + str(row.s1022user) +','+ str(row.s1022date)+','+ formatTime(row.s1022time)
112        # Each row contains a form with two buttons and columns with fields from database
113        multiform.append(TR(TD(
114                    XML("<button class='submit-button' onclick=\"showPopup(\'"),statusfields,XML("\')\">View History</button>"),BR(),
115                    FORM(
116                          INPUT(_type='submit',_name='btn2',_value='Show Status Form',_class="submit-button" ),
117                          INPUT(_type='hidden',_name='row',_value=row.closureid))),
118                          TD(row.closureid[0]),TD(row.closureid,HR(),row.lognum), TD(row.route,' ',row.direction,HR(),row.closuretype), TD(row.startdate,' ',formatTime(row.starttime),HR(),row.enddate,' ',formatTime(row.endtime),HR(),row.estdelay), TD(row.facility,HR(),row.closedlanes),
119TD(row.startlocation,HR(),row.endlocation), TD(row.worktype), TD(row.tmpcozeep,BR(),row.tmpdetour), TD(row.supervisor,HR(),db(db.supervisors.name == row.supervisor).select().first().radiocallnum) ))
120
121    session.chosenid = request.vars.row #Pass the hidden field containing the closure ID
122    if request.vars.btn2:
123        redirect(URL('statuslist'))
124    return dict(msg=msg, count=count, highways=hwy, table=header, multiform=multiform)
125
126# Show a selected closure with a status update form
127def statuslist():
128    closedItems = []
129    if (session.chosenid):
130        if (type(session.chosenid) is str):
131            retrieved = db(db.closures.closureid == session.chosenid).select().first()
132            closedItems.append(retrieved)
133        else:
134            # This logic is available to show multiple results, for possible future use.
135            for item in session.chosenid:
136                retrieved = db(db.closures.closureid == item).select().first()
137                closedItems.append(retrieved)
138        # Build the table rows       
139        tblrows = TR()       
140        for row in closedItems:
141            # Construct the status radio buttons; disable if date already in database
142            statusflags = "disabled" if row.s1097date == "" else "" 
143            if row.s1097date == "":
144                btn = LABEL('1097'), INPUT(_type='radio', _name='statustype', _value='1097'+row.closureid)
145            else:
146                btn = LABEL('1097 ○',_class='labelgray'),
147            btngroup = btn
148            if row.s1098date == "":
149                btn = LABEL('1098'), INPUT(_type='radio', _name='statustype', _value='1098'+row.closureid)
150            else:
151                btn = LABEL('1098 ○',_class='labelgray'),
152            btngroup += btn
153            if row.s1022date == "":
154                btn = LABEL('1022'), INPUT(_type='radio', _name='statustype', _value='1022'+row.closureid)
155            else:
156                btn = LABEL('1022 ○',_class='labelgray'),
157            btngroup += btn
158
159            if row.s1097date != "" and row.s1098date != "" and row.s1022date != "":
160                btngroup += BR(),LABEL('Statuser:', _class='labelgray')
161            else:   
162                btngroup += BR(),LABEL('Statuser:'),INPUT(_name='statuser',_size='9'),BR(),BR(),INPUT(_type='submit',_value="submit status update",_class="submit-button")
163#            LABEL('1097 ○',_class='colorgray'), INPUT(_type='radio', _name='statustype', _value='1097'+row.closureid),LABEL('1098'), INPUT(_type='radio', _name='statustype', _value='1098'+row.closureid),LABEL('1022'), INPUT(_type='radio', _name='statustype', _value='1022'+row.closureid),BR(), LABEL('Statuser:'),INPUT(_name='statuser',_size='9')
164            tblrows += TR(TD(row.closureid,HR(),row.lognum),TD(row.route,' ',row.direction,HR(),row.closuretype),TD(row.startdate,HR(),row.enddate,HR(),row.estdelay),TD(row.supervisor,BR(),db(db.supervisors.name == row.supervisor).select().first().radiocallnum),TD(btngroup))
165        form = FORM(BR(),
166                TABLE(THEAD(TR(TH('Closure ID/',BR(),'Log No.'), TH('Route & Dir',BR(),'Type of Closure'),TH('Start Date/',BR(),'End Date/',BR(),'Est. Delay'),TH('Requestor/',BR(),'Radio Call No.'),TH('Status'))),
167                    tblrows,
168                     
169                    _border='1', _cellpadding='5', _width="70%"))
170       
171    else:
172        msg = "No items were selected.  Use the checkbox in the lefthand column."
173        form = ""
174        return dict(msg=msg,form=form)
175   
176    if form.process().accepted:
177        #session.flash = 'Status submit acknowledgement appears here.'
178        session.statustype = form.vars.statustype
179        session.statuser = form.vars.statuser
180        redirect(URL('statusAck'))
181    return dict(form=form)
182
183# show status update acknowledgement - and update database
184def statusAck():
185    if (session.statustype):
186        if (type(session.statustype) is str):
187            msg = "You submitted a status update for " + session.statustype[4:] + ": " + session.statustype[0:4]
188#           Perform the update on the database
189            # Construct the name of the field to update
190            fieldname = "s"+session.statustype[0:4]+"user"
191            db(db.closures.closureid == session.statustype[4:]).update(**{fieldname:session.statuser})
192            import datetime
193            now = datetime.datetime.today()
194            fieldname = "s"+session.statustype[0:4]+"date"
195            db(db.closures.closureid == session.statustype[4:]).update(**{fieldname:now.strftime("%Y-%m-%d")})
196            fieldname = "s"+session.statustype[0:4]+"time"
197            db(db.closures.closureid == session.statustype[4:]).update(**{fieldname:now.strftime("%H%M")})
198            # Log the update to external file
199            logmessage = getSimTime() + ", LCS status update: " + session.username + ", " + session.statustype[4:] + ", " + session.statustype[0:4] + ", " + session.statuser + " " + "\n"
200            text_file = open(kLogfile, "a")
201            text_file.write(logmessage)
202            text_file.close()
203        else:
204            msg = "error because only checking one box is allowed."
205    else:
206        msg = "Error no statustype checkbox was checked"
207       
208    return dict(msg=msg)
209# Utility functions for formatting
210def formatTime(msg):
211    if (msg):
212        return msg[0:2]+':'+msg[2:4]
213    else:
214        return ""
215
216# Fetch simulation time and format it into a timestamp
217def getSimTime():
218    import json,datetime
219    try:
220        jsontime = json.load(open(kSimtimefile,'r'))
221        currentSimTime = jsontime["elapsedtime"]
222        timestamp = str(datetime.timedelta(seconds = int(currentSimTime)))
223        return '0'+timestamp  # assume simtime is < 10 and prefix a zero
224    except:
225        # Fallback if missing file, use current time
226        now = datetime.datetime.today()
227        return now.strftime("%H:%M:%S")
228
229# Create a new record
230def submit():
231    # Don't name this function 'request' because it creates a name conflict with http.request
232    hournames = ['','00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23']
233    closuretypes = ['', 'Lane', 'Full', 'Moving', 'One-Way Traffic', 'Alternating Lanes', 'Traffic Break']
234    facilities = ['', 'Connector', 'Conventional_Hwy', 'Mainline', 'Off Ramp', 'On Ramp', 'Rest Area', 'Surface Street']
235    worktypes = ['','AC Paving', 'Accident Investigation', 'Attenuator Repair', 'Blasting', 'Bridge Inspection', 'Bridge Work', 'Brush Fire', 'Chip Seal Operation', 'Concrete Pour', 'Core Drilling', 'Crack Seal Operation', 'Curb/Gutter/Sidewalk Work', 'Drainage Cleaning', 'Drainage Inspection', 'Drainage Work', 'Electrical Work', 'Emergency Work', 'Falsework Installation', 'Falsework Removal', 'Fence Work', 'Filming Activity', 'Fog Seal Operation', 'Graffiti Removal', 'Grinding and Paving', 'Grinding Operation', 'Guardrail Repair', 'Guardrail Work', 'Highway Construction', 'K-rail Installation', 'K-rail Removal', 'Landscape Work', 'Litter Removal', 'Maintenance Operation', 'Median Barrier Work', 'Miscellaneous Work', 'Pavement Marker Replacement', 'Pavement Repair', 'Pavement Work', 'Paving Operation', 'Pile Driving', 'Police Investigation', 'Roadway Excavation', 'Roadway Flooding', 'Sewer Work', 'Shoulder Work', 'Sign Work', 'Slab Replacement', 'Slide Removal', 'Slope Clearing', 'Soundwall Work', 'Special Event', 'Spray Operation', 'Striping Operation', 'Survey Work', 'Sweeping Operation', 'Traffic Signal Work', 'Tree Work', 'Utility Work', 'Vegetation Spraying']
236    supervisors = ['']  # List of names for the dropdown box
237    # Obtain all the supervisor names from the database
238    for row in db().select(db.supervisors.ALL):
239        supervisors.append(row.radiocallnum + ' ' + row.name)
240    crew = ['']  # List of names for the dropdown box
241    crewlookup = []
242    # Obtain all the crew names from the database
243    for row in db().select(db.crew.ALL):
244        crew.append(row.radiocallnum + ' ' + row.name)
245        crewlookup.append(row.radiocallnum + ' ' + row.name)
246    # Build the list of street locations and a hidden cross street lookup table
247    streets = ['']
248    streetlookup = []
249    for row in db().select(db.streets.ALL, orderby=db.streets.street):
250        streets.append(row.street)
251        streetlookup.append(row.route + ',' + row.street)
252    # Build the list of existing closures   
253    existingclosures = []
254    existingclosures.append("")
255    for row in db().select(db.closures.ALL, orderby=db.closures.closureid):
256        # Omit duplicate ID's (with different lognumbers)
257        if row.closureid not in existingclosures:
258            existingclosures.append(row.closureid)
259       
260    form = FORM(
261                LABEL('*Route',_for='route'), SELECT(hwys,_name='route', _id='routecombo', _onchange='routechanged()', requires=IS_LENGTH(minsize=1,error_message='route cannot be empty')), XML('&nbsp;&nbsp;&nbsp;'),
262           LABEL('*Direction',_for='direction'), SELECT(hwyDirections,_name='direction', requires=IS_LENGTH(minsize=1,error_message='direction cannot be empty')), XML('&nbsp;&nbsp;&nbsp;'),
263           LABEL('*Facility',_for='facility'), SELECT(facilities,_name='facility', _id='facilitycombo', requires=IS_LENGTH(minsize=1,error_message='facility cannot be empty')), BR(),BR(),
264           TABLE(TR(TD(),TD(LABEL('*County')),TD(LABEL('*Location'))),
265                TR(TD(LABEL('BEGIN=')),TD(SELECT('ORA',_name='startcounty')),
266                TD(SELECT(streets,_name='startlocation',_id='startlocation')),
267           TR(TD(LABEL('END=')),TD(SELECT('ORA',_name='endcounty')),TD(SELECT(streets,_name='endlocation',_id='endlocation'))))),BR(),
268           LABEL('Date Range:'),BR(),
269           LABEL('From',_for='startdate'),INPUT(_name='startdate',_size='8',_class='date'), XML('&nbsp;&nbsp;&nbsp;'),
270           LABEL('to:',_for='enddate'), INPUT(_name='enddate',_size='8',_class='date'),XML('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'),
271           LABEL('Times',_for='starttime'),SELECT(hournames,_name='starttime'),
272           LABEL(':',_for='starttimemin'),SELECT('','00','15','30','45','59',_name='starttimemin'), XML('&nbsp;&nbsp;'),
273           LABEL('to:',_for='endtime'),SELECT(hournames,_name='endtime'),
274           LABEL(':',_for='endtimemin'),SELECT('','00','15','30','45','59',_name='endtimemin'), BR(),BR(),
275           TABLE(TR(TD(LABEL('*Type of Closure') ),
276                    TD(LABEL('*Type of Work')),
277                    TD(LABEL('Estimated Delay')),
278                    TD(LABEL('TMP Details'))),
279                 TR(TD(SELECT(closuretypes,_name='closuretype',_id='closuretype', _onchange='closuretypechanged()',requires=IS_LENGTH(minsize=1,error_message='type of closure cannot be empty'))),
280                    TD(SELECT(worktypes,_name='worktype', requires=IS_LENGTH(minsize=1,error_message='type of work cannot be empty'))),
281                    TD(INPUT(_name='estdelay',_size='4'),'minutes'), 
282                    TD(INPUT(_type='checkbox',_name='cozeep'),'CoZeep MaZeep/CHP',BR(),
283                       INPUT(_type='checkbox', _name='detour'),'Detour Available')),
284                 TR(TD(DIV(LABEL("Lanes closed"),DIV(INPUT(_type='checkbox', _name='lanes', _id='lanes', _value=' '), _id='boxes'),_id='lanechooser',_style='display:none')),
285                    TD(INPUT(_type='hidden', _name='lanecount', _id='lanecount', _value='4')),
286                    TD(),
287                    TD()),
288                 _width='100%' ),
289    TABLE(TR(TD(LABEL('*Supervisor')),
290            TD(LABEL('Field Rep'))
291            ),
292          TR(TD(SELECT(supervisors,_name='supervisor', _id='supervisorcombo', _onchange='supervisorchanged()', requires=IS_LENGTH(minsize=1,error_message='supervisor cannot be empty'))),
293             TD(SELECT(crew,_name='fieldrep',_id='fieldrep')),
294             TD(XML("&nbsp;&nbsp;&nbsp;&nbsp;")),
295             TD('Is this an existing incident?',
296                INPUT(_type='radio',_name='existing',_value='No',_onclick='radioclicked()'),
297                'No',
298                INPUT(_type='radio',_name='existing',_value='Yes',value='Yes',_onclick='radioclicked()'),
299                'Yes'
300               )
301             ),
302          TR(TD(),TD(),TD(), TD('    Select closure ID:',SELECT(existingclosures,_name='existingid'),_id='closureselect'))),
303    TABLE(TR(TD( LABEL('Meeting Place/CHP Contact')),
304            TD(LABEL('Reason for Closure')),
305            TD(LABEL('Additional Remarks / Detour '))),
306                  TR(TD(INPUT(_name='meeting', _size='25')),TD(INPUT(_name='reason',_size='25')),TD(INPUT(_name='remarks',_size='25'))) ), BR(),
307            INPUT(_type='submit',_value='Submit Closure', _class="btn btn-primary btn-default", _style="margin:  2% 45% 2% 40%;"),
308            XML('\n'),SELECT(streetlookup,_name='stlookup', _id='stlookup', _class='hideme'),
309SELECT(crewlookup,_name='crewlookup', _id='crewlookup', _class='hideme'))
310
311    if form.process(onvalidation=validate_existing_id).accepted:
312        newLognum = calcNextLogNum(form.vars.existingid)
313        if newLognum == '1':
314            newID = calcNextClosureID(form.vars.route)
315        else:
316            newID = form.vars.existingid
317        supervisor_name = form.vars.supervisor[3:]
318        fieldrep_name = form.vars.fieldrep[5:]
319        selectedlanes = buildLanesClosedString(form.vars.lanes,form.vars.lanecount)
320        # Insert the record into the database
321        newrec = db.closures.insert(closureid=newID, lognum=newLognum, route=form.vars.route, direction=form.vars.direction, facility=form.vars.facility, startcounty=form.vars.startcounty, endcounty=form.vars.endcounty, startlocation=form.vars.startlocation, endlocation=form.vars.endlocation, startdate=form.vars.startdate, enddate=form.vars.enddate, starttime=form.vars.starttime+form.vars.starttimemin, endtime=form.vars.endtime+form.vars.endtimemin, closuretype=form.vars.closuretype, closedlanes=selectedlanes, worktype=form.vars.worktype, estdelay=form.vars.estdelay, tmpcozeep=getCheckbox(form.vars.cozeep), tmpdetour=getCheckbox(form.vars.detour), supervisor=supervisor_name, fieldrep=fieldrep_name, s1097date='', s1098date='', s1022date='' )
322        session.flash = 'New lane closure added: ' + newID + ' ' + newLognum + ': ' + selectedlanes
323        # Log the new closure to external file. Username, closureID, route, dir, type of closure, type of work
324        logmessage = getSimTime() + ", LCS new closure: " + session.username + ", " + newID + '.' + newLognum + ', ' + form.vars.route + form.vars.direction + ', ' + form.vars.closuretype + ', ' + form.vars.worktype + "\n"
325        text_file = open(kLogfile, "a")
326        text_file.write(logmessage)
327        text_file.close()
328        redirect(URL('search.html'))
329    return dict(form=form)
330
331# An unlinked page to allow admin to reset the database to simulation start state
332def resetdb():
333    form = FORM("Press this button to reset the closure database to its original state at the start of a simulation.",BR(),
334                "Warning: this will delete all the current closures.",BR(),
335                "Import filename is 'db_closures_start.csv'.",BR(),
336                INPUT(_value="Reset Database", _type='submit', _class="btn btn-primary btn-default"))
337    if form.process().accepted:
338        db(db.closures.id > 0).delete()   # remove all current records
339        with open('db_closures_start.csv', 'rb') as dumpfile:
340            db.closures.import_from_csv_file(dumpfile)  # import from starting state
341        session.flash = 'Closure database has been reset'
342        redirect(URL('search.html'))
343    return dict(form=form)
344
345# Validation for existing closure button
346# If user selected Yes (it's existing incident) then they must select a closure ID
347def validate_existing_id(form):
348    if form.vars.existing == 'Yes' and form.vars.existingid == '':
349        form.errors.existingid = "Existing incidents require selecting an existing closure ID"
350
351# Calculate the closure id to assign to the new closure
352def calcNextClosureID(routeNum):
353    # Retrieve the last existing closure on this route
354    #item = db(db.closures.closureid.startswith('T'+routeNum)).select().last() # defective
355    item = db(db.closures.route == routeNum).select().last()
356    if (item != None):
357        currID = item.closureid
358        lastchar = currID[-1:]  # Get last character of ID
359        lastchar = chr(ord(lastchar) + 1) # increment it to next character (need bounds check)
360        newID = currID[:-1] + lastchar  # append char to ID
361        return newID
362    else:
363        return 'T'+routeNum+'AA'  # For a non-existing route
364   
365# If existing incident closure ID is provided, increment the log number by 1
366def calcNextLogNum(existingid):
367    if existingid != '':
368        item = db(db.closures.closureid.startswith(existingid)).select().last()
369        prevLog = int(item.lognum)
370        nextLog = prevLog + 1
371        return str(nextLog)
372    else:
373        return '1'
374
375
376# Convert checkbox value to YES/NO
377def getCheckbox(ckBox):
378    if (ckBox == "on"):
379        return "YES"
380    else:
381        return "NO"
382
383# Swap the fields in a name, changing lastname first to firstname first.
384def reverseNameFields(formattedname):
385    # Divide the name into last and first names
386    x = formattedname.split(',')
387    # If there isn't a comma, return the entire name
388    if len(x) == 1:
389        return x[0].strip()
390    else:  # return the swapped fields
391        return x[1].strip() + ' ' + x[0]
392
393# Convert the lanes closed checkboxes into a human readable string
394# E.g.  #1 #3 of 4
395# Note: ckBoxGroup parameter contains only checked items
396def buildLanesClosedString(ckBoxGroup,lanecount):
397    result = ""
398    if ckBoxGroup is not None:
399        # Append each checked value to a string
400        for item in ckBoxGroup:
401            result = result + "#"+item + " "
402        result = result + "of " + lanecount
403    return result
Note: See TracBrowser for help on using the repository browser.