1 # rec_agent.tcl --
2 #
3 # FIXME: This file needs a description here.
4 #
5 # Copyright (c) 1997-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #
31 # @(#) $Header: /usr/mash/src/repository/mash/mash-1/tcl/applications/pathfinder/rec_agent.tcl,v 1.18 2002/02/03 04:22:06 lim Exp $
32
33
34 import AnnounceListenManager/AS/Client/Platform ArchiveSystem/Record
35
36 #
37 # The Rec_Agent class handles requests to record a particular Program.
38 #
39 Class Rec_Agent
40
41 Rec_Agent public init { } {
42
43 $self instvar archive_ schedule_ rec_list_ max_duration_
44
45 # Initialize the archive and schedule directories.
46 #set archive_ /h/mash/archive/web/
47 #set schedule_ ~/mash/tcl/applications/mash_server/schedule/
48 #set o [$self options]
49 #$o load_preferences "mserver"
50 set archive_ [$self get_option archive_root]
51 append archive_ [$self get_option archive_dir]
52 set schedule_ [$self get_option rec_schedule_dir]
53
54 # Initialize the maximum duration of a recording.
55 set max_duration_ [expr [$self get_option max_duration] * 60]
56
57
58 # Initialize the list of sessions being recorded and scheduled
59 # to be recorded. Read the cache to find out any programs that
60 # were scheduled previously.
61 set rec_list_ {}
62 $self read_cache
63 }
64
65
66 Rec_Agent private read_cache { } {
67
68 mtrace trcNet "In Rec_Agent::read_cache"
69
70 $self instvar schedule_ rec_list_
71
72 cd $schedule_
73 set ctgfiles [glob -nocomplain -- *]
74
75 foreach f $ctgfiles {
76 mtrace trcNet "-> Reading file $f"
77 set catalog [new SessionCatalog]
78 $catalog open $f
79 $catalog read
80
81 set msg [lindex [ [new SDPParser 0] parse [$catalog get_sdp]] 0]
82 set program [new Program $msg]
83
84 # Add this program to the list of recordings as well as to
85 # the list of session lists.
86 lappend rec_list_ $f $msg
87
88 set start_time [$catalog get_info rec_start]
89 set end_time [$catalog get_info rec_end]
90
91 $self reschedule $program $start_time $end_time
92
93 $catalog destroy
94 }
95 }
96
97
98 Rec_Agent private reschedule { program start_time end_time } {
99
100 mtrace trcNet "In Rec_Agent::reschedule"
101
102 set current [clock seconds]
103 set start_offset [expr $start_time - $current]
104 set end_offset [expr $end_time - $current]
105
106 if { $end_offset < 0 } {
107 $self removeprog $program
108 return
109 } else {
110 $self schedule stop $program $end_offset
111 }
112
113 if { $start_offset <= 0 } {
114 # For now, begin recording into a new module.
115 $self start_recording $program
116 } else {
117 $self schedule start $program $start_offset
118 }
119 }
120
121
122 #
123 # The record method schedules a recording of the given program.
124 #
125 Rec_Agent public record { program } {
126
127 $self instvar archive_ stop_status_array_ start_status_array_ \
128 max_duration_
129
130 set key [get_key $program]
131
132 set sdp_time [ [$program base] set alltimedes_]
133 set repeat [$sdp_time readable_repeat]
134 set start_time [ntp_to_unix [$sdp_time set starttime_]]
135 set end_time [ntp_to_unix [$sdp_time set endtime_]]
136 set orig_end_time $end_time
137 set orig_start_time $start_time
138 set current [clock seconds]
139
140 # Do time zone adjustment
141 set session_zone [$sdp_time readable_zone starttime_]
142 set current_zone [clock format $current -format {%Z}]
143 if { $session_zone != $current_zone } {
144 set offset 3600
145 if { [string match *D* $current_zone] } {
146 set offset -3600
147 }
148 set start_time [expr $start_time + $offset]
149 set end_time [expr $end_time + $offset]
150 }
151
152 # Find the start_offset and end_offset; i.e. the number of
153 # seconds in the future to start and end.
154 set start_offset [expr $start_time - $current]
155 set end_offset [expr $end_time - $current]
156 set max_duration_offset 0
157
158 # These variables will contain the actual start time and end
159 # time for the recording. They will then be passed into the
160 # addprog method.
161 set act_start_time 0
162 set act_end_time 0
163
164
165 if { $end_offset < 0 && $orig_end_time != 0 } {
166 set start_status_array_($key) "Session expired; no recording made"
167 set stop_status_array_($key) ""
168
169 } elseif { $repeat == "None" } {
170
171 # If there is no repeat interval, simply base the record
172 # time on starttime_ and endtime_.
173 if { $start_time <= $current && $current < $end_time || \
174 $orig_start_time == 0 && $orig_end_time == 0 || \
175 $start_time == 0 && $current < $end_time || \
176 $start_time <= $current && $end_time == 0 } {
177 # Begin recording if the current time is in the start/end
178 # interval.
179 $self start_recording $program
180 set act_start_time $current
181 set max_duration_offset $max_duration_
182
183 } elseif { $start_offset >= 0 } {
184 # Otherwise, schedule the recording for the future.
185 $self schedule start $program $start_offset
186 set act_start_time [expr $current + $start_offset]
187 set max_duration_offset [expr $start_offset + $max_duration_]
188
189 } else {
190 puts "Error: Recording not scheduled or started."
191 exit
192 }
193
194 # Schedule an end to the recording if possible.
195 if { $orig_end_time == 0 || $end_offset >= $max_duration_offset } {
196 # If the end_time is 0, then this session goes on
197 # indefinitely; cap the recording time to max_duration_.
198 # Also cap the recording time if the end_offset is greater
199 # than max_duration_.
200 $self schedule stop $program $max_duration_offset
201 set act_end_time [expr $current + $max_duration_offset]
202
203 } elseif { $end_offset >= 0 && $end_offset < $max_duration_offset } {
204 # Otherwise, have the recordings stopped in the future.
205 $self schedule stop $program $end_offset
206 set act_end_time [expr $current + $end_offset]
207
208 } else {
209 puts "Error: Recording end not scheduled."
210 exit
211 }
212
213 } else {
214 # Handle the recording of this repeated session.
215 set interval [$sdp_time get repeat_interval_]
216 set duration [$sdp_time get active_duration_]
217
218 set offset_list [$sdp_time get offlist_]
219 # Assume for now, no offsets. Pain!
220
221 set rep_start $start_time
222 set rep_end [expr $start_time + $duration]
223 set end_offset [expr $rep_end - $current]
224 set start_scheduled 0
225 while { $rep_start < $end_time && $current < $end_time } {
226
227 # Between repeated sessions or before the first session ->
228 # schedule a recording for the future.
229 if { $current < $rep_start } {
230 set start_offset [expr $rep_start - $current]
231 $self schedule start $program $start_offset
232 set act_start_time [expr $current + $start_offset]
233 set max_duration_offset [expr $start_offset + $max_duration_]
234 set start_scheduled 1
235
236 # In the middle of a repeated session -> begin recording now.
237 } elseif { $rep_start <= $current && $current < $rep_end } {
238 $self start_recording $program
239 set act_start_time $current
240 set max_duration_offset $max_duration_
241 set start_scheduled 1
242 }
243
244 # Schedule the end of recording if end_offset has been set
245 # above to a non-zero value.
246 if { $start_scheduled } {
247 if { $end_offset < $max_duration_offset } {
248 $self schedule stop $program $end_offset
249 set act_end_time [expr $current + $end_offset]
250 } else {
251 $self schedule stop $program $max_duration_offset
252 set act_end_time [expr $current + $max_duration_offset]
253 }
254 break
255 }
256
257 set rep_start [expr $rep_start + $interval]
258 set rep_end [expr $rep_start + $duration]
259 set end_offset [expr $rep_end - $current]
260 mtrace trcNet "-> start/current/end: \
261 [$self readable_time $rep_start]/\
262 [$self readable_time $current]/\
263 [$self readable_time $rep_end]"
264 }
265 }
266
267 # Add the program and the rec_list_ and write it to file.
268 # Also, add the archive_sys to the archive_list_ so that
269 # it can be stopped later.
270 $self addprog $program $act_start_time $act_end_time
271 }
272
273
274 Rec_Agent private schedule { command program interval } {
275
276 $self instvar stop_status_array_ start_status_array_
277
278 mtrace trcNet "-> Schedule $command recording."
279 append full_command $command _recording
280 $self schedule_helper "$self $full_command $program" $program $interval
281
282 # Update the right status array
283 set key [get_key $program]
284 set time_str [$self readable_time [expr [clock seconds] + $interval]]
285
286 if { $command == "start" } {
287 set start_status_array_($key) "Scheduled for $time_str"
288
289 } elseif { $command == "stop" } {
290 set stop_status_array_($key) "Scheduled for $time_str"
291
292 } else {
293 puts "Error: Invalid command to schedule"
294 exit
295 }
296 }
297
298
299 Rec_Agent private readable_time { time } {
300 return [clock format $time -format {%a %B %d, %Y at %H:%M}]
301 }
302
303
304 Rec_Agent private schedule_helper { command program interval } {
305
306 $self instvar schedule_array_
307
308 if { $interval < 0 } {
309 puts "Error: Parameter interval to proc schedule < 0"
310 exit
311 }
312
313 mtrace trcNet "-> Scheduling command: $command"
314
315 set interval_ms [expr $interval * 1000]
316 set extra 0
317 if { $interval_ms < 0 } {
318 set extra [expr $extra + 86400]
319 set interval [expr $interval - 86400]
320 set interval_ms [expr $interval * 1000]
321 }
322
323 set new_command ""
324 if { $extra == 0 } {
325 after $interval_ms $command
326 set new_command $command
327
328 } elseif { $extra > 0 } {
329 set extra_ms [expr $extra * 1000]
330 set new_command "$self schedule_helper $command $program $extra_ms"
331 after $interval_ms "$self schedule_helper $command $program $extra_ms"
332
333 } else {
334 puts "Error: $extra < 0"
335 exit
336 }
337
338 mtrace trcNet "-> Command scheduled: $new_command"
339
340 set key [get_key $program]
341 set schedule_array_($key) $new_command
342 }
343
344
345 #
346 # The addprog method adds a given program to the list of scheduled
347 # Programs. Also, the archive_sys is added to the archive_array_ so
348 # that the Program recording can later be stopped.
349 #
350 Rec_Agent private addprog { program start_time end_time } {
351
352 $self instvar schedule_ rec_list_
353 global tcl_platform
354
355 # Extract the unique key and message of this Program
356 set key [get_key $program]
357 set msg [$program base]
358
359 # Add this program to the list of recordings as well as to the list
360 # of session lists.
361 lappend rec_list_ $key $msg
362
363 # Store the message in a file with the filename key in the cache.
364 if {$tcl_platform(platform) == "windows"} {
365 # semi-colons are illegal in windows filenames
366 regsub -all ":" $key "+" newkey
367 append filename $schedule_ $newkey
368 } else {
369 append filename $schedule_ $key
370 }
371 set catalog [new SessionCatalog]
372 $catalog open $filename w
373 $catalog write_sdp [$msg obj2str]
374 $catalog write_info "rec_start=$start_time\nrec_end=$end_time"
375 $catalog destroy
376 }
377
378
379 #
380 # The return_schedule method returns a list of SDP key and Program
381 # pairs for scheduled recordings. This list can then be converted into
382 # an associated array.
383 #
384 Rec_Agent public return_progs { } {
385 $self instvar rec_list_
386 return $rec_list_
387 }
388
389
390 Rec_Agent public return_path { key } {
391
392 $self instvar module_array_ archive_
393 global tcl_platform
394
395 set path ""
396 if { [array names module_array_ $key] != "" } {
397 if {$tcl_platform(platform) == "windows"} {
398 regsub -all ":" $module_array($key) "+" newmod
399 append path $newmod "\cat.ctg"
400 } else {
401 append path $module_array_($key) "/cat.ctg"
402 }
403 }
404 return $path
405 }
406
407
408 Rec_Agent public return_status { type key } {
409
410 $self instvar start_status_array_ stop_status_array_ \
411 module_array_ archive_
412 global tcl_platform
413
414 if { $type == "start" } {
415
416 set status $start_status_array_($key)
417
418 # Check if there are actually video/audio streams being
419 # transmitted and recorded.
420 # Need to collect and report local quality as well
421 if { $status == "Recording" } {
422 if {$tcl_platform(platform) == "windows"} {
423 # semi-colons are illegal in windows filenames
424 regsub -all ":" $module_array($key) "+" newmod
425 append filename $archive_ $newmod "\cat.ctg"
426
427 } else {
428 append filename $archive_ $module_array_($key) "/cat.ctg"
429 }
430 if { ![string match *START_STREAM* [read_file $filename]] } {
431 set status "Recording (waiting for video/audio stream)."
432 }
433 }
434 } elseif { $type == "stop" } {
435 set status $stop_status_array_($key)
436
437 } else {
438 puts "Error: Invalid type to return_status."
439 exit
440 }
441
442 return $status
443 }
444
445
446 # start a local recorder
447 Rec_Agent private start_recording { program } {
448
449 mtrace trcNet "-> Starting recorder"
450 $self instvar archive_ archive_array_ start_status_array_ \
451 module_array_ schedule_array_
452
453 set key [get_key $program]
454
455 # Use a timestamp for the module name and add the module to the
456 # module_array_.
457 set module [string trim [clock clicks] -]
458 set module_array_($key) $module
459
460 # Use the ArchiveSystem/Record class for recording and write
461 # the SDP Program information to the catalog file.
462 set archive_sys [new ArchiveSystem/Record]
463 $archive_sys open $archive_ $module
464 $archive_sys write_announcement $program
465
466 # Write relevant recording information to the catalog file
467 set current [$self readable_time [clock seconds]]
468 set info "record_start=$current"
469 $archive_sys write_info $info
470
471 # Begin recording and add the archive_sys object to the
472 # archive_array_ so that the recording can later be stopped.
473 $archive_sys record_program $program $module
474 set archive_array_($key,local) $archive_sys
475
476 # Update the start-status array.
477 set start_status_array_($key) "Recording"
478
479 # Update the schedule array by deleting the entry for this
480 # program, if the entry exists.
481 # ???
482 set exists [array names schedule_array_ $key]
483 if { $exists != "" } {
484 # ???
485 }
486 }
487
488
489
490
491 #
492 # The stop_recording method stops the recording of the specified
493 # Program. If the recording has not yet begun, the scheduled recording
494 # is cancelled.
495 #
496 Rec_Agent public stop_recording { program } {
497
498 $self instvar archive_array_ schedule_array_ start_status_array_ \
499 end_status_array_ rec_list_ archive_ module_array_
500
501 set key [get_key $program]
502
503 set start_status [$self return_status start $key]
504 mtrace trcNet "-> Start status: $start_status"
505
506 set is_recording [string match *Recording* $start_status]
507 set is_expired [string match *expired* $start_status]
508 set is_scheduled [string match *Scheduled* $start_status]
509
510 if { $is_recording } {
511
512 # Update the catalog file's info block to include the end time.
513 set current [$self readable_time [clock seconds]]
514 set info "record_end=$current"
515 $archive_array_($key,local) write_info $info
516
517 # Stop the recording by deleting the archive_sys object.
518 $archive_array_($key,local) close
519 delete $archive_array_($key,local)
520
521 # Check if any streams were actually recorded, and remove the
522 # archive module if not.
523 append directory $archive_ $module_array_($key)
524 append filename $directory /cat.ctg
525 set rec_started [string match *START_STREAM* [read_file $filename]]
526 if { !$rec_started } {
527 mtrace trcNet "-> Deleting archive directory"
528 file delete $filename
529 # ??? Why can't the directory be deleted
530 file delete $directory
531 }
532
533
534 } elseif { $is_scheduled } {
535 # Stop any future recordings that have been scheduled.
536 after cancel $schedule_array_($key)
537
538 } elseif { $is_expired } {
539
540 } else {
541 mtrace trcNet "-> Unknown start status"
542
543 }
544
545 # Remove this Program from rec_list_ and delete the corresponding
546 # file.
547 $self removeprog $program
548
549 # Update the status_array.
550 set start_status_array_($key) "stopped expired"
551 set end_status_array_($key) ""
552 }
553
554
555 #
556 # The removeprog method removes a Program from the list of Programs
557 # currently and scheduled to be recorded. The information is also
558 # taken out of the from the schedule directory.
559 #
560 Rec_Agent private removeprog { program } {
561
562 $self instvar schedule_ rec_list_
563 global tcl_platform
564
565 # Extract the unique key of this Program
566 set key [get_key $program]
567 mtrace trcNet "-> Removing recording: $key"
568
569 # Remove this program from the list of recordings.
570 set index [lsearch -exact $rec_list_ $key]
571 if {$index != -1} {
572 set rec_list_ [lreplace $rec_list_ $index [expr $index + 1]]
573 }
574 # Remove the file in the schedule directory.
575 if {$tcl_platform(platform) == "windows"} {
576 # semi-colons are illegal in windows filenames
577 regsub -all ":" $key "+" newkey
578 append filename $schedule_ $newkey
579
580 } else {
581 append filename $schedule_ $key
582
583 }
584 file delete $filename
585 }
586
587
588 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
589
590
591 import HTTP_Agent Rec_Agent/Distrib
592
593 #
594 # The HTTP_Agent/Rec_Agent class is an HTTP-aware agent that can be
595 # used in the MASH_Server. This object contains a plain Rec_Agent
596 # which is used to schedule recordings.
597 #
598 Class HTTP_Agent/Rec_Agent -superclass HTTP_Agent
599
600 HTTP_Agent/Rec_Agent public init { } {
601
602 $self next
603 $self instvar agent_ html_dir_ sessions_dir_ platform_alm_
604
605 if {[$self get_option allow_distrib] == "yes" } {
606 set agent_ [new Rec_Agent/Distrib]
607 # Fix gspec
608 set gspec [$self get_option glob_announce]
609 #Listen to the global AS1 platform channel for distributed recording placement
610 set platform_alm_ [new AnnounceListenManager/AS/Client/Platform $gspec]
611 } else {
612 set agent_ [new Rec_Agent]
613 }
614
615
616 # Initialize the html and sessions directories.
617 #set html_dir_ ~/mash/tcl/applications/mash_server/html/
618 #set o [$self options]
619 #$o load_preferences "mserver"
620 set html_dir_ [$self get_option html_dir]
621 set sessions_dir_ [$self get_option sdp_sessions_dir]
622
623 }
624
625
626 #
627 # The handle_request method is called by the MASH_Server when an
628 # HTTP request is received. This method checks for the "magic URLs"
629 # it cares about and returns the corresponding page.
630 #
631 HTTP_Agent/Rec_Agent instproc handle_request { url key source reply_var } {
632 upvar $reply_var reply
633 $self instvar agent_ html_dir_
634 mtrace trcNet "-> Rec_Agent::handle_request called"
635 set page ""
636 set status 200
637 set type "text/html"
638 set msg ""
639
640 # Check for the "magic" URLs.
641 if { $url == "/record" } {
642
643 mtrace trcNet "-> Request to record program received"
644
645 # Validate that the source can record programs.
646 if { [$self validate_source $source] } {
647
648 set scheduled [$self check_scheduled $key]
649 if { $scheduled == 0 } {
650
651
652 set program [$self get_program $key]
653 if { $program != "" } {
654 $agent_ record $program
655 append html_file $html_dir_ record.html
656 set page [read_file $html_file]
657
658 } else {
659 mtrace trcNet "-> File does not exist in session cache."
660 set msg "Session expired or not in cache."
661 set page [$self get_error_page $msg]
662 }
663
664 } else {
665 mtrace trcNet "-> Program already scheduled: $scheduled"
666 append html_file $html_dir_ record.html
667 set page [read_file $html_file]
668 }
669
670 } else {
671 set msg "Access to recorder not granted."
672 set page [$self get_error_page $msg]
673 }
674
675 } elseif { $url == "/record-list.html" } {
676 mtrace trcNet "-> Recordings schedule page requested"
677 set page [$self get_page recordings_list]
678
679 } elseif { $url == "/stop_record" } {
680
681 mtrace trcNet "-> Request to stop recording received"
682
683 # Validate that the source can record programs.
684 if { [$self validate_source $source] } {
685 $agent_ stop_recording [$self get_program $key]
686 set page [$self get_page recordings_list]
687
688 } else {
689 set msg "Access to recorder not granted."
690 set page [$self get_error_page $msg]
691 }
692
693 } elseif { $url == "/record-status" } {
694 mtrace trcNet "-> Request for recording status received"
695 set page [$self get_status_page $key]
696
697 } elseif { $url == "/add-recorder" } {
698 mtrace trcNet "-> Request to add a distributed recorder"
699 # pull the platform address out of the key
700 set pk [split $key +]
701 set newkey [lindex $pk 0]
702 set platform [lindex $pk 1]
703
704 # add recorder with the specified platform
705 set program [$self get_program $newkey]
706 if { $program != "" } {
707 $agent_ add_recorder $program $platform
708 }
709 set page [$self get_status_page $newkey]
710 }
711 if { $page != {} } {
712 set reply(headers) [list content-type $type]
713 set reply(data) $page
714 set reply(status) $status
715 return 1
716 } else {
717 return 0
718 }
719 }
720
721
722
723 # Produce another page containing available platforms
724 HTTP_Agent/Rec_Agent private get_status_page { key } {
725 $self instvar platform_alm_ list_ agent_ cur_platform_
726
727 $self update_agent_list
728 array set rec_array $list_
729
730
731 if {[$self get_option allow_distrib] == "yes" } {
732
733 # Use the key to find the program which will then create the
734 # HTML to be returned.
735 if [info exists rec_array($key)] {
736 set status_page [$rec_array($key) create_dynamic_html \
737 [DynamicHTMLifier set html_(distrib_recordings)]]
738 set start_status [$agent_ return_status start $key]
739 set distrib_status [$agent_ return_distrib_status $key]
740 if [string match *Recording* $start_status] {
741 foreach ALM $distrib_status {
742 set p_status([$ALM get_platform]) [$ALM get_status]
743 }
744 }
745
746 set platforms [$platform_alm_ get_platform_list]
747 foreach p $platforms {
748 if [info exists p_status($p)] {
749 append status_page "$p $p_status($p)<br>"
750 } else {
751 set cur_platform_ $p
752 append status_page "$p <a href=/add-recorder^$key+$p target=\"record-desc\"><img src=\"/images/recbut.gif\" border=0></a><font color=\#ffffff>.</font>
753 <br>"
754 }
755 }
756
757 set stop_status [$agent_ return_status stop $key]
758 append status_page "Local recording start status: " $start_status "<br\n"
759 append status_page "Stop status: " $stop_status "<br>\n"
760
761 append status_page "</body></html>"
762 } else {
763 set status_page "<html> No longer recording this session </html>"
764 }
765 return $status_page
766 } else {
767
768 # Use the key to find the program which will then create the
769 # HTML to be returned.
770 set status_page [$rec_array($key) create_dynamic_html \
771 [DynamicHTMLifier set html_(recordings_status)]]
772 set start_status [$agent_ return_status start $key]
773 set stop_status [$agent_ return_status stop $key]
774 set path [$agent_ return_path $key]
775 append status_page "Start status: " $start_status "<br>\n"
776 append status_page "Stop status: " $stop_status "<br>\n"
777 append status_page "Recording location: $path <br>\n"
778 append status_page "</body>\n</html>"
779 return $status_page
780 }
781 }
782
783
784
785
786 #
787 # The get_program method takes a key and returns the Program
788 # associated with that key. The Program is found in the SDP_Agent's
789 # sessions directory.
790 #
791 HTTP_Agent/Rec_Agent private get_program { key } {
792
793 $self instvar sessions_dir_
794 global tcl_platform
795
796 # Create the filename and find out whether it exists.
797 if {$tcl_platform(platform) == "windows"} {
798 # semi-colons are illegal in windows filenames
799 regsub -all ":" $key "+" newkey
800 append filename $sessions_dir_ $newkey
801
802 } else {
803 append filename $sessions_dir_ $key
804
805 }
806 if { [file exists $filename] } {
807 set data [file_dump $filename]
808 set msg [lindex [ [new SDPParser 0] parse $data] 0]
809 set program [new Program $msg]
810
811 } else {
812 mtrace trcNet "-> $filename does not exist in cache."
813 set program ""
814 }
815
816 return $program
817 }
818
819
820 #
821 # The check_scheduled method returns 0 or 1 depending on whether
822 # the Program specified by key is currently scheduled to be recorded.
823 #
824 HTTP_Agent/Rec_Agent private check_scheduled { key } {
825
826 $self instvar list_
827
828 # Update the list of scheduled recordings and check if an element
829 # for key is in the list.
830 $self update_agent_list
831 set exists [lsearch -exact $list_ $key]
832
833 if { $exists == -1 } {
834 return 0
835 } else {
836 return 1
837 }
838 }
839
840
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.