#lang scheme/base
(require scheme/contract
scheme/file
(prefix-in 19: srfi/19))
(provide/contract [copy-directory/files* (path-string? path-string? . -> . any)]
[copy-or-overwrite-file (path-string? path-string? . -> . any)]
[upper-camel-case (string? . -> . string?)]
[make-temporary-directory (() (#:parent-directory path?) . ->* . path?)]
[get-file-bytes (path? . -> . bytes?)]
[get-input-port-bytes (input-port? . -> . bytes?)]
[now-date-string (-> string?)]
[string->date (string? . -> . date?)]
[with-temporary-directory ((path? . -> . any) . -> . any)])
(define (copy-or-overwrite-file src-path dest-path)
(when (file-exists? dest-path)
(delete-file dest-path))
(copy-file src-path dest-path))
(define (copy-directory/files* from-path dest-path)
(for ([entry (directory-list from-path)])
(cond [(file-exists? (build-path from-path entry))
(when (file-exists? (build-path dest-path entry))
(delete-file (build-path dest-path entry)))
(make-directory* dest-path)
(copy-file (build-path from-path entry)
(build-path dest-path entry))]
[else
(when (file-exists? (build-path dest-path entry))
(delete-file (build-path dest-path entry)))
(when (not (directory-exists? (build-path dest-path entry)))
(make-directory* (build-path dest-path entry)))
(copy-directory/files* (build-path from-path entry)
(build-path dest-path entry))])))
(define (get-file-bytes a-path)
(call-with-input-file a-path
get-input-port-bytes))
(define (get-input-port-bytes ip)
(let loop ([b (bytes)])
(let ([chunk (read-bytes 8196 ip)])
(cond
[(eof-object? chunk)
b]
[else
(loop (bytes-append b chunk))]))))
(define (make-temporary-directory #:parent-directory (parent-dir #f))
(let ([f (make-temporary-file "tmp~a" #f parent-dir)])
(delete-file f)
(make-directory f)
f))
(define (with-temporary-directory f)
(let ([dir #f])
(dynamic-wind
(lambda ()
(set! dir (make-temporary-file))
(delete-file dir)
(make-directory dir))
(lambda ()
(f dir))
(lambda ()
(delete-directory/files dir)))))
(define (now-date-string)
(19:date->string (19:current-date) "~5"))
(define (string->date an-str)
(let* ([d (19:string->date an-str "~Y-~m-~dT~H:~M:~S")]
[second (19:date-second d)]
[minute (19:date-minute d)]
[hour (19:date-hour d)]
[day (19:date-day d)]
[month (19:date-month d)]
[year (19:date-year d)]
[week-day (19:date-week-day d)]
[year-day (19:date-year-day d)]
[dst? #f] [time-zone-offset (19:date-zone-offset d)])
(make-date second
minute
hour
day
month
year
week-day
year-day
dst?
time-zone-offset)))
(define (upper-camel-case name)
(apply string-append
(map string-titlecase (regexp-split #px"[\\s]+"
(regexp-replace* #px"[^\\s\\w]+" name " ")))))