2003-01-19 11:57:27 -05:00
|
|
|
(define-structure surflet surflet-interface
|
2002-12-08 10:49:27 -05:00
|
|
|
(open scheme-with-scsh
|
2003-01-19 11:57:27 -05:00
|
|
|
surflets
|
|
|
|
surflet-handler/admin
|
2002-10-01 13:44:58 -04:00
|
|
|
httpd-responses
|
2003-01-16 07:53:10 -05:00
|
|
|
httpd-requests
|
|
|
|
url
|
2002-10-02 09:39:55 -04:00
|
|
|
handle-fatal-error
|
|
|
|
let-opt
|
2003-01-16 07:53:10 -05:00
|
|
|
srfi-1 ;filter-map, last
|
2002-10-01 13:44:58 -04:00
|
|
|
sort
|
|
|
|
)
|
|
|
|
(begin
|
|
|
|
|
2003-01-19 11:57:27 -05:00
|
|
|
(define remove-surflet-path
|
|
|
|
(let ((regexp (rx ,(file-name-as-directory (options-surflet-path))
|
2002-10-01 13:44:58 -04:00
|
|
|
(submatch (* any)))))
|
|
|
|
(lambda (file-name)
|
|
|
|
(let ((match (regexp-search regexp file-name)))
|
|
|
|
(if match
|
|
|
|
(match:substring match 1)
|
|
|
|
file-name)))))
|
2002-10-02 09:39:55 -04:00
|
|
|
|
|
|
|
;; returns two values: an action to perform out of ACTIONS and a
|
|
|
|
;; list of selected elements out of TABLE-ELEMENTS.
|
|
|
|
(define (select-table title header header-row
|
|
|
|
table-elements selector actions footer)
|
|
|
|
(let* ((checkboxes (map (lambda (_)
|
|
|
|
(make-checkbox-input-field))
|
|
|
|
table-elements))
|
|
|
|
(action-title "Choose an action")
|
|
|
|
(select (make-select-input-field (cons action-title actions)
|
|
|
|
'(@ (size 1))))
|
|
|
|
(req
|
|
|
|
(send-html/suspend
|
|
|
|
(lambda (new-url)
|
|
|
|
`(html
|
|
|
|
(title ,title)
|
|
|
|
(body
|
|
|
|
,header
|
2003-01-19 11:57:27 -05:00
|
|
|
(surflet-form
|
2002-10-02 09:39:55 -04:00
|
|
|
,new-url
|
2002-10-09 11:14:54 -04:00
|
|
|
POST
|
2002-10-02 09:39:55 -04:00
|
|
|
(table
|
|
|
|
,@(cons '(th) header-row)
|
|
|
|
,@(map (lambda (checkbox table-element)
|
|
|
|
`(tr
|
|
|
|
(td ,checkbox)
|
|
|
|
,@(selector table-element)))
|
|
|
|
checkboxes
|
|
|
|
table-elements))
|
|
|
|
(p ,select
|
|
|
|
,(make-submit-button "Do it")))
|
|
|
|
,footer)))))
|
|
|
|
(bindings (get-bindings req))
|
|
|
|
(action (input-field-value select bindings)))
|
|
|
|
|
|
|
|
(if (string=? action action-title)
|
2003-01-16 07:53:10 -05:00
|
|
|
(values #f #f req)
|
2002-10-21 04:38:46 -04:00
|
|
|
(values action
|
|
|
|
(filter-map (lambda (checkbox table-element)
|
2002-11-07 15:41:35 -05:00
|
|
|
(if (input-field-value checkbox bindings)
|
2002-10-21 04:38:46 -04:00
|
|
|
table-element
|
|
|
|
#f))
|
|
|
|
checkboxes
|
2003-01-16 07:53:10 -05:00
|
|
|
table-elements)
|
|
|
|
req))))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
2003-01-19 11:57:27 -05:00
|
|
|
(define (unload-surflets outdated? surflet-names)
|
2002-10-02 09:39:55 -04:00
|
|
|
(if-outdated outdated?
|
2003-01-19 11:57:27 -05:00
|
|
|
(show-outdated (make-callback show-surflets))
|
|
|
|
(for-each unload-surflet surflet-names)))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
2003-01-19 11:57:27 -05:00
|
|
|
(define (no-surflets)
|
|
|
|
`(p "Currently, there are no SUrflets loaded "
|
|
|
|
(URL ,(make-callback show-surflets) "(reload)")
|
2003-01-16 07:53:10 -05:00
|
|
|
", but there may be "
|
|
|
|
(URL ,(make-callback show-sessions) "sessions")
|
|
|
|
" you want to administer."))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
2003-01-19 11:57:27 -05:00
|
|
|
(define (show-surflets req . maybe-update-text)
|
2002-10-02 09:39:55 -04:00
|
|
|
(let* ((update-text (:optional maybe-update-text ""))
|
2003-01-19 11:57:27 -05:00
|
|
|
(loaded-surflets (sort-list! (get-loaded-surflets) string<?))
|
2002-10-02 09:39:55 -04:00
|
|
|
(outdated? (make-outdater))
|
2003-01-19 11:57:27 -05:00
|
|
|
(title "SUrflet-Administration -- SUrflets")
|
|
|
|
(header `((h1 "SUrflet Administration")
|
|
|
|
(h2 "SUrflets")
|
2002-10-02 09:39:55 -04:00
|
|
|
(p (font (@ (color "red")) ,update-text))))
|
|
|
|
(footer `((hr)
|
2002-10-21 04:38:46 -04:00
|
|
|
(URL ,(make-callback return-to-main-page) "Return to administration menu.")
|
|
|
|
(br)
|
|
|
|
(URL "/" "Return to main menu.")))
|
2002-11-03 13:15:53 -05:00
|
|
|
(actions '("unload" "unload all")))
|
2003-01-19 11:57:27 -05:00
|
|
|
(if (null? loaded-surflets)
|
|
|
|
(send-html `(html (title ,title) (body ,header ,(no-surflets) ,footer)))
|
|
|
|
(receive (action selected-surflets req)
|
2002-10-02 09:39:55 -04:00
|
|
|
(select-table title ; title
|
|
|
|
header ; header
|
|
|
|
'((th "Name")) ; table-header
|
2003-01-19 11:57:27 -05:00
|
|
|
loaded-surflets ; list of elements
|
|
|
|
(lambda (surflet) ; selector
|
2002-10-02 09:39:55 -04:00
|
|
|
`((td
|
2003-01-19 11:57:27 -05:00
|
|
|
,(remove-surflet-path surflet))))
|
2002-10-02 09:39:55 -04:00
|
|
|
actions ; actions to perform
|
|
|
|
(cons ; footer
|
2003-01-19 11:57:27 -05:00
|
|
|
`(p "Note that unloading the SUrflets does not imply "
|
|
|
|
"the unloading of sessions of this SUrflet. " (br)
|
2002-10-02 09:39:55 -04:00
|
|
|
"This can be done on the "
|
2002-12-07 17:26:40 -05:00
|
|
|
(URL ,(make-callback show-sessions)
|
|
|
|
"sessions adminstration page."))
|
2002-10-02 09:39:55 -04:00
|
|
|
footer))
|
2002-10-21 04:38:46 -04:00
|
|
|
(if (not action)
|
2003-01-19 11:57:27 -05:00
|
|
|
(show-surflets 'no-req "Choose an action.")
|
|
|
|
(if (and (null? selected-surflets)
|
2002-10-21 04:38:46 -04:00
|
|
|
(not (string=? action "unload all")))
|
2003-01-19 11:57:27 -05:00
|
|
|
(show-surflets 'no-req "You must choose at least one element.")
|
2002-10-21 04:38:46 -04:00
|
|
|
(cond
|
|
|
|
((string=? action "unload")
|
2003-01-19 11:57:27 -05:00
|
|
|
(unload-surflets outdated? selected-surflets)
|
|
|
|
(show-surflets 'no-req "SUrflets unloaded."))
|
2002-10-21 04:38:46 -04:00
|
|
|
((string=? action "unload all")
|
2003-01-19 11:57:27 -05:00
|
|
|
(unload-surflets outdated? loaded-surflets)
|
|
|
|
(show-surflets 'no-req "SUrflets unloaded."))
|
2002-10-21 04:38:46 -04:00
|
|
|
(else
|
|
|
|
(error "unknown action" action)))))))))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
2003-01-19 11:57:27 -05:00
|
|
|
(define (session-surflet-name<? entry1 entry2)
|
|
|
|
(let ((name1 (session-surflet-name (cdr entry1)))
|
|
|
|
(name2 (session-surflet-name (cdr entry2))))
|
2002-12-07 17:26:40 -05:00
|
|
|
;; handle multiple session names
|
2002-10-02 09:39:55 -04:00
|
|
|
(if (string=? name1 name2)
|
2002-12-07 17:26:40 -05:00
|
|
|
(session-id<? entry1 entry2)
|
2002-10-02 09:39:55 -04:00
|
|
|
(string<? name1 name2))))
|
2002-12-07 17:26:40 -05:00
|
|
|
(define (session-id<? entry1 entry2)
|
|
|
|
;; there are no multiple session-ids
|
2002-10-01 13:44:58 -04:00
|
|
|
(< (car entry1) (car entry2)))
|
2002-12-07 17:26:40 -05:00
|
|
|
(define (session-id>? entry1 entry2)
|
|
|
|
(session-id<? entry2 entry1))
|
2003-01-19 11:57:27 -05:00
|
|
|
(define (session-surflet-name>? entry1 entry2)
|
|
|
|
(session-surflet-name<? entry2 entry1))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
2002-12-07 17:26:40 -05:00
|
|
|
(define (no-current-sessions)
|
2002-10-01 13:44:58 -04:00
|
|
|
;; Avoid using send/suspend in this context as there
|
2002-12-07 17:26:40 -05:00
|
|
|
;; are no sessions available any more.
|
|
|
|
'(p "Currently, there are no sessions, "
|
2003-01-19 11:57:27 -05:00
|
|
|
"i.e. the administration SUrflet is no longer running. "
|
2002-12-07 17:26:40 -05:00
|
|
|
;; Can't use callback here, as there are no valid sessions left.
|
2002-10-01 13:44:58 -04:00
|
|
|
(URL "admin.scm" "Go back to main page.")))
|
|
|
|
|
2002-12-07 17:26:40 -05:00
|
|
|
(define (show-sessions req . maybe-update-text)
|
2002-10-02 09:39:55 -04:00
|
|
|
(let* ((update-text (:optional maybe-update-text ""))
|
2003-01-19 11:57:27 -05:00
|
|
|
(current-sessions (sort-list! (get-sessions) session-surflet-name<?)))
|
2003-01-16 07:53:10 -05:00
|
|
|
(real-sessions current-sessions update-text
|
|
|
|
(resume-url-session-id
|
|
|
|
(last (http-url-path (request-url req)))))))
|
2002-10-02 09:39:55 -04:00
|
|
|
|
2003-01-16 07:53:10 -05:00
|
|
|
(define (real-sessions current-sessions update-text this-session-id)
|
2002-10-02 09:39:55 -04:00
|
|
|
(let ((outdated? (make-outdater))
|
2003-01-19 11:57:27 -05:00
|
|
|
(title "SUrflet Adminstration - Sessions")
|
|
|
|
(header `((h1 "SUrflet Administration")
|
2002-12-07 17:26:40 -05:00
|
|
|
(h2 "Sessions")
|
2002-10-02 09:39:55 -04:00
|
|
|
(p (font (@ (color "red")) ,update-text))))
|
2003-01-16 07:53:10 -05:00
|
|
|
(footer `(,(if (not (null? current-sessions))
|
|
|
|
`(p "Be careful not to kill this adminstration's "
|
|
|
|
"session (id: " ,this-session-id ").")
|
|
|
|
#f)
|
|
|
|
(hr)
|
2003-01-19 11:57:27 -05:00
|
|
|
(URL ,(make-callback show-surflets) "Return to SUrflets menu.") (br)
|
2002-10-21 04:38:46 -04:00
|
|
|
(URL ,(make-callback return-to-main-page) "Return to administration menu.")
|
|
|
|
(br)
|
|
|
|
(URL "/" "Return to main menu.")))
|
2002-10-02 09:39:55 -04:00
|
|
|
(actions '("kill"
|
|
|
|
"adjust timeout"
|
|
|
|
"view continuations"))
|
2002-12-07 17:26:40 -05:00
|
|
|
(sessions-callback (make-callback show-sessions)))
|
|
|
|
(if (null? current-sessions)
|
2002-10-02 09:39:55 -04:00
|
|
|
(send-html `(html (title ,title)
|
2002-12-07 17:26:40 -05:00
|
|
|
(body ,@header ,(no-current-sessions) ,footer)))
|
2003-01-16 07:53:10 -05:00
|
|
|
(receive (action selected-sessions req)
|
2002-10-02 09:39:55 -04:00
|
|
|
(select-table title
|
|
|
|
header
|
2003-01-19 11:57:27 -05:00
|
|
|
`((th "SUrflet Name") (th "Session-Id"))
|
2002-12-07 17:26:40 -05:00
|
|
|
current-sessions
|
|
|
|
(lambda (session-pair)
|
|
|
|
(let ((session-id (car session-pair))
|
|
|
|
(session-entry (cdr session-pair)))
|
2003-01-19 11:57:27 -05:00
|
|
|
`((td ,(session-surflet-name session-entry))
|
2003-01-16 07:58:01 -05:00
|
|
|
(td (@ (align "right")) ,session-id))))
|
2002-10-02 09:39:55 -04:00
|
|
|
actions
|
|
|
|
footer)
|
2002-10-21 04:38:46 -04:00
|
|
|
(if (not action)
|
2002-12-07 17:26:40 -05:00
|
|
|
(show-sessions current-sessions "Choose an action.")
|
2002-10-21 04:38:46 -04:00
|
|
|
(let ((new-update-text
|
|
|
|
(cond
|
|
|
|
((string=? action "kill")
|
|
|
|
(if-outdated outdated?
|
2002-12-07 17:26:40 -05:00
|
|
|
(show-outdated sessions-callback)
|
|
|
|
(for-each delete-session!
|
|
|
|
(map car selected-sessions)))
|
|
|
|
"Sessions killed.")
|
2002-10-21 04:38:46 -04:00
|
|
|
((string=? action "adjust timeout")
|
|
|
|
(if-outdated outdated?
|
2002-12-07 17:26:40 -05:00
|
|
|
(show-outdated sessions-callback)
|
|
|
|
(for-each session-adjust-timeout!
|
|
|
|
(map car selected-sessions)))
|
2002-10-21 04:38:46 -04:00
|
|
|
"Timeout adjusted.")
|
|
|
|
((string=? action "view continuations")
|
|
|
|
(if-outdated outdated?
|
2002-12-07 17:26:40 -05:00
|
|
|
(show-outdated sessions-callback)
|
|
|
|
(if (zero? (length selected-sessions))
|
|
|
|
"You must choose at least one session."
|
2002-10-21 04:38:46 -04:00
|
|
|
;; this does not return
|
2003-01-16 07:53:10 -05:00
|
|
|
(show-continuations selected-sessions req))))
|
2002-10-21 04:38:46 -04:00
|
|
|
(else
|
|
|
|
(error "unknown action" action)))))
|
2003-01-25 08:21:36 -05:00
|
|
|
(show-sessions req new-update-text)))))))
|
2002-10-02 09:39:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
2003-01-16 07:53:10 -05:00
|
|
|
(define (no-current-continuations session req)
|
2002-12-07 17:26:40 -05:00
|
|
|
`((p "Currently, there are no continuations for this session. ")
|
2002-10-02 09:39:55 -04:00
|
|
|
(p "You may " (URL ,(make-callback
|
2003-01-16 07:53:10 -05:00
|
|
|
(lambda (req) (show-continuations (list session) req)))
|
2002-10-01 13:44:58 -04:00
|
|
|
"reload")
|
2002-10-02 09:39:55 -04:00
|
|
|
" this page or go back to the "
|
2002-12-07 17:26:40 -05:00
|
|
|
(URL ,(make-callback show-sessions) "session table overview."))))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
2003-01-16 07:53:10 -05:00
|
|
|
(define (no-more-than-one-session title header1 sessions req)
|
2002-10-02 09:39:55 -04:00
|
|
|
(send-html
|
|
|
|
`(html (title ,title)
|
2003-01-19 11:57:27 -05:00
|
|
|
(body (h1 "SUrflet Administration")
|
2002-10-02 09:39:55 -04:00
|
|
|
(p "Currently, you may only view the continuations of "
|
2002-12-07 17:26:40 -05:00
|
|
|
"one session at a time. This will be changed in "
|
2002-10-02 09:39:55 -04:00
|
|
|
"future revisions. Sorry for any inconvenience.")
|
|
|
|
(p "You may choose to go back to the "
|
2002-12-07 17:26:40 -05:00
|
|
|
(URL ,(make-callback show-sessions)
|
|
|
|
"sessions administration page")
|
|
|
|
" where you can select one session"
|
|
|
|
" or select one session from your chosen sessions:" (br)
|
2002-11-03 13:15:53 -05:00
|
|
|
(ul
|
2002-12-07 17:26:40 -05:00
|
|
|
,@(map (lambda (session)
|
2002-11-03 13:15:53 -05:00
|
|
|
`(li (URL ,(make-callback
|
|
|
|
(lambda (req)
|
2003-01-16 07:53:10 -05:00
|
|
|
(show-continuations (list session) req)))
|
2003-01-19 11:57:27 -05:00
|
|
|
,(session-surflet-name (cdr session))
|
2002-12-07 17:26:40 -05:00
|
|
|
" (" ,(car session) ")")))
|
|
|
|
sessions)))))))
|
2002-10-02 09:39:55 -04:00
|
|
|
|
2002-10-01 13:44:58 -04:00
|
|
|
(define (continuation-id<? entry1 entry2)
|
|
|
|
(< (car entry1) (car entry2)))
|
|
|
|
|
2003-01-16 07:53:10 -05:00
|
|
|
(define (show-continuations sessions req . maybe-update-text)
|
2003-01-19 11:57:27 -05:00
|
|
|
(let ((title "SUrflet Adminstration - Continuations")
|
|
|
|
(header1 '(h1 "SUrflet Administration")))
|
2002-12-07 17:26:40 -05:00
|
|
|
(if (not (= 1 (length sessions)))
|
2003-01-16 07:53:10 -05:00
|
|
|
(no-more-than-one-session title header1 sessions req)
|
2002-12-07 17:26:40 -05:00
|
|
|
(let* ((session-pair (car sessions))
|
|
|
|
(session-id (car session-pair))
|
|
|
|
(session-entry (cdr session-pair))
|
2003-01-16 07:53:10 -05:00
|
|
|
(this-continuation-id (resume-url-continuation-id
|
|
|
|
(last (http-url-path (request-url req)))))
|
2002-10-02 09:39:55 -04:00
|
|
|
(update-text (:optional maybe-update-text "")))
|
2003-01-16 07:53:10 -05:00
|
|
|
(let* ((current-continuations
|
|
|
|
(sort-list! (get-continuations session-id)
|
|
|
|
continuation-id<?))
|
|
|
|
(outdated? (make-outdater))
|
|
|
|
|
|
|
|
(header (cons header1
|
|
|
|
`((h2 "Continuations of " ,session-id)
|
2003-01-19 11:57:27 -05:00
|
|
|
(p "(belongs to the SUrflet '"
|
|
|
|
,(session-surflet-name session-entry) "')")
|
2003-01-16 07:53:10 -05:00
|
|
|
(p (font (@ (color "red")) ,update-text)))))
|
|
|
|
(footer
|
|
|
|
`(,(if (not (null? current-continuations))
|
|
|
|
`(p "Be careful not to delete this adminstration's "
|
|
|
|
"continuation (id: " ,this-continuation-id ").")
|
|
|
|
#f)
|
|
|
|
(hr)
|
2003-01-19 11:57:27 -05:00
|
|
|
(URL ,(make-callback show-surflets) "Return to SUrflets menu.") (br)
|
2003-01-16 07:53:10 -05:00
|
|
|
(URL ,(make-callback show-sessions) "Return to sessions menu.") (br)
|
|
|
|
(URL ,(make-callback return-to-main-page) "Return to administration menu.")
|
|
|
|
(br)
|
|
|
|
(URL "/" "Return to main menu.")))
|
|
|
|
(actions '("delete" "delete all"))
|
|
|
|
(continuations-callback
|
|
|
|
(make-callback (lambda (req)
|
|
|
|
(show-continuations sessions req)))))
|
2002-10-02 09:39:55 -04:00
|
|
|
(if (null? current-continuations)
|
|
|
|
(send-html `(html (title ,title)
|
|
|
|
(body ,header
|
2003-01-16 07:53:10 -05:00
|
|
|
,(no-current-continuations session-pair req)
|
2002-10-02 09:39:55 -04:00
|
|
|
,footer)))
|
2003-01-16 07:53:10 -05:00
|
|
|
(receive (action selected-continuations req)
|
2002-10-02 09:39:55 -04:00
|
|
|
(select-table title
|
|
|
|
header
|
|
|
|
'((th "Continuation-Id"))
|
|
|
|
current-continuations
|
|
|
|
(lambda (continuation-pair)
|
|
|
|
(let ((continuation-id (car continuation-pair)))
|
2003-01-16 07:58:01 -05:00
|
|
|
`((td (@ (align "right")) ,continuation-id))))
|
2002-10-02 09:39:55 -04:00
|
|
|
actions
|
|
|
|
footer)
|
2002-10-21 04:38:46 -04:00
|
|
|
(if (not action)
|
2003-01-16 07:53:10 -05:00
|
|
|
(show-continuations sessions req
|
|
|
|
"Choose an action.")
|
2002-10-21 04:38:46 -04:00
|
|
|
(begin
|
|
|
|
(cond
|
|
|
|
((string=? action "delete")
|
|
|
|
(delete-continuations outdated? continuations-callback
|
2002-12-07 17:26:40 -05:00
|
|
|
session-id selected-continuations))
|
2002-10-21 04:38:46 -04:00
|
|
|
((string=? action "delete all")
|
|
|
|
(delete-continuations outdated? continuations-callback
|
2002-12-07 17:26:40 -05:00
|
|
|
session-id current-continuations))
|
2002-10-21 04:38:46 -04:00
|
|
|
(else
|
|
|
|
(error "unknown action" action)))
|
2003-01-16 07:53:10 -05:00
|
|
|
(show-continuations sessions req
|
|
|
|
"Deleted."))))))))))
|
2002-10-02 09:39:55 -04:00
|
|
|
|
|
|
|
(define (delete-continuations outdated? continuations-callback
|
2002-12-07 17:26:40 -05:00
|
|
|
session-id continuations)
|
2002-10-02 09:39:55 -04:00
|
|
|
(if-outdated outdated?
|
|
|
|
(show-outdated continuations-callback)
|
2002-12-07 17:26:40 -05:00
|
|
|
;; Do it this way to easily expand to more sessions in the
|
2002-10-02 09:39:55 -04:00
|
|
|
;; future.
|
|
|
|
(for-each delete-continuation!
|
|
|
|
(make-list (length continuations)
|
2002-12-07 17:26:40 -05:00
|
|
|
session-id)
|
2002-10-02 09:39:55 -04:00
|
|
|
(map car continuations))))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
|
|
|
(define (return-to-main-page req)
|
2003-01-10 04:52:35 -05:00
|
|
|
(send/finish (make-error-response (status-code moved-perm) req
|
|
|
|
"admin.scm" "admin.scm")))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
|
|
|
(define (main req)
|
2003-01-19 11:57:27 -05:00
|
|
|
(show-surflets req))
|
2002-10-01 13:44:58 -04:00
|
|
|
|
|
|
|
))
|