fcp-example.scm 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env bash
  2. # -*- scheme -*-
  3. # A Freenet Client Protocol library for Guile Scheme.
  4. exec -a "${0}" guile -L $(dirname $(realpath "$0")) -e '(fcp-example)' -c '' "${@}"
  5. ; !#
  6. ;; for emacs (defun test-this-file () (interactive) (save-current-buffer) (async-shell-command (concat (buffer-file-name (current-buffer)) " --test")))
  7. (define-module (fcp-example)
  8. #:export (main))
  9. (import
  10. (only (fcp) message-create message-task message-type message-data message-fields
  11. message-client-get message-client-get-realtime message-client-get-bulk
  12. message-client-put message-client-put-realtime message-client-put-bulk
  13. message-remove-request
  14. send-message processor-put! processor-delete!
  15. printing-passthrough-processor printing-discarding-processor
  16. discarding-processor processor-nodehello-printer
  17. processor-datafound-getdata
  18. node-ip-set! node-port-set!
  19. task-id
  20. call-with-fcp-connection with-fcp-connection)
  21. (only (ice-9 pretty-print) pretty-print)
  22. (only (srfi srfi-1) first second third assoc)
  23. (only (srfi srfi-26) cut)
  24. (srfi srfi-37 );; commandline handling
  25. (only (rnrs bytevectors) string->utf8 utf8->string))
  26. (define (request-successful-upload message)
  27. "When the put succeeds, download the data."
  28. (if (equal? 'PutSuccessful (message-type message))
  29. (let ((fields (message-fields message)))
  30. (when (and=> (assoc 'URI fields) (λ (uri-cel) (equal? key (cdr uri-cel))))
  31. (send-message
  32. (message-client-get-realtime get-task key)))
  33. #f)
  34. message))
  35. (define (record-successful-download message)
  36. "When the download succeeds, display the result"
  37. (if (equal? 'AllData (message-type message))
  38. (let ((task (message-task message)))
  39. (when (equal? task get-task)
  40. (format #t "Received Message: ~a\n" (utf8->string (message-data message)))
  41. (set! successful #t))
  42. #f)
  43. message))
  44. (define (remove-successful-tasks-from-queue message)
  45. "Cleanup the task because we use the global queue for easier debugging"
  46. (when (member (message-type message) '(AllData PutSuccessful))
  47. (send-message (message-remove-request (message-task message))))
  48. message)
  49. (define put-task (task-id))
  50. (define get-task (task-id))
  51. (define key (string-append "KSK@" put-task))
  52. (define successful #f)
  53. (define (setup-handlers)
  54. ;; standard processors
  55. (processor-put! printing-discarding-processor)
  56. (processor-put! processor-nodehello-printer)
  57. ;; immediately request data from successfull get requests
  58. (processor-put! processor-datafound-getdata)
  59. ;; custom processors
  60. (processor-put! request-successful-upload)
  61. (processor-put! record-successful-download)
  62. (processor-put! remove-successful-tasks-from-queue))
  63. ;; commandline handling via srfi-37
  64. (define options
  65. (list
  66. (option '(#\V "version") #f #f
  67. (λ (opt name args loads)
  68. (display "Guile FCP version 0.2\n")
  69. (quit)))
  70. (option '(#\h "help") #f #f
  71. (λ (opt name args loads)
  72. (format #t "Usage: ~a [options]
  73. Options:
  74. -h --help show this dialog
  75. -V --version show the version
  76. -H IP_OR_HOSTNAME --host=IP_OR_HOSTNAME set the node address
  77. -P PORT --port=PORT set the FCP port
  78. " (car (program-arguments)))
  79. (quit)))
  80. (option '(#\P "port") #t #f
  81. (λ (opt name arg loads)
  82. (node-port-set! arg)
  83. loads))
  84. (option '(#\H "host") #t #f
  85. (λ (opt name arg loads)
  86. (node-ip-set! arg)
  87. loads))))
  88. (define (main args)
  89. (define arguments
  90. (args-fold (cdr args)
  91. options
  92. (lambda (opt name arg loads)
  93. (error "Unrecognized option `~A'" name))
  94. (lambda (op loads) (cons op loads))
  95. '()))
  96. (setup-handlers)
  97. ;; open the FCP connection. Anything inside this scope can
  98. ;; communicate directly with Freenet via FCP, other interaction
  99. ;; must be done through processing procedures as setup above.
  100. (with-fcp-connection
  101. ;; get the ball rolling
  102. (send-message
  103. (message-client-put-realtime put-task key
  104. (string->utf8 (string-append "Hello " key))))
  105. (while (not successful)
  106. (display ".")
  107. (sleep 1))))