#lang racket/base (require racket/class "../library/library-factory.rkt" "../library/track-store.rkt" "../library/base/track.rkt" "../misc/utils.rkt") (provide playlist-entry% track->playlist-entry store->playlist-entry) (define playlist-entry% (class object% (init-field stored [track #f]) (check/c* playlist-entry% (stored track-store?) (track (or/c #f (is-a?/c track<%>)))) (define/public (is-valid?) (not (eq? track #f))) (define/public (get-track) track) (define cache-file (and track (send (send track get-resource) get-file))) (define cache-status (if cache-file 'available 'unavailable)) (define cache-error #f) (define/public (get-cache-file) (if (and cache-file (file-exists? cache-file)) cache-file (begin (set! cache-file #f) (unless (eq? cache-status 'downloading) (set! cache-status 'unavailable)) #f))) (define/public (get-cache-status) cache-status) (define/public (get-cache-error) cache-error) (define/public (is-available?) (and (send this is-valid?) (eq? cache-status 'available) (send this get-cache-file) #t)) (define/public (set-cache-downloading!) (set! cache-file #f) (set! cache-status 'downloading) (set! cache-error #f)) (define/public (set-cache-file! file) (set! cache-file file) (set! cache-status 'available) (set! cache-error #f)) (define/public (set-cache-failed! message) (set! cache-file #f) (set! cache-status 'failed) (set! cache-error message)) (define/public (get-id) (track-store-id stored)) (define/public (get-number) (if track (send track get-number) (track-store-number stored))) (define/public (get-title) (if track (send track get-title) (track-store-title stored))) (define/public (get-artist) (if track (send track get-artist) "")) (define/public (get-album) (if track (send track get-album) "")) (define/public (get-length) (if track (send track get-length) 0)) (define/public (->store) stored) (super-new))) (define (track->playlist-entry track) (check/c track->playlist-entry track (is-a?/c track<%>)) (new playlist-entry% [stored (track->store track)] [track track])) (define (store->playlist-entry stored factory) (check/c store->playlist-entry factory (is-a?/c library-factory%)) (and (track-store? stored) (new playlist-entry% [stored stored] [track (store->track stored factory)]))) (module+ test (require rackunit "../library/library-ref.rkt" "../library/track-filesystem.rkt") (define stored (list 'track 1 'playlist-track 3 "Stored title" (library-ref 'test-library 'filesystem 1) 'file (list (string->path "track.mp3")))) (define invalid-entry (new playlist-entry% [stored stored])) (check-false (send invalid-entry is-valid?)) (check-false (send invalid-entry get-track)) (check-equal? (send invalid-entry get-id) 'playlist-track) (check-equal? (send invalid-entry get-number) 3) (check-equal? (send invalid-entry get-title) "Stored title") (check-equal? (send invalid-entry get-artist) "") (check-equal? (send invalid-entry get-album) "") (check-equal? (send invalid-entry get-length) 0) (check-equal? (send invalid-entry ->store) stored) (define cfg% (class object% (define/public (get-id) 'test-library) (define/public (get-kind) 'filesystem) (define/public (get-kind-version) 1) (super-new))) (define library% (class object% (define/public (resolve-path relative-path) (apply build-path relative-path)) (define/public (get-cfg) (new cfg%)) (super-new))) (define track (new track-filesystem% [library (new library%)] [relative-path (list (string->path "track.mp3"))])) (define valid-entry (track->playlist-entry track)) (check-true (send valid-entry is-valid?)) (check-eq? (send valid-entry get-track) track) (check-equal? (send valid-entry get-title) (send track get-title)) (check-true (track-store? (send valid-entry ->store))))