#lang racket/base (require file/sha1 racket/os racket/path racket/random racket/string simple-ini) (provide (struct-out player-agent-config) load-player-agent-config save-player-agent-config! valid-app-id?) (struct player-agent-config (file ini app-id server-url name) #:transparent) (define (fresh-app-id) (bytes->hex-string (crypto-random-bytes 32))) (define (valid-app-id? value) (and (string? value) (regexp-match? #px"^[0-9a-fA-F]{64}$" value))) (define (load-player-agent-config [file (get-ini-file 'rkt-web-player-agent)]) (define ini (file->ini file)) (define configured-id (ini-get ini 'agent 'app-id #f)) (define value (player-agent-config file ini (if (valid-app-id? configured-id) (string-downcase configured-id) (fresh-app-id)) (ini-get ini 'server 'url "http://127.0.0.1:8080") (ini-get ini 'agent 'name (format "~a playback" (gethostname))))) (save-player-agent-config! value) value) (define (save-player-agent-config! value) (define ini (player-agent-config-ini value)) (ini-set! ini 'agent 'app-id (player-agent-config-app-id value)) (ini-set! ini 'agent 'name (player-agent-config-name value)) (ini-set! ini 'server 'url (player-agent-config-server-url value)) (ini->file ini (player-agent-config-file value) #:private? #t)) (module+ test (require rackunit racket/file) (define test-directory (make-temporary-file "rkt-agent-config-~a" 'directory)) (define test-file (build-path test-directory "agent.ini")) (dynamic-wind void (lambda () (define first (load-player-agent-config test-file)) (check-true (valid-app-id? (player-agent-config-app-id first))) (define changed (struct-copy player-agent-config first (server-url "https://music.example.test") (name "Test output"))) (save-player-agent-config! changed) (define second (load-player-agent-config test-file)) (check-equal? (player-agent-config-app-id second) (player-agent-config-app-id first)) (check-equal? (player-agent-config-server-url second) "https://music.example.test") (check-equal? (player-agent-config-name second) "Test output")) (lambda () (delete-directory/files test-directory))))