/
server.dyalog
141 lines (125 loc) · 4.02 KB
/
server.dyalog
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
:NameSpace Server
calendars ← ⍬
∇ Start port;r;name;mode
load_conga_drc_if_not_already_present
name ← 'Booking Server'
mode ← 'Text'
#.DRC.Init ''
r ← #.DRC.Srv name '' port mode
:If 0≠⊃r
⎕ ← 'Error: ',⍕r
:Else
⎕ ← name,' Started [',⍕port,']'
connect_receive_loop name
⎕ ← name, 'Terminating'
{}#.DRC.Close name
:EndIf
∇
∇ load_conga_drc_if_not_already_present
:If 0=⎕NC '#.DRC'
'DRC' #.⎕CY 'conga'
:EndIf
∇
∇ connect_receive_loop name;DONE;event
DONE ← 0
:While ~DONE
event ← #.DRC.Wait name 10000
:If 0=⊃event
DONE ← handle_event name event
:EndIf
:EndWhile
∇
∇ Z ← handle_event (name event);event_name
event_name ← ⍕event[3]
:Select event_name
:Case ' Connect '
⎕ ← 'Connected'
Z ← 0
:Case ' Block '
Z ← handle_data_received event
:Else
Z ← 0
:EndSelect
∇
∇ Z ← handle_data_received event;reply;done
(done reply)← generate_reply ⍕event[4]
#.DRC.Send event[2] reply 1
Z ← done
∇
∇ Z ← generate_reply data;command;rest;done;reply
command ← #.Command.parse data
rest ← 1↓command
done ← 0
:Select ⊃ command
:Case 'add'
reply ← add_new_bookable rest
:Case 'remove'
reply ← remove_bookable rest
:Case 'show'
reply ← show_calendar rest
:Case 'book'
reply ← book_slots rest
:Case 'stop'
reply ← 'stopped server'
done ← 1
:EndSelect
Z ← done reply
∇
∇ Z ← add_new_bookable data
calendars,← { #.Calendar.new_calendar ⍵ 3 3 } ¨ data
Z ← 'added a new calendar for ',⊃{⍺,' ',⍵ }/data
∇
∇ Z ← remove_bookable data;hits;removed;missing
hits ← {(⊂⊃⍵) ∊ data} ¨ calendars
removed ← ⊃ ¨ hits/calendars
missing ← ({~(⊂⍵) ∊ (data ∩ removed) } ¨ data)/data
:If 1 = ^/ data∊missing
Z ← 'no such bookable ',⊃{⍺,' ',⍵}/missing
:Else
calendars ← (~hits)/calendars
Z ← 'removed ',⊃{⍺,' ',⍵}/removed
:EndIf
∇
∇ Z ← show_calendar data;selected
selected ← ({ (⊂⊃⍵) ∊ data } ¨ calendars)/calendars
:If 0=⊃⍴selected
Z ← 'no such bookable ',⊃{⍺,' ',⍵}/data
:Else
Z ← ⊃{⍺,(⎕UCS 10),⍵}/ #.Calendar.visualize ¨ selected
:EndIf
∇
∇ Z ← book_slots data;mode
mode ← ⊃data
:Select mode
:Case 'all'
Z ← book_all data
:Case 'maximize'
Z ← maximize_booking data
:Case 'mustcould'
Z ← book_musts_and_could data
:EndSelect
∇
∇ Z ← book_all data;from;to;duration;indices;slices;slots;selected
(from duration) ← data[2 3]
indices ← indices_of_named_calendars 3↓data
selected ← calendars[indices]
slots ← (⍎from),(⍎from) + ⍳ (¯1 + ⍎duration)
calendars[indices] ← { #.Calendar.mark_as_booked ⍵ slots 1 } ¨ selected
Z ← 'booked slots ',⍕slots
∇
∇ Z ← maximize_booking data;from;to;duration;indices;selected;slices;slots
(from to duration) ← data[2 3 4]
indices ← indices_of_named_calendars 4↓data
selected ← calendars[indices]
slices ← { #.Calendar.calendar_slice ⍵ (⍎from) (⍎to) } ¨ selected
slots ← #.Booking.indices_of_slots_maximizing_attending slices (⍎duration)
calendars[indices] ← { #.Calendar.mark_as_booked ⍵ slots 1 } ¨ selected
Z ← 'booked slots ',⍕slots
∇
∇ Z ← book_musts_and_could data
Z ← 'not implemented yet'
∇
∇ Z ← indices_of_named_calendars data
Z ← ({ (⊂⊃⍵) ∊ data } ¨ calendars)/⍳⍴calendars
∇
:EndNameSpace