Peter Siebel - Practical Common Lisp
Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:Practical Common Lisp
- Автор:
- Издательство:Apress
- Жанр:
- Год:2005
- ISBN:1-59059-239-5
- Рейтинг книги:4 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 80
- 1
- 2
- 3
- 4
- 5
Practical Common Lisp: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
(let ((playlist (lookup-playlist playlist-id)))
(with-playlist-locked (playlist)
Since lookup-playlist
will create a new playlist if necessary, this will always return a playlist
object. Then you take care of any necessary queue manipulation, dispatching on the value of the action
parameter in order to call one of the playlist
functions.
(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 playlist
function is the actual HTML generation. Again, you can use the :mp3-browser-page
HTML 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 :header
argument in order to leave out the H1
header. 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-toolbar
generates a toolbar containing links to playlist
to perform the various :action
manipulations. And delete-songs-link
generates a link to playlist
with the :action
parameter set to :delete-songs
and 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 playlist
page with an explicit playlist-id
query parameter, which will then be made sticky by the playlist
URL 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-database
function from Chapter 27, publish the CSS style sheet, set *song-source-type*
to playlist
so find-song-source
uses 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» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.