Index: datashare.scm
==================================================================
--- datashare.scm
+++ datashare.scm
@@ -31,12 +31,12 @@
(use sqlite3 srfi-1 posix regex regex-case srfi-69)
(import (prefix sqlite3 sqlite3:))
(declare (uses configf))
(declare (uses tree))
+(declare (uses margs))
;; (declare (uses dcommon))
-;; (declare (uses margs))
;; (declare (uses launch))
;; (declare (uses gutils))
;; (declare (uses db))
;; (declare (uses synchash))
;; (declare (uses server))
@@ -47,14 +47,17 @@
;;
;; GLOBALS
;;
(define *datashare:current-tab-number* 0)
+(define *args-hash* (make-hash-table))
(define datashare:help (conc "Usage: datashare [action [params ...]]
Note: run datashare without parameters to start the gui.
+ list-areas : List the allowed areas
+ list-versions : List versions available in
publish : Publish data to share, use group to protect
get : Get a link to data, put the link in destpath (i)
update : Update the link to data to the latest iteration.
(i) Uses local path or looks up script to find path in configs
@@ -259,10 +262,22 @@
(conc "SELECT id,area,version_name,store_type,copied,source_path,iteration,submitter,datetime,storegrp,datavol,quality,disk_id,comment,stored_path "
" FROM pkgs WHERE area like ? AND version_name LIKE ? AND iteration " iter-filter ";")
area-filter version-filter)
(reverse res)))
+(define (datashare:get-versions-for-area db area-name #!key (version-patt "%"))
+ (let ((res '())
+ (data (make-hash-table)))
+ (sqlite3:for-each-row
+ (lambda (version-name submitter iteration submitted-time comment)
+ ;; 0 1 2 3 4
+ (hash-table-set! data version-name (vector version-name submitter iteration submitted-time comment)))
+ db
+ "SELECT version_name,submitter,iteration,datetime,comment FROM pkgs WHERE area='megatest' AND version_name != 'latest' AND version_name LIKE ? ORDER BY datetime asc;"
+ version-patt)
+ (map (lambda (x)(hash-table-ref data x))(sort (hash-table-keys data) string-ci>=))))
+
;;======================================================================
;; DATA IMPORT/EXPORT
;;======================================================================
(define (datashare:import-data configdat source-path dest-path area version iteration)
@@ -288,27 +303,38 @@
(print "ERROR: Not enough space in storage area " dest-path)
(datashare:set-copied db id "no")
(sqlite3:finalize! db)
#f))))
-(define (datashare:publish area-name version comment spath submitter quality)
- (let ((db (datashare:open-db configdat))
- (iteration (datashare:register-data db area-name version publish-type submitter quality spath comment))
- (dest-store (datashare:get-best-storage configdat)))
- (if iteration
- (if (eq? 'copy publish-type)
- (begin
- (datashare:import-data configdat spath dest-store area-name version iteration)
- (let ((id (datashare:get-id db area-name version iteration)))
- (datashare:set-latest db id area-name version iteration)))
- (let ((id (datashare:get-id db area-name version iteration)))
- (datashare:set-stored-path db id spath)
- (datashare:set-copied db id "yes")
- (datashare:set-copied db id "n/a")
- (datashare:set-latest db id area-name version iteration)))
- (print "ERROR: Failed to get an iteration number"))
- (sqlite3:finalize! db)))
+(define (datashare:get-areas configdat)
+ (let* ((areadat (configf:get-section configdat "areas"))
+ (areas (if areadat (map car areadat) '())))
+ areas))
+
+(define (datashare:publish configdat publish-type area-name version comment spath submitter quality)
+ ;; input checks
+ (cond
+ ((not (member area-name (datashare:get-areas configdat)))
+ (cons #f (conc "Illegal area name \"" area-name "\"")))
+ (else
+ (let ((db (datashare:open-db configdat))
+ (iteration (datashare:register-data db area-name version publish-type submitter quality spath comment))
+ (dest-store (datashare:get-best-storage configdat)))
+ (if iteration
+ (if (eq? 'copy publish-type)
+ (begin
+ (datashare:import-data configdat spath dest-store area-name version iteration)
+ (let ((id (datashare:get-id db area-name version iteration)))
+ (datashare:set-latest db id area-name version iteration)))
+ (let ((id (datashare:get-id db area-name version iteration)))
+ (datashare:set-stored-path db id spath)
+ (datashare:set-copied db id "yes")
+ (datashare:set-copied db id "n/a")
+ (datashare:set-latest db id area-name version iteration)))
+ (print "ERROR: Failed to get an iteration number"))
+ (sqlite3:finalize! db)
+ (cons #t "Successfully saved data")))))
(define (datashare:get-best-storage configdat)
(let* ((storage (configf:lookup configdat "settings" "storage"))
(store-areas (if storage (string-split storage) '())))
(print "Looking for available space in " store-areas)
@@ -401,11 +427,11 @@
(version (iup:attribute version-tb "VALUE"))
(comment (iup:attribute comment-tb "VALUE"))
(spath (iup:attribute source-tb "VALUE"))
(submitter (current-user-name))
(quality 2))
- (datashare:publish area-name version comment spath submitter quality))))
+ (datashare:publish configdat publish-type area-name version comment spath submitter quality))))
(copy (iup:button "Copy and Publish"
#:expand "HORIZONTAL"
#:action (lambda (obj)
(publish 'copy))))
(link (iup:button "Link and Publish"
@@ -600,10 +626,21 @@
;;======================================================================
;; MISC
;;======================================================================
+
+(define (datashare:do-as-calling-user proc)
+ (let ((eid (current-effective-user-id))
+ (cid (current-user-id)))
+ (if (not (eq? eid cid)) ;; running suid
+ (set! (current-effective-user-id) cid))
+ ;; (print "running as " (current-effective-user-id))
+ (proc)
+ (if (not (eq? eid cid))
+ (set! (current-effective-user-id) eid))))
+
(define (datashare:find name paths)
(if (null? paths)
#f
(let loop ((hed (car paths))
(tal (cdr paths)))
@@ -624,22 +661,62 @@
(if (file-exists? fname)
;; (ini:read-ini fname)
(read-config fname #f #t)
(make-hash-table))))
-(define (datashare:process-action configdat action args)
+(define (datashare:process-action configdat action . args)
(case (string->symbol action)
((publish)
(if (< (length args) 3)
(begin
(print "ERROR: Missing arguments; " (string-intersperse args ", "))
- (exit))
+ (exit 1))
(let* ((srcpath (list-ref args 0))
(areaname (list-ref args 1))
(version (list-ref args 2))
- (remargs (drop args 3)))
- (datashare:import-data configdat srcpath dest-path area version iteration))))))
+ (remargs (args:get-args (drop args 3)
+ '("-type" ;; link or copy (default is copy)
+ "-m")
+ '()
+ args:arg-hash
+ 0))
+ (publish-type (if (equal? (args:get-arg "-type") "link") 'link 'copy))
+ (comment (args:get-arg "-m"))
+ (submitter (current-user-name))
+ (quality (args:get-arg "-quality"))
+ (publish-res (datashare:publish configdat publish-type areaname version comment srcpath submitter quality)))
+ (if (not (car publish-res))
+ (begin
+ (print "ERROR: " (cdr publish-res))
+ (exit 1))))))
+ ((list-versions)
+ (let ((area-name (car args)) ;; version patt full print
+ (remargs (args:get-args args '("-vpatt") '("-full") args:arg-hash 0))
+ (db (datashare:open-db configdat))
+ (versions (datashare:get-versions-for-area db (car args) version-patt: (args:get-arg "-vpatt"))))
+ ;; (print "area-name=" area-name " args=" args " *args-hash*=" (hash-table->alist *args-hash*))
+ (map (lambda (x)
+ (if (args:get-arg "-full")
+ (format #t
+ "~10a~10a~4a~27a~30a\n"
+ (vector-ref x 0)
+ (vector-ref x 1)
+ (vector-ref x 2)
+ (conc "\"" (time->string (seconds->local-time (vector-ref x 3))) "\"")
+ (conc "\"" (vector-ref x 4) "\""))
+ (print (vector-ref x 0))))
+ versions)
+ (sqlite3:finalize! db)))))
+;; use for get
+
+;; (remargs (args:get-args (drop args 3)
+;; '("-i") ;; iteration
+;; '()
+;; *args-hash*
+;; 0))
+;; ;; if -i specified use it as a number, default to -1 which is use highest iteration
+;; (iteration (if (args:get-arg "-i")(string->number (args:get-arg "-i")) -1)))
;; ease debugging by loading ~/.dashboardrc - remove from production!
(let ((debugcontrolf (conc (get-environment-variable "HOME") "/.datasharerc")))
(if (file-exists? debugcontrolf)
(load debugcontrolf)))
@@ -651,17 +728,21 @@
(exe-name (pathname-file (car (argv))))
(exe-dir (or (pathname-directory prog)
(datashare:find exe-name (string-split (get-environment-variable "PATH") ":"))))
(configdat (datashare:load-config exe-dir exe-name)))
(cond
+ ;; one-word commands
((eq? (length rema) 1)
(case (string->symbol (car rema))
((help -h -help --h --help)
(print datashare:help))
+ ((list-areas)
+ (map print (datashare:get-areas configdat)))
(else
(print "ERROR: Unrecognised command. Try \"datashare help\""))))
+ ;; multi-word commands
((null? rema)(datashare:gui configdat))
((>= (length rema) 2)
(apply datashare:process-action configdat (car rema)(cdr rema)))
(else (print "ERROR: Unrecognised command. Try \"datashare help\"")))))
(main)