Casting and Costume Management Application
Check-in [cdb54e1e07]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add support for multiple types of clients.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:cdb54e1e0734996cd4b9cc73f76883d2d4b30f04
User & Date: gerald 2014-12-08 18:24:56
Context
2014-12-08
18:25
Add in the client builders. check-in: c55dd1dba7 user: gerald tags: trunk
18:24
Add support for multiple types of clients. check-in: cdb54e1e07 user: gerald tags: trunk
2014-07-01
03:01
Added Audition Entry Client application. check-in: 984e364058 user: gerald tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added src/Functions/AuditionClientRoutines.tcl.





























































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : SynchronizeAuditionsWithServer
#
# Description : Synchronize the audition database with the server.  First we push
#               the changes.  Then we pull the changes.
#
# Arguments : None
#
# Returns : Nothing
#
# Side-Effects : None.
#
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc SynchronizeAuditionsWithServer {} {
    ::log::log debug "[string repeat { } [info level]][info level 0]"
    variable DisplayConnectionStatusGui

    set DisplayConnectionStatusGui(statusMessage) {}
    set DisplayConnectionStatusGui(status) 0
    DisplayConnectionStatus
    set DisplayConnectionStatusGui(statusMessage) {Locating Server...}
    GetServerAddress
    set DisplayConnectionStatusGui(statusMessage) {Sending changes to server...}
    PushAuditionDatabase
    set DisplayConnectionStatusGui(statusMessage) {Refreshing data from server...}
    PullAuditionDatabase
    UndisplayConnectionStatus
    return
}

###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : PushAuditionDatabase
#
# Description : Push the changes to the server.  This will be all the
#               performers with a negative performer id, along with there
#               audition information, and all the audition information
#               marked as needing to be pushed.
#
# Arguments : None
#
# Returns : Nothing
#
# Side-Effects : None.
#
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc PushAuditionDatabase {} {
    ::log::log debug "[string repeat { } [info level]][info level 0]"
    variable serverInfo
    variable systemInfo

    ##
    ## Start with an empty dictionary
    ##
    set dataRecord [dict create]

    ##
    ## Get all of the new performers and their audition information
    ##
    set performerRecords {}
    set performerCols {
        HysellId FirstName LastName Birthdate ParentName
        ParentLast PhoneNumber MobileNumber EmailAddress
        ParentName2 ParentLast2 PhoneNumber2 MobileNumber2
        EmailAddress2 Address City State ZipCode School
        DancingSchool Active Report Notes
    }
    db eval {
        select  HysellId, FirstName, LastName, Birthdate, ParentName,
                ParentLast, PhoneNumber, MobileNumber, EmailAddress,
                ParentName2, ParentLast2, PhoneNumber2, MobileNumber2,
                EmailAddress2, Address, City, State, ZipCode, School,
                DancingSchool, Active, Report, Notes
            from Performers
            where HysellId  < 0
    } dbArr {
        parray dbArr
        set performerDict [dict create]
        foreach item $performerCols {
            dict set performerDict $item $dbArr($item)
        }
        lappend performerRecords $performerDict
    }
    foreach performerDict $performerRecords {
        set HysellId [dict get $performerDict HysellId]
        ##
        ## Get the audition info
        ##
        ::log::log info "\t Looking for HysellId = {$HysellId}"
        db eval {
            select ShowId, auditionnumber, changed
                from Casting
                where HysellId = $HysellId
        } dbArr {
            parray dbArr
            dict set performerDict AuditionNumber $dbArr(auditionnumber)
            dict set performerDict ShowId $dbArr(ShowID)
        }
        dict lappend dataRecord Performers $performerDict
        ::log::log info "\t Adding Performer Record {$performerDict}"
    }

    ##
    ## Get all of the Casting that was updated
    ##
    db eval {
        select ShowId, HysellId, auditionnumber
            from Casting
            where HysellId > 0
              and changed = 'Y'
    } dbArr {
        set auditionRecord [list $dbArr(ShowID) $dbArr(HysellId) $dbArr(auditionnumber)]
        dict lappend dataRecord Castings $auditionRecord
        ::log::log info "\t Adding Audition Record {$auditionRecord}"
    }

    ##
    ## Build the data record to send
    ##
    set cmdRecord [format {UPDATE %s %d AUDITIONDATA} $systemInfo(clientId) [string length $dataRecord]]

    ##
    ## Open the socket
    ##
    set socket [socket $serverInfo(host) $serverInfo(port)]
    fconfigure $socket -translation lf -blocking no

    ##
    ## Send the update
    ##
    ::log::log info "\t Sending {$cmdRecord}"
    puts $socket $cmdRecord
    puts -nonewline $socket $dataRecord
    flush $socket

    ##
    ## Close the socket
    ##
    close $socket

    return
}

###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : PullAuditionDatabase
#
# Description : Pull the changes from the server.  This means we first clear
#               the current tables.
#
# Arguments : None
#
# Returns : Nothing
#
# Side-Effects : None.
#
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc PullAuditionDatabase {} {
    ::log::log debug "[string repeat { } [info level]][info level 0]"
    variable serverInfo
    variable systemInfo

    ##
    ## Clear the show, performers and casting tables
    ##
    db eval {
        delete from Show
    }
    db eval {
        delete from Performers
    }
    db eval {
        delete from Casting
    }

    ##
    ## Request information from the server
    ##
    set cmdRecord [format {GET %s AUDITIONDATA} $systemInfo(clientId)]

    ##
    ## Open the socket
    ##
    set socket [socket $serverInfo(host) $serverInfo(port)]
    fconfigure $socket -translation lf -blocking yes

    ##
    ## Send the request
    ##
    ::log::log info "\t Sending {$cmdRecord}"
    puts $socket $cmdRecord
    flush $socket
    set response {}
    set status [gets $socket response]
    ::log::log info "\t Received {$response} with status {$status}"
    if {($status > 0) && [string equal [lindex $response 0] DATA]} {
        set length [lindex $response end]
        set dbDictionary [read -nonewline $socket]
        set lengthReceived [string length $dbDictionary]
        if {$length != $lengthReceived} {
            tk_messageBox \
                -default ok \
                -detail  "Received {$length} expected {$lengthReceived}." \
                -icon error \
                -message {Short message received.} \
                -parent . \
                -title {Applicaiton Error}
                -type ok
            after 1 {destroy .}
        }
    } else {
        tk_messageBox \
            -default ok \
            -icon error \
            -message {Server connection failed.} \
            -parent . \
            -title {Applicaiton Error} \
            -type ok
        after 1 {destroy .}
    }

    ##
    ## Close the socket
    ##
    close $socket

    ##
    ## Populate the Show
    ##
    lassign [dict get $dbDictionary ShowInfo] ShowID ShowDescription ShowClass
    db eval {
        insert into Show (ShowID, ShowDescription, ShowClass)
        values ($ShowID, $ShowDescription, $ShowClass)
    }

    ##
    ## Populate the Performers
    ##
    foreach performerRecord [dict get $dbDictionary Performers] {
        lassign $performerRecord \
                HysellId FirstName LastName BirthDate ParentName ParentLast \
                PhoneNumber MobileNumber EmailAddress ParentName2 ParentLast2 \
                PhoneNumber2 MobileNumber2 EmailAddress2 Address City State \
                ZipCode School DancingSchool Active Report Notes
        db eval {
            insert into Performers (
                HysellId, FirstName, LastName, BirthDate, ParentName,
                ParentLast, PhoneNumber, MobileNumber, EmailAddress,
                ParentName2, ParentLast2, PhoneNumber2, MobileNumber2,
                EmailAddress2, Address, City, State, ZipCode, School,
                DancingSchool, Active, Report, Notes
            ) values (
                $HysellId, $FirstName, $LastName, $BirthDate, $ParentName,
                $ParentLast, $PhoneNumber, $MobileNumber, $EmailAddress,
                $ParentName2, $ParentLast2, $PhoneNumber2, $MobileNumber2,
                $EmailAddress2, $Address, $City, $State, $ZipCode, $School,
                $DancingSchool, $Active, $Report, $Notes
            )
        }
    }

    ##
    ## Populate the Casting
    ##
    foreach castingRecord [dict get $dbDictionary Casting] {
        lassign $castingRecord ShowId HysellId auditionnumber
        db eval {
            insert into Casting (ShowId,HysellId,auditionnumber,changed)
            values ($ShowId,$HysellId,$auditionnumber,'N')
        }
    }

    return
}

Changes to src/Functions/ClientRoutines.tcl.

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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
}

###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : SynchronizeWithServer
#
# Description : Synchronize the database with the server.  First we push
#               the changes.  Then we pull the changes.
#
# Arguments : None
#
# Returns : Nothing
#
# Side-Effects : None.
#
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc SynchronizeWithServer {} {
    ::log::log debug "[string repeat { } [info level]][info level 0]"
    variable DisplayConnectionStatusGui

    set DisplayConnectionStatusGui(statusMessage) {}
    set DisplayConnectionStatusGui(status) 0
    DisplayConnectionStatus
    set DisplayConnectionStatusGui(statusMessage) {Locating Server...}
    GetServerAddress
    set DisplayConnectionStatusGui(statusMessage) {Sending changes to server...}
    PushDatabase
    set DisplayConnectionStatusGui(statusMessage) {Refreshing data from server...}
    PullDatabase
    UndisplayConnectionStatus
    return
}

###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : udpEventHandler
#
# Description : Handle a UDP message from the server.
#
# Arguments :
#   sock - the socket we were listening on
#
................................................................................

    set DisplayConnectionStatusGui(statusMessage) {Searching for server...}
    update idletasks
    set serverInfo(host) {}
    set serverInfo(port) {}

    set group 224.5.1.21
    set port  7771

    set socket [udp_open $port]
    fconfigure $socket -mcastadd $group
    fileevent $socket readable [list udpEventHandler $socket]
    vwait serverInfo(host)
    if {![info exists systemInfo(clientId)] || [string equal $systemInfo(clientId) {}]} {
        RegisterClient
................................................................................

    ##
    ## Close the socket
    ##
    close $socket
}


###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : PushDatabase
#
# Description : Push the changes to the server.  This will be all the
#               performers with a negative performer id, along with there
#               audition information, and all the audition information
#               marked as needing to be pushed.
#
# Arguments : None
#
# Returns : Nothing
#
# Side-Effects : None.
#
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc PushDatabase {} {
    ::log::log debug "[string repeat { } [info level]][info level 0]"
    variable serverInfo
    variable systemInfo

    ##
    ## Start with an empty dictionary
    ##
    set dataRecord [dict create]

    ##
    ## Get all of the new performers and their audition information
    ##
    set performerRecords {}
    set performerCols {
        HysellId FirstName LastName Birthdate ParentName
        ParentLast PhoneNumber MobileNumber EmailAddress
        ParentName2 ParentLast2 PhoneNumber2 MobileNumber2
        EmailAddress2 Address City State ZipCode School
        DancingSchool Active Report Notes
    }
    db eval {
        select  HysellId, FirstName, LastName, Birthdate, ParentName,
                ParentLast, PhoneNumber, MobileNumber, EmailAddress,
                ParentName2, ParentLast2, PhoneNumber2, MobileNumber2,
                EmailAddress2, Address, City, State, ZipCode, School,
                DancingSchool, Active, Report, Notes
            from Performers
            where HysellId  < 0
    } dbArr {
        parray dbArr
        set performerDict [dict create]
        foreach item $performerCols {
            dict set performerDict $item $dbArr($item)
        }
        lappend performerRecords $performerDict
    }
    foreach performerDict $performerRecords {
        set HysellId [dict get $performerDict HysellId]
        ##
        ## Get the audition info
        ##
        ::log::log info "\t Looking for HysellId = {$HysellId}"
        db eval {
            select ShowId, auditionnumber, changed
                from Casting
                where HysellId = $HysellId
        } dbArr {
            parray dbArr
            dict set performerDict AuditionNumber $dbArr(auditionnumber)
            dict set performerDict ShowId $dbArr(ShowID)
        }
        dict lappend dataRecord Performers $performerDict
        ::log::log info "\t Adding Performer Record {$performerDict}"
    }

    ##
    ## Get all of the Casting that was updated
    ##
    db eval {
        select ShowId, HysellId, auditionnumber
            from Casting
            where HysellId > 0
              and changed = 'Y'
    } dbArr {
        set auditionRecord [list $dbArr(ShowID) $dbArr(HysellId) $dbArr(auditionnumber)]
        dict lappend dataRecord Castings $auditionRecord
        ::log::log info "\t Adding Audition Record {$auditionRecord}"
    }

    ##
    ## Build the data record to send
    ##
    set cmdRecord [format {UPDATE %s %d} $systemInfo(clientId) [string length $dataRecord]]

    ##
    ## Open the socket
    ##
    set socket [socket $serverInfo(host) $serverInfo(port)]
    fconfigure $socket -translation lf -blocking no

    ##
    ## Send the update
    ##
    ::log::log info "\t Sending {$cmdRecord}"
    puts $socket $cmdRecord
    puts -nonewline $socket $dataRecord
    flush $socket

    ##
    ## Close the socket
    ##
    close $socket

    return
}

###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : PullDatabase
#
# Description : Pull the changes from the server.  This means we first clear
#               the current tables.
#
# Arguments : None
#
# Returns : Nothing
#
# Side-Effects : None.
#
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc PullDatabase {} {
    ::log::log debug "[string repeat { } [info level]][info level 0]"
    variable serverInfo
    variable systemInfo

    ##
    ## Clear the show, performers and casting tables
    ##
    db eval {
        delete from Show
    }
    db eval {
        delete from Performers
    }
    db eval {
        delete from Casting
    }

    ##
    ## Request information from the server
    ##
    set cmdRecord [format {GET %s} $systemInfo(clientId)]

    ##
    ## Open the socket
    ##
    set socket [socket $serverInfo(host) $serverInfo(port)]
    fconfigure $socket -translation lf -blocking yes

    ##
    ## Send the request
    ##
    ::log::log info "\t Sending {$cmdRecord}"
    puts $socket $cmdRecord
    flush $socket
    set response {}
    set status [gets $socket response]
    ::log::log info "\t Received {$response} with status {$status}"
    if {($status > 0) && [string equal [lindex $response 0] DATA]} {
        set length [lindex $response end]
        set dbDictionary [read -nonewline $socket]
        set lengthReceived [string length $dbDictionary]
        if {$length != $lengthReceived} {
            tk_messageBox \
                -default ok \
                -detail  "Received {$length} expected {$lengthReceived}." \
                -icon error \
                -message {Short message received.} \
                -parent . \
                -title {Applicaiton Error}
                -type ok
            after 1 {destroy .}
        }
    } else {
        tk_messageBox \
            -default ok \
            -icon error \
            -message {Server connection failed.} \
            -parent . \
            -title {Applicaiton Error} \
            -type ok
        after 1 {destroy .}
    }

    ##
    ## Close the socket
    ##
    close $socket

    ##
    ## Populate the Show
    ##
    lassign [dict get $dbDictionary ShowInfo] ShowID ShowDescription ShowClass
    db eval {
        insert into Show (ShowID, ShowDescription, ShowClass)
        values ($ShowID, $ShowDescription, $ShowClass)
    }

    ##
    ## Populate the Performers
    ##
    foreach performerRecord [dict get $dbDictionary Performers] {
        lassign $performerRecord \
                HysellId FirstName LastName BirthDate ParentName ParentLast \
                PhoneNumber MobileNumber EmailAddress ParentName2 ParentLast2 \
                PhoneNumber2 MobileNumber2 EmailAddress2 Address City State \
                ZipCode School DancingSchool Active Report Notes
        db eval {
            insert into Performers (
                HysellId, FirstName, LastName, BirthDate, ParentName,
                ParentLast, PhoneNumber, MobileNumber, EmailAddress,
                ParentName2, ParentLast2, PhoneNumber2, MobileNumber2,
                EmailAddress2, Address, City, State, ZipCode, School,
                DancingSchool, Active, Report, Notes
            ) values (
                $HysellId, $FirstName, $LastName, $BirthDate, $ParentName,
                $ParentLast, $PhoneNumber, $MobileNumber, $EmailAddress,
                $ParentName2, $ParentLast2, $PhoneNumber2, $MobileNumber2,
                $EmailAddress2, $Address, $City, $State, $ZipCode, $School,
                $DancingSchool, $Active, $Report, $Notes
            )
        }
    }

    ##
    ## Populate the Casting
    ##
    foreach castingRecord [dict get $dbDictionary Casting] {
        lassign $castingRecord ShowId HysellId auditionnumber
        db eval {
            insert into Casting (ShowId,HysellId,auditionnumber,changed)
            values ($ShowId,$HysellId,$auditionnumber,'N')
        }
    }

    return
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
129
130
131
132
133
134
135








































136
137
138
139
140
141
142
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
279
280
281
282
283
284
285







































































































































































































































































}

###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#








































# Procedure Name : udpEventHandler
#
# Description : Handle a UDP message from the server.
#
# Arguments :
#   sock - the socket we were listening on
#
................................................................................

    set DisplayConnectionStatusGui(statusMessage) {Searching for server...}
    update idletasks
    set serverInfo(host) {}
    set serverInfo(port) {}

    set group 224.5.1.21
    set port  7772

    set socket [udp_open $port]
    fconfigure $socket -mcastadd $group
    fileevent $socket readable [list udpEventHandler $socket]
    vwait serverInfo(host)
    if {![info exists systemInfo(clientId)] || [string equal $systemInfo(clientId) {}]} {
        RegisterClient
................................................................................

    ##
    ## Close the socket
    ##
    close $socket
}








































































































































































































































































Changes to src/Functions/ServerFunctions.tcl.

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
...
105
106
107
108
109
110
111

112
113
114
115
116
117
118
...
161
162
163
164
165
166
167


168








169
170
171
172
173
174
175
176


177










178
179
180
181
182
183
184
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
...
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
    variable serverInfo

    if {$serverInfo(state)} {
        ##
        ## Now active
        ##
        GetMyIp
        set serverInfo(tcpSocket) [socket -server AcceptConnection 8080]
        set group 224.5.1.21
        set port  7771
        set serverInfo(udpSocket)  [udp_open]
        fconfigure $serverInfo(udpSocket) -buffering none -remote [list $group $port]
        BroadCastIp
        ::log::log info "\t Started server on $serverInfo(ipAddr):8080"
    } else {
        ##
        ## Now inactive
................................................................................
###########################################################################
proc GetMyIp {} {
    variable serverInfo

    if { [ catch {
        set ip 127.0.0.1
        set sid [ socket -async [ info hostname ] 22 ]

        set serverInfo(ipAddr) [ lindex [ fconfigure $sid -sockname ] 0 ]
        ::close $sid
    } err ] } {
        catch { ::close $sid }
        puts stderr "myIP error: '$err' on port 22 (sshd). using 127.0.0.1"
    }
    return
................................................................................
                    flush $channel
                }
                UPDATE  {
                    set clientId [lindex $clientRequest 1]
                    set dataLength [lindex $clientRequest 2]
                    set data [read $channel $dataLength]
                    ::log::log info "\t\t Data is {$data}"


                    ProcessUpdate $data








                    db eval {
                        update Clients
                            set UploadedAt = $now
                            where ClientId = $clientId
                    }
                }
                GET     {
                    set clientId [lindex $clientRequest 1]


                    set reply [ProccesGet $clientId]










                    ::log::log info "\tReply is {$reply}"
                    puts -nonewline $channel $reply
                    flush $channel
                    db eval {
                        update Clients
                            set DownloadedAt = $now
                            where ClientId = $clientId
................................................................................


###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : ProccesGet
#
# Description : Get the data for a client.
#
# Arguments :
#   clientId    - ID of client to get data for
#
# Returns :
#   The reply to the client that consisting of:
#       DATA <dataLenght>
................................................................................
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc ProccesGet {clientId} {
    variable systemInfo

    set result {}
    set dataDict [dict create]

    ##
    ## Build the data dictionary
................................................................................


###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : ProcessUpdate
#
# Description : Handle an update from the client.
#
# Arguments :
#   data        - dictionary of information to update
#
# Returns : Nothing
#
# Side-Effects : None.
................................................................................
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc ProcessUpdate {dataDict} {
    set result {}

    if {[dict exists $dataDict Performers]} {
        ::log::log info "Processing Performers"
        foreach performerDict [dict get $dataDict Performers] {
            ProcessAddPerformer $performerDict
        }







|

|







 







>







 







>
>
|
>
>
>
>
>
>
>
>








>
>
|
>
>
>
>
>
>
>
>
>
>







 







|

|







 







|







 







|

|







 







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
    variable serverInfo

    if {$serverInfo(state)} {
        ##
        ## Now active
        ##
        GetMyIp
        set serverInfo(tcpSocket) [socket -server AcceptConnection 8082]
        set group 224.5.1.21
        set port  7772
        set serverInfo(udpSocket)  [udp_open]
        fconfigure $serverInfo(udpSocket) -buffering none -remote [list $group $port]
        BroadCastIp
        ::log::log info "\t Started server on $serverInfo(ipAddr):8080"
    } else {
        ##
        ## Now inactive
................................................................................
###########################################################################
proc GetMyIp {} {
    variable serverInfo

    if { [ catch {
        set ip 127.0.0.1
        set sid [ socket -async [ info hostname ] 22 ]
        update idletasks
        set serverInfo(ipAddr) [ lindex [ fconfigure $sid -sockname ] 0 ]
        ::close $sid
    } err ] } {
        catch { ::close $sid }
        puts stderr "myIP error: '$err' on port 22 (sshd). using 127.0.0.1"
    }
    return
................................................................................
                    flush $channel
                }
                UPDATE  {
                    set clientId [lindex $clientRequest 1]
                    set dataLength [lindex $clientRequest 2]
                    set data [read $channel $dataLength]
                    ::log::log info "\t\t Data is {$data}"
                    switch -exact -- [lindex $clientRequest 3] {
                        AUDITIONDATA {
                            ProcessAuditionUpdate $data
                        }
                        BACKSTAGEDATA -
                        default {
                            ##
                            ## Not supported at this time, so do nothing
                            ##
                        }
                    }
                    db eval {
                        update Clients
                            set UploadedAt = $now
                            where ClientId = $clientId
                    }
                }
                GET     {
                    set clientId [lindex $clientRequest 1]
                    switch -exact -- [lindex $clientRequest 2] {
                        AUDITIONDATA {
                            set reply [ProccesGetAudition $clientId]
                        }
                        BACKSTAGEDATA {
                            set reply [ProccesGetBackstage $clientId]
                        }
                        default {
                            ##
                            ## Not supported at this time, so do nothing
                            ##
                        }                    }

                    ::log::log info "\tReply is {$reply}"
                    puts -nonewline $channel $reply
                    flush $channel
                    db eval {
                        update Clients
                            set DownloadedAt = $now
                            where ClientId = $clientId
................................................................................


###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : ProccesGetAudition
#
# Description : Get the audition data for a client.
#
# Arguments :
#   clientId    - ID of client to get data for
#
# Returns :
#   The reply to the client that consisting of:
#       DATA <dataLenght>
................................................................................
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc ProccesGetAudition {clientId} {
    variable systemInfo

    set result {}
    set dataDict [dict create]

    ##
    ## Build the data dictionary
................................................................................


###########################################################################
#
# Procedure Header - as this procedure is modified, please be sure
#                           that you update this header block. Thanks.
#
# Procedure Name : ProcessAuditionUpdate
#
# Description : Handle an audtion update from the client.
#
# Arguments :
#   data        - dictionary of information to update
#
# Returns : Nothing
#
# Side-Effects : None.
................................................................................
# Exception Conditions : None
#
# Pre-requisite Conditions : None
#
# Original Author : Gerald W. Lester
#
###########################################################################
proc ProcessAuditionUpdate {dataDict} {
    set result {}

    if {[dict exists $dataDict Performers]} {
        ::log::log info "Processing Performers"
        foreach performerDict [dict get $dataDict Performers] {
            ProcessAddPerformer $performerDict
        }

Changes to src/Guis/AuditionEntryGui.tcl.

264
265
266
267
268
269
270
271
272
273
274
275
276
277
    menu $menuWidget.file
    $menuWidget add cascade \
        -label {File} \
        -menu $menuWidget.file
    $menuWidget.file add command \
        -label {Synch} \
        -underline 1 \
        -command SynchronizeWithServer
    $menuWidget.file add separator
    $menuWidget.file add command \
        -label {Exit} \
        -underline 1 \
        -command [list after 1 ExitApplication]
}







|






264
265
266
267
268
269
270
271
272
273
274
275
276
277
    menu $menuWidget.file
    $menuWidget add cascade \
        -label {File} \
        -menu $menuWidget.file
    $menuWidget.file add command \
        -label {Synch} \
        -underline 1 \
        -command SynchronizeAuditionsWithServer
    $menuWidget.file add separator
    $menuWidget.file add command \
        -label {Exit} \
        -underline 1 \
        -command [list after 1 ExitApplication]
}

Changes to src/Guis/MainWindow.tcl.

159
160
161
162
163
164
165

166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
        -menu $menuWidget.file
    menu $menuWidget.file
    $menuWidget.file add cascade \
        -label {Reports} \
        -underline 0 \
        -menu $menuWidget.file.report
    menu $menuWidget.file.report -postcommand [list BuildReportMenu $menuWidget.file.report]

    $menuWidget.file add checkbutton \
        -label {Serve DB} \
        -underline 1 \
        -command {ChangeServerState} \
        -onvalue yes \
        -offvalue no \
        -variable ::serverInfo(state)
    $menuWidget.file add separator

    $menuWidget.file add command \
        -label {Exit} \
        -underline 1 \
        -command [list after 1 ExitApplication]

    ##
    ## Add in track menu







>
|
|
|
|
|
|
|
|
>







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        -menu $menuWidget.file
    menu $menuWidget.file
    $menuWidget.file add cascade \
        -label {Reports} \
        -underline 0 \
        -menu $menuWidget.file.report
    menu $menuWidget.file.report -postcommand [list BuildReportMenu $menuWidget.file.report]
    if {$::udpPresent} {
        $menuWidget.file add checkbutton \
            -label {Serve DB} \
            -underline 1 \
            -command {ChangeServerState} \
            -onvalue yes \
            -offvalue no \
            -variable ::serverInfo(state)
        $menuWidget.file add separator
    }
    $menuWidget.file add command \
        -label {Exit} \
        -underline 1 \
        -command [list after 1 ExitApplication]

    ##
    ## Add in track menu

Changes to src/Main.tcl.

39
40
41
42
43
44
45

46




47
48
49
50
51
52
53
package require tdbc 1.0
package require tdbc::sqlite3
package require msgcat
package require csv
package require log
package require struct
package require struct::set

package require udp





set baseDir [file dirname [info script]]

set CopyFamilyInfo(fieldList) {EmailAddress Address City State ZipCode ParentName ParentLast PhoneNumber MobileNumber  ParentName2 ParentLast2 PhoneNumber2 MobileNumber2}
set PerformerColList {HysellId FirstName LastName BirthDate EmailAddress Address City State ZipCode School DancingSchool ParentName ParentLast PhoneNumber MobileNumber  ParentName2 ParentLast2 PhoneNumber2 MobileNumber2 Active Report Notes fnsort lnsort}
set CostumeColList {ShowId charctercode auditionnumber FirstName LastName Costume1 Costume2 Costume3 Costume4 Notes}
set ReportColDisplayList {ReportName Description ReportType InitalFile PrependShowId Title}







>
|
>
>
>
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package require tdbc 1.0
package require tdbc::sqlite3
package require msgcat
package require csv
package require log
package require struct
package require struct::set

if {[catch {package require udp}]} {
    set udpPresent yes
} else {
    set udpPresent no
}

set baseDir [file dirname [info script]]

set CopyFamilyInfo(fieldList) {EmailAddress Address City State ZipCode ParentName ParentLast PhoneNumber MobileNumber  ParentName2 ParentLast2 PhoneNumber2 MobileNumber2}
set PerformerColList {HysellId FirstName LastName BirthDate EmailAddress Address City State ZipCode School DancingSchool ParentName ParentLast PhoneNumber MobileNumber  ParentName2 ParentLast2 PhoneNumber2 MobileNumber2 Active Report Notes fnsort lnsort}
set CostumeColList {ShowId charctercode auditionnumber FirstName LastName Costume1 Costume2 Costume3 Costume4 Notes}
set ReportColDisplayList {ReportName Description ReportType InitalFile PrependShowId Title}