Peter Siebel - Practical Common Lisp

Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Practical Common Lisp: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

(let ((playlist (lookup-playlist playlist-id)))

(with-playlist-locked (playlist)

Since lookup-playlistwill create a new playlist if necessary, this will always return a playlistobject. Then you take care of any necessary queue manipulation, dispatching on the value of the actionparameter in order to call one of the playlistfunctions.

(case action

(:add-songs (add-songs playlist what (or values (list file))))

(:delete-songs (delete-songs

playlist

:file file :genre genre

:artist artist :album album))

(:clear (clear-playlist playlist))

(:sort (sort-playlist playlist order-by))

(:shuffle (shuffle-playlist playlist shuffle))

(:set-repeat (setf (repeat playlist) repeat)))

All that's left of the playlistfunction is the actual HTML generation. Again, you can use the :mp3-browser-pageHTML macro to make sure the basic form of the page matches the other pages in the application, though this time you pass NIL to the :headerargument in order to leave out the H1header. Here's the rest of the function:

(html

(:mp3-browser-page

(:title (:format "Playlist - ~a" (id playlist)) :header nil)

(playlist-toolbar playlist)

(if (empty-p playlist)

(html (:p (:i "Empty.")))

(html

((:table :class "playlist")

(:table-row "#" "Song" "Album" "Artist" "Genre")

(let ((idx 0)

(current-idx (current-idx playlist)))

(do-rows (row (songs-table playlist))

(with-column-values (track file song album artist genre) row

(let ((row-style (if (= idx current-idx) "now-playing" "normal")))

(html

((:table-row :class row-style)

track

(:progn song (delete-songs-link :file file))

(:progn album (delete-songs-link :album album))

(:progn artist (delete-songs-link :artist artist))

(:progn genre (delete-songs-link :genre genre)))))

(incf idx))))))))))))

The function playlist-toolbargenerates a toolbar containing links to playlistto perform the various :actionmanipulations. And delete-songs-linkgenerates a link to playlistwith the :actionparameter set to :delete-songsand the appropriate arguments to delete an individual file, or all files on an album, by a particular artist or in a specific genre.

(defun playlist-toolbar (playlist)

(let ((current-repeat (repeat playlist))

(current-sort (ordering playlist))

(current-shuffle (shuffle playlist)))

(html

(:p :class "playlist-toolbar"

(:i "Sort by:")

" [ "

(sort-playlist-button "genre" current-sort) " | "

(sort-playlist-button "artist" current-sort) " | "

(sort-playlist-button "album" current-sort) " | "

(sort-playlist-button "song" current-sort) " ] "

(:i "Shuffle by:")

" [ "

(playlist-shuffle-button "none" current-shuffle) " | "

(playlist-shuffle-button "song" current-shuffle) " | "

(playlist-shuffle-button "album" current-shuffle) " ] "

(:i "Repeat:")

" [ "

(playlist-repeat-button "none" current-repeat) " | "

(playlist-repeat-button "song" current-repeat) " | "

(playlist-repeat-button "all" current-repeat) " ] "

"[ " (:a :href (link "playlist" :action "clear") "Clear") " ] "))))

(defun playlist-button (action argument new-value current-value)

(let ((label (string-capitalize new-value)))

(if (string-equal new-value current-value)

(html (:b label))

(html (:a :href (link "playlist" :action action argument new-value) label)))))

(defun sort-playlist-button (order-by current-sort)

(playlist-button :sort :order-by order-by current-sort))

(defun playlist-shuffle-button (shuffle current-shuffle)

(playlist-button :shuffle :shuffle shuffle current-shuffle))

(defun playlist-repeat-button (repeat current-repeat)

(playlist-button :set-repeat :repeat repeat current-repeat))

(defun delete-songs-link (what value)

(html " [" (:a :href (link "playlist" :action :delete-songs what value) "x") "]"))

Finding a Playlist

The last of the three URL functions is the simplest. It presents a table listing all the playlists that have been created. Ordinarily users won't need to use this page, but during development it gives you a useful view into the state of the system. It also provides the mechanism to choose a different playlist—each playlist ID is a link to the playlistpage with an explicit playlist-idquery parameter, which will then be made sticky by the playlistURL function. Note that you need to acquire the *playlists-lock*to make sure the *playlists*hash table doesn't change out from under you while you're iterating over it.

(define-url-function all-playlists (request)

(:mp3-browser-page

(:title "All Playlists")

((:table :class "all-playlists")

(:table-row "Playlist" "# Songs" "Most recent user agent")

(with-process-lock (*playlists-lock*)

(loop for playlist being the hash-values of *playlists* do

(html

(:table-row

(:a :href (link "playlist" :playlist-id (id playlist)) (:print (id playlist)))

(:print (table-size (songs-table playlist)))

(:print (user-agent playlist)))))))))

Running the App

And that's it. To use this app, you just need to load the MP3 database with the load-databasefunction from Chapter 27, publish the CSS style sheet, set *song-source-type*to playlistso find-song-sourceuses playlists instead of the singleton song source defined in the previous chapter, and start AllegroServe. The following function takes care of all these steps for you, after you fill in appropriate values for the two parameters *mp3-dir*, which is the root directory of your MP3 collection, and *mp3-css*, the filename of the CSS style sheet:

(defparameter *mp3-dir* ...)

(defparameter *mp3-css* ...)

(defun start-mp3-browser ()

(load-database *mp3-dir* *mp3s*)

(publish-file :path "/mp3-browser.css" :file *mp3-css* :content-type "text/css")

(setf *song-source-type* 'playlist)

(net.aserve::debug-on :notrap)

(net.aserve:start :port 2001))

When you invoke this function, it will print dots while it loads the ID3 information from your ID3 files. Then you can point your MP3 client at this URL:

http://localhost:2001/stream.mp3

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Practical Common Lisp»

Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Practical Common Lisp»

Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x