chiark / gitweb /
web support for noticed.db
authorRichard Kettlewell <rjk@greenend.org.uk>
Tue, 2 Oct 2007 17:37:16 +0000 (18:37 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Tue, 2 Oct 2007 17:37:16 +0000 (18:37 +0100)
14 files changed:
CHANGES
lib/client.h
server/dcgi.c
server/dcgi.h
server/trackdb-int.h
server/trackdb.h
templates/Makefile.am
templates/choose.html
templates/disorder.css
templates/help.html
templates/new.html [new file with mode: 0644]
templates/options.labels
templates/sidebar.html
templates/topbar.html

diff --git a/CHANGES b/CHANGES
index 92615e4a7dd972b6dd233f6e450ac5dac5e41c60..7ea23b257551338f8f2fcdf8fd1565c50512cf73 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -41,6 +41,11 @@ tracks kept on the queue to be controlled.
 There is a new utility disorder-decode which can decode OGG, MP3, WAV
 and FLAC.  The example config file uses it.
 
 There is a new utility disorder-decode which can decode OGG, MP3, WAV
 and FLAC.  The example config file uses it.
 
+** Web Interface
+
+The "New" screen display tracks recently added to the database.  From
+here they can be played or their preferences changed.
+
 ** Network Play
 
 DisOrder can broadcast audio over a network, allowing it to be played on
 ** Network Play
 
 DisOrder can broadcast audio over a network, allowing it to be played on
index a7d0ff972f2d6e977f67541f2fbaf3d08c04cc57..773c555baf8e11620c6f1dd5c797da4bb2f50ed9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 2006, 2007 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
  *
  * 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
index 2892a43189f8e0ea200321f59c84ac9d729a213b..b8188838a10e0af79567db2de778608ebc627612 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 2006, 2007 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
  *
  * 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
@@ -117,6 +117,8 @@ static void lookups(dcgi_state *ds, unsigned want) {
       disorder_queue(ds->g->client, &ds->g->queue);
     if(need & DC_PLAYING)
       disorder_playing(ds->g->client, &ds->g->playing);
       disorder_queue(ds->g->client, &ds->g->queue);
     if(need & DC_PLAYING)
       disorder_playing(ds->g->client, &ds->g->playing);
+    if(need & DC_NEW)
+      disorder_new_tracks(ds->g->client, &ds->g->new, &ds->g->nnew, 0);
     if(need & DC_RECENT) {
       /* we need to reverse the order of the list */
       disorder_recent(ds->g->client, &r);
     if(need & DC_RECENT) {
       /* we need to reverse the order of the list */
       disorder_recent(ds->g->client, &r);
@@ -483,7 +485,7 @@ static void exp_length(int attribute((unused)) nargs,
                       cgi_sink *output,
                       void *u) {
   dcgi_state *ds = u;
                       cgi_sink *output,
                       void *u) {
   dcgi_state *ds = u;
-  long length;
+  long length = 0;
 
   if(ds->track
      && (ds->track->state == playing_started
 
   if(ds->track
      && (ds->track->state == playing_started
@@ -491,8 +493,11 @@ static void exp_length(int attribute((unused)) nargs,
      && ds->track->sofar >= 0)
     cgi_output(output, "%ld:%02ld/",
               ds->track->sofar / 60, ds->track->sofar % 60);
      && ds->track->sofar >= 0)
     cgi_output(output, "%ld:%02ld/",
               ds->track->sofar / 60, ds->track->sofar % 60);
-  if(!ds->track || disorder_length(ds->g->client, ds->track->track, &length))
-    length = 0;
+  length = 0;
+  if(ds->track)
+    disorder_length(ds->g->client, ds->track->track, &length);
+  else if(ds->tracks)
+    disorder_length(ds->g->client, ds->tracks[0], &length);
   if(length)
     cgi_output(output, "%ld:%02ld", length / 60, length % 60);
   else
   if(length)
     cgi_output(output, "%ld:%02ld", length / 60, length % 60);
   else
@@ -627,6 +632,25 @@ static void exp_recent(int attribute((unused)) nargs,
   }
 }
 
   }
 }
 
+static void exp_new(int attribute((unused)) nargs,
+                   char **args,
+                   cgi_sink *output,
+                   void  *u) {
+  dcgi_state *ds = u;
+  dcgi_state s;
+
+  lookups(ds, DC_NEW);
+  memset(&s, 0, sizeof s);
+  s.g = ds->g;
+  s.first = 1;
+  for(s.index = 0; s.index < ds->g->nnew; ++s.index) {
+    s.last = s.index + 1 < ds->g->nnew;
+    s.tracks = &ds->g->new[s.index];
+    expandstring(output, args[0], &s);
+    s.first = 0;
+  }
+}
+
 static void exp_url(int attribute((unused)) nargs,
                    char attribute((unused)) **args,
                    cgi_sink *output,
 static void exp_url(int attribute((unused)) nargs,
                    char attribute((unused)) **args,
                    cgi_sink *output,
@@ -918,6 +942,16 @@ static void exp_isrecent(int attribute((unused)) nargs,
   sink_printf(output->sink, "%s", bool2str(!!ds->g->recent));
 }
 
   sink_printf(output->sink, "%s", bool2str(!!ds->g->recent));
 }
 
+static void exp_isnew(int attribute((unused)) nargs,
+                     char attribute((unused)) **args,
+                     cgi_sink *output,
+                     void *u) {
+  dcgi_state *ds = u;
+
+  lookups(ds, DC_NEW);
+  sink_printf(output->sink, "%s", bool2str(!!ds->g->nnew));
+}
+
 static void exp_id(int attribute((unused)) nargs,
                   char attribute((unused)) **args,
                   cgi_sink *output,
 static void exp_id(int attribute((unused)) nargs,
                   char attribute((unused)) **args,
                   cgi_sink *output,
@@ -1385,6 +1419,7 @@ static const struct cgi_expansion expansions[] = {
   { "isfiles", 0, 0, 0, exp_isfiles },
   { "isfirst", 0, 0, 0, exp_isfirst },
   { "islast", 0, 0, 0, exp_islast },
   { "isfiles", 0, 0, 0, exp_isfiles },
   { "isfirst", 0, 0, 0, exp_isfirst },
   { "islast", 0, 0, 0, exp_islast },
+  { "isnew", 0, 0, 0, exp_isnew },
   { "isplaying", 0, 0, 0, exp_isplaying },
   { "isqueue", 0, 0, 0, exp_isqueue },
   { "isrecent", 0, 0, 0, exp_isrecent },
   { "isplaying", 0, 0, 0, exp_isplaying },
   { "isqueue", 0, 0, 0, exp_isqueue },
   { "isrecent", 0, 0, 0, exp_isrecent },
@@ -1392,6 +1427,7 @@ static const struct cgi_expansion expansions[] = {
   { "length", 0, 0, 0, exp_length },
   { "navigate", 2, 2, EXP_MAGIC, exp_navigate },
   { "ne", 2, 2, 0, exp_ne },
   { "length", 0, 0, 0, exp_length },
   { "navigate", 2, 2, EXP_MAGIC, exp_navigate },
   { "ne", 2, 2, 0, exp_ne },
+  { "new", 1, 1, EXP_MAGIC, exp_new },
   { "nfiles", 0, 0, 0, exp_nfiles },
   { "nonce", 0, 0, 0, exp_nonce },
   { "not", 1, 1, 0, exp_not },
   { "nfiles", 0, 0, 0, exp_nfiles },
   { "nonce", 0, 0, 0, exp_nonce },
   { "not", 1, 1, 0, exp_not },
index 6f832f186e6f277b16cb11fe90accca4e15517f1..89908a2bcb5574c104bb1c45139714ea4f50397e 100644 (file)
@@ -30,10 +30,13 @@ typedef struct dcgi_global {
 #define DC_VOLUME 0x0008
 #define DC_DIRS 0x0010
 #define DC_FILES 0x0020
 #define DC_VOLUME 0x0008
 #define DC_DIRS 0x0010
 #define DC_FILES 0x0020
+#define DC_NEW 0x0040
   struct queue_entry *queue, *playing, *recent;
   int volume_left, volume_right;
   char **files, **dirs;
   int nfiles, ndirs;
   struct queue_entry *queue, *playing, *recent;
   int volume_left, volume_right;
   char **files, **dirs;
   int nfiles, ndirs;
+  char **new;
+  int nnew;
 } dcgi_global;
 
 typedef struct dcgi_state {
 } dcgi_global;
 
 typedef struct dcgi_state {
index 1ba890b9340bb263ad38fc41b5e3fb822902cf70..2b12c8114b0c9c8e4a7b0e68d116b22852e703bb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder
 /*
  * This file is part of DisOrder
- * Copyright (C) 2005 Richard Kettlewell
+ * Copyright (C) 2005, 2007 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
  *
  * 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
index 3e7976aaebdb2ec756b5f658cec5f75bf0c4a42c..b3b37157e8213f2e371da847c366ddb77c48d8f9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder
 /*
  * This file is part of DisOrder
- * Copyright (C) 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2005, 2006, 2007 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
  *
  * 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
index b799dbbf00ba438d7661b3cc479531a31ccd56d8..db7c83699948e1b56a0f17019ead0ca686e059de 100644 (file)
@@ -21,7 +21,7 @@
 pkgdata_DATA=about.html choose.html credits.html playing.html recent.html \
             stdhead.html stylesheet.html search.html about.html volume.html \
             sidebar.html prefs.html help.html choosealpha.html topbar.html \
 pkgdata_DATA=about.html choose.html credits.html playing.html recent.html \
             stdhead.html stylesheet.html search.html about.html volume.html \
             sidebar.html prefs.html help.html choosealpha.html topbar.html \
-            sidebarend.html topbarend.html error.html \
+            sidebarend.html topbarend.html error.html new.html \
             options options.labels \
             options.columns
 static_DATA=disorder.css
             options options.labels \
             options.columns
 static_DATA=disorder.css
index 03744f7cd9e1a42c45914eb13e2b48d20f1d0402..e6a39cb68af440bda80aa619889f6794e0d7bff6 100644 (file)
@@ -58,9 +58,9 @@ USA
       <img class=button src="@label:images.edit@"
       title="@label:choose.prefsverbose@" alt="@label:choose.prefs@">
      </a>
       <img class=button src="@label:images.edit@"
       title="@label:choose.prefsverbose@" alt="@label:choose.prefs@">
      </a>
-     <a class=file href="@url@?action=play&#38;file=@urlquote{@file@}@&#38;back=@urlquote{@thisurl@}@&#38;nonce=@nonce@">
-      @transform{@file@}{track}{display}@
-     </a>
+     <a class=file
+     href="@url@?action=play&#38;file=@urlquote{@file@}@&#38;back=@urlquote{@thisurl@}@&#38;nonce=@nonce@"
+     title="@label:choose.play@">@transform{@file@}{track}{display}@</a>
      @if{@eq{@trackstate{@file@}@}{playing}@}{[<b>playing</b>]}@
      @if{@eq{@trackstate{@file@}@}{queued}@}{[<b>queued</b>]}@
     </p>
      @if{@eq{@trackstate{@file@}@}{playing}@}{[<b>playing</b>]}@
      @if{@eq{@trackstate{@file@}@}{queued}@}{[<b>queued</b>]}@
     </p>
index 34c44db777ff4b7dd4fb1d82898424806a470ee9..dd1364cd6db4477962b8a79ac36170a8a647229f 100644 (file)
@@ -24,7 +24,7 @@ h1.title {
   font-size: 18pt
 }
 
   font-size: 18pt
 }
 
-/* playing and recent *********************************************************/
+/* playing, recent and new ***************************************************/
 
 /* table of current and future tracks */
 table.playing {
 
 /* table of current and future tracks */
 table.playing {
@@ -38,6 +38,12 @@ table.recent {
   border-spacing: 0            /* no unsightly gaps between cells */
 }
 
   border-spacing: 0            /* no unsightly gaps between cells */
 }
 
+/* table of newly added played tracks */
+table.new {
+  width: 100%;                 /* use the full available width */
+  border-spacing: 0            /* no unsightly gaps between cells */
+}
+
 /* titles in tables */
 th {
   text-align: left
 /* titles in tables */
 th {
   text-align: left
index 00dc9782ec115f967aaaf975a089f9ceed4d6987..e9a5c8437cc3e8965a04ae2e2ff6b01e51a63321 100644 (file)
@@ -133,6 +133,24 @@ USA
 
    </div>
 
 
    </div>
 
+   <h2 class=sidebarlink><a name=new>New</a></h2>
+
+   <div class=helpsection>
+
+    <p>This screen displays tracks recently added to the database,
+    most recent first.  The <img class=button
+    src="@label:images.edit@" title="@label:choose.prefs@"
+    alt="@label:choose.prefs@"> button can be used to edit the details
+    for a track; see <a href="#prefs">Editing Preferences</a> below,
+    and clicking on the track title will add it to the queue.</p>
+
+    <p>The time tracks are remembered for is controlled by the server
+    configuration.  See the "noticed_history" option in <a
+    href="@url@?action=disorder_config.5">disorder_config(5)</a> for
+    more details.</p>
+
+   </div>
+
    <h2 class=sidebarlink><a name=choose>Choose</a></h2>
 
    <div class=helpsection>
    <h2 class=sidebarlink><a name=choose>Choose</a></h2>
 
    <div class=helpsection>
diff --git a/templates/new.html b/templates/new.html
new file mode 100644 (file)
index 0000000..e98f7af
--- /dev/null
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<!--
+This file is part of DisOrder.
+Copyright (C) 2004, 2005, 2007 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
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+USA
+-->
+<html>
+ <head>
+@include:stdhead@
+  <title>@label:new.title@</title>
+ </head>
+ <body>
+@include{@label{menu}@}@
+  <h1 class=title>@label:new.title@</h1>
+
+@#{only display the table if there is something to put in it}@
+@if{@isnew@}{
+  <table class=new>
+    <tr class=headings>
+     <th class=artist>@label:heading.artist@</th>
+     <th class=album>@label:heading.album@</th>
+     <th class=title>@label:heading.title@</th>
+     <th class=length>@label:heading.length@</th>
+      <th class=button>&nbsp;</th>
+    </tr>
+    @new{
+    <tr class=@parity@>
+     <td class=artist><a class=directory href="@url@?action=choose&amp;directory=@urlquote{@dirname{@dirname{@part:path@}@}@}@">@part:artist@</a></td>
+     <td class=album><a class=directory href="@url@?action=choose&amp;directory=@urlquote{@dirname{@part:path@}@}@">@part:album@</a></td>
+     <td class=title><a
+      class=file
+      href="@url@?action=play&#38;file=@urlquote{@file@}@&#38;back=@urlquote{@thisurl@}@&#38;nonce=@nonce@"
+      title="@label:choose.play@">@part:title@</a></td>
+     <td class=length>@length@</td>
+     <td class=imgbutton><a class=imgbutton
+      href="@url@?action=prefs&#38;nonce=@nonce@&#38;0_file=@urlquote{@file@}@"><img
+       class=button src="@label:images.edit@"
+       title="@label:choose.prefsverbose@"
+       alt="@label:choose.prefs@"></a></td>
+    </tr>
+    }@
+  </table>
+}@
+
+@include{@label{menu}@end}@
+ </body>
+</html>
+@@
+<!--
+Local variables:
+mode:sgml
+sgml-always-quote-attributes:nil
+sgml-indent-step:1
+sgml-indent-data:t
+End:
+-->
index bd87554ba0baa111875fedbdfd08b6a8580c075b..1e7131593cee0d45d57c123c0571a8a160c05ebb 100644 (file)
@@ -78,6 +78,9 @@ label playing.albumverbose    "more tracks from this album"
 # <TITLE> for recently played page
 label  recent.title            "Recently Played"
 
 # <TITLE> for recently played page
 label  recent.title            "Recently Played"
 
+# <TITLE> for new tracks page
+label  new.title               "New tracks"
+
 # <TITLE> for choose track page
 label  choose.title            "Pick track"
 
 # <TITLE> for choose track page
 label  choose.title            "Pick track"
 
@@ -98,6 +101,9 @@ label        choose.prefsverbose     "edit track information"
 label  choose.allprefs         "Edit all"
 label  choose.allprefsverbose  "edit all track information"
 
 label  choose.allprefs         "Edit all"
 label  choose.allprefsverbose  "edit all track information"
 
+# Caption for play-track links
+label  choose.play             "Add track to queue"
+
 # <TITLE> for search page
 label  search.title            Search
 
 # <TITLE> for search page
 label  search.title            Search
 
@@ -145,6 +151,7 @@ label       sidebar.choose          Choose
 label  sidebar.random          Random
 label  sidebar.search          Search
 label  sidebar.recent          Recent
 label  sidebar.random          Random
 label  sidebar.search          Search
 label  sidebar.recent          Recent
+label  sidebar.new             New
 label  sidebar.about           About
 label  sidebar.volume          Volume
 label  sidebar.help            Help
 label  sidebar.about           About
 label  sidebar.volume          Volume
 label  sidebar.help            Help
@@ -155,6 +162,7 @@ label       sidebar.playingverbose  "current and queued tracks"
 label  sidebar.chooseverbose   "choose tracks"
 label  sidebar.searchverbose   "word search among track names"
 label  sidebar.recentverbose   "recently played tracks"
 label  sidebar.chooseverbose   "choose tracks"
 label  sidebar.searchverbose   "word search among track names"
 label  sidebar.recentverbose   "recently played tracks"
+label  sidebar.newverbose      "newly added tracks"
 label  sidebar.aboutverbose    "about DisOrder"
 label  sidebar.volumeverbose   "volume control"
 label  sidebar.helpverbose     "basic user guide"
 label  sidebar.aboutverbose    "about DisOrder"
 label  sidebar.volumeverbose   "volume control"
 label  sidebar.helpverbose     "basic user guide"
index acdaba8f4cc98e6fc647da54e65b15bd75ec79ee..9a075c328de9b6cb9f12c3de05a39d1529187d9b 100644 (file)
@@ -5,6 +5,9 @@
  <p class=sidebarlink>
   <a class=sidebarlink href="@url@?action=recent&amp;nonce=@nonce@">@label:sidebar.recent@</a>
  </p>
  <p class=sidebarlink>
   <a class=sidebarlink href="@url@?action=recent&amp;nonce=@nonce@">@label:sidebar.recent@</a>
  </p>
+ <p class=sidebarlink>
+  <a class=sidebarlink href="@url@?action=new&amp;nonce=@nonce@">@label:sidebar.new@</a>
+ </p>
  <p class=sidebarlink>
   <a class=sidebarlink href="@url@?action=@label:sidebar.choosewhich@&amp;nonce=@nonce@">@label:sidebar.choose@</a>
  </p>
  <p class=sidebarlink>
   <a class=sidebarlink href="@url@?action=@label:sidebar.choosewhich@&amp;nonce=@nonce@">@label:sidebar.choose@</a>
  </p>
@@ -28,7 +31,7 @@
 @@
 <!--
 This file is part of DisOrder.
 @@
 <!--
 This file is part of DisOrder.
-Copyright (C) 2004, 2005 Richard Kettlewell
+Copyright (C) 2004, 2005, 2007 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
 
 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
index 654e4f9f141c583ee72af8d531a85094c66b0850..1dbbdd37cfd33ea53304de52235cede80b8bd0c4 100644 (file)
@@ -5,6 +5,9 @@
   <a class=@if{@eq{@action@}{recent}@}{activemenu}{inactivemenu}@
  href="@url@?action=recent&amp;nonce=@nonce@"
  title="@label:sidebar.recentverbose@">@label:sidebar.recent@</a>
   <a class=@if{@eq{@action@}{recent}@}{activemenu}{inactivemenu}@
  href="@url@?action=recent&amp;nonce=@nonce@"
  title="@label:sidebar.recentverbose@">@label:sidebar.recent@</a>
+  <a class=@if{@eq{@action@}{new}@}{activemenu}{inactivemenu}@
+ href="@url@?action=new&amp;nonce=@nonce@"
+ title="@label:sidebar.newverbose@">@label:sidebar.new@</a>
   <a class=@if{@or{@eq{@action@}{choose}@}
                   {@eq{@action@}{choosealpha}@}@}
               {activemenu}
   <a class=@if{@or{@eq{@action@}{choose}@}
                   {@eq{@action@}{choosealpha}@}@}
               {activemenu}
@@ -33,7 +36,7 @@
 @@
 <!--
 This file is part of DisOrder.
 @@
 <!--
 This file is part of DisOrder.
-Copyright (C) 2005 Richard Kettlewell
+Copyright (C) 2005, 2007 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
 
 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