guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] 16/17: Add a record type for GNUNET_FS_ProgressInfo and a few t


From: Rémi Birot-Delrue
Subject: [gnunet] 16/17: Add a record type for GNUNET_FS_ProgressInfo and a few tests. * progress-info.scm: add a record type for `GNUNET_FS_ProgressInfo` and alter `parse-c-progress-info` to handle it. * fs.scm: - correct `make-file-information`; - deprecate directory-scan (too many bugs to fix, `make-file-information will` do for now); - replace `*block-options*` with `make-block-options`; - update `procedure->*` functions to use `parse-c-progress-info`. * examples/*.scm: follow modifications on fs.scm. * tests/progress-info.scm: add a fake progress-info to test `parse-c-progress-info`. * tests/fs.scm: add a small test for `make-file-information`.
Date: Wed, 12 Aug 2015 18:24:42 +0000

remibd pushed a commit to branch master
in repository gnunet.

commit cd20d8d6d06043d8dff49d8b421e1c9cf1c85c2e
Author: RĂ©mi Birot-Delrue <address@hidden>
Date:   Wed Aug 12 19:31:27 2015 +0200

    Add a record type for GNUNET_FS_ProgressInfo and a few tests.
    * progress-info.scm: add a record type for `GNUNET_FS_ProgressInfo` and 
alter
                         `parse-c-progress-info` to handle it.
    * fs.scm: - correct `make-file-information`;
              - deprecate directory-scan (too many bugs to fix,
                `make-file-information will` do for now);
              - replace `*block-options*` with `make-block-options`;
              - update `procedure->*` functions to use `parse-c-progress-info`.
    * examples/*.scm: follow modifications on fs.scm.
    * tests/progress-info.scm: add a fake progress-info to test
                               `parse-c-progress-info`.
    * tests/fs.scm: add a small test for `make-file-information`.
---
 examples/download.scm           |   18 +--
 examples/identity.scm           |    2 +-
 examples/publish.scm            |  297 +++++++++++++++++++++------------------
 examples/search-ns.scm          |   50 +++----
 examples/search.scm             |   82 ++++++------
 gnu/gnunet/fs.scm               |   85 ++++++++----
 gnu/gnunet/fs/progress-info.scm |  175 ++++++++++++++++++++++-
 tests/fs.scm                    |   39 +++++
 tests/progress-info.scm         |   33 ++++-
 9 files changed, 529 insertions(+), 252 deletions(-)

diff --git a/examples/download.scm b/examples/download.scm
index 6c7a283..93c3681 100755
--- a/examples/download.scm
+++ b/examples/download.scm
@@ -56,20 +56,14 @@ the download."
                        (stop-download *dl-handle*))
                      #:delay (time-rel #:seconds 5))))))))
 
-(define (progress-cb %info)
-  (let ((status (progress-info-status %info)))
+(define (progress-cb info status)
+  (let ((filename (pinfo-download-filename info)))
     (cond ((equal? status '(#:download #:start))
-          (match (parse-c-progress-info %info)
-            (((%context cctx pctx sctx %uri %filename . _) . _)
-             (simple-format #t "Starting download `~a'.\n"
-                            (pointer->string %filename)))))
+          (simple-format #t "Starting download `~a'.\n" filename))
          ((equal? status '(#:download #:completed))
-          (match (parse-c-progress-info %info)
-            (((%context cctx pctx sctx %uri %filename . _) . _)
-             (simple-format #t "Downloaded `~a'.\n"
-                            (pointer->string %filename))))
+          (simple-format #t "Downloaded `~a'.\n" filename)
           ;; the download is complete, we want to execute the kill-task now
           (schedule-shutdown!))
          ((equal? status '(#:download #:stopped))
-          (set-next-task! (lambda (_)
-                            (close-filesharing-service! *fs-handle*)))))))
+          (add-task! (lambda (_)
+                       (close-filesharing-service! *fs-handle*)))))))
diff --git a/examples/identity.scm b/examples/identity.scm
index 7b7298f..4231543 100755
--- a/examples/identity.scm
+++ b/examples/identity.scm
@@ -38,7 +38,7 @@
           (simple-format #t "~a - ~a\n" name (ecdsa-public-key->string key))))
        ((not ego)
         (cancel-task! *kill-task*)
-        (set-next-task! shutdown-task))))
+        (add-task! shutdown-task))))
 
 (define (first-task _)
   (set! *handle* (open-identity-service *config* print-ego))
diff --git a/examples/publish.scm b/examples/publish.scm
index cea056e..25b0aa4 100755
--- a/examples/publish.scm
+++ b/examples/publish.scm
@@ -18,154 +18,181 @@
 
 (define-module (gnunet-publish)
   #:use-module (ice-9 match)
+  #:use-module (ice-9 getopt-long)
+  #:use-module (rnrs bytevectors)
   #:use-module (system foreign)
+  #:use-module (gnu gnunet binding-utils)
   #:use-module (gnu gnunet common)
-  #:use-module (gnu gnunet fs)
-  #:use-module (gnu gnunet fs uri)
-  #:use-module (gnu gnunet fs progress-info)
   #:use-module (gnu gnunet configuration)
   #:use-module (gnu gnunet scheduler)
   #:use-module (gnu gnunet identity)
-  #:export     (main))
+  #:use-module (gnu gnunet container metadata)
+  #:use-module (gnu gnunet fs)
+  #:use-module (gnu gnunet fs uri)
+  #:use-module (gnu gnunet fs progress-info)
+  #:export (main))
+
+;;; foreign utilities
+
+(define-gnunet %relative-time-to-string
+  "GNUNET_STRINGS_relative_time_to_string" : (list time-relative int) -> '*)
+
+(define* (time-relative->string t #:optional (round? #t))
+  (let ((s (%relative-time-to-string t (bool->int round?))))
+    (when (eq? %null-pointer s)
+      (throw 'invalid-result "time-relative->string" "%relative-time-to-string"
+            s (list t (bool->int round?))))
+    (pointer->string s)))
 
-(define *index?*      #t)
-(define *simulate?*   #f)
+;;; parameters
+
+(define %options
+  '((simulate  (single-char #\s) (value #f))
+    (pseudonym (single-char #\P) (value #t))
+    (this-id   (single-char #\t) (value #t))
+    (update-id (single-char #\N) (value #t))))
+
+(define %block-options
+  (make-block-options (time-relative->absolute (time-rel #:days 365)) 0))
 
 (define *config-file* "~/.gnunet/gnunet.conf")
-(define *config*          #f)
+(define *simulate?* #f)
+(define *index?*    #t)
+(define *pseudonym* #f) ; a string
+(define *ego*       #f) ; an instance of <ego>
+(define *path*      #f)
+(define *id*        #f) ; file identifier
+(define *update-id* #f) ; update file identifier
+(define *args*      #f) ; ordinary arguments to the command line
 
-(define *binary-name*     #f)
-(define *filename*        #f)
+;;; handles
 
-;;+TODO: add kill tasks everywhere!
-;;+TODO: each continuation shalt check its indirect arguments.
-;; The kill task is the task that will end the program, either because it has
-;; reached a timeout or because it has come to a normal or abnormal ending.
-(define *kill-task*       #f)
+(define *config* #f)
+(define *identity* #f)
+(define *fs*     #f)
+(define *publish* #f)
 
-(define *namespace-name*  #f)
-(define *namespace-ego*   #f)
+;;; cleaning
 
-(define *file-identifier* #f)
+(define (do-stop-task _)
+  "We are finished with the publishing operation, clean up all FS state."
+  (when *identity*
+    (close-identity-service *identity*)
+    (set! *identity* #f))
+  (cond (*publish* 
+        (stop-publish *publish*)
+        (set! *publish* #f))
+       (*fs*
+        (close-filesharing-service! *fs*)
+        (set! *fs* #f))))
 
-(define *fs-handle*       #f)
-(define *identity-handle* #f)
-(define *publish-handle*  #f)
-(define *dir-scanner*     #f)
+;;; callbacks
 
-
-(define (main args)
-  "Entry point of the program."
-  (set! *config* (load-configuration *config-file*))
-  (call-with-scheduler *config* (first-task args)))
-
-(define (first-task args)
-  "The initial task: parse the command line and either find the
-demanded ego or call IDENTITY-CONTINUATION."
-  (lambda (_)
-    (match args
-      ((binary filename namespace identifier)
-       (set! *binary-name*     binary)
-       (set! *filename*        filename)
-       (set! *namespace-name*  namespace)
-       (set! *file-identifier* identifier)
-       (set! *identity-handle*
-        (open-identity-service *config* identity-callback))
-       (set! *kill-task*
-        (add-task! (lambda (_)
-                     (close-identity-service *identity-handle*))
-                   #:delay (time-rel #:seconds 5))))
-      ((binary file-name)
-       (set! *binary-name* binary)
-       (set! *filename*    file-name)
-       (identity-continuation))
-      ((binary . _)
-       (simple-format #t "Usage: ~a filename [namespace identifier]\n"
-                     binary)
-       (schedule-shutdown!)))))
-
-(define (identity-callback ego name)
-  "The first callback, called repeatedly by the identity service. Set
-NAMESPACE-EGO to the right ego, then continue with
-IDENTITY-CONTINUATION."
-  (cond ((and ego name (string= *namespace-name* name))
-        (set! *namespace-ego* ego))
-       ((and (not ego) (not name)) ; last call
-        (cancel-task! *kill-task*)
-        (identity-continuation))))
+(define (progress-cb info status)
+  "Called by FS client to give information about the progress of an operation."
+  (match status
+    ((#:publish #:start) *unspecified*)
+    ((#:publish (or #:progress #:progress-directory))
+     (simple-format #t "Publishing `~a' at ~a/~a (~a remaining)\n"
+                   (pinfo-publish-filename info)
+                   (pinfo-publish-completed info)
+                   (pinfo-publish-size info)
+                   (time-relative->string (pinfo-publish-eta info))))
+    ((#:publish #:error)
+     (simple-format #t "Error publishing: ~a\n" (pinfo-publish-message info))
+     (schedule-shutdown!))
+    ((#:publish #:completed)
+     (simple-format #t "Publishing `~a' done.\nURI is `~a'.\n"
+                   (pinfo-publish-filename info)
+                   (uri->string (pinfo-publish-chk-uri info)))
+     (when (pinfo-publish-sks-uri info)
+       (simple-format #t "Namespace URI is `~a'.\n"
+                     (uri->string (pinfo-publish-sks-uri info))))
+     (schedule-shutdown!))
+    ((#:publish #:stopped)
+     (add-task! do-stop-task))))
+
+(define (meta-printer name type format mime-type data)
+  "Print metadata entries (except binary metadata and the filename).
+
+NAME:      name of the plugin that generated the meta data;
+TYPE:      type of the meta data;
+FORMAT:    format of data;
+MIME-TYPE: mime type of data;
+DATA:      bytevector containing the value of the metadata."
+  (define (textual? fmt) (or (eq? #:utf8 fmt)
+                            (eq? #:c-string fmt)))
+  (when (and (textual? format)
+            (not (eq? #:original-filename type)))
+    (simple-format #t "\t~a - ~a\n" type (utf8->string data))))
 
 (define (identity-continuation)
-  "The second task: open the filesharing service and start a directory
-scan on *FILENAME*."
-  (cond
-   ((or (and *namespace-name* *namespace-ego*)
-       (and (not *namespace-name*) (not *namespace-ego*)))
-    (set! *fs-handle*   (open-filesharing-service *config* *binary-name*
-                                                 progress-callback))
-    (set! *dir-scanner* (start-directory-scan *filename* dirscan-callback))
-    (set! *kill-task*   (add-task! (lambda (_)
-                                    (display "Stopping directory scan 
(unexpected)\n")
-                                    (stop-directory-scan *dir-scanner*)
-                                    (close-filesharing-service! *fs-handle*))
-                                  #:delay (time-rel #:seconds 5))))
-   (else
-    (simple-format #t "Error: no ego named ~a has been found!\n"
-                  *namespace-name*)
-    ;; there’s an error, we must execute the killing task right now
-    (schedule-shutdown!))))
-
-(define (dirscan-callback filename directory? reason)
-  "The second callback, called repeatedly by the directory scanning
-tasks: wait until the scan is finished, interpret its results and
-start the publication by calling DIRSCAN-CONTINUATION."
-  (case reason
-    ((#:finished)
-     (cancel-task! *kill-task*)
-     (let* ((%share-tree (directory-scanner-result *fs-handle* *dir-scanner*))
-           (file-info   (share-tree->file-information *fs-handle* %share-tree
-                                                      *index?*)))
-       (dirscan-continuation file-info)))
-    ((#:internal-error)
-     (display "dirscan-callback: internal error.\n")
-     (schedule-shutdown!))))
-
-(define (dirscan-continuation file-info)
-  "Start the publication of FILE-INFO."
-  (set! *publish-handle*
-    (start-publish *fs-handle* file-info
-                  #:namespace *namespace-ego*
-                  #:identifier *file-identifier*
-                  #:simulate? *simulate?*))
-  (set! *kill-task* (add-task! (lambda (_)
-                                (display "Stopping publication (unexpected)\n")
-                                (stop-publish *publish-handle*))
-                              #:delay (time-rel #:seconds 5))))
-
-(define (progress-callback %info)
-  "The third callback, called repeteadly by the publishing tasks once the
-publication is engaged: when the publication starts, print a little something,
-and when it’s complete print the published file’s URI and stop the 
publication."
-  (let ((status (progress-info-status %info)))
-    (case (cadr status) ; status is of the form (#:publish <something>)
-      ((#:start)
-       (match (parse-c-progress-info %info)
-        (((%context %file-info cctx pctx %filename . _) _ _)
-         (simple-format #t "Publishing `~a'.\n" (pointer->string %filename)))))
-      ((#:completed)
-       (cancel-task! *kill-task*)
-       (match (parse-c-progress-info %info)
-        (((%context %file-info cctx pctx %filename _ _ _ _ _ (%chk-uri)) _ _)
-         (simple-format #t "Published `~a'.\n~a\n" (pointer->string %filename)
-                        (uri->string (wrap-uri %chk-uri)))))
-       ;; We must avoid calling `stop-publish` inside the progress-callback, as
-       ;; it frees the publish-handle that might still be used just after this
-       ;; call to progress-callback ends. Therefore, we continue with a new 
kill
-       ;; task.
-       (set! *kill-task*
-        (set-next-task! (lambda (_)
-                          (display "Stopping publication\n")
-                          (stop-publish *publish-handle*)))))
-      ((#:stopped)
-       (display "Publication stopped\n")
-       (set-next-task! (lambda (_)
-                        (close-filesharing-service! *fs-handle*)))))))
+  "Continuation proceeding with initialization after identity
+subsystem has been initialized."
+  (cond ((and *pseudonym* (not *ego*))
+        (simple-format (current-error-port)
+                       "Selected pseudonym `~a' unknown.\n" *pseudonym*)
+        (schedule-shutdown!))
+       (else
+        (let ((info (make-file-information *fs* *path* %block-options
+                                           #:index? *index?*)))
+          (cond ((not info)
+                 (simple-format (current-error-port)
+                                "Failed to access `~a'.\n" *path*)
+                 (schedule-shutdown!))
+                (else
+                 (catch 'invalid-result
+                   (lambda ()
+                     (set! *publish*
+                       (start-publish *fs* info #:namespace *ego*
+                                      #:identifier *id*
+                                      #:update-identifier *update-id*
+                                      #:simulate? *simulate?*)))
+                   (lambda ()
+                     (display "Could not start publishing.\n"
+                              (current-error-port))
+                     (schedule-shutdown!)))))))))
+
+(define (identity-cb ego name)
+  "Function called by identity service with known pseudonyms."
+  (cond ((not ego)  (identity-continuation))
+       ((and name (string=? *pseudonym* name))
+        (set! *ego* ego))))
+
+(define (first-task _)
+  "Main function that will be run by the scheduler."
+  (let ((err (current-error-port)))
+    (cond
+     ((or (not *args*) (null? *args*) (> (length *args*) 1))
+      (display "Usage: examples/gnunet-publish.scm [options] filename\n" err))
+     ((and *pseudonym* (not *id*))
+      (display "Option `-t' is required when using option `-P'.\n" err)) 
+     ((and (not *pseudonym*) *id*)
+      (display "Option `-t' makes no sense without option `-P'.\n" err))
+     ((and (not *id*) *update-id*)
+      (display "Option `-N' makes no sense without option `-P'.\n" err))
+     (else
+      (set! *path* (car *args*))
+      (set! *fs* (open-filesharing-service *config* "gnunet-publish"
+                                          progress-cb))
+      (add-task! do-stop-task #:delay (time-rel #:seconds 5))
+      (if *pseudonym*
+         (catch 'invalid-result
+           (lambda ()
+             (set! *identity* (open-identity-service *config* identity-cb)))
+           (lambda ()
+             (display "Could not connect to the identity service.\n"
+                      (current-error-port))))
+         (identity-continuation))))))
+
+(define (main args)
+  "The main function to publish content to GNUnet."
+  (setup-log "publish.scm" #:debug)
+  (set! *config* (load-configuration "~/.gnunet/gnunet.conf"))
+  (let* ((options (getopt-long args %options)))
+    (set! *simulate?* (option-ref options 'simulate  #f))
+    (set! *pseudonym* (option-ref options 'pseudonym #f))
+    (set! *id*        (option-ref options 'this-id   #f))
+    (set! *update-id* (option-ref options 'update-id #f))
+    (set! *args*      (option-ref options '()        #f)))
+  (call-with-scheduler *config* first-task))
diff --git a/examples/search-ns.scm b/examples/search-ns.scm
index 60efc83..e90f1bb 100755
--- a/examples/search-ns.scm
+++ b/examples/search-ns.scm
@@ -78,30 +78,26 @@
                                     #:delay (time-rel #:seconds 5)))
     (simple-format #t "Searching ~a\n" (uri->string *uri*)))))
 
-(define (progress-callback %info)
-  (let ((status (progress-info-status %info)))
-    (when (equal? '(#:search #:result) status)
-      (match (parse-c-progress-info %info)
-       (((context cctx pctx %query duration anonymity
-                  (%metadata %uri %result applicability-rank)) _ _)
-        (let* ((result-uri        (uri->string (wrap-uri %uri)))
-               (metadata          (wrap-metadata %metadata))
-               (result-directory? (is-directory? metadata))
-               (result-filename   (metadata-ref metadata #:original-filename)))
-          (cond ((and result-directory?
-                      (string-null? result-filename))
-                 (simple-format
-                  #t "gnunet-download -o \"collection.gnd\" -R ~a\n"
-                  result-uri))
-                (result-directory?
-                 (simple-format #t
-                                "gnunet-download -o \"~a.gnd\" -R ~a\n"
-                                result-filename result-uri))
-                ((string-null? result-filename)
-                 (simple-format #t "gnunet-download ~a\n" result-uri))
-                (else
-                 (simple-format #t "gnunet-download -o \"~a\" ~a\n"
-                                result-filename result-uri)))))))
-    (when (equal? '(#:search #:stopped) status)
-      (set-next-task!
-       (lambda (_) (close-filesharing-service! *fs-handle*))))))
+(define (progress-callback info status)
+  (when (equal? '(#:search #:result) status)
+    (let* ((result-uri        (uri->string (pinfo-search-uri info)))
+          (metadata          (pinfo-search-metadata info))
+          (result-directory? (is-directory? metadata))
+          (result-filename   (metadata-ref metadata #:original-filename)))
+      (cond ((and result-directory?
+                 (string-null? result-filename))
+            (simple-format
+             #t "gnunet-download -o \"collection.gnd\" -R ~a\n"
+             result-uri))
+           (result-directory?
+            (simple-format #t
+                           "gnunet-download -o \"~a.gnd\" -R ~a\n"
+                           result-filename result-uri))
+           ((string-null? result-filename)
+            (simple-format #t "gnunet-download ~a\n" result-uri))
+           (else
+            (simple-format #t "gnunet-download -o \"~a\" ~a\n"
+                           result-filename result-uri)))))
+  (when (equal? '(#:search #:stopped) status)
+    (add-task!
+     (lambda (_) (close-filesharing-service! *fs-handle*)))))
diff --git a/examples/search.scm b/examples/search.scm
index ed3cbec..4e07b0b 100755
--- a/examples/search.scm
+++ b/examples/search.scm
@@ -28,47 +28,47 @@
   #:use-module (gnu gnunet scheduler)
   #:export     (main))
 
-(define config-file "~/.gnunet/gnunet.conf")
+(define *config-file* "~/.gnunet/gnunet.conf")
+(define *config* (load-configuration *config-file*))
 
-
-(define (progress-cb %info)
-  (let ((status (progress-info-status %info)))
-    (when (equal? '(#:search #:result) status)
-      (match (parse-c-progress-info %info)
-       (((context _ _ query duration anonymity
-                  (%metadata %uri %result applicability-rank)) _ _)
-        (let* ((uri  (uri->string (wrap-uri %uri)))
-               (meta (wrap-metadata %metadata))
-               (result-directory? (is-directory? meta))
-               (result-filename (metadata-ref meta #:original-filename)))
-          (cond ((and result-directory?
-                      (string-null? result-filename))
-                 (simple-format
-                  #t "gnunet-download -o \"collection.gnd\" -R ~a\n" uri))
-                (result-directory?
-                 (simple-format #t
-                                "gnunet-download -o \"~a.gnd\" -R ~a\n"
-                                result-filename uri))
-                ((string-null? result-filename)
-                 (simple-format #t "gnunet-download ~a\n"
-                                uri))
-                (else
-                 (simple-format #t "gnunet-download -o \"~a\" ~a\n"
-                                result-filename uri)))))))
-    (when (equal? '(#:search #:stopped) status)
-      (match (parse-c-progress-info %info)
-       ((_ _ %handle)
-        (set-next-task! (lambda (_)
-                          (close-filesharing-service! %handle))))))))
+(define *fs-handle*     #f)
+(define *search-handle* #f)
+(define *search-uri*    #f)
 
+
 (define (main args)
-  (let ((config (load-configuration config-file)))
-    (define (first-task _)
-      (let* ((fs-service (open-filesharing-service config (car args)
-                                                  progress-cb))
-            (uri        (apply make-ksk-uri (cdr args)))
-            (search     (start-search fs-service uri)))
-       ;; adds a timeout in 5 seconds
-       (add-task! (lambda (_) (stop-search search))
-                  #:delay (time-rel #:seconds 5))))
-    (call-with-scheduler config first-task)))
+  (call-with-scheduler *config* (first-task args)))
+
+(define (first-task args)
+  (lambda (_)
+    (set! *fs-handle*     (open-filesharing-service *config* (car args)
+                                                   progress-cb))
+    (set! *search-uri*    (apply make-ksk-uri (cdr args)))
+    (set! *search-handle* (start-search *fs-handle* *search-uri*))
+    ;; add a timeout in 5 seconds
+    (add-task! (lambda (_) (stop-search *search-handle*))
+              #:delay (time-rel #:seconds 5))))
+
+(define (progress-cb info status)
+  (when (equal? '(#:search #:result) status)
+    (let* ((meta              (pinfo-search-metadata info))
+          (uri               (uri->string (pinfo-search-uri info)))
+          (result-directory? (is-directory? meta))
+          (result-filename   (metadata-ref meta #:original-filename)))
+      (cond ((and result-directory?
+                 (string-null? result-filename))
+            (simple-format
+             #t "gnunet-download -o \"collection.gnd\" -R ~a\n" uri))
+           (result-directory?
+            (simple-format #t
+                           "gnunet-download -o \"~a.gnd\" -R ~a\n"
+                           result-filename uri))
+           ((string-null? result-filename)
+            (simple-format #t "gnunet-download ~a\n"
+                           uri))
+           (else
+            (simple-format #t "gnunet-download -o \"~a\" ~a\n"
+                           result-filename uri)))))
+  (when (equal? '(#:search #:stopped) status)
+    (add-task! (lambda (_)
+                (close-filesharing-service! *fs-handle*)))))
diff --git a/gnu/gnunet/fs.scm b/gnu/gnunet/fs.scm
index 2715157..048d1ee 100644
--- a/gnu/gnunet/fs.scm
+++ b/gnu/gnunet/fs.scm
@@ -15,7 +15,6 @@
 ;;;; You should have received a copy of the GNU General Public License
 ;;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-;;+TODO: export <file-information>
 (define-module (gnu gnunet fs)
   #:use-module (ice-9 match)
   #:use-module (srfi srfi-9)
@@ -31,7 +30,10 @@
   #:export (<file-information>
             wrap-file-information
             unwrap-file-information
+            file-information-filename
+            file-information-directory?
 
+            make-block-options
             open-filesharing-service
             close-filesharing-service!
             start-search
@@ -41,10 +43,14 @@
             start-publish
             stop-publish
             is-directory?
-            start-directory-scan
-            stop-directory-scan
-            directory-scanner-result
-            share-tree->file-information))
+            ;; to publish a single file
+            make-file-information))
+            ;; to publish a directory
+            ;; buggy/unfinished
+;            start-directory-scan
+;            stop-directory-scan
+;            directory-scanner-result
+;            share-tree->file-information))
 
 
 (define struct-fs-handle
@@ -117,28 +123,54 @@
 (define-gnunet-fs %test-for-directory
   "GNUNET_FS_meta_data_test_for_directory" : (list '*) -> int)
 
+(define* (make-block-options expiration-time anonymity-level
+                             #:key (content-priority 365)
+                                   (replication-level  1))
+  "For the filesharing service at the lower level, everything on the network is
+exchanged as blocks. Block options allow you to specify how to publish such
+blocks."
+  (make-c-struct (list time-absolute uint32 uint32 uint32)
+                 (list expiration-time anonymity-level
+                       content-priority replication-level)))
+
 (define-record-type <file-information>
   (wrap-file-information pointer)
   file-information?
   (pointer unwrap-file-information))
 
-(define* (make-file-information filesharing-handle filename
-                                #:key keywords metadata (index? #t))
+(define* (make-file-information filesharing-handle filename block-options
+                                #:key (keywords '()) metadata (index? #t))
+  "Builds a <file-information> object from FILENAME to be published under
+BLOCK-OPTIONS.
+
+KEYWORDS is a list of additional keywords (as strings) under which the file 
will
+be published, METADATA is some initial metadata, and INDEX? specifies if the
+file should be indexed or not (#t by default)."
   (when (string-null? filename)
     (throw 'invalid-arg "make-file-information" filename))
+  (when (or (null? block-options) (not (pointer? block-options)))
+    (throw 'invalid-arg "make-file-information" block-options))
   (let ((%filename     (string->pointer* filename))
         (%keywords-str (string->pointer* (keyword-list->string keywords)))
         (%metadata     (if metadata (unwrap-metadata metadata) %null-pointer))
         (%index?       (if index? gnunet-yes gnunet-no)))
-    (wrap-file-information (%file-information-create-from-file
-                             filesharing-handle %null-pointer %filename
-                             %keywords-str %metadata %index? %null-pointer))))
+    (let ((%info (%file-information-create-from-file
+                  filesharing-handle %null-pointer %filename
+                  %keywords-str %metadata %index? block-options)))
+      (if (eq? %null-pointer %info)
+          #f
+          (wrap-file-information %info)))))
 
 (define (file-information-filename file-info)
-  (%file-information-get-filename (unwrap-file-information file-info)))
+  (let ((%s (%file-information-get-filename
+             (unwrap-file-information file-info))))
+    (if (eq? %null-pointer %s)
+        #f
+        (pointer->string %s))))
 
 (define (file-information-directory? file-info)
-  (%file-information-is-directory (unwrap-file-information file-info)))
+  (int->bool (%file-information-is-directory
+              (unwrap-file-information file-info))))
 
 (define (file-information-destroy %file-info)
   "Free a file-information structure.
@@ -157,14 +189,8 @@ associated memory is freed)."
     (%share-tree-trim! res)
     res))
 
-;; block options
-;; 
-;; this value must remain accessible for the C functions as long as
-;; the file-information that refers it are alive.
-(define *block-options*
-  (make-c-struct (list uint64 uint32 uint32 uint32) '(0 0 365 1)))
-
-(define (share-tree->file-information filesharing-handle share-tree index?)
+(define (share-tree->file-information filesharing-handle share-tree index?
+                                      block-options)
   "Transform a pointer to a “share-tree” to an instance of <file-information>.
 
 WARNING: the share-tree is unusable after a call to
@@ -177,7 +203,7 @@ SHARE-TREE->FILE-INFORMATION (the associated memory is 
freed)."
               %directory-scan-get-result (list (pointer->string* %filename))))
      (let ((%fi (%file-information-create-from-file
                  filesharing-handle %null-pointer %filename %ksk-uri %metadata
-                 (bool->int index?) *block-options*)))
+                 (bool->int index?) block-options)))
        (when (eq? %null-pointer %fi)
          (throw 'invalid-result "share-tree->file-information"
                 "%file-information-create-from-file"
@@ -207,7 +233,9 @@ SHARE-TREE->FILE-INFORMATION (the associated memory is 
freed)."
 (define* (start-directory-scan filename progress-cb
                                #:key disable-extractor?)
   "Start a directory scan on FILENAME, extracting metadata (unless
-DISABLE-EXTRACTOR? is #t) and calling PROGRESS-CB each time there’s an update.
+DISABLE-EXTRACTOR? is #t) and calling PROGRESS-CB each time there’s an
+update. The scanning is done asynchronously in a separate process (an instance
+of `gnunet-helper-fs-publish`).
 
 PROGRESS-CB must be a procedure of three arguments:
  – the filename of the file currently being scanned;
@@ -229,14 +257,14 @@ PROGRESS-CB must be a procedure of three arguments:
   "Abort a scan.
 
 WARNING: must NEVER be called inside the “progress callback” of the scanner;
-instead, use ADD-TASK! or SET-NEXT-TASK! to schedule its call outside the
-callback."
+instead, use ADD-TASK! to schedule its call outside the callback."
   (%directory-scan-abort scanner))
 
 
 (define (progress-callback->pointer thunk)
-  (procedure->pointer '* (lambda (cls info)
-                           (thunk info)
+  (procedure->pointer '* (lambda (_ %info)
+                           (thunk (parse-c-progress-info %info)
+                                  (progress-info-status %info))
                            %null-pointer)
                       (list '* '*)))
 
@@ -341,14 +369,13 @@ identify the publication in place of the extracted 
keywords)."
     (or% (%publish-start filesharing-handle (unwrap-file-information
                                              file-information) %priv 
%identifier
                                              %update-id %simulate?)
-         (throw 'invalid-arg "start-publish" "%publish-start" %null-pointer))))
+         (throw 'invalid-result "start-publish" "%publish-start" 
%null-pointer))))
 
 (define (stop-publish publish-handle)
   "Stops a publication.
 
 WARNING: must NEVER be called inside the “progress callback” of the Filesharing
-system; instead, use ADD-TASK! or SET-NEXT-TASK! to schedule its call outside
-the callback."
+system; instead, use ADD-TASK! to schedule its call outside the callback."
   (%publish-stop publish-handle))
 
 ;;+TODO: should be (is-directory? search-result) or
diff --git a/gnu/gnunet/fs/progress-info.scm b/gnu/gnunet/fs/progress-info.scm
index fdd73af..25cb6ee 100644
--- a/gnu/gnunet/fs/progress-info.scm
+++ b/gnu/gnunet/fs/progress-info.scm
@@ -26,7 +26,57 @@
   #:use-module (gnu gnunet container metadata)
   #:use-module (gnu gnunet fs uri)
   #:export (progress-info-status
-            parse-c-progress-info))
+            parse-c-progress-info
+
+            <pinfo-publish>
+            pinfo-publish?
+            wrap-pinfo-publish
+            unwrap-pinfo-publish
+            pinfo-publish-status
+            pinfo-publish-filename
+            pinfo-publish-size
+            pinfo-publish-eta
+            pinfo-publish-duration
+            pinfo-publish-completed
+            pinfo-publish-anonymity
+            pinfo-publish-chk-uri
+            pinfo-publish-sks-uri
+            pinfo-publish-message
+
+            <pinfo-download>
+            pinfo-download?
+            wrap-pinfo-download
+            unwrap-pinfo-download
+            pinfo-download-status
+            pinfo-download-uri
+            pinfo-download-filename
+            pinfo-download-size
+            pinfo-download-eta
+            pinfo-download-duration
+            pinfo-download-completed
+            pinfo-download-anonymity
+            pinfo-download-active?
+            pinfo-download-message
+
+            <pinfo-search>
+            pinfo-search?
+            wrap-pinfo-search
+            unwrap-pinfo-search
+            pinfo-search-status
+            pinfo-search-query
+            pinfo-search-duration
+            pinfo-search-anonymity
+            pinfo-search-metadata
+            pinfo-search-uri
+            pinfo-search-result
+            pinfo-search-message
+
+            <pinfo-unindex>
+            pinfo-unindex?
+            wrap-pinfo-unindex
+            unwrap-pinfo-unindex
+            pinfo-unindex-status))
+
 
 
 (define %progress-info-type
@@ -55,9 +105,11 @@
                 time-relative)       ;    GNUNET_TIME_Relative eta;
           (list #:resume             ;   struct {…} resume
                 '*                   ;    char *message;
-                '*)                  ;    GNUNET_FS_URI *chk_uri;
+                '*                   ;    GNUNET_FS_URI *chk_uri;
+                 '*)                  ;    GNUNET_FS_URI *sks_uri;
           (list #:completed          ;   struct {…} completed
-                '*)                  ;    GNUNET_FS_URI *chk_uri;
+                '*                   ;    GNUNET_FS_URI *chk_uri;
+                 '*)                  ;    GNUNET_FS_URI *sks_uri;
           (list #:error              ;   struct {…} error
                 '*)))                ;    char *message;
     (list #:download                  ;  struct {…} download
@@ -156,6 +208,7 @@
    unsigned-int                       ; enum GNUNET_FS_Status status;
    '*))                               ; GNUNET_FS_Handle *fsh;
 
+
 (define progress-info-status-alist
   `((0  #:publish  #:start)
     (1  #:publish  #:resume)
@@ -211,6 +264,59 @@
         uint32 uint32 uint32 uint32 uint32))
 
 
+(define-record-type <pinfo-publish>
+  (wrap-pinfo-publish pointer status filename size eta duration completed
+                      anonymity chk-uri sks-uri message)
+  pinfo-publish?
+  (pointer   unwrap-pinfo-publish)
+  (status    pinfo-publish-status)
+  (filename  pinfo-publish-filename)
+  (size      pinfo-publish-size)
+  (eta       pinfo-publish-eta)
+  (duration  pinfo-publish-duration)
+  (completed pinfo-publish-completed)
+  (anonymity pinfo-publish-anonymity)
+  (chk-uri   pinfo-publish-chk-uri)
+  (sks-uri   pinfo-publish-sks-uri)
+  (message   pinfo-publish-message))
+
+(define-record-type <pinfo-download>
+  (wrap-pinfo-download pointer status uri filename size eta duration completed
+                       anonymity active? message)
+  pinfo-download?
+  (pointer    unwrap-pinfo-download)
+  (status     pinfo-download-status)
+  (uri        pinfo-download-uri)
+  (filename   pinfo-download-filename)
+  (size       pinfo-download-size)
+  (eta        pinfo-download-eta)
+  (duration   pinfo-download-duration)
+  (completed  pinfo-download-completed)
+  (anonymity  pinfo-download-anonymity)
+  (active?    pinfo-download-active?)
+  (message    pinfo-download-message))
+
+(define-record-type <pinfo-search>
+  (wrap-pinfo-search pointer status query duration anonymity metadata
+                     uri result message)
+  pinfo-search?
+  (pointer   unwrap-pinfo-search)
+  (status    pinfo-search-status)
+  (query     pinfo-search-query)
+  (duration  pinfo-search-duration)
+  (anonymity pinfo-search-anonymity)
+  (metadata  pinfo-search-metadata)
+  (uri       pinfo-search-uri)
+  (result    pinfo-search-result)
+  (message   pinfo-search-message))
+
+(define-record-type <pinfo-unindex>
+  (wrap-pinfo-unindex pointer status)
+  pinfo-unindex?
+  (pointer unwrap-pinfo-unindex)
+  (status  pinfo-unindex-status))
+
+
 (define (integer->progress-info-status n)
   (or (assq-ref progress-info-status-alist n)
       (throw 'invalid-arg "integer->progress-info-status" n)))
@@ -240,10 +346,67 @@ two keywords. If status is unknown, raises an error."
         (list (car status) #f)
         status)))
 
-(define (parse-c-progress-info pointer)
-  (apply parse-c-struct* pointer %progress-info-type
-         (progress-info-status pointer #t)))
+;;; incomplete mappings of ProgressInfo structures, to be completed on demand.
+
+(define (make-pinfo-publish status pointer vals)
+  (destructuring-bind ((_ _ _ _ %filename size eta duration
+                        completed anonymity specs) _ _)
+      vals
+    (apply wrap-pinfo-publish pointer status
+           (pointer->string* %filename)
+           size eta duration completed anonymity
+           (case (cadr status)
+             ((#:completed)
+              (destructuring-bind (%chk-uri %sks-uri) specs
+                (list (wrap-uri %chk-uri)
+                      (wrap-uri %sks-uri)
+                      #f)))
+             ((#:error)
+              (list #f #f (pointer->string* (car specs))))
+             (else '(#f #f #f))))))
 
+(define (make-pinfo-download status pointer vals)
+  (destructuring-bind ((_ _ _ _ %uri %filename size eta duration
+                        completed anonymity %active? specs) _ _)
+      vals
+    (apply wrap-pinfo-download pointer status
+           (wrap-uri %uri)
+           (pointer->string %filename)
+           size eta duration completed anonymity
+           (int->bool %active?)
+           (if (eq? #:error (cadr status))
+               (list (pointer->string* (car specs)))
+               '(#f)))))
+
+(define (make-pinfo-search status pointer vals)
+  (destructuring-bind ((_ _ _ %query duration anonymity specs) _ _)
+      vals
+    (apply wrap-pinfo-search pointer status
+           %query duration anonymity
+           (case (cadr status)
+             ((#:result #:resume-result)
+              (destructuring-bind (%meta %uri %result . rest) specs
+                (list (wrap-metadata %meta) (wrap-uri %uri) %result #f)))
+             ((#:update #:result-suspend #:result-stopped)
+              (destructuring-bind (_ %meta %uri . rest) specs
+                (list (wrap-metadata %meta) (wrap-uri %uri) #f #f)))
+             ((#:resume #:error)
+              (list #f #f #f (pointer->string* (car specs))))
+             (else '(#f #f #f #f))))))
+
+;;+TODO: write this mapping
+(define (make-pinfo-unindex status pointer vals)
+  (wrap-pinfo-unindex pointer status))
+
+(define (parse-c-progress-info pointer)
+  (let* ((status (progress-info-status pointer #t))
+         (vals   (apply parse-c-struct* pointer %progress-info-type status))
+         (maker  (case (car status)
+                   ((#:publish)  make-pinfo-publish)
+                   ((#:download) make-pinfo-download)
+                   ((#:search)   make-pinfo-search)
+                   ((#:unindex)  make-pinfo-unindex))))
+    (maker status pointer vals)))
 
 ;;; incomplete mapping of GNUNET_FS_SearchResult
 ;;;+TODO: complete mapping of GNUNET_FS_SearchResult
diff --git a/tests/fs.scm b/tests/fs.scm
new file mode 100644
index 0000000..0baa9f5
--- /dev/null
+++ b/tests/fs.scm
@@ -0,0 +1,39 @@
+;;;; -*- mode: Scheme; indent-tabs-mode: nil; fill-column: 80; -*-
+;;;; 
+;;;; Copyright © 2015 Rémi Delrue <address@hidden>
+;;;; 
+;;;; This program is free software: you can redistribute it and/or modify
+;;;; it under the terms of the GNU General Public License as published by
+;;;; the Free Software Foundation, either version 3 of the License, or
+;;;; (at your option) any later version.
+;;;; 
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;;; GNU General Public License for more details.
+;;;; 
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (test-fs)
+  #:use-module (srfi srfi-64)
+  #:use-module (system foreign)
+  #:use-module (gnu gnunet common)
+  #:use-module (gnu gnunet fs))
+
+(test-begin "test-fs")
+
+(define %block-options (make-block-options 0 1))
+
+;;; <file-information>
+
+(define readme (make-file-information %null-pointer ; no fs for this test
+                                     "README"
+                                      %block-options
+                                     #:keywords '("manual" "important")
+                                     #:index? #t))
+
+(test-equal "README" (file-information-filename   readme))
+(test-equal #f       (file-information-directory? readme))
+
+(test-end)
diff --git a/tests/progress-info.scm b/tests/progress-info.scm
index f001baa..2781c52 100644
--- a/tests/progress-info.scm
+++ b/tests/progress-info.scm
@@ -20,8 +20,10 @@
   #:use-module (srfi srfi-64)
   #:use-module (rnrs bytevectors)
   #:use-module (system foreign)
+  #:use-module (system foreign unions)
   #:use-module (gnu gnunet common)
   #:use-module (gnu gnunet container metadata)
+  #:use-module (gnu gnunet fs uri)
   #:use-module (gnu gnunet fs progress-info))
 
 
@@ -32,7 +34,29 @@
 (pi-import integer->progress-info-status
            progress-info-status->integer
            bytevector-u8-fold
-           u8-bitmap->list)
+           u8-bitmap->list
+           %progress-info-type)
+
+(define *test-uri*
+  (parse-uri 
"gnunet://fs/chk/AH11VENCEPEH119B1TQQ06CT170TA400J653E9G2D7JPV57HRN528KK71270D81PAV23GBNNPS6KKQM48C1H7FG41JT1ETPK551MRH8.74DJF0M1T999MC6K65NV1MC0RG11S81127JS9SV1M79QE2S6GMSQE0K87110D95J9HV0VDCGFG11BK97C2E5BD2T5F6TQTAFF6KP3F0.50"))
+
+(define *test-pinfo-ptr*
+  (make-c-struct* %progress-info-type
+                  (list (list %null-pointer                ; context
+                              %null-pointer                ; cctx
+                              %null-pointer                ; pctx
+                              %null-pointer                ; sctx
+                              (unwrap-uri *test-uri*)      ; download uri
+                              (string->pointer "trek.txt") ; filename
+                              50                           ; size
+                              (time-rel #:milli 2)         ; eta
+                              (time-rel #:seconds 1.3)     ; duration
+                              50                           ; completed
+                              0                            ; anonymity
+                              0)                           ; is_active
+                        12               ; GNUNET_FS_STATUS_DOWNLOAD_COMPLETED
+                        %null-pointer)   ; filesharing handle
+                  #:download #f))
 
 (test-begin "test-fs-progress-info")
 
@@ -45,6 +69,13 @@
 (test-error 'invalid-arg (progress-info-status->integer
                           '(#:beam-me-up #:scotty)))
 
+;; parse-c-progress-info
+(define *test-pinfo*   (parse-c-progress-info *test-pinfo-ptr*))
+
+(test-equal "trek.txt" (pinfo-download-filename *test-pinfo*))
+(test-equal 50 (pinfo-download-size *test-pinfo*))
+(test-equal #f         (pinfo-download-active?  *test-pinfo*))
+
 
 ;; bytevector-u8-fold
 (let ((bv (make-bytevector 1)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]