redirect(0);
}
+static void act_remove(void) {
+ const char *id;
+ struct queue_entry *q;
+
+ if(dcgi_client) {
+ if(!(id = cgi_get("id")))
+ error(0, "missing 'id' argument");
+ else if(!(q = dcgi_findtrack(id)))
+ error(0, "unknown queue id %s", id);
+ else switch(q->state) {
+ case playing_isscratch:
+ case playing_failed:
+ case playing_no_player:
+ case playing_ok:
+ case playing_quitting:
+ case playing_scratched:
+ error(0, "does not make sense to scratch %s", id);
+ break;
+ case playing_paused: /* started but paused */
+ case playing_started: /* started to play */
+ disorder_scratch(dcgi_client, id);
+ break;
+ case playing_random: /* unplayed randomly chosen track */
+ case playing_unplayed: /* haven't played this track yet */
+ disorder_remove(dcgi_client, id);
+ break;
+ }
+ }
+ redirect(0);
+}
+
/** @brief Table of actions */
static const struct action {
/** @brief Action name */
{ "playing", act_playing },
{ "random-disable", act_random_disable },
{ "random-enable", act_random_enable },
+ { "remove", act_remove },
};
/** @brief Expand a template
char *dcgi_cookie_header(void);
void dcgi_login(void);
void dcgi_get_cookie(void);
+struct queue_entry *dcgi_findtrack(const char *id);
void option_set(const char *name, const char *value);
const char *option_label(const char *key);
/** @brief Cached data */
static unsigned flags;
+/** @brief Map of hashes to queud data */
+static hash *queuemap;
+
struct queue_entry *dcgi_queue;
struct queue_entry *dcgi_playing;
struct queue_entry *dcgi_recent;
int dcgi_enabled;
int dcgi_random_enabled;
+static void queuemap_add(struct queue_entry *q) {
+ if(!queuemap)
+ queuemap = hash_new(sizeof (struct queue_entry *));
+ for(; q; q = q->next)
+ hash_add(queuemap, q->id, &q, HASH_INSERT_OR_REPLACE);
+}
+
/** @brief Fetch cachable data */
void dcgi_lookup(unsigned want) {
unsigned need = want ^ (flags & want);
if(!dcgi_client || !need)
return;
- if(need & DCGI_QUEUE)
+ if(need & DCGI_QUEUE) {
disorder_queue(dcgi_client, &dcgi_queue);
- if(need & DCGI_PLAYING)
+ queuemap_add(dcgi_queue);
+ }
+ if(need & DCGI_PLAYING) {
disorder_playing(dcgi_client, &dcgi_playing);
+ queuemap_add(dcgi_playing);
+ }
if(need & DCGI_NEW)
disorder_new_tracks(dcgi_client, &dcgi_new, &dcgi_nnew, 0);
if(need & DCGI_RECENT) {
dcgi_recent = r;
r = rnext;
}
+ queuemap_add(dcgi_recent);
}
if(need & DCGI_VOLUME)
disorder_get_volume(dcgi_client,
flags |= need;
}
+/** @brief Locate a track by ID */
+struct queue_entry *dcgi_findtrack(const char *id) {
+ struct queue_entry *q, **qq;
+
+ if(queuemap && (qq = hash_find(id)))
+ return *q;
+ dcgi_lookup(DCGI_PLAYING);
+ if(queuemap && (qq = hash_find(id)))
+ return *q;
+ dcgi_lookup(DCGI_QUEUE);
+ if(queuemap && (qq = hash_find(id)))
+ return *q;
+ dcgi_lookup(DCGI_RECENT);
+ if(queuemap && (qq = hash_find(id)))
+ return *q;
+ return NULL;
+}
+
void dcgi_lookup_reset(void) {
/* Forget everything we knew */
flags = 0;
+ queuemap = 0;
dcgi_recent = 0;
dcgi_queue = 0;
dcgi_playing = 0;
/** @brief For error template */
char *dcgi_error_string;
-/** @brief Locate a track by ID */
-static struct queue_entry *findtrack(const char *id) {
- struct queue_entry *q;
-
- dcgi_lookup(DCGI_PLAYING);
- if(dcgi_playing && !strcmp(dcgi_playing->id, id))
- return dcgi_playing;
- dcgi_lookup(DCGI_QUEUE);
- for(q = dcgi_queue; q; q = q->next)
- if(!strcmp(q->id, id))
- return q;
- dcgi_lookup(DCGI_RECENT);
- for(q = dcgi_recent; q; q = q->next)
- if(!strcmp(q->id, id))
- return q;
- return NULL;
-}
-
/** @brief Return @p i as a string */
static const char *make_index(int i) {
char *s;
char *s;
if(track[0] != '/') {
- struct queue_entry *q = findtrack(track);
+ struct queue_entry *q = dcgi_findtrack(track);
if(q)
track = q->track;
char **args,
struct sink *output,
void attribute((unused)) *u) {
- struct queue_entry *q = findtrack(args[0]);
+ struct queue_entry *q = dcgi_findtrack(args[0]);
if(q && q->submitter)
return sink_writes(output, cgi_sgmlquote(q->submitter)) < 0 ? -1 : 0;
char **args,
struct sink *output,
void attribute((unused)) *u) {
- struct queue_entry *q = findtrack(args[0]);
+ struct queue_entry *q = dcgi_findtrack(args[0]);
const struct tm *w = 0;
if(q) {
name = args[0];
else {
/* Track identified by queue ID */
- if(!(q = findtrack(args[0])))
+ if(!(q = dcgi_findtrack(args[0])))
return 0;
if(q->state == playing_started || q->state == playing_paused)
if(sink_printf(output, "%ld:%02ld/", q->sofar / 60, q->sofar % 60) < 0)
char **args,
struct sink *output,
void attribute((unused)) *u) {
- struct queue_entry *q = findtrack(args[0]);
+ struct queue_entry *q = dcgi_findtrack(args[0]);
/* TODO would be better to reject recent */
if(!q || !dcgi_client)
char **args,
struct sink *output,
void attribute((unused)) *u) {
- struct queue_entry *q = findtrack(args[0]);
+ struct queue_entry *q = dcgi_findtrack(args[0]);
/* TODO would be better to recent playing/recent */
if(!q || !dcgi_client)
char **args,
struct sink *output,
void attribute((unused)) *u) {
- struct queue_entry *q = findtrack(args[0]);
+ struct queue_entry *q = dcgi_findtrack(args[0]);
if(q)
return sink_writes(output, playing_states[q->state]) < 0 ? -1 : 0;
-<p class=credits><a
-href="http://www.greenend.org.uk/rjk/disorder/"
-title="DisOrder web site">DisOrder
-version @version@</a> © 2003-2008 Richard Kettlewell</p>
-@@
-<!--
+@discard{
This file is part of DisOrder.
Copyright (C) 2004-2008 Richard Kettlewell
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
-->
+}@#
+<p class=credits>
+ <a href="http://www.greenend.org.uk/rjk/disorder/"
+ title="DisOrder web site">DisOrder
+ version @version</a>
+ © 2003-2008 Richard Kettlewell et al
+</p>
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
-@define {ifmanage} {yes} {no}
- {@if {@eq {@arg{action}}{manage}}
- {@yes}
- {@no}}
+@# Expand to @yes for the Manage page and @no for the playing page
+@define {ifmanage} {yes no}
+ {@if {@eq {@arg{action}}{manage}}
+ {@yes}
+ {@no}}
-}@@@
+@# Expand to &back=manage or to nothing
+@define {back} {}
+ {@ifmanage{&back=manage}{}}
+
+@# Expand to the time that @id will be played
+@define {mwhen} {what id}
+ {@when{@id}</td>}
+
+@# Expand to the 'who' field for @id
+@define {mwho} {what id}
+ {@if{@eq{@who{@id}}{}}
+ {@if{@eq{@state{@id}}{random}}
+ {@label{@what.randomtrack}}
+ { }}
+ {@who{@id}}}
+
+@# Expand to the artist for @track
+@define {martist} {what track}
+ {@right{play}
+ {<a class=directory
+ href="@url?action=choose&directory=@urlquote{@dirname{@dirname{@track}}}"
+ title="@label{@what.artistverbose}">@part{@track}{short}{artist}</a>}
+ {<span class=directory
+ title="@part{@track}{artist}@">@part{@track}{short}{artist}</span>}}
+
+@# Expand to the album for @track
+@define {malbum} {what track}
+ {@right{play}
+ {<a class=directory
+ href="@url?action=choose&directory=@urlquote{@dirname{@track}}"
+ title="@label{@what.albumverbose}">@part{@track}{short}{album}</a>}
+ {<span class=directory
+ title="@part{@track}{album}@">@part{@track}{short}{album}</span>}}
+
+@# Expand to the title for @track
+@define {mtitle} {what track}
+ {<span title="@part{@track}{title}">@part{@track}{short}{title}</span>}
+
+@# Expand to the remove/scratch entry for @id
+@define {mremove} {what id}
+ {@if{@removable{@id}}
+ {<a class=imgbutton
+ href="@url?action=remove&id=@id@back">
+ <img class=button src="@image{remove}"
+ title="@label{@what.removeverbose}"
+ alt="@label{@what.scratch}">
+ </a>}
+ {<img class=button src="@image{noremove}"
+ title="@label{@what.removeverbose}"
+ alt="@label{@what.scratch}">}}
+
+}@#
label queue.randomtrack random
# Short and long text for scratch (remove playing track) button
-label playing.scratch Scratch
-label playing.scratchverbose "stop playing this track"
+label playing.remove Scratch
+label playing.removeverbose "stop playing this track"
# Short and long text for remove queued track button
-label playing.remove Remove
-label playing.removeverbose "remove track from queue"
+label queue.remove Remove
+label queue.removeverbose "remove track from queue"
# Text for banner above currently playing track
label playing.now "Now playing"
# Role images. See the documentation for @images:NAME@.
label images.enabled tick.png
label images.disabled cross.png
-label images.scratch cross.png
-label images.noscratch nocross.png
+label images.remove cross.png
+label images.noremove nocross.png
label images.noup noup.png
label images.upall upup.png
label images.noupall noupup.png
USA
-->
@discard{
- @define {ifmanage} {yes no}
- {@if {@eq {@arg{action}}{manage}}
- {@yes}
- {@no}}
- @define {back} {}
- {@ifmanage{&back=manage}{}}
@include{macros.tmpl}
}@#
<html>
<td colspan=@ifmanage{11}{7}>@label{playing.now}</td>
</tr>
<tr class=playing>
- <td class=when>@when{@id}</td>
- <td class=who>@if{@eq{@who{@id}}{}}
- {@if{@eq{@state{@id}}{random}}
- {@label{playing.randomtrack}}
- { }}
- {@who{@id}}
- </td>
- <td class=artist>@right{play}
- {<a class=directory
- href="@url?action=choose&directory=@urlquote{@dirname{@dirname{@track}}}"
- title="@label{playing.artistverbose}">@part{@id}{short}{artist}</a>}
- {<span class=directory
- title="@part{artist}@">@part{short}{artist}</span>}
- </td>
- <td class=album>@right{play}
- {<a class=directory
- href="@url?action=choose&directory=@urlquote{@dirname{@track}}"
- title="@label{playing.albumverbose}">@part{short}{album}</a>}
- {<span class=directory
- title="@part{album}@">@part{short}{album}</span>}
- </td>
- <td class=title><span title="@part{@id}{title}">@part{@id}{short}{title}</span></td>
+ <td class=when>@mwhen{playing}{@id}</td>
+ <td class=who>@mwho{playing}{@id}</td>
+ <td class=artist>@martist{playing}{@track}</td>
+ <td class=album>@malbum{playing}{@track}</td>
+ <td class=title>@mtitle{playing}{@track}</td>
<td class=length>@length{@id}</td>
- <td class=imgbutton>@if{@removabl{@id}}
- {<a class=imgbutton
- href="@url?action=scratch&id=@id@back">
- <img class=button src="@image{scratch}"
- title="@label{playing.scratchverbose}"
- alt="@label{playing.scratch}"></a>}
- {<img class=button src="@image{noscratch}"
- title="@label{playing.scratchverbose}"
- alt="@label{playing.scratch}">}
- </td>
+ <td class=imgbutton>@mremove{playing}{@id}</td>
@ifmanage{
<td class=imgbutton> </td>
<td class=imgbutton> </td>
}
@queue{
<tr class=@parity@>
- <td class=when>@when</td>
- <td class=who>@if{@eq{@who@}{}@}{@if{@eq{@state@}{random}@}{@label{queue.randomtrack}}{ }@}{@who@}</td>
- <td class=artist>@right{play}{<a class=directory
- title="@part{@id}{artist}@"
- href="@url?action=choose&directory=@urlquote{@dirname{@dirname{@track}@}@}@"
- >@part{@id}{short}{artist}</a>}{<span class=directory
- title="@part{@id}{artist}@"
- >@part{@id}{short}{artist}</span>}</td>
- <td class=album>@right{play}{<a class=directory
- title="@part{@id}{album}@"
- href="@url?action=choose&directory=@urlquote{@dirname{@track}@}@"
- >@part{@id}{short}{album}</a>}{<span class=directory
- title="@part{@id}{album}@"
- >@part{@id}{short}{album}@}</td>
- <td class=title><span
- title="@part{@id}{title}@">@part{@id}{short}{title}</span></td>
+ <td class=when>@mwhen{queue}{@id}</td>
+ <td class=who>@mwho{queue}{@id}</td>
+ <td class=artist>@martist{queue}{@track}</td>
+ <td class=album>@malbum{queue}{@track}</td>
+ <td class=title>@mtitle{queue}{@track}</td>
<td class=length>@length</td>
- <td class=imgbutton>@if{@removable@}{<a class=imgbutton
- href="@url?action=remove&id=@id@@back"><img
- class=button src="@image{scratch}"
- title="@label{playing.removeverbose}"
- alt="@label{playing.remove}"></a>}{<img
- class=button src="@image{noscratch}"
- title="@label{playing.removeverbose}"
- alt="@label{playing.remove}">}</td>
+ <td class=imgbutton>@mremove{queue}{@id}</td>
@if{@eq{@arg{action}}{manage}}{
@if{@or{@isfirst@}
</table>
}
-@include{topbarend}@#
+@include{topbarend.tmpl}@#
</body>
</html>
@discard{
-@include:credits@
-@@
-<!--
+@discard{
This file is part of DisOrder.
-Copyright (C) 2005 Richard Kettlewell
+Copyright (C) 2005, 2008 Richard Kettlewell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
--->
+}@#
+@include{credits.tmpl}@#