Merge "media cache: Add CLI commands"

This commit is contained in:
Matt Jordan 2015-07-16 20:41:10 -05:00 committed by Gerrit Code Review
commit daf284944b

View file

@ -36,6 +36,7 @@ ASTERISK_REGISTER_FILE()
#include "asterisk/config.h"
#include "asterisk/bucket.h"
#include "asterisk/astdb.h"
#include "asterisk/cli.h"
#include "asterisk/media_cache.h"
/*! The name of the AstDB family holding items in the cache. */
@ -176,7 +177,7 @@ static void media_cache_item_del_from_astdb(struct ast_bucket_file *bucket_file)
}
ast_db_deltree(hash_value, NULL);
ast_db_del(AST_DB_FAMILY, hash_value);
ast_db_del(AST_DB_FAMILY, ast_sorcery_object_get_id(bucket_file));
ast_free(hash_value);
}
@ -376,16 +377,6 @@ int ast_media_cache_delete(const char *uri)
return res;
}
/*!
* \internal
* \brief Shutdown the media cache
*/
static void media_cache_shutdown(void)
{
ao2_ref(media_cache, -1);
media_cache = NULL;
}
/*!
* \internal
* \brief Remove a media cache item from the AstDB
@ -474,6 +465,229 @@ static void media_cache_populate_from_astdb(void)
ast_db_freetree(db_tree);
}
/*!
* \internal
* \brief ao2 callback function for \ref media_cache_handle_show_all
*/
static int media_cache_prnt_summary(void *obj, void *arg, int flags)
{
#define FORMAT_ROW "%-40s\n\t%-40s\n"
struct ast_bucket_file *bucket_file = obj;
struct ast_cli_args *a = arg;
ast_cli(a->fd, FORMAT_ROW, ast_sorcery_object_get_id(bucket_file), bucket_file->path);
#undef FORMAT_ROW
return CMP_MATCH;
}
static char *media_cache_handle_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
switch (cmd) {
case CLI_INIT:
e->command = "media cache show all";
e->usage =
"Usage: media cache show all\n"
" Display a summary of all current items\n"
" in the media cache.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
ast_cli(a->fd, "URI\n\tLocal File\n");
ast_cli(a->fd, "---------------\n");
ao2_callback(media_cache, OBJ_NODATA | OBJ_MULTIPLE, media_cache_prnt_summary, a);
return CLI_SUCCESS;
}
/*!
* \internal
* \brief CLI tab completion function for URIs
*/
static char *cli_complete_uri(const char *word, int state)
{
struct ast_bucket_file *bucket_file;
struct ao2_iterator it_media_items;
int wordlen = strlen(word);
int which = 0;
char *result = NULL;
it_media_items = ao2_iterator_init(media_cache, 0);
while ((bucket_file = ao2_iterator_next(&it_media_items))) {
if (!strncasecmp(word, ast_sorcery_object_get_id(bucket_file), wordlen)
&& ++which > state) {
result = ast_strdup(ast_sorcery_object_get_id(bucket_file));
}
ao2_ref(bucket_file, -1);
if (result) {
break;
}
}
ao2_iterator_destroy(&it_media_items);
return result;
}
static char *media_cache_handle_show_item(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
#define FORMAT_ROW "\t%20s: %-40.40s\n"
struct ast_bucket_file *bucket_file;
struct ao2_iterator it_metadata;
struct ast_bucket_metadata *metadata;
switch (cmd) {
case CLI_INIT:
e->command = "media cache show";
e->usage =
"Usage: media cache show <uri>\n"
" Display all information about a particular\n"
" item in the media cache.\n";
return NULL;
case CLI_GENERATE:
return cli_complete_uri(a->word, a->n);
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
bucket_file = ao2_find(media_cache, a->argv[3], OBJ_SEARCH_KEY);
if (!bucket_file) {
ast_cli(a->fd, "Unable to find '%s' in the media cache\n", a->argv[3]);
return CLI_SUCCESS;
}
ast_cli(a->fd, "URI: %s\n", ast_sorcery_object_get_id(bucket_file));
ast_cli(a->fd, "%s\n", "----------------------------------------");
ast_cli(a->fd, FORMAT_ROW, "Path", bucket_file->path);
it_metadata = ao2_iterator_init(bucket_file->metadata, 0);
while ((metadata = ao2_iterator_next(&it_metadata))) {
ast_cli(a->fd, FORMAT_ROW, metadata->name, metadata->value);
ao2_ref(metadata, -1);
}
ao2_iterator_destroy(&it_metadata);
ao2_ref(bucket_file, -1);
#undef FORMAT_ROW
return CLI_SUCCESS;
}
static char *media_cache_handle_delete_item(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
switch (cmd) {
case CLI_INIT:
e->command = "media cache delete";
e->usage =
"Usage: media cache delete <uri>\n"
" Delete an item from the media cache.\n"
" Note that this will also remove any local\n"
" storage of the media associated with the URI,\n"
" and will inform the backend supporting the URI\n"
" scheme that it should remove the item.\n";
return NULL;
case CLI_GENERATE:
return cli_complete_uri(a->word, a->n);
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
if (ast_media_cache_delete(a->argv[3])) {
ast_cli(a->fd, "Unable to delete '%s'\n", a->argv[3]);
} else {
ast_cli(a->fd, "Deleted '%s' from the media cache\n", a->argv[3]);
}
return CLI_SUCCESS;
}
static char *media_cache_handle_refresh_item(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
char file_path[PATH_MAX];
switch (cmd) {
case CLI_INIT:
e->command = "media cache refresh";
e->usage =
"Usage: media cache refresh <uri>\n"
" Ask for a refresh of a particular URI.\n"
" If the item does not already exist in the\n"
" media cache, the item will be populated from\n"
" the backend supporting the URI scheme.\n";
return NULL;
case CLI_GENERATE:
return cli_complete_uri(a->word, a->n);
}
if (a->argc != 4) {
return CLI_SHOWUSAGE;
}
if (ast_media_cache_retrieve(a->argv[3], NULL, file_path, sizeof(file_path))) {
ast_cli(a->fd, "Unable to refresh '%s'\n", a->argv[3]);
} else {
ast_cli(a->fd, "Refreshed '%s' to local storage '%s'\n", a->argv[3], file_path);
}
return CLI_SUCCESS;
}
static char *media_cache_handle_create_item(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
switch (cmd) {
case CLI_INIT:
e->command = "media cache create";
e->usage =
"Usage: media cache create <uri> <file>\n"
" Create an item in the media cache by associating\n"
" a local media file with some URI.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 5) {
return CLI_SHOWUSAGE;
}
if (ast_media_cache_create_or_update(a->argv[3], a->argv[4], NULL)) {
ast_cli(a->fd, "Unable to create '%s' associated with local file '%s'\n",
a->argv[3], a->argv[4]);
} else {
ast_cli(a->fd, "Created '%s' for '%s' in the media cache\n",
a->argv[3], a->argv[4]);
}
return CLI_SUCCESS;
}
static struct ast_cli_entry cli_media_cache[] = {
AST_CLI_DEFINE(media_cache_handle_show_all, "Show all items in the media cache"),
AST_CLI_DEFINE(media_cache_handle_show_item, "Show a single item in the media cache"),
AST_CLI_DEFINE(media_cache_handle_delete_item, "Remove an item from the media cache"),
AST_CLI_DEFINE(media_cache_handle_refresh_item, "Refresh an item in the media cache"),
AST_CLI_DEFINE(media_cache_handle_create_item, "Create an item in the media cache"),
};
/*!
* \internal
* \brief Shutdown the media cache
*/
static void media_cache_shutdown(void)
{
ao2_ref(media_cache, -1);
media_cache = NULL;
ast_cli_unregister_multiple(cli_media_cache, ARRAY_LEN(cli_media_cache));
}
int ast_media_cache_init(void)
{
ast_register_atexit(media_cache_shutdown);
@ -484,6 +698,11 @@ int ast_media_cache_init(void)
return -1;
}
if (ast_cli_register_multiple(cli_media_cache, ARRAY_LEN(cli_media_cache))) {
ao2_ref(media_cache, -1);
return -1;
}
media_cache_populate_from_astdb();
return 0;