/*
- * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2006-2007 Andre Noll <maan@systemlinux.org>
*
- * 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, USA.
+ * Licensed under the GPL v2. For licencing details see COPYING.
*/
/** \file playlist_selector.c The playlist audio file selector of paraslash */
#include "server.h"
-#include "db.h"
+#include "afs.h"
#include "error.h"
#include "net.h"
#include "string.h"
#include "ipc.h"
+#include "user_list.h"
+#include "playlist_selector_command_list.h"
/**
* structure used for transmission of the playlist
static char **playlist;
static struct audio_file_selector *self;
-static int com_ppl(int, int, char **);
-static int com_lpl(int, int, char **);
extern struct misc_meta_data *mmd;
-/* array of supported commands */
-static struct server_command cmds[] = {
-{
-.name = "ppl",
-.handler = com_ppl,
-.perms = DB_READ,
-.description = "print playlist",
-.synopsis = "ppl",
-.help =
-"Print out the current playlist"
-}, {
-.name = "lpl",
-.handler = com_lpl,
-.perms = DB_WRITE,
-.description = "load playlist",
-.synopsis = "lpl",
-.help =
-"Read a new playlist from stdin. Example:\n"
-"\tfind /audio -name '*.mp3' | para_client lpl"
-}, {
-.name = NULL,
-}
-};
-
static void playlist_add(char *path)
{
if (playlist_len >= playlist_size) {
int ret, shm_mutex = -1, shm_id = -1;
void *shm = NULL;
- PARA_DEBUG_LOG("new playlist (%d bytes)\n", size);
+ PARA_DEBUG_LOG("new playlist (%zd bytes)\n", size);
ret = mutex_new();
if (ret < 0)
return ret;
}
-static int com_lpl(int fd, __unused int argc, __unused char *argv[])
+int com_lpl(int fd, __a_unused int argc, __a_unused char *argv[])
{
unsigned loaded = 0;
size_t bufsize = 4096; /* guess that's enough */
return ret;
}
-static int com_ppl(int fd, __unused int argc, __unused char *argv[])
+int com_ppl(int fd, __a_unused int argc, __a_unused char *argv[])
{
unsigned i;
char **file_list;
unsigned i;
- num = MIN(num, playlist_len);
+ num = PARA_MIN(num, playlist_len);
if (!num)
return NULL;
file_list = para_malloc((num + 1) * sizeof(char *));
for (i = 0; i < num; i++) {
- unsigned j = (current_playlist_entry + i) % playlist_len;
+ unsigned j = (current_playlist_entry + i + 1) % playlist_len;
file_list[i] = para_strdup(playlist[j]);
}
file_list[i] = NULL;
playlist_size = 0;
}
-static void pls_post_select(__unused fd_set *rfds, __unused fd_set *wfds)
+static void pls_post_select(__a_unused fd_set *rfds, __a_unused fd_set *wfds)
{
struct private_pls_data *ppd = self->private_data;
struct pls_client_data *pcd = ppd->client_data;
PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
goto out;
}
- PARA_DEBUG_LOG("loading new playlist (%d bytes)\n", pcd->size);
+ PARA_DEBUG_LOG("loading new playlist (%zd bytes)\n", pcd->size);
ret = for_each_line((char *)shm, pcd->size, &playlist_add);
shm_detach(shm);
PARA_NOTICE_LOG("new playlist (%d entries)\n", playlist_len);
+ sprintf(mmd->selector_info, "dbinfo1:new playlist: %d files\n"
+ "dbinfo2:\ndbinfo3:\n", playlist_len);
pcd->retval = 1;
pcd->size = 0;
mutex_unlock(pcd->mutex);
mutex_unlock(ppd->server_mutex);
}
-void pls_update_audio_file(char *audio_file)
+static size_t string_offset(const char *str, size_t max)
{
- unsigned i;
+ size_t l = strlen(str);
- for (i = 0; i < playlist_len; i++) {
+ if (l <= max)
+ return 0;
+ return l - max;
+}
+
+static void pls_update_audio_file(char *audio_file)
+{
+ unsigned i;
+ char *dir = para_dirname(audio_file),
+ *prev = playlist[current_playlist_entry % playlist_len];
+ size_t dir_off = string_offset(dir, 50),
+ prev_off = string_offset(prev, 70);
+
+ for (i = 1; i <= playlist_len; i++) {
+ char *next;
+ size_t next_off;
unsigned j = (current_playlist_entry + i) % playlist_len;
if (strcmp(playlist[j], audio_file))
continue;
- current_playlist_entry = (j + 1) % playlist_len;
+ current_playlist_entry = j;
+ next = playlist[(j + 1) %playlist_len];
+ next_off = string_offset(next, 70);
+ snprintf(mmd->selector_info, MMD_INFO_SIZE,
+ "dbinfo1: %d files, current dir: %s%s\n"
+ "dbinfo2: prev: %s%s\n"
+ "dbinfo3: next: %s%s\n",
+ playlist_len,
+ dir_off? "... " : "", dir + dir_off,
+ prev_off? "... " : "", prev + prev_off,
+ next_off? "... " : "", next + next_off
+ );
+ break;
}
+ free(dir);
}
/**
* the init function for the playlist selector
*
- * Init all function pointers of \a db
+ * \param afs pointer to the struct to initialize
+ *
+ * Init all function pointers of \a afs
*
* \sa struct audio_file_selector, misc_meta_data::selector_info, mysql.c
* random_selector.c.
*/
-int playlist_selector_init(struct audio_file_selector *db)
+int playlist_selector_init(struct audio_file_selector *afs)
{
int ret;
struct private_pls_data *ppd = NULL;
void *shm = NULL;
- self = db;
- db->cmd_list = cmds;
- db->get_audio_file_list = pls_get_audio_file_list;
- db->shutdown = pls_shutdown;
- db->post_select = pls_post_select;
- db->update_audio_file = pls_update_audio_file;
+ self = afs;
+ afs->cmd_list = playlist_selector_cmds;
+ afs->get_audio_file_list = pls_get_audio_file_list;
+ afs->shutdown = pls_shutdown;
+ afs->post_select = pls_post_select;
+ afs->update_audio_file = pls_update_audio_file;
ppd = para_calloc(sizeof(struct private_pls_data));
- db->private_data = ppd;
+ afs->private_data = ppd;
ppd->client_mutex = -1;
ppd->server_mutex = -1;
goto err_out;
ppd->client_data = shm;
ppd->client_data->size = 0;
- sprintf(mmd->selector_info, "playlist selector initialized");
+ sprintf(mmd->selector_info, "dbinfo1: Welcome to the playlist "
+ "selector\ndbinfo2: no playlist loaded\ndbinfo3:\n");
return 1;
err_out:
if (ppd->client_data_shm_id >= 0)