97 lines
4.1 KiB
Racket
97 lines
4.1 KiB
Racket
#lang racket
|
|
;; cab is a verb now.
|
|
;; =============================================================================
|
|
;; usage:
|
|
;; ./racket cab.rkt
|
|
;; ./racket cab.rkt -v
|
|
;; ./racket cab.rkt -p "/home/user/messy/folder/to/cab"
|
|
;; ============================================================================
|
|
;; SET UP CABINETS AND ASSOCIATED EXTENSIONS HERE
|
|
;; ============================================================================
|
|
(define cabinets '("archives" "audio" "dirs" "docs" "misc" "pics" "q3" "vids"))
|
|
(define (get-cabinet-name ext)
|
|
(define s
|
|
(if (bytes? ext) (bytes->string/utf-8 ext) ext))
|
|
(cond
|
|
[(string=? s "dir") "dirs"]
|
|
[(member s '("7z" "gz" "rar" "tar" "zip")) "archives"]
|
|
[(member s '("jpg" "jpeg" "png" "gif" "webp" "bmp" "tga")) "pics"]
|
|
[(member s '("txt" "doc" "docx" "odt" "xls" "ods" "pdf" "md" "epub")) "docs"]
|
|
[(member s '("wav" "ogg" "mp3")) "audio"]
|
|
[(member s '("avi" "mp4" "mpg" "mkv" "webm")) "vids"]
|
|
[(member s '("pk3" "dm_68")) "q3"]
|
|
[(member s '("crdownload")) #f] ;; don't touch chrome temp downloads
|
|
[else "misc"]))
|
|
|
|
(define (xdg-user-dir name)
|
|
(define config-file (expand-user-path "~/.config/user-dirs.dirs"))
|
|
(if (file-exists? config-file)
|
|
(let* ([lines (file->lines config-file)]
|
|
[prefix (string-append "XDG_" name "_DIR=")])
|
|
(for/or ([line lines])
|
|
(if (string-prefix? line prefix)
|
|
(let* ([raw (substring line (string-length prefix))]
|
|
[unquoted (regexp-replace* #px"\"" raw "")]
|
|
[expanded (regexp-replace
|
|
#px"\\$HOME"
|
|
unquoted
|
|
(path->string (find-system-path 'home-dir)))])
|
|
(path->complete-path (expand-user-path expanded)))
|
|
#f)))
|
|
#f))
|
|
(define xdg-download-dir (xdg-user-dir "DOWNLOAD"))
|
|
|
|
(define (create-cabinets)
|
|
(for ([cabinet cabinets])
|
|
(when (not (directory-exists? cabinet))
|
|
(make-directory cabinet))))
|
|
|
|
(define verbose? (make-parameter #f))
|
|
(define path-param (make-parameter xdg-download-dir))
|
|
(define (cab)
|
|
(command-line
|
|
#:once-each
|
|
[("-v") "Verbose mode" (verbose? #t)]
|
|
[("-p" "--path") path "Specify path" (path-param path)]
|
|
#:args ()
|
|
(void))
|
|
(define (process-files files)
|
|
(cond
|
|
[(empty? files) 'done]
|
|
[else
|
|
(let ([file-name (first files)])
|
|
(cond
|
|
[(and (equal? (file-or-directory-type file-name) 'directory)
|
|
(or (member (path->string file-name) cabinets)
|
|
(string=? (path->string file-name) ".")))
|
|
(when (verbose?) (displayln (format "Skipping cabinet/current directory: ~a" file-name)))
|
|
(process-files (rest files))]
|
|
[(equal? (file-or-directory-type file-name) 'file)
|
|
(let ([ext (filename-extension file-name)])
|
|
(let ([cabinet-name (get-cabinet-name ext)])
|
|
(if cabinet-name
|
|
(begin
|
|
(let ([new-path (build-path cabinet-name file-name)])
|
|
(rename-file-or-directory file-name new-path))
|
|
(let ([display-ext (if (bytes? ext) (bytes->string/utf-8 ext) ext)])
|
|
(when (verbose?) (displayln (format "~a -> ~a" display-ext cabinet-name)))))
|
|
(when (verbose?) (displayln (format "Skipping ~a (no move)" file-name))))))
|
|
(process-files (rest files))]
|
|
[(equal? (file-or-directory-type file-name) 'directory)
|
|
(let ([cabinet-name (get-cabinet-name "dir")])
|
|
(let ([new-path (build-path cabinet-name file-name)])
|
|
(rename-file-or-directory file-name new-path))
|
|
(when (verbose?) (displayln (format "~a -> ~a" file-name cabinet-name))))
|
|
(process-files (rest files))]))]))
|
|
(cond
|
|
[(directory-exists? (path-param))
|
|
(create-cabinets)
|
|
(let ([files (directory-list (path-param))])
|
|
(process-files files))]
|
|
[else
|
|
(displayln (format "Error: Directory not found at ~a" (path-param)))
|
|
#f]))
|
|
|
|
(current-directory xdg-download-dir)
|
|
(cab)
|