[asterisk-commits] oej: branch oej/minivoicemail r58070 - in /team/oej/minivoicemail: apps/ conf...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Mar 6 13:53:33 MST 2007


Author: oej
Date: Tue Mar  6 14:53:32 2007
New Revision: 58070

URL: http://svn.digium.com/view/asterisk?view=rev&rev=58070
Log:
Adding application for recording greetings for account owners

Modified:
    team/oej/minivoicemail/apps/app_minivm.c
    team/oej/minivoicemail/configs/minivm.conf.sample

Modified: team/oej/minivoicemail/apps/app_minivm.c
URL: http://svn.digium.com/view/asterisk/team/oej/minivoicemail/apps/app_minivm.c?view=diff&rev=58070&r1=58069&r2=58070
==============================================================================
--- team/oej/minivoicemail/apps/app_minivm.c (original)
+++ team/oej/minivoicemail/apps/app_minivm.c Tue Mar  6 14:53:32 2007
@@ -41,6 +41,7 @@
  *	- minivmGreet - Play user's greeting or default greeting ( \ref minivm_greet_exec() )
  *	- minivmNotify - Notify user of message ( \ref minivm_notify_exec() )
  * 	- minivmDelete - Delete voicemail message ( \ref minivm_delete_exec() )
+ *	- minivmAccMess - Record personal messages (busy | unavailable | temporary)
  *
  *	Dialplan functions
  *	- MINIVMACCOUNT() - A dialplan function
@@ -71,8 +72,10 @@
  *	
  * \par See also
  * \arg \ref Config_minivm
+ * \arg \ref Minivm_directories
  * \arg \ref app_minivm.c
  * \arg Comedian mail: app_voicemail.c
+ * \arg \ref descrip_minivm_accmess
  * \arg \ref descrip_minivm_greet
  * \arg \ref descrip_minivm_record
  * \arg \ref descrip_minivm_delete
@@ -80,6 +83,28 @@
  *
  * \arg \ref App_minivm_todo
  */
+/*! \page Minivm_directories Asterisk Mini-Voicemail Directory structure
+ *
+ *	The directory structure for storing voicemail
+ *		- AST_SPOOL_DIR - usually /var/spool/asterisk (configurable in asterisk.conf)
+ *		- MVM_SPOOL_DIR - should be configurable, usually AST_SPOOL_DIR/voicemail
+ *		- Domain	MVM_SPOOL_DIR/domain
+ *		- Username	MVM_SPOOL_DIR/domain/username
+ *			- /greet	: Recording of account owner's name
+ *			- /busy		: Busy message
+ *			- /unavailable  : Unavailable message
+ *			- /temp		: Temporary message
+ *
+ *	For account anita at localdomain.xx the account directory would as a default be
+ *		\b /var/spool/asterisk/voicemail/localdomain.xx/anita
+ *
+ *	To avoid transcoding, these sound files should be converted into several formats
+ *	They are recorded in the format closest to the incoming streams
+ *
+ *
+ * Back: \ref App_minivm
+ */
+
 
 /*! \page App_minivm_todo Asterisk Mini-Voicemail - todo
  *	- Record all voice files in standard temp directory - configurable
@@ -95,6 +120,9 @@
  *	- New app for creating directory for account if it does not exist
  *	- Re-insert code for IMAP storage at some point
  *	- Jabber integration for notifications
+ *	- Figure out how to handle video in voicemail
+ *	- Integration with the HTTP server
+ *	- New app for moving messages between mailboxes, and optionally mark it as "new"
  *
  *	For Asterisk 1.4
  *	- Use string fields for minivm_account
@@ -188,6 +216,7 @@
 static char *app_minivm_greet = "MinivmGreet";		/* Play voicemail prompts */
 static char *app_minivm_notify = "MinivmNotify";	/* Notify about voicemail by using one of several methods */
 static char *app_minivm_delete = "MinivmDelete";	/* Notify about voicemail by using one of several methods */
+static char *app_minivm_accmess = "MinivmAccMess";	/* Record personal voicemail messages */
 
 static char *synopsis_minivm_record = "Receive Mini-Voicemail and forward via e-mail";
 static char *descrip_minivm_record = 
@@ -246,7 +275,7 @@
 
 static char *synopsis_minivm_delete = "Delete Mini-Voicemail voicemail messages";
 static char *descrip_minivm_delete = 
-	"Syntax: MinivmDelete(username at domain [,filename])\n"
+	"Syntax: MinivmDelete(filename)\n"
 	"This application is part of the Mini-Voicemail system, configured in minivm.conf.\n"
 	"It deletes voicemail file set in MVM_FILENAME or given filename.\n"
 	"\n"
@@ -255,13 +284,31 @@
 	"	 FAILED is set if the file does not exist or can't be deleted.\n"
 	"\n";
 
+static char *synopsis_minivm_accmess = "Record account specific messages\n";
+static char *descrip_minivm_accmess = 
+	"Syntax: MinivmAccmess(username at domain,option)\n"
+	"This application is part of the Mini-Voicemail system, configured in minivm.conf.\n"
+	"Use this application to record account specific audio/video messages for\n"
+	"busy, unavailable and temporary messages.\n"
+	"Account specific directories will be created if they do not exist.\n"
+	"\nThe option selects message to be recorded:\n"
+	"   u      Unavailable\n"
+	"   b      Busy\n"
+	"   t      Temporary (overrides busy and unavailable)\n"
+	"   n      Account name\n"
+	"\n"
+	"Result is given in channel variable MINIVMACCMESSSTATUS\n"
+	"        The possible values are:     SUCCESS |  FAILED\n"
+	"	 FAILED is set if the file can't be created.\n"
+	"\n";
+
 enum {
 	OPT_SILENT =	   (1 << 0),
 	OPT_BUSY_GREETING =    (1 << 1),
 	OPT_UNAVAIL_GREETING = (1 << 2),
-	OPT_RECORDGAIN =       (1 << 3),
-	OPT_PREPEND_MAILBOX =  (1 << 4),
-	OPT_PRIORITY_JUMP =    (1 << 5),
+	OPT_TEMP_GREETING = (1 << 3),
+	OPT_NAME_GREETING = (1 << 4),
+	OPT_RECORDGAIN =  (1 << 5),
 } minivm_option_flags;
 
 enum {
@@ -274,10 +321,14 @@
 	AST_APP_OPTION('b', OPT_BUSY_GREETING),
 	AST_APP_OPTION('u', OPT_UNAVAIL_GREETING),
 	AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN),
-	AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
 });
 
-
+AST_APP_OPTIONS(minivm_accmess_options, {
+	AST_APP_OPTION('b', OPT_BUSY_GREETING),
+	AST_APP_OPTION('u', OPT_UNAVAIL_GREETING),
+	AST_APP_OPTION('t', OPT_TEMP_GREETING),
+	AST_APP_OPTION('n', OPT_NAME_GREETING),
+});
 
 /*! \brief Structure for linked list of Mini-Voicemail users: \ref minivm_accounts */
 struct minivm_account {
@@ -370,6 +421,7 @@
 static int global_vmminmessage;		/*!< Minimum duration of messages */
 static int global_vmmaxmessage;		/*!< Maximum duration of message */
 static int global_maxsilence;		/*!< Maximum silence during recording */
+static int global_maxgreet;		/*!< Maximum length of prompts  */
 static int global_silencethreshold = 128;
 static char global_mailcmd[160];	/*!< Configurable mail cmd */
 static char global_externnotify[160]; 	/*!< External notification application */
@@ -380,7 +432,6 @@
 static int global_saydurationminfo;
 
 static char global_fromstring[100];		/*!< Global fromstring in voicemail */
-static char global_pagerfromstring[100];	/*!< Global fromstring in pager */
 static char global_charset[32];			/*!< Global charset in messages */
 
 static double global_volgain;	/*!< Volume gain for voicmemail via e-mail */
@@ -440,7 +491,7 @@
 
 	while (var) {
 		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "-_-_- Configuring template option %s = %s for template %s\n", var->name, var->value, name);
+			ast_log(LOG_DEBUG, "-_-_- Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name);
 		if (!strcasecmp(var->name, "fromaddress")) {
 			ast_copy_string(template->fromstring, var->value, sizeof(template->fromstring));
 		} else if (!strcasecmp(var->name, "subject")) {
@@ -1044,7 +1095,7 @@
  * \param domain  String. Ignored if is null or empty string.
  * \param folder  String. Ignored if is null or empty string. 
  * \param ext	  String. Ignored if is null or empty string.
- * \return 0 on failure, 1 on success.
+ * \return -1 on failure, 0 on success.
  */
 static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
 {
@@ -1054,26 +1105,26 @@
 		make_dir(dest, len, domain, "", "");
 		if(mkdir(dest, mode) && errno != EEXIST) {
 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
-			return 0;
+			return -1;
 		}
 	}
 	if(!ast_strlen_zero(username)) {
 		make_dir(dest, len, domain, username, "");
 		if(mkdir(dest, mode) && errno != EEXIST) {
 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
-			return 0;
+			return -1;
 		}
 	}
 	if(!ast_strlen_zero(folder)) {
 		make_dir(dest, len, domain, username, folder);
 		if(mkdir(dest, mode) && errno != EEXIST) {
 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
-			return 0;
+			return -1;
 		}
 	}
 	if (option_debug > 1)
 		ast_log(LOG_DEBUG, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest);
-	return 1;
+	return 0;
 }
 
 
@@ -1137,7 +1188,7 @@
 	return res;
 }
 
-/*! \brief Delete attribute file */
+/*! \brief Delete media files and attribute file */
 static int vm_delete(char *file)
 {
 	char *txt;
@@ -1401,8 +1452,6 @@
 	if (!(vmu = find_account(domain, username))) {
 		/* We could not find user, let's exit */
 		ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain);
-		if (ast_test_flag(options, OPT_PRIORITY_JUMP) || option_priority_jumping)
-			ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
 		pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "FAILED");
 		return 0;
 	}
@@ -1598,6 +1647,8 @@
 		/* We could not find user, let's exit */
 		ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
 		pbx_builtin_setvar_helper(chan, "MINIVMNOTIFYSTATUS", "FAILED");
+		LOCAL_USER_REMOVE(u);
+		return -1;
 	}
 	
 	filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME");
@@ -1606,7 +1657,6 @@
 	/* Notify of new message to e-mail and pager */
 	if (!ast_strlen_zero(filename))
 		notify_new_message(chan, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name);
-	else
 
 
 	if(ast_test_flag(vmu, MVM_ALLOCED))
@@ -1657,7 +1707,7 @@
 			LOCAL_USER_REMOVE(u);
 			return -1;
 		}
-		ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
+		ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
 		if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
 			int gain;
 
@@ -1676,9 +1726,6 @@
 	if (res == ERROR_LOCK_PATH) {
 		ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
 		/* Send the call to n+101 priority, where n is the current priority*/
-		if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || option_priority_jumping)
-			if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
-				ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
 		pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "FAILED");
 		res = 0;
 	}
@@ -1734,7 +1781,7 @@
 			LOCAL_USER_REMOVE(u);
 			return -1;
 		}
-		ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
+		ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
 	}
 
 	ast_copy_string(tmp, argv[0], sizeof(tmp));
@@ -1910,6 +1957,7 @@
 	if (ast_strlen_zero(filename)) {
 		LOCAL_USER_REMOVE(u);
 		ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n");
+		return res;
 	} 
 
 	/* Go ahead and delete audio files from system, they're not needed any more */
@@ -1935,6 +1983,112 @@
 	return res;
 }
 
+/*! \brief Record specific messages for voicemail account */
+static int minivm_accmess_exec(struct ast_channel *chan, void *data)
+{
+	struct localuser *u;
+	int argc = 0;
+	char *argv[2];
+	int res = 0;
+	char filename[PATH_MAX];
+	char tmp[PATH_MAX];
+	char *domain;
+	char *tmpptr;
+	struct minivm_account *vmu;
+	char *username = argv[0];
+	struct ast_flags flags = { 0 };
+	char *opts[OPT_ARG_ARRAY_SIZE];
+	int error = FALSE;
+	char *message = NULL;
+	char *prompt = NULL;
+	int duration;
+	
+	LOCAL_USER_ADD(u);
+
+	if (ast_strlen_zero(data))  {
+		ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
+		error = TRUE;
+	} else 
+		tmpptr = ast_strdupa((char *)data);
+	if (!error) {
+		if (!tmpptr) {
+			ast_log(LOG_ERROR, "Out of memory\n");
+			error = TRUE;
+		} else
+			argc = ast_app_separate_args(tmpptr, '|', argv, sizeof(argv) / sizeof(argv[0]));
+	}
+
+	if (argc <=1) {
+		ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
+		error = TRUE;
+	}
+	if (!error && strlen(argv[1]) > 1) {
+		ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]);
+		error = TRUE;
+	}
+
+	if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) {
+		ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]);
+		error = TRUE;
+	}
+
+	if (error) {
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+
+	ast_copy_string(tmp, argv[0], sizeof(tmp));
+	username = tmp;
+	domain = strchr(tmp, '@');
+	if (domain) {
+		*domain = '\0';
+		domain++;
+	} 
+	if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
+		ast_log(LOG_ERROR, "Need username at domain as argument. Sorry. Argument 0 %s\n", argv[0]);
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+
+	if(!(vmu = find_account(domain, username))) {
+		/* We could not find user, let's exit */
+		ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
+		pbx_builtin_setvar_helper(chan, "MINIVMNOTIFYSTATUS", "FAILED");
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+	
+	/* Here's where the action is */
+	if (ast_test_flag(&flags, OPT_BUSY_GREETING)) {
+		message = "busy";
+		prompt = "vm-rec-busy";
+	} else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) {
+		message = "unavailable";
+		prompt = "vm-rec-unavail";
+	} else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) {
+		message = "temp";
+		prompt = "vm-temp-greeting";
+	} else if (ast_test_flag(&flags, OPT_NAME_GREETING)) {
+		message = "greet";
+		prompt = "vm-rec-name";
+	}
+	snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message);
+	/* Maybe we should check the result of play_record_review ? */
+	play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, FALSE);
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Recorded new %s message in %s (duration %d)\n", message, filename, duration);
+
+	if(ast_test_flag(vmu, MVM_ALLOCED))
+		free_user(vmu);
+
+
+	/* Ok, we're ready to rock and roll. Return to dialplan */
+	LOCAL_USER_REMOVE(u);
+
+	return res;
+
+}
 
 /*! \brief Append new mailbox to mailbox list from configuration file */
 static int create_vmaccount(char *name, struct ast_variable *var, int realtime)
@@ -1977,7 +2131,7 @@
 
 	while (var) {
 		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "---- Configuring %s = %s for account %s\n", var->name, var->value, name);
+			ast_log(LOG_DEBUG, "---- Configuring %s = \"%s\" for account %s\n", var->name, var->value, name);
 		if (!strcasecmp(var->name, "serveremail")) {
 			ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail));
 		} else if (!strcasecmp(var->name, "email")) {
@@ -2121,8 +2275,6 @@
 		}
 		ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf));
 		writepos += strlen(readbuf) - 1;
-		if (option_debug > 3) 
-			ast_log(LOG_DEBUG, "---> Reading message template : Line %d: %s\n", lines, readbuf);
 	}
 	fclose(fi);
 	messagebody = calloc(1, strlen(buf + 1));
@@ -2171,6 +2323,8 @@
 		/* Mail command */
 		if (!strcmp(var->name, "mailcmd")) {
 			ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */
+		} else if (!strcmp(var->name, "maxgreet")) {
+			global_maxgreet = atoi(var->value);
 		} else if (!strcmp(var->name, "maxsilence")) {
 			global_maxsilence = atoi(var->value);
 			if (global_maxsilence > 0)
@@ -2243,6 +2397,7 @@
 	global_externnotify[0] = '\0';
 	global_silencethreshold = 256;
 	global_vmmaxmessage = 2000;
+	global_maxgreet = 2000;
 	global_vmminmessage = 0;
 	strcpy(global_mailcmd, SENDMAIL);
 	global_maxsilence = 0;
@@ -2671,6 +2826,7 @@
 	res = ast_register_application(app_minivm_greet, minivm_greet_exec, synopsis_minivm_greet, descrip_minivm_greet);
 	res = ast_register_application(app_minivm_notify, minivm_notify_exec, synopsis_minivm_notify, descrip_minivm_notify);
 	res = ast_register_application(app_minivm_delete, minivm_delete_exec, synopsis_minivm_delete, descrip_minivm_delete);
+	res = ast_register_application(app_minivm_accmess, minivm_accmess_exec, synopsis_minivm_accmess, descrip_minivm_accmess);
 
 	ast_custom_function_register(&minivm_account_function);
 	if (res)

Modified: team/oej/minivoicemail/configs/minivm.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/minivoicemail/configs/minivm.conf.sample?view=diff&rev=58070&r1=58069&r2=58070
==============================================================================
--- team/oej/minivoicemail/configs/minivm.conf.sample (original)
+++ team/oej/minivoicemail/configs/minivm.conf.sample Tue Mar  6 14:53:32 2007
@@ -28,6 +28,8 @@
 maxsilence=10
 ; Silence threshold (what we consider silence: the lower, the more sensitive)
 silencethreshold=128
+; How long greeting messages (busy/unavailable/temp/name) are allowed to be, in seconds
+;maxgreet=120
 ; If you need to have an external program, i.e. /usr/bin/myapp called when a
 ; voicemail is received by the server. The arguments are
 ;



More information about the asterisk-commits mailing list