]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Add VM_INFO() dialplan function to gather information about a mailbox.
authorWalter Doekes <walter+asterisk@wjd.nu>
Tue, 6 Dec 2011 20:23:13 +0000 (20:23 +0000)
committerWalter Doekes <walter+asterisk@wjd.nu>
Tue, 6 Dec 2011 20:23:13 +0000 (20:23 +0000)
Deprecates MAILBOX_EXISTS. Provides count, email, exists, fullname,
language, locale, pager, password, tz.

(closes issue ASTERISK-18634)
Patch by: Kris Shaw
Review: https://reviewboard.asterisk.org/r/1568
Reviewed by: Walter Doekes

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@347192 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
UPGRADE.txt
apps/app_voicemail.c

diff --git a/CHANGES b/CHANGES
index 3554d45cf750a9cc6c4f716f873e848da80cd00d..cbde5635361163b323d18911fd365633db33b5e1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -74,6 +74,13 @@ Core changes
    affect the core console verbosity, 'remote set verbose' will now set a
    separate level for each remote console without affecting any other console.
 
+Dialplan functions
+------------------
+ * Addition of the VM_INFO function that can be used to retrieve voicemail
+   user information, such as the email address and full name.
+   The MAILBOX_EXISTS dialplan function has been deprecated in favour of
+   VM_INFO.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.8 to Asterisk 10 -------------------
 ------------------------------------------------------------------------------
index ac88afddf9c4f05d1e06d60f1921ace40143f36f..ee804275be505be7a627257ed7adf5cb0a949e7f 100644 (file)
 
 From 10 to 11:
 
+Dialplan Functions:
+ - MAILBOX_EXISTS has been deprecated. Use VM_INFO with the 'exists' parameter
+   instead.
+
 func_enum:
  - ENUM query functions now return a count of -1 on lookup error to
    differentiate between a failed query and a successful query with 0 results
index ed94bc21a269998ba9c2766d4f5c319e9ef66826..a62a39b87305b11e5478f3555424d0de90809a95 100644 (file)
@@ -284,6 +284,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                        </parameter>
                </syntax>
                <description>
+                       <note><para>DEPRECATED. Use VM_INFO(mailbox[@context],exists) instead.</para></note>
                        <para>Check to see if the specified <replaceable>mailbox</replaceable> exists. If no voicemail
                        <replaceable>context</replaceable> is specified, the <literal>default</literal> context
                        will be used.</para>
@@ -297,6 +298,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                                </variable>
                        </variablelist>
                </description>
+               <see-also>
+                       <ref type="function">VM_INFO</ref>
+               </see-also>
        </application>
        <application name="VMAuthenticate" language="en_US">
                <synopsis>
@@ -354,10 +358,67 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                        <parameter name="context" />
                </syntax>
                <description>
+                       <note><para>DEPRECATED. Use VM_INFO(mailbox[@context],exists) instead.</para></note>
                        <para>Returns a boolean of whether the corresponding <replaceable>mailbox</replaceable> exists.
                        If <replaceable>context</replaceable> is not specified, defaults to the <literal>default</literal>
                        context.</para>
                </description>
+               <see-also>
+                       <ref type="function">VM_INFO</ref>
+               </see-also>
+       </function>
+       <function name="VM_INFO" language="en_US">
+               <synopsis>
+                       Returns the selected attribute from a mailbox.
+               </synopsis>
+               <syntax argsep=",">
+                       <parameter name="mailbox" argsep="@" required="true">
+                               <argument name="mailbox" required="true" />
+                               <argument name="context" />
+                       </parameter>
+                       <parameter name="attribute" required="true">
+                               <optionlist>
+                                       <option name="count">
+                                               <para>Count of messages in specified <replaceable>folder</replaceable>.
+                                               If <replaceable>folder</replaceable> is not specified, defaults to <literal>INBOX</literal>.</para>
+                                       </option>
+                                       <option name="email">
+                                               <para>E-mail address associated with the mailbox.</para>
+                                       </option>
+                                       <option name="exists">
+                                               <para>Returns a boolean of whether the corresponding <replaceable>mailbox</replaceable> exists.</para>
+                                       </option>
+                                       <option name="fullname">
+                                               <para>Full name associated with the mailbox.</para>
+                                       </option>
+                                       <option name="language">
+                                               <para>Mailbox language if overridden, otherwise the language of the channel.</para>
+                                       </option>
+                                       <option name="locale">
+                                               <para>Mailbox locale if overridden, otherwise global locale.</para>
+                                       </option>
+                                       <option name="pager">
+                                               <para>Pager e-mail address associated with the mailbox.</para>
+                                       </option>
+                                       <option name="password">
+                                               <para>Mailbox access password.</para>
+                                       </option>
+                                       <option name="tz">
+                                               <para>Mailbox timezone if overridden, otherwise global timezone</para>
+                                       </option>
+                               </optionlist>
+                       </parameter>
+                       <parameter name="folder" required="false">
+                               <para>If not specified, <literal>INBOX</literal> is assumed.</para>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>Returns the selected attribute from the specified <replaceable>mailbox</replaceable>.
+                       If <replaceable>context</replaceable> is not specified, defaults to the <literal>default</literal>
+                       context. Where the <replaceable>folder</replaceable> can be specified, common folders
+                       include <literal>INBOX</literal>, <literal>Old</literal>, <literal>Work</literal>,
+                       <literal>Family</literal> and <literal>Friends</literal>.</para>
+               </description>
        </function>
        <manager name="VoicemailUsersList" language="en_US">
                <synopsis>
@@ -5223,11 +5284,15 @@ static int messagecount(const char *context, const char *mailbox, const char *fo
        char sql[PATH_MAX];
        char rowdata[20];
        struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };
-       if (!folder)
-               folder = "INBOX";
+
        /* If no mailbox, return immediately */
-       if (ast_strlen_zero(mailbox))
+       if (ast_strlen_zero(mailbox)) {
                return 0;
+       }
+
+       if (ast_strlen_zero(folder)) {
+               folder = "INBOX";
+       }
 
        obj = ast_odbc_request_obj(odbc_database, 0);
        if (obj) {
@@ -10975,7 +11040,7 @@ static int vm_box_exists(struct ast_channel *chan, const char *data)
 
        if (!dep_warning) {
                dep_warning = 1;
-               ast_log(AST_LOG_WARNING, "MailboxExists is deprecated.  Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data);
+               ast_log(AST_LOG_WARNING, "MailboxExists is deprecated.  Please use ${VM_INFO(%s,exists)} instead.\n", data);
        }
 
        box = ast_strdupa(data);
@@ -11005,6 +11070,7 @@ static int acf_mailbox_exists(struct ast_channel *chan, const char *cmd, char *a
                AST_APP_ARG(mbox);
                AST_APP_ARG(context);
        );
+       static int dep_warning = 0;
 
        AST_NONSTANDARD_APP_ARGS(arg, args, '@');
 
@@ -11013,15 +11079,99 @@ static int acf_mailbox_exists(struct ast_channel *chan, const char *cmd, char *a
                return -1;
        }
 
+       if (!dep_warning) {
+               dep_warning = 1;
+               ast_log(AST_LOG_WARNING, "MAILBOX_EXISTS is deprecated.  Please use ${VM_INFO(%s,exists)} instead.\n", args);
+       }
+
        ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len);
        return 0;
 }
 
+static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len)
+{
+       struct ast_vm_user *vmu = NULL;
+       char *tmp, *mailbox, *context, *parse;
+       int res = 0;
+
+       AST_DECLARE_APP_ARGS(arg,
+               AST_APP_ARG(mailbox_context);
+               AST_APP_ARG(attribute);
+               AST_APP_ARG(folder);
+       );
+
+       buf[0] = '\0';
+
+       if (ast_strlen_zero(args)) {
+               ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
+               return -1;
+       }
+
+       parse = ast_strdupa(args);
+       AST_STANDARD_APP_ARGS(arg, parse);
+
+       if (ast_strlen_zero(arg.mailbox_context) || ast_strlen_zero(arg.attribute)) {
+               ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
+               return -1;
+       }
+
+       tmp = ast_strdupa(arg.mailbox_context);
+       mailbox = strsep(&tmp, "@");
+       context = strsep(&tmp, "");
+
+       if (ast_strlen_zero(context)) {
+                context = "default";
+       }
+
+       vmu = find_user(NULL, context, mailbox);
+
+       if (!strncasecmp(arg.attribute, "exists", 5)) {
+               ast_copy_string(buf, vmu ? "1" : "0", len);
+               return 0;
+       }
+
+       if (vmu) {
+               if (!strncasecmp(arg.attribute, "password", 8)) {
+                       ast_copy_string(buf, vmu->password, len);
+               } else if (!strncasecmp(arg.attribute, "fullname", 8)) {
+                       ast_copy_string(buf, vmu->fullname, len);
+               } else if (!strncasecmp(arg.attribute, "email", 5)) {
+                       ast_copy_string(buf, vmu->email, len);
+               } else if (!strncasecmp(arg.attribute, "pager", 5)) {
+                       ast_copy_string(buf, vmu->pager, len);
+               } else if (!strncasecmp(arg.attribute, "language", 8)) {
+                       ast_copy_string(buf, S_OR(vmu->language, chan->language), len);
+               } else if (!strncasecmp(arg.attribute, "locale", 6)) {
+                       ast_copy_string(buf, vmu->locale, len);
+               } else if (!strncasecmp(arg.attribute, "tz", 2)) {
+                       ast_copy_string(buf, vmu->zonetag, len);
+               } else if (!strncasecmp(arg.attribute, "count", 5)) {
+                       /* If mbxfolder is empty messagecount will default to INBOX */
+                       res = messagecount(context, mailbox, arg.folder);
+                       if (res < 0) {
+                               ast_log(LOG_ERROR, "Unable to retrieve message count for mailbox %s\n", arg.mailbox_context);
+                               return -1;
+                       }
+                       snprintf(buf, len, "%d", res);
+               } else {
+                       ast_log(LOG_ERROR, "Unknown attribute '%s' for VM_INFO\n", arg.attribute);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 static struct ast_custom_function mailbox_exists_acf = {
        .name = "MAILBOX_EXISTS",
        .read = acf_mailbox_exists,
 };
 
+static struct ast_custom_function vm_info_acf = {
+       .name = "VM_INFO",
+       .read = acf_vm_info,
+};
+
 static int vmauthenticate(struct ast_channel *chan, const char *data)
 {
        char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = "";
@@ -13018,6 +13168,88 @@ cleanup:
        return res;
 }
 
+AST_TEST_DEFINE(test_voicemail_vm_info)
+{
+       struct ast_vm_user *vmu;
+       struct ast_channel *chan = NULL;
+       const char testcontext[] = "test";
+       const char testmailbox[] = "00000000";
+       const char vminfo_cmd[] = "VM_INFO";
+       char vminfo_buf[256], vminfo_args[256];
+       int res = AST_TEST_PASS;
+       int test_ret = 0;
+       int test_counter = 0;
+
+       struct {
+               char *vminfo_test_args;
+               char *vminfo_expected;
+               int vminfo_ret;
+       } test_items[] = {
+               { "", "", -1 },                         /* Missing argument */
+               { "00000000@test,badparam", "", -1 },   /* Wrong argument */
+               { "00000000@test", "", -1 },            /* Missing argument */
+               { "00000000@test,exists", "1", 0 },
+               { "11111111@test,exists", "0", 0 },     /* Invalid mailbox */
+               { "00000000@test,email", "vm-info-test@example.net", 0 },
+               { "11111111@test,email", "", 0 },       /* Invalid mailbox */
+               { "00000000@test,fullname", "Test Framework Mailbox", 0 },
+               { "00000000@test,pager", "vm-info-pager-test@example.net", 0 },
+               { "00000000@test,locale", "en_US", 0 },
+               { "00000000@test,tz", "central", 0 },
+               { "00000000@test,language", "en", 0 },
+               { "00000000@test,password", "9876", 0 },
+       };
+
+       switch (cmd) {
+               case TEST_INIT:
+                       info->name = "test_voicemail_vm_info";
+                       info->category = "/apps/app_voicemail/";
+                       info->summary = "VM_INFO unit test";
+                       info->description =
+                               "This tests passing various parameters to VM_INFO";
+                       return AST_TEST_NOT_RUN;
+               case TEST_EXECUTE:
+                       break;
+       }
+
+       if (!(chan = ast_dummy_channel_alloc())) {
+               ast_test_status_update(test, "Unable to create dummy channel\n");
+               return AST_TEST_FAIL;
+       }
+
+       if (!(vmu = find_user(NULL, testcontext, testmailbox)) &&
+                       !(vmu = find_or_create(testcontext, testmailbox))) {
+               ast_test_status_update(test, "Cannot create vmu structure\n");
+               chan = ast_channel_unref(chan);
+               return AST_TEST_FAIL;
+       }
+
+       populate_defaults(vmu);
+
+       ast_copy_string(vmu->email, "vm-info-test@example.net", sizeof(vmu->email));
+       ast_copy_string(vmu->fullname, "Test Framework Mailbox", sizeof(vmu->fullname));
+       ast_copy_string(vmu->pager, "vm-info-pager-test@example.net", sizeof(vmu->pager));
+       ast_copy_string(vmu->language, "en", sizeof(vmu->language));
+       ast_copy_string(vmu->zonetag, "central", sizeof(vmu->zonetag));
+       ast_copy_string(vmu->locale, "en_US", sizeof(vmu->zonetag));
+       ast_copy_string(vmu->password, "9876", sizeof(vmu->password));
+
+       for (test_counter = 0; test_counter < ARRAY_LEN(test_items); test_counter++) {
+               ast_copy_string(vminfo_args, test_items[test_counter].vminfo_test_args, sizeof(vminfo_args));
+               test_ret = acf_vm_info(chan, vminfo_cmd, vminfo_args, vminfo_buf, sizeof(vminfo_buf));
+               if (strcmp(vminfo_buf, test_items[test_counter].vminfo_expected)) {
+                       ast_test_status_update(test, "VM_INFO respose was: '%s', but expected: '%s'\n", vminfo_buf, test_items[test_counter].vminfo_expected);
+                       res = AST_TEST_FAIL;
+               }
+               if (!(test_ret == test_items[test_counter].vminfo_ret)) {
+                       ast_test_status_update(test, "VM_INFO return code was: '%i', but expected '%i'\n", test_ret, test_items[test_counter].vminfo_ret);
+                       res = AST_TEST_FAIL;
+               }
+       }
+
+       chan = ast_channel_unref(chan);
+       return res;
+}
 #endif /* defined(TEST_FRAMEWORK) */
 
 static int reload(void)
@@ -13035,6 +13267,7 @@ static int unload_module(void)
        res |= ast_unregister_application(app4);
        res |= ast_unregister_application(sayname_app);
        res |= ast_custom_function_unregister(&mailbox_exists_acf);
+       res |= ast_custom_function_unregister(&vm_info_acf);
        res |= ast_manager_unregister("VoicemailUsersList");
        res |= ast_data_unregister(NULL);
 #ifdef TEST_FRAMEWORK
@@ -13043,6 +13276,7 @@ static int unload_module(void)
        res |= AST_TEST_UNREGISTER(test_voicemail_vmuser);
        res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl);
        res |= AST_TEST_UNREGISTER(test_voicemail_load_config);
+       res |= AST_TEST_UNREGISTER(test_voicemail_vm_info);
 #endif
        ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail));
        ast_uninstall_vm_functions();
@@ -13086,6 +13320,7 @@ static int load_module(void)
        res |= ast_register_application_xml(app4, vmauthenticate);
        res |= ast_register_application_xml(sayname_app, vmsayname_exec);
        res |= ast_custom_function_register(&mailbox_exists_acf);
+       res |= ast_custom_function_register(&vm_info_acf);
        res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users);
 #ifdef TEST_FRAMEWORK
        res |= AST_TEST_REGISTER(test_voicemail_vmsayname);
@@ -13093,6 +13328,7 @@ static int load_module(void)
        res |= AST_TEST_REGISTER(test_voicemail_vmuser);
        res |= AST_TEST_REGISTER(test_voicemail_notify_endl);
        res |= AST_TEST_REGISTER(test_voicemail_load_config);
+       res |= AST_TEST_REGISTER(test_voicemail_vm_info);
 #endif
 
        if (res)