ladishd: recent list for studios
This commit is contained in:
parent
46528c8874
commit
fb15df6218
|
@ -942,6 +942,8 @@ static bool run(void * command_context)
|
||||||
ladish_graph_dump(g_studio.jack_graph);
|
ladish_graph_dump(g_studio.jack_graph);
|
||||||
ladish_graph_dump(g_studio.studio_graph);
|
ladish_graph_dump(g_studio.studio_graph);
|
||||||
|
|
||||||
|
ladish_recent_store_use_item(g_studios_recent_store, g_studio.name);
|
||||||
|
|
||||||
ladish_studio_announce();
|
ladish_studio_announce();
|
||||||
|
|
||||||
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
|
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
|
||||||
|
|
|
@ -269,6 +269,24 @@ reorder:
|
||||||
ladish_recent_store_save(store_ptr);
|
ladish_recent_store_save(store_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ladish_recent_store_check_known(
|
||||||
|
ladish_recent_store_handle store_handle,
|
||||||
|
const char * item)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < store_ptr->max_items && store_ptr->items[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(store_ptr->items[i], item) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ladish_recent_store_iterate_items(
|
ladish_recent_store_iterate_items(
|
||||||
ladish_recent_store_handle store_handle,
|
ladish_recent_store_handle store_handle,
|
||||||
|
|
|
@ -46,6 +46,11 @@ ladish_recent_store_use_item(
|
||||||
ladish_recent_store_handle store,
|
ladish_recent_store_handle store,
|
||||||
const char * item);
|
const char * item);
|
||||||
|
|
||||||
|
bool
|
||||||
|
ladish_recent_store_check_known(
|
||||||
|
ladish_recent_store_handle store,
|
||||||
|
const char * item);
|
||||||
|
|
||||||
void
|
void
|
||||||
ladish_recent_store_iterate_items(
|
ladish_recent_store_iterate_items(
|
||||||
ladish_recent_store_handle store,
|
ladish_recent_store_handle store,
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#include "studio_internal.h"
|
#include "studio_internal.h"
|
||||||
#include "../dbus_constants.h"
|
#include "../dbus_constants.h"
|
||||||
|
@ -43,7 +42,12 @@
|
||||||
#include "../proxies/notify_proxy.h"
|
#include "../proxies/notify_proxy.h"
|
||||||
|
|
||||||
#define STUDIOS_DIR "/studios/"
|
#define STUDIOS_DIR "/studios/"
|
||||||
|
|
||||||
|
#define RECENT_STUDIOS_STORE_FILE "recent_studios"
|
||||||
|
#define RECENT_STUDIOS_STORE_MAX_ITEMS 50
|
||||||
|
|
||||||
char * g_studios_dir;
|
char * g_studios_dir;
|
||||||
|
ladish_recent_store_handle g_studios_recent_store;
|
||||||
|
|
||||||
struct studio g_studio;
|
struct studio g_studio;
|
||||||
|
|
||||||
|
@ -530,6 +534,8 @@ static void ladish_studio_on_jack_server_disappeared(void)
|
||||||
|
|
||||||
bool ladish_studio_init(void)
|
bool ladish_studio_init(void)
|
||||||
{
|
{
|
||||||
|
char * studios_recent_store_path;
|
||||||
|
|
||||||
log_info("studio object construct");
|
log_info("studio object construct");
|
||||||
|
|
||||||
g_studios_dir = catdup(g_base_dir, STUDIOS_DIR);
|
g_studios_dir = catdup(g_base_dir, STUDIOS_DIR);
|
||||||
|
@ -544,6 +550,21 @@ bool ladish_studio_init(void)
|
||||||
goto free_studios_dir;
|
goto free_studios_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
studios_recent_store_path = catdup(g_base_dir, "/" RECENT_STUDIOS_STORE_FILE);
|
||||||
|
if (studios_recent_store_path == NULL)
|
||||||
|
{
|
||||||
|
log_error("catdup failed for to compose recent studios store file path");
|
||||||
|
goto free_studios_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ladish_recent_store_create(studios_recent_store_path, 10, &g_studios_recent_store))
|
||||||
|
{
|
||||||
|
free(studios_recent_store_path);
|
||||||
|
goto free_studios_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(studios_recent_store_path);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&g_studio.all_connections);
|
INIT_LIST_HEAD(&g_studio.all_connections);
|
||||||
INIT_LIST_HEAD(&g_studio.all_ports);
|
INIT_LIST_HEAD(&g_studio.all_ports);
|
||||||
INIT_LIST_HEAD(&g_studio.all_clients);
|
INIT_LIST_HEAD(&g_studio.all_clients);
|
||||||
|
@ -567,7 +588,7 @@ bool ladish_studio_init(void)
|
||||||
if (!ladish_graph_create(&g_studio.jack_graph, NULL))
|
if (!ladish_graph_create(&g_studio.jack_graph, NULL))
|
||||||
{
|
{
|
||||||
log_error("ladish_graph_create() failed to create jack graph object.");
|
log_error("ladish_graph_create() failed to create jack graph object.");
|
||||||
goto free_studios_dir;
|
goto destroy_recent_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ladish_graph_create(&g_studio.studio_graph, STUDIO_OBJECT_PATH))
|
if (!ladish_graph_create(&g_studio.studio_graph, STUDIO_OBJECT_PATH))
|
||||||
|
@ -603,6 +624,8 @@ studio_graph_destroy:
|
||||||
ladish_graph_destroy(g_studio.studio_graph);
|
ladish_graph_destroy(g_studio.studio_graph);
|
||||||
jack_graph_destroy:
|
jack_graph_destroy:
|
||||||
ladish_graph_destroy(g_studio.jack_graph);
|
ladish_graph_destroy(g_studio.jack_graph);
|
||||||
|
destroy_recent_store:
|
||||||
|
ladish_recent_store_destroy(g_studios_recent_store);
|
||||||
free_studios_dir:
|
free_studios_dir:
|
||||||
free(g_studios_dir);
|
free(g_studios_dir);
|
||||||
fail:
|
fail:
|
||||||
|
@ -620,6 +643,8 @@ void ladish_studio_uninit(void)
|
||||||
ladish_graph_destroy(g_studio.studio_graph);
|
ladish_graph_destroy(g_studio.studio_graph);
|
||||||
ladish_graph_destroy(g_studio.jack_graph);
|
ladish_graph_destroy(g_studio.jack_graph);
|
||||||
|
|
||||||
|
ladish_recent_store_destroy(g_studios_recent_store);
|
||||||
|
|
||||||
free(g_studios_dir);
|
free(g_studios_dir);
|
||||||
|
|
||||||
log_info("studio object destroy");
|
log_info("studio object destroy");
|
||||||
|
@ -781,75 +806,6 @@ ladish_app_supervisor_handle ladish_studio_find_app_supervisor(const char * opat
|
||||||
return ctx.supervisor;
|
return ctx.supervisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ladish_studios_iterate(void * call_ptr, void * context, bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime))
|
|
||||||
{
|
|
||||||
DIR * dir;
|
|
||||||
struct dirent * dentry;
|
|
||||||
size_t len;
|
|
||||||
struct stat st;
|
|
||||||
char * path;
|
|
||||||
char * name;
|
|
||||||
|
|
||||||
dir = opendir(g_studios_dir);
|
|
||||||
if (dir == NULL)
|
|
||||||
{
|
|
||||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Cannot open directory '%s': %d (%s)", g_studios_dir, errno, strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((dentry = readdir(dir)) != NULL)
|
|
||||||
{
|
|
||||||
len = strlen(dentry->d_name);
|
|
||||||
if (len <= 4 || strcmp(dentry->d_name + (len - 4), ".xml") != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
path = catdup(g_studios_dir, dentry->d_name);
|
|
||||||
if (path == NULL)
|
|
||||||
{
|
|
||||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "catdup() failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(path, &st) != 0)
|
|
||||||
{
|
|
||||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "failed to stat '%s': %d (%s)", path, errno, strerror(errno));
|
|
||||||
free(path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode))
|
|
||||||
{
|
|
||||||
//log_info("Ignoring direntry that is not regular file. Mode is %07o", st.st_mode);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = malloc(len - 4 + 1);
|
|
||||||
if (name == NULL)
|
|
||||||
{
|
|
||||||
log_error("malloc() failed.");
|
|
||||||
closedir(dir);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
name[unescape(dentry->d_name, len - 4, name)] = 0;
|
|
||||||
//log_info("name = '%s'", name);
|
|
||||||
|
|
||||||
if (!callback(call_ptr, context, name, st.st_mtime))
|
|
||||||
{
|
|
||||||
free(name);
|
|
||||||
closedir(dir);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ladish_studio_delete(void * call_ptr, const char * studio_name)
|
bool ladish_studio_delete(void * call_ptr, const char * studio_name)
|
||||||
{
|
{
|
||||||
char * filename;
|
char * filename;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "app_supervisor.h"
|
#include "app_supervisor.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "studio.h"
|
#include "studio.h"
|
||||||
|
#include "recent_store.h"
|
||||||
|
|
||||||
#define JACK_CONF_MAX_ADDRESS_SIZE 1024
|
#define JACK_CONF_MAX_ADDRESS_SIZE 1024
|
||||||
|
|
||||||
|
@ -184,6 +185,8 @@ struct conf_callback_context
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct studio g_studio;
|
extern struct studio g_studio;
|
||||||
|
extern char * g_studios_dir;
|
||||||
|
extern ladish_recent_store_handle g_studios_recent_store;
|
||||||
|
|
||||||
extern const struct dbus_interface_descriptor g_interface_studio;
|
extern const struct dbus_interface_descriptor g_interface_studio;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||||
|
/*
|
||||||
|
* LADI Session Handler (ladish)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||||
|
*
|
||||||
|
**************************************************************************
|
||||||
|
* This file contains studio list implementation
|
||||||
|
**************************************************************************
|
||||||
|
*
|
||||||
|
* LADI Session Handler 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.
|
||||||
|
*
|
||||||
|
* LADI Session Handler 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 LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
* or write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include "studio_internal.h"
|
||||||
|
#include "../common/catdup.h"
|
||||||
|
#include "escape.h"
|
||||||
|
|
||||||
|
struct ladish_studios_iterate_context
|
||||||
|
{
|
||||||
|
void * call_ptr;
|
||||||
|
void * context;
|
||||||
|
bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime);
|
||||||
|
unsigned int counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ctx_ptr ((struct ladish_studios_iterate_context *)callback_context)
|
||||||
|
|
||||||
|
bool recent_studio_callback(void * callback_context, const char * item)
|
||||||
|
{
|
||||||
|
char * path;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (!ladish_studio_compose_filename(item, &path, NULL))
|
||||||
|
{
|
||||||
|
log_error("failed to compose path of (recent) studio \%s\" file", item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(path, &st) != 0)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
{
|
||||||
|
log_error("failed to stat '%s': %d (%s)", path, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISREG(st.st_mode))
|
||||||
|
{
|
||||||
|
log_info("Ignoring recent studio that is not regular file. Mode is %07o", st.st_mode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx_ptr->callback(ctx_ptr->call_ptr, ctx_ptr->context, item, st.st_mtime);
|
||||||
|
ctx_ptr->counter++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ctx_ptr
|
||||||
|
|
||||||
|
bool ladish_studios_iterate(void * call_ptr, void * context, bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime))
|
||||||
|
{
|
||||||
|
DIR * dir;
|
||||||
|
struct dirent * dentry;
|
||||||
|
size_t len;
|
||||||
|
struct stat st;
|
||||||
|
char * path;
|
||||||
|
char * name;
|
||||||
|
struct ladish_studios_iterate_context ctx;
|
||||||
|
|
||||||
|
ctx.call_ptr = call_ptr;
|
||||||
|
ctx.context = context;
|
||||||
|
ctx.callback = callback;
|
||||||
|
ctx.counter = 0;
|
||||||
|
|
||||||
|
ladish_recent_store_iterate_items(g_studios_recent_store, &ctx, recent_studio_callback);
|
||||||
|
|
||||||
|
/* TODO: smarter error handling based on ctx.counter (dbus error vs just logged error) */
|
||||||
|
|
||||||
|
dir = opendir(g_studios_dir);
|
||||||
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Cannot open directory '%s': %d (%s)", g_studios_dir, errno, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((dentry = readdir(dir)) != NULL)
|
||||||
|
{
|
||||||
|
len = strlen(dentry->d_name);
|
||||||
|
if (len <= 4 || strcmp(dentry->d_name + (len - 4), ".xml") != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
path = catdup(g_studios_dir, dentry->d_name);
|
||||||
|
if (path == NULL)
|
||||||
|
{
|
||||||
|
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "catdup() failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(path, &st) != 0)
|
||||||
|
{
|
||||||
|
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "failed to stat '%s': %d (%s)", path, errno, strerror(errno));
|
||||||
|
free(path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
if (!S_ISREG(st.st_mode))
|
||||||
|
{
|
||||||
|
//log_info("Ignoring direntry that is not regular file. Mode is %07o", st.st_mode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = malloc(len - 4 + 1);
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
log_error("malloc() failed.");
|
||||||
|
closedir(dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
name[unescape(dentry->d_name, len - 4, name)] = 0;
|
||||||
|
//log_info("name = '%s'", name);
|
||||||
|
|
||||||
|
if (!ladish_recent_store_check_known(g_studios_recent_store, name))
|
||||||
|
{
|
||||||
|
if (!callback(call_ptr, context, name, st.st_mtime))
|
||||||
|
{
|
||||||
|
free(name);
|
||||||
|
closedir(dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in New Issue