[asterisk-commits] kmoore: branch kmoore/stasis-http_sounds r389655 - in /team/kmoore/stasis-htt...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 23 17:25:20 CDT 2013


Author: kmoore
Date: Thu May 23 17:25:17 2013
New Revision: 389655

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389655
Log:
Finish pulling sounds indexer out of the generic media indexer

Added:
    team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h   (with props)
    team/kmoore/stasis-http_sounds/main/sounds_index.c   (with props)
Modified:
    team/kmoore/stasis-http_sounds/include/asterisk/_private.h
    team/kmoore/stasis-http_sounds/include/asterisk/media_index.h
    team/kmoore/stasis-http_sounds/main/asterisk.c
    team/kmoore/stasis-http_sounds/main/media_index.c
    team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c

Modified: team/kmoore/stasis-http_sounds/include/asterisk/_private.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/include/asterisk/_private.h?view=diff&rev=389655&r1=389654&r2=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/include/asterisk/_private.h (original)
+++ team/kmoore/stasis-http_sounds/include/asterisk/_private.h Thu May 23 17:25:17 2013
@@ -124,6 +124,6 @@
 /*! \brief initializes the rtp engine arrays */
 int ast_rtp_engine_init(void);
 
-/*! \brief initialize the media indexer */
-int ast_media_index_init(void);
+/*! \brief initialize the sounds index */
+int ast_sounds_index_init(void);
 #endif /* _ASTERISK__PRIVATE_H */

Modified: team/kmoore/stasis-http_sounds/include/asterisk/media_index.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/include/asterisk/media_index.h?view=diff&rev=389655&r1=389654&r2=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/include/asterisk/media_index.h (original)
+++ team/kmoore/stasis-http_sounds/include/asterisk/media_index.h Thu May 23 17:25:17 2013
@@ -17,7 +17,7 @@
  */
 
 /*! \file
- * \brief Sound file format and description indexer.
+ * \brief Media file format and description indexing engine.
  */
 
 #ifndef _ASTERISK_MEDIA_INDEX_H
@@ -33,6 +33,14 @@
  * \brief Object representing a media index
  */
 struct ast_media_index;
+
+/*!
+ * \brief Creates a new media index
+ *
+ * \retval NULL on error
+ * \retval A new AO2 refcounted media index
+ */
+struct ast_media_index *ast_media_index_create(void);
 
 /*!
  * \brief Get the description for a media file
@@ -80,21 +88,18 @@
 struct ao2_container *ast_media_get_media(struct ast_media_index *index);
 
 /*!
- * \brief Reload the sounds index
+ * \brief Update a media index
  *
- * \retval zero on success
- * \retval non-zero on failure
+ * \param index Media index in which to query information
+ * \param base_dir Base directory in which to start the indexing
+ * \param variant Media variant for which to get the description
+ *
+ * \retval non-zero on error
+ * \return zero on success
  */
-int ast_sounds_reindex(void);
-
-/*!
- * \brief Get the sounds index
- *
- * \retval sounds index
- * \retval NULL on failure
- */
-struct ast_media_index *ast_sounds_get_index(void);
-
+int ast_media_index_update(struct ast_media_index *index,
+	const char *base_dir,
+	const char *variant);
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Added: team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h?view=auto&rev=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h (added)
+++ team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h Thu May 23 17:25:17 2013
@@ -1,0 +1,55 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kinsey Moore <kmoore at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Sound file format and description indexer.
+ */
+
+#ifndef _ASTERISK_SOUNDS_INDEX_H
+#define _ASTERISK_SOUNDS_INDEX_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*!
+ * \brief Object representing a media index
+ */
+struct ast_media_index;
+
+/*!
+ * \brief Reload the sounds index
+ *
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_sounds_reindex(void);
+
+/*!
+ * \brief Get the sounds index
+ *
+ * \retval sounds index
+ * \retval NULL on failure
+ */
+struct ast_media_index *ast_sounds_get_index(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_SOUNDS_INDEX_H */

Propchange: team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kmoore/stasis-http_sounds/include/asterisk/sounds_index.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/kmoore/stasis-http_sounds/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/main/asterisk.c?view=diff&rev=389655&r1=389654&r2=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/main/asterisk.c (original)
+++ team/kmoore/stasis-http_sounds/main/asterisk.c Thu May 23 17:25:17 2013
@@ -4350,7 +4350,7 @@
 		exit(1);
 	}
 
-	if (ast_media_index_init()) {
+	if (ast_sounds_index_init()) {
 		printf("%s", term_quit());
 		exit(1);
 	}

Modified: team/kmoore/stasis-http_sounds/main/media_index.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/main/media_index.c?view=diff&rev=389655&r1=389654&r2=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/main/media_index.c (original)
+++ team/kmoore/stasis-http_sounds/main/media_index.c Thu May 23 17:25:17 2013
@@ -29,12 +29,8 @@
 #include "asterisk/lock.h"
 #include "asterisk/format.h"
 #include "asterisk/format_cap.h"
-#include "asterisk/paths.h"	/* use ast_config_AST_DATA_DIR */
 #include "asterisk/media_index.h"
 #include "asterisk/file.h"
-#include "asterisk/cli.h"
-#include "asterisk/module.h"
-#include "asterisk/_private.h"
 
 /*** MODULEINFO
 	<support_level>core</support_level>
@@ -43,16 +39,16 @@
 /*! \brief The number of buckets to be used for storing language-keyed objects */
 #define VARIANT_BUCKETS 7
 
-/*! \brief The number of buckets to be used for storing sound filename-keyed objects */
+/*! \brief The number of buckets to be used for storing media filename-keyed objects */
 #define INDEX_BUCKETS 157
 
-/*! \brief Structure to hold a list of the format variations for a sound file in a specific language */
+/*! \brief Structure to hold a list of the format variations for a media file for a specific variant */
 struct media_variant {
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(variant);	/*!< The variant this media is available in */
-		AST_STRING_FIELD(description);	/*!< The description of the sound */
+		AST_STRING_FIELD(description);	/*!< The description of the media */
 	);
-	struct ast_format_cap *formats;	/*!< The formats this sound is available in for this language */
+	struct ast_format_cap *formats;	/*!< The formats this media is available in for this variant */
 };
 
 static void media_variant_destroy(void *obj)
@@ -95,26 +91,26 @@
 	return strcasecmp(opt1->variant, language) ? 0 : CMP_MATCH | CMP_STOP;
 }
 
-/*! \brief Structure to hold information about a sound file */
-struct sound_info {
+/*! \brief Structure to hold information about a media file */
+struct media_info {
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(name);		/*!< The name of the sound */
+		AST_STRING_FIELD(name);		/*!< The file name of the media */
 	);
-	struct ao2_container *variant_list;	/*!< The list of (language, format) tuples for which this sound is available */
+	struct ao2_container *variant_list;	/*!< The variants for which this media is available */
 };
 
-static void sound_info_destroy(void *obj)
-{
-	struct sound_info *info = obj;
+static void media_info_destroy(void *obj)
+{
+	struct media_info *info = obj;
 
 	ast_string_field_free_memory(info);
 	ao2_cleanup(info->variant_list);
 	info->variant_list = NULL;
 }
 
-static struct sound_info *sound_info_alloc(const char *name)
-{
-	RAII_VAR(struct sound_info *, info, ao2_alloc(sizeof(*info), sound_info_destroy), ao2_cleanup);
+static struct media_info *media_info_alloc(const char *name)
+{
+	RAII_VAR(struct media_info *, info, ao2_alloc(sizeof(*info), media_info_destroy), ao2_cleanup);
 
 	if (ast_string_field_init(info, 128)) {
 		return NULL;
@@ -131,21 +127,22 @@
 	return info;
 }
 
-static int sound_info_hash(const void *obj, const int flags)
-{
-	const char *name = (flags & OBJ_KEY) ? obj : ((struct sound_info*) obj)->name;
+static int media_info_hash(const void *obj, const int flags)
+{
+	const char *name = (flags & OBJ_KEY) ? obj : ((struct media_info*) obj)->name;
 	return ast_str_case_hash(name);
 }
 
-static int sound_info_cmp(void *obj, void *arg, int flags)
-{
-	struct sound_info *opt1 = obj, *opt2 = arg;
+static int media_info_cmp(void *obj, void *arg, int flags)
+{
+	struct media_info *opt1 = obj, *opt2 = arg;
 	const char *name = (flags & OBJ_KEY) ? arg : opt2->name;
 	return strcasecmp(opt1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
 }
 
 struct ast_media_index {
-	struct ao2_container *index;
+	struct ao2_container *index;            /*!< The index of media that has requested */
+	struct ao2_container *media_list_cache; /*!< Cache of filenames to prevent them from being regenerated so often */
 };
 
 static void media_index_dtor(void *obj)
@@ -153,13 +150,15 @@
 	struct ast_media_index *index = obj;
 	ao2_cleanup(index->index);
 	index->index = NULL;
+	ao2_cleanup(index->media_list_cache);
+	index->media_list_cache = NULL;
 }
 
 static struct ast_media_index *media_index_alloc(void)
 {
 	RAII_VAR(struct ast_media_index *, index, ao2_alloc(sizeof(*index), media_index_dtor), ao2_cleanup);
 
-	index->index = ao2_container_alloc(INDEX_BUCKETS, sound_info_hash, sound_info_cmp);
+	index->index = ao2_container_alloc(INDEX_BUCKETS, media_info_hash, media_info_cmp);
 	if (!index->index) {
 		return NULL;
 	}
@@ -168,55 +167,9 @@
 	return index;
 }
 
-static struct ast_media_index *sounds_index;
-
-/*! \brief Get the languages in which sound files are available */
-static struct ao2_container *get_languages(void)
-{
-	RAII_VAR(struct ao2_container *, lang_dirs, NULL, ao2_cleanup);
-	struct dirent* dent;
-	DIR* srcdir;
-	RAII_VAR(struct ast_str *, media_dir, ast_str_create(64), ast_free);
-
-	lang_dirs = ast_str_container_alloc(VARIANT_BUCKETS);
-	if (!media_dir || !lang_dirs) {
-		return NULL;
-	}
-
-	ast_str_set(&media_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);
-
-	srcdir = opendir(ast_str_buffer(media_dir));
-
-	if (srcdir == NULL) {
-		ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(media_dir));
-		return NULL;
-	}
-
-	while((dent = readdir(srcdir)) != NULL) {
-		struct stat st;
-
-		if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
-			continue;
-		}
-
-		if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) {
-			ast_log(LOG_ERROR, "Failed to stat %s\n", dent->d_name);
-			continue;
-		}
-
-		if (S_ISDIR(st.st_mode)) {
-			ast_str_container_add(lang_dirs, dent->d_name);
-		}
-	}
-
-	closedir(srcdir);
-	ao2_ref(lang_dirs, +1);
-	return lang_dirs;
-}
-
 static struct media_variant *find_variant(struct ast_media_index *index, const char *filename, const char *lang)
 {
-	RAII_VAR(struct sound_info *, info, NULL, ao2_cleanup);
+	RAII_VAR(struct media_info *, info, NULL, ao2_cleanup);
 
 	info = ao2_find(index->index, filename, OBJ_KEY);
 	if (!info) {
@@ -229,14 +182,14 @@
 /*! \brief create the appropriate media_variant and any necessary structures */
 static struct media_variant *alloc_variant(struct ast_media_index *index, const char *filename, const char *variant_str)
 {
-	RAII_VAR(struct sound_info *, info, NULL, ao2_cleanup);
+	RAII_VAR(struct media_info *, info, NULL, ao2_cleanup);
 	RAII_VAR(struct media_variant *, variant, NULL, ao2_cleanup);
 
 	info = ao2_find(index->index, filename, OBJ_KEY);
 	if (!info) {
 		/* This is the first time the index has seen this filename,
 		 * allocate and link */
-		info = sound_info_alloc(filename);
+		info = media_info_alloc(filename);
 		if (!info) {
 			return NULL;
 		}
@@ -301,7 +254,7 @@
 
 struct ao2_container *ast_media_get_variants(struct ast_media_index *index, const char *filename)
 {
-	RAII_VAR(struct sound_info *, info, NULL, ao2_cleanup);
+	RAII_VAR(struct media_info *, info, NULL, ao2_cleanup);
 	RAII_VAR(struct ao2_container *, variants, NULL, ao2_cleanup);
 	if (!filename) {
 		return NULL;
@@ -323,10 +276,10 @@
 	return variants;
 }
 
-/*! \brief Add the sound_info's sound filename to the container of filenames requested */
-static int add_sound_cb(void *obj, void *arg, int flags)
-{
-	struct sound_info *info = obj;
+/*! \brief Add the media_info's filename to the container of filenames requested */
+static int add_media_cb(void *obj, void *arg, int flags)
+{
+	struct media_info *info = obj;
 	struct ao2_container *media = arg;
 	ast_str_container_add(media, info->name);
 	return 0;
@@ -336,15 +289,22 @@
 {
 	RAII_VAR(struct ao2_container *, media, NULL, ao2_cleanup);
 
-	media = ast_str_container_alloc(INDEX_BUCKETS);
-	if (!media) {
-		return NULL;
-	}
-
-	ao2_callback(index->index, OBJ_NODATA, add_sound_cb, media);
-
-	ao2_ref(media, +1);
-	return media;
+	if (!index->media_list_cache) {
+		media = ast_str_container_alloc(INDEX_BUCKETS);
+		if (!media) {
+			return NULL;
+		}
+
+		ao2_callback(index->index, OBJ_NODATA, add_media_cb, media);
+
+		/* Ref to the cache */
+		ao2_ref(media, +1);
+		index->media_list_cache = media;
+	}
+
+	/* Ref to the caller */
+	ao2_ref(index->media_list_cache, +1);
+	return index->media_list_cache;
 }
 
 /*! \brief Update an index with new format/language information */
@@ -362,8 +322,8 @@
 	return 0;
 }
 
-/*! \brief Process a sound file into the index */
-static int process_sound_file(struct ast_media_index *index, const char *variant, const char *subdir, const char *filename_stripped, const char *ext)
+/*! \brief Process a media file into the index */
+static int process_media_file(struct ast_media_index *index, const char *variant, const char *subdir, const char *filename_stripped, const char *ext)
 {
 	const struct ast_format *file_format;
 	const char *file_identifier = filename_stripped;
@@ -398,7 +358,7 @@
  * This currently processes core-sounds-*.txt and extra-sounds-*.txt, but will
  * process others if present.
  */
-static int process_description_file(struct ast_media_index *index, const char *variant_str, const char *filename)
+static int process_description_file(struct ast_media_index *index, const char *base_dir, const char *variant_str, const char *filename)
 {
 	RAII_VAR(struct ast_str *, description_file_path, ast_str_create(64), ast_free);
 	RAII_VAR(struct ast_str *, cumulative_description, ast_str_create(64), ast_free);
@@ -415,10 +375,10 @@
 		return -1;
 	}
 
-	ast_str_set(&description_file_path, 0, "%s/sounds/%s/%s", ast_config_AST_DATA_DIR, variant_str, filename);
+	ast_str_set(&description_file_path, 0, "%s/%s/%s", base_dir, variant_str, filename);
 	f = fopen(ast_str_buffer(description_file_path), "r");
 	if (!f) {
-		ast_log(LOG_WARNING, "Could not open sound description file '%s'\n", ast_str_buffer(description_file_path));
+		ast_log(LOG_WARNING, "Could not open media description file '%s'\n", ast_str_buffer(description_file_path));
 		return -1;
 	}
 
@@ -506,7 +466,7 @@
 }
 
 /*! \brief process an individual file listing */
-static int process_file(struct ast_media_index *index, const char *variant_str, const char *subdir, const char *filename)
+static int process_file(struct ast_media_index *index, const char *base_dir, const char *variant_str, const char *subdir, const char *filename)
 {
 	RAII_VAR(char *, filename_stripped, ast_strdup(filename), ast_free);
 	char *ext;
@@ -523,40 +483,43 @@
 
 	*ext++ = '\0';
 	if (!strcmp(ext, "txt")) {
-		if (!subdir && process_description_file(index, variant_str, filename)) {
+		if (!subdir && process_description_file(index, base_dir, variant_str, filename)) {
 			return -1;
 		}
 	} else {
-		if (process_sound_file(index, variant_str, subdir, filename_stripped, ext)) {
+		if (process_media_file(index, variant_str, subdir, filename_stripped, ext)) {
 			return -1;
 		}
 	}
 	return 0;
 }
 
-/*! \brief Callback to process an individual language directory or subdirectory */
-static int update_index_cb(void *obj, void *arg, int flags)
-{
-	char *lang = obj;
-	char *subdir = arg;
+/*! \brief internal function for updating the index, recursive */
+static int media_index_update(struct ast_media_index *index,
+	const char *base_dir,
+	const char *variant,
+	const char *subdir)
+{
 	struct dirent* dent;
 	DIR* srcdir;
-	RAII_VAR(struct ast_str *, sounds_lang_dir, ast_str_create(64), ast_free);
+	RAII_VAR(struct ast_str *, index_dir, ast_str_create(64), ast_free);
 	int res = 0;
 
-	if (!sounds_lang_dir) {
+	if (!index_dir) {
 		return 0;
 	}
 
-	if (subdir) {
-		ast_str_set(&sounds_lang_dir, 0, "%s/sounds/%s/%s", ast_config_AST_DATA_DIR, lang, subdir);
-	} else {
-		ast_str_set(&sounds_lang_dir, 0, "%s/sounds/%s", ast_config_AST_DATA_DIR, lang);
-	}
-
-	srcdir = opendir(ast_str_buffer(sounds_lang_dir));
+	ast_str_set(&index_dir, 0, "%s", base_dir);
+	if (!ast_strlen_zero(variant)) {
+		ast_str_append(&index_dir, 0, "/%s", variant);
+	}
+	if (!ast_strlen_zero(subdir)) {
+		ast_str_append(&index_dir, 0, "/%s", subdir);
+	}
+
+	srcdir = opendir(ast_str_buffer(index_dir));
 	if (srcdir == NULL) {
-		ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(sounds_lang_dir));
+		ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(index_dir));
 		return -1;
 	}
 
@@ -574,12 +537,12 @@
 		}
 
 		if (S_ISDIR(st.st_mode)) {
-			if (!subdir) {
-				update_index_cb(lang, dent->d_name, flags);
+			if (ast_strlen_zero(subdir)) {
+				media_index_update(index, base_dir, variant, dent->d_name);
 			} else {
 				RAII_VAR(struct ast_str *, new_subdir, ast_str_create(64), ast_free);
 				ast_str_set(&new_subdir, 0, "%s/%s", subdir, dent->d_name);
-				update_index_cb(lang, ast_str_buffer(new_subdir), flags);
+				media_index_update(index, base_dir, variant, ast_str_buffer(new_subdir));
 			}
 			continue;
 		}
@@ -588,7 +551,7 @@
 			continue;
 		}
 
-		if (process_file(sounds_index, lang, subdir, dent->d_name)) {
+		if (process_file(index, base_dir, variant, subdir, dent->d_name)) {
 			res = -1;
 			break;
 		}
@@ -598,173 +561,14 @@
 	return res;
 }
 
-/*! \brief Index sounds and sound descriptions */
-static int index_sounds(void)
-{
-	RAII_VAR(struct ao2_container *, languages, get_languages(), ao2_cleanup);
-
-	if (sounds_index || !languages) {
-		return -1;
-	}
-
-	sounds_index = media_index_alloc();
-	if (!sounds_index) {
-		return -1;
-	}
-
-	ao2_callback(languages, OBJ_NODATA, update_index_cb, NULL);
-	return 0;
-}
-
-/*! \brief Free the current sounds index */
-static void drop_sound_index(void)
-{
-	ao2_cleanup(sounds_index);
-	sounds_index = NULL;
-}
-
-/*! \brief Drop and then reindex available sounds */
-int ast_sounds_reindex(void)
-{
-	drop_sound_index();
-	if (index_sounds()) {
-		return -1;
-	}
-	return 0;
-}
-
-static int show_sounds_cb(void *obj, void *arg, int flags)
-{
-	struct sound_info *info = obj;
-	struct ast_cli_args *a = arg;
-	ast_cli(a->fd, "%s\n", info->name);
-	return 0;
-}
-
-static int show_sound_info_cb(void *obj, void *arg, int flags)
-{
-	struct media_variant *variant = obj;
-	struct ast_cli_args *a = arg;
-        struct ast_format format;
-
-	ast_cli(a->fd, "  Language %s:\n", variant->variant);
-	ast_cli(a->fd, "    Description: %s\n", variant->description);
-
-        ast_format_cap_iter_start(variant->formats);
-        while (!ast_format_cap_iter_next(variant->formats, &format)) {
-		ast_cli(a->fd, "    Format: %s\n", ast_getformatname(&format));
-        }
-        ast_format_cap_iter_end(variant->formats);
-
-	return 0;
-}
-
-/*! \brief Allow for reloading of sounds via the command line */
-static char *handle_cli_sounds_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-	switch (cmd) {
-	case CLI_INIT:
-		e->command = "sounds reload";
-		e->usage =
-			"Usage: sounds reload\n"
-			"       Reloads the index of sound files and their descriptions.\n";
-		return NULL;
-	case CLI_GENERATE:
-		return NULL;
-	}
-
-	if (a->argc != 2) {
-		return CLI_SHOWUSAGE;
-	}
-
-	if (ast_sounds_reindex()) {
-		ast_cli(a->fd, "Sound re-indexing failed.\n");
-		return CLI_FAILURE;
-	}
-
-	ast_cli(a->fd, "Sound files re-indexed.\n");
-	return CLI_SUCCESS;
-}
-
-/*! \brief Allow for reloading of sounds via the command line */
-static char *handle_cli_sounds_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
-	switch (cmd) {
-	case CLI_INIT:
-		e->command = "sounds show";
-		e->usage =
-			"Usage: sounds show[ soundid]\n"
-			"       Shows a listing of sound files or information about the specified sound.\n";
-		return NULL;
-	case CLI_GENERATE:
-	{
-                int length = strlen(a->word);
-                int which = 0;
-                struct ao2_iterator it_sounds;
-		char *match = NULL;
-		struct sound_info *info;
-
-		it_sounds = ao2_iterator_init(sounds_index->index, 0);
-                while ((info = ao2_iterator_next(&it_sounds))) {
-                        if (!strncasecmp(a->word, info->name, length) && ++which > a->n) {
-                                match = ast_strdup(info->name);
-                                ao2_ref(info, -1);
-                                break;
-                        }
-                        ao2_ref(info, -1);
-                }
-                ao2_iterator_destroy(&it_sounds);
-                return match;
-	}
-	}
-
-	if (a->argc == 2) {
-		ast_cli(a->fd, "Available audio files:\n");
-		ao2_callback(sounds_index->index, OBJ_MULTIPLE | OBJ_NODATA, show_sounds_cb, a);
-		return CLI_SUCCESS;
-	}
-
-	if (a->argc == 3) {
-		RAII_VAR(struct sound_info *, info, ao2_find(sounds_index->index, a->argv[2], OBJ_KEY), ao2_cleanup);
-		if (!info) {
-			ast_cli(a->fd, "ERROR: File %s not found in index\n", a->argv[2]);
-			return CLI_FAILURE;
-		}
-
-		ast_cli(a->fd, "Indexed Information for %s:\n", info->name);
-		ao2_callback(info->variant_list, OBJ_MULTIPLE | OBJ_NODATA, show_sound_info_cb, a);
-		return CLI_SUCCESS;
-	}
-
-	return CLI_SHOWUSAGE;
-}
-
-/*! \brief Struct for registering CLI commands */
-static struct ast_cli_entry cli_sounds[] = {
-	AST_CLI_DEFINE(handle_cli_sounds_show, "Shows available sounds"),
-	AST_CLI_DEFINE(handle_cli_sounds_reload, "Reload sounds index"),
-};
-
-static void media_cleanup(void)
-{
-	ast_cli_unregister_multiple(cli_sounds, ARRAY_LEN(cli_sounds));
-	drop_sound_index();
-}
-
-int ast_media_index_init(void)
-{
-	ao2_cleanup(sounds_index);
-	sounds_index = NULL;
-	if (index_sounds()) {
-		return -1;
-	}
-	ast_cli_register_multiple(cli_sounds, ARRAY_LEN(cli_sounds));
-	ast_register_atexit(media_cleanup);
-	return 0;
-}
-
-struct ast_media_index *ast_sounds_get_index(void)
-{
-	ao2_ref(sounds_index, +1);
-	return sounds_index;
-}
+int ast_media_index_update(struct ast_media_index *index,
+	const char *base_dir,
+	const char *variant)
+{
+	return media_index_update(index, base_dir, variant, NULL);
+}
+
+struct ast_media_index *ast_media_index_create(void)
+{
+	return media_index_alloc();
+}

Added: team/kmoore/stasis-http_sounds/main/sounds_index.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/main/sounds_index.c?view=auto&rev=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/main/sounds_index.c (added)
+++ team/kmoore/stasis-http_sounds/main/sounds_index.c Thu May 23 17:25:17 2013
@@ -1,0 +1,293 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kinsey Moore <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Sound file format and description index.
+ */
+
+#include "asterisk.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include "asterisk/utils.h"
+#include "asterisk/lock.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
+#include "asterisk/paths.h"	/* use ast_config_AST_DATA_DIR */
+#include "asterisk/media_index.h"
+#include "asterisk/sounds_index.h"
+#include "asterisk/file.h"
+#include "asterisk/cli.h"
+#include "asterisk/_private.h"
+
+/*** MODULEINFO
+	<support_level>core</support_level>
+ ***/
+
+/*! \brief The number of buckets to be used for storing language-keyed objects */
+#define LANGUAGE_BUCKETS 7
+
+static struct ast_media_index *sounds_index;
+
+/*! \brief Get the languages in which sound files are available */
+static struct ao2_container *get_languages(void)
+{
+	RAII_VAR(struct ao2_container *, lang_dirs, NULL, ao2_cleanup);
+	struct dirent* dent;
+	DIR* srcdir;
+	RAII_VAR(struct ast_str *, media_dir, ast_str_create(64), ast_free);
+
+	lang_dirs = ast_str_container_alloc(LANGUAGE_BUCKETS);
+	if (!media_dir || !lang_dirs) {
+		return NULL;
+	}
+
+	ast_str_set(&media_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);
+
+	srcdir = opendir(ast_str_buffer(media_dir));
+
+	if (srcdir == NULL) {
+		ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(media_dir));
+		return NULL;
+	}
+
+	while((dent = readdir(srcdir)) != NULL) {
+		struct stat st;
+
+		if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+			continue;
+		}
+
+		if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) {
+			ast_log(LOG_ERROR, "Failed to stat %s\n", dent->d_name);
+			continue;
+		}
+
+		if (S_ISDIR(st.st_mode)) {
+			ast_str_container_add(lang_dirs, dent->d_name);
+		}
+	}
+
+	closedir(srcdir);
+	ao2_ref(lang_dirs, +1);
+	return lang_dirs;
+}
+
+/*! \brief Callback to process an individual language directory or subdirectory */
+static int update_index_cb(void *obj, void *arg, int flags)
+{
+	char *lang = obj;
+	RAII_VAR(struct ast_str *, sounds_lang_dir, ast_str_create(64), ast_free);
+
+	if (!sounds_lang_dir) {
+		return CMP_STOP;
+	}
+
+	ast_str_set(&sounds_lang_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);
+
+	if (ast_media_index_update(sounds_index, ast_str_buffer(sounds_lang_dir), lang)) {
+		return CMP_STOP;
+	}
+	return 0;
+}
+
+/*! \brief Index sounds and sound descriptions */
+static int index_sounds(void)
+{
+	RAII_VAR(struct ao2_container *, languages, get_languages(), ao2_cleanup);
+
+	if (sounds_index || !languages) {
+		return -1;
+	}
+
+	sounds_index = ast_media_index_create();
+	if (!sounds_index) {
+		return -1;
+	}
+
+	ao2_callback(languages, OBJ_NODATA, update_index_cb, NULL);
+	return 0;
+}
+
+/*! \brief Free the current sounds index */
+static void drop_sound_index(void)
+{
+	ao2_cleanup(sounds_index);
+	sounds_index = NULL;
+}
+
+/*! \brief Drop and then reindex available sounds */
+int ast_sounds_reindex(void)
+{
+	drop_sound_index();
+	if (index_sounds()) {
+		return -1;
+	}
+	return 0;
+}
+
+static int show_sounds_cb(void *obj, void *arg, int flags)
+{
+	char *name = obj;
+	struct ast_cli_args *a = arg;
+	ast_cli(a->fd, "%s\n", name);
+	return 0;
+}
+
+static int show_sound_info_cb(void *obj, void *arg, int flags)
+{
+	char *language = obj;
+	struct ast_cli_args *a = arg;
+        struct ast_format format;
+	RAII_VAR(struct ast_format_cap *, cap, NULL, ast_format_cap_destroy);
+	RAII_VAR(char *, description, ast_media_get_description(sounds_index, a->argv[2], language), ast_free);
+
+	ast_cli(a->fd, "  Language %s:\n", language);
+	if (!ast_strlen_zero(description)) {
+		ast_cli(a->fd, "    Description: %s\n", description);
+	}
+
+	cap = ast_media_get_format_cap(sounds_index, a->argv[2], language);
+        ast_format_cap_iter_start(cap);
+        while (!ast_format_cap_iter_next(cap, &format)) {
+		ast_cli(a->fd, "    Format: %s\n", ast_getformatname(&format));
+        }
+        ast_format_cap_iter_end(cap);
+
+	return 0;
+}
+
+/*! \brief Allow for reloading of sounds via the command line */
+static char *handle_cli_sounds_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "sounds reload";
+		e->usage =
+			"Usage: sounds reload\n"
+			"       Reloads the index of sound files and their descriptions.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	if (a->argc != 2) {
+		return CLI_SHOWUSAGE;
+	}
+
+	if (ast_sounds_reindex()) {
+		ast_cli(a->fd, "Sound re-indexing failed.\n");
+		return CLI_FAILURE;
+	}
+
+	ast_cli(a->fd, "Sound files re-indexed.\n");
+	return CLI_SUCCESS;
+}
+
+/*! \brief Allow for reloading of sounds via the command line */
+static char *handle_cli_sounds_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "sounds show";
+		e->usage =
+			"Usage: sounds show[ soundid]\n"
+			"       Shows a listing of sound files or information about the specified sound.\n";
+		return NULL;
+	case CLI_GENERATE:
+	{
+                int length = strlen(a->word);
+                int which = 0;
+                struct ao2_iterator it_sounds;
+		char *match = NULL;
+		char *filename;
+		RAII_VAR(struct ao2_container *, sound_files, ast_media_get_media(sounds_index), ao2_cleanup);
+		if (!sound_files) {
+			return NULL;
+		}
+
+		it_sounds = ao2_iterator_init(sound_files, 0);
+                while ((filename = ao2_iterator_next(&it_sounds))) {
+                        if (!strncasecmp(a->word, filename, length) && ++which > a->n) {
+                                match = ast_strdup(filename);
+                                ao2_ref(filename, -1);
+                                break;
+                        }
+                        ao2_ref(filename, -1);
+                }
+                ao2_iterator_destroy(&it_sounds);
+                return match;
+	}
+	}
+
+	if (a->argc == 2) {
+		RAII_VAR(struct ao2_container *, sound_files, ast_media_get_media(sounds_index), ao2_cleanup);
+		if (!sound_files) {
+			return CLI_FAILURE;
+		}
+
+		ast_cli(a->fd, "Available audio files:\n");
+		ao2_callback(sound_files, OBJ_MULTIPLE | OBJ_NODATA, show_sounds_cb, a);
+		return CLI_SUCCESS;
+	}
+
+	if (a->argc == 3) {
+		RAII_VAR(struct ao2_container *, variants, ast_media_get_variants(sounds_index, a->argv[2]), ao2_cleanup);
+		if (!variants || !ao2_container_count(variants)) {
+			ast_cli(a->fd, "ERROR: File %s not found in index\n", a->argv[2]);
+			return CLI_FAILURE;
+		}
+
+		ast_cli(a->fd, "Indexed Information for %s:\n", a->argv[2]);
+		ao2_callback(variants, OBJ_MULTIPLE | OBJ_NODATA, show_sound_info_cb, a);
+		return CLI_SUCCESS;
+	}
+
+	return CLI_SHOWUSAGE;
+}
+
+/*! \brief Struct for registering CLI commands */
+static struct ast_cli_entry cli_sounds[] = {
+	AST_CLI_DEFINE(handle_cli_sounds_show, "Shows available sounds"),
+	AST_CLI_DEFINE(handle_cli_sounds_reload, "Reload sounds index"),
+};
+
+static void sounds_cleanup(void)
+{
+	ast_cli_unregister_multiple(cli_sounds, ARRAY_LEN(cli_sounds));
+	drop_sound_index();
+}
+
+int ast_sounds_index_init(void)
+{
+	ao2_cleanup(sounds_index);
+	sounds_index = NULL;
+	if (index_sounds()) {
+		return -1;
+	}
+	ast_cli_register_multiple(cli_sounds, ARRAY_LEN(cli_sounds));
+	ast_register_atexit(sounds_cleanup);
+	return 0;
+}
+
+struct ast_media_index *ast_sounds_get_index(void)
+{
+	ao2_ref(sounds_index, +1);
+	return sounds_index;
+}

Propchange: team/kmoore/stasis-http_sounds/main/sounds_index.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kmoore/stasis-http_sounds/main/sounds_index.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kmoore/stasis-http_sounds/main/sounds_index.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c?view=diff&rev=389655&r1=389654&r2=389655
==============================================================================
--- team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c (original)
+++ team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c Thu May 23 17:25:17 2013
@@ -29,6 +29,7 @@
 
 #include "resource_sounds.h"
 #include "asterisk/media_index.h"
+#include "asterisk/sounds_index.h"
 #include "asterisk/format.h"
 #include "asterisk/format_cap.h"
 #include "asterisk/json.h"




More information about the asterisk-commits mailing list