switch_ivr/xml: Change the structure of the phrases/language system. Previously…

switch_ivr/xml: Change the structure of the phrases/language system. Previously it was fxml->phrases->macros->language->macro.  Changed it so fxml->languages->language->phrases->macros->macro
You can have sub macros <macros name="voicemail"><macro ...> and allow you to call it login@voicemail.
Change the sound-path to sound-prefix to make it constistant with the rest of freeswitch.
Also allow to set a sound-prefix to a macros, so you can override it for a specific file set.
You can set say-modules="en" or whatever in the <language section to define that say module to use.
上级 6dd12374
......@@ -52,14 +52,12 @@
<X-PRE-PROCESS cmd="include" data="directory/*.xml"/>
</section>
<!-- phrases section (under development still) -->
<section name="phrases" description="Speech Phrase Management">
<macros>
<X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
</macros>
<!-- languages section (under development still) -->
<section name="languages" description="Language Management">
<X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
<X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
</section>
</document>
<include>
<language name="de" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
<X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
<!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
<X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
<language name="de" sound-prefix="/snds" tts-engine="cepstral" tts-voice="david">
<phrases>
<macros>
<X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
<!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
<X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
</macros>
</phrases>
</language>
</include>
<include>
<language name="en" sound-path="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
<language name="en" say-module="en" sound-prefix="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
<phrases>
<macros>
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
</macros>
</phrases>
</language>
</include>
<include>
<language name="fr" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
<X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
<!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
<language name="fr" say-module="fr" sound-prefix="$${sounds_dir}/fr/ca/june" tts-engine="cepstral" tts-voice="david">
<phrases>
<macros>
<X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
<!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
</macros>
</phrases>
</language>
</include>
<include>
<language name="he" sound-path="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
<language name="he" sound-prefix="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
<phrases>
<macros>
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
<X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
</macros>
</phrases>
</language>
</include>
<?xml version="1.0" encoding="utf-8"?>
<!--тестовые файлы Вы звуковые файлы можно взять тут svn co http://svn.freeswitch.ru/bbv/mod_say_ru/ru/ -->
<include>
<language name="ru" sound-path="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
<language name="ru" sound-prefix="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
<phrases>
<macros>
<X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
<!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
<X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
</macros>
</phrases>
</language>
</include>
......@@ -417,6 +417,8 @@ SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(_In_opt_z_
SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language);
SWITCH_END_EXTERN_C
///\}
#endif // _SWITCH_XML_H
......
......@@ -17,7 +17,7 @@
<menus>
<menu name="std_authenticate">
<phrases>
<phrase name="fail_auth" value="protovm_fail_auth" />
<phrase name="fail_auth" value="fail_auth@protovm" />
</phrases>
<keys>
</keys>
......@@ -25,7 +25,7 @@
<menu name="std_authenticate_ask_user">
<phrases>
<phrase name="instructions" value="protovm_enter_id" />
<phrase name="instructions" value="enter_id@protovm" />
</phrases>
<keys>
<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
......@@ -34,7 +34,7 @@
<menu name="std_authenticate_ask_password">
<phrases>
<phrase name="instructions" value="protovm_enter_pass" />
<phrase name="instructions" value="enter_pass@protovm" />
</phrases>
<keys>
<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
......@@ -43,12 +43,12 @@
<menu name="std_navigator">
<phrases>
<phrase name="msg_count" value="protovm_message_count" />
<phrase name="say_date" value="protovm_say_date_event" />
<phrase name="say_msg_number" value="protovm_say_message_number" />
<phrase name="menu_options" value="protovm_listen_file_check" />
<phrase name="ack" value="protovm_ack" />
<phrase name="play_message" value="protovm_play_message" />
<phrase name="msg_count" value="message_count@protovm" />
<phrase name="say_date" value="say_date_event@protovm" />
<phrase name="say_msg_number" value="say_message_number@protovm" />
<phrase name="menu_options" value="listen_file_check@protovm" />
<phrase name="ack" value="ack@protovm" />
<phrase name="play_message" value="play_message@protovm" />
</phrases>
<keys>
<key dtmf="1" action="skip_intro" variable="VM-Key-Main-Listen-File" />
......@@ -62,7 +62,7 @@
<menu name="std_preference">
<phrases>
<phrase name="menu_options" value="protovm_config_menu" />
<phrase name="menu_options" value="config_menu@protovm" />
</phrases>
<keys>
<key dtmf="1" action="menu:std_record_greeting_with_slot" variable="VM-Key-Record-Greeting" />
......@@ -75,9 +75,9 @@
<menu name="std_record_greeting">
<phrases>
<phrase name="instructions" value="voicemail_record_greeting" />
<phrase name="play_recording" value="protovm_play_recording" />
<phrase name="menu_options" value="protovm_record_file_check" />
<phrase name="instructions" value="record_greeting@protovm" />
<phrase name="play_recording" value="play_recording@protovm" />
<phrase name="menu_options" value="record_file_check@protovm" />
</phrases>
<keys>
<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
......@@ -90,9 +90,9 @@
<menu name="std_record_name">
<phrases>
<phrase name="instructions" value="protovm_record_name" />
<phrase name="play_recording" value="protovm_play_recording" />
<phrase name="menu_options" value="protovm_record_file_check" />
<phrase name="instructions" value="record_name@protovm" />
<phrase name="play_recording" value="play_recording@protovm" />
<phrase name="menu_options" value="record_file_check@protovm" />
</phrases>
<keys>
<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
......@@ -106,9 +106,9 @@
<menu name="std_select_greeting_slot">
<phrases>
<phrase name="instructions" value="protovm_choose_greeting" />
<phrase name="invalid_slot" value="protovm_choose_greeting_fail" />
<phrase name="selected_slot" value="protovm_greeting_selected" />
<phrase name="instructions" value="choose_greeting@protovm" />
<phrase name="invalid_slot" value="choose_greeting_fail@protovm" />
<phrase name="selected_slot" value="greeting_selected@protovm" />
</phrases>
<keys>
</keys>
......@@ -116,7 +116,7 @@
<menu name="std_record_greeting_with_slot">
<phrases>
<phrase name="instructions" value="protovm_choose_greeting" />
<phrase name="instructions" value="choose_greeting@protovm" />
</phrases>
<keys>
</keys>
......@@ -124,7 +124,7 @@
<menu name="std_set_password">
<phrases>
<phrase name="instructions" value="protovm_enter_pass" />
<phrase name="instructions" value="enter_pass@protovm" />
</phrases>
<keys>
</keys>
......
......@@ -50,7 +50,8 @@ typedef enum {
XML_LDAP_CONFIG = 0,
XML_LDAP_DIRECTORY,
XML_LDAP_DIALPLAN,
XML_LDAP_PHRASE
XML_LDAP_PHRASE,
XML_LDAP_LANGUAGE
} xml_ldap_query_type_t;
SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load);
......@@ -247,6 +248,8 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c
query_type = XML_LDAP_DIALPLAN;
} else if (!strcmp(section, "phrases")) {
query_type = XML_LDAP_PHRASE;
} else if (!strcmp(section, "languages")) {
query_type = XML_LDAP_LANGUAGE;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n");
return NULL;
......@@ -269,6 +272,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c
case XML_LDAP_DIALPLAN:
case XML_LDAP_PHRASE:
case XML_LDAP_LANGUAGE:
break;
}
}
......@@ -326,6 +330,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c
break;
case XML_LDAP_PHRASE:
case XML_LDAP_LANGUAGE:
break;
}
} else {
......
......@@ -29,6 +29,7 @@
* Matt Klein <mklein@nmedia.net>
* Michael Jerris <mike@jerris.com>
* Ken Rice <krice at suspicious dot org>
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
* switch_ivr.c -- IVR Library
*
......@@ -2327,9 +2328,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
switch_say_interface_t *si;
switch_channel_t *channel;
switch_status_t status = SWITCH_STATUS_FALSE;
const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *lname = NULL, *sound_path = NULL;
const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
switch_event_t *hint_data;
switch_xml_t cfg, xml = NULL, language, macros;
switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
char *p;
switch_assert(session);
......@@ -2341,6 +2342,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
}
if (module_name) {
char *p;
p = switch_core_session_strdup(session, module_name);
module_name = p;
......@@ -2371,58 +2373,35 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
switch_channel_event_set_data(channel, hint_data);
if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
goto done;
}
if (!(macros = switch_xml_child(cfg, "macros"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
goto done;
if ((p = (char *) switch_xml_attr(language, "say-module"))) {
module_name = switch_core_session_strdup(session, p);
} else if ((p = (char *) switch_xml_attr(language, "module"))) {
module_name = switch_core_session_strdup(session, p);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
} else {
module_name = chan_lang;
}
if (!(language = switch_xml_child(macros, "language"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
goto done;
if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
}
}
while (language) {
if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
const char *tmp;
if ((tmp = switch_xml_attr(language, "module"))) {
module_name = tmp;
if (channel) {
const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
if (!switch_true(p)) {
save_path = switch_channel_get_variable(channel, "sound_prefix");
if (sound_path) {
switch_channel_set_variable(channel, "sound_prefix", sound_path);
}
break;
}
language = language->next;
}
if (!language) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
goto done;
}
if (!module_name) {
module_name = chan_lang;
}
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
}
save_path = switch_channel_get_variable(channel, "sound_prefix");
if (sound_path) {
switch_channel_set_variable(channel, "sound_prefix", sound_path);
p = switch_core_session_strdup(session, sound_path);
sound_path = p;
}
if (xml) {
switch_xml_free(xml);
}
if ((si = switch_loadable_module_get_say_interface(module_name))) {
/* should go back and proto all the say mods to const.... */
switch_say_args_t say_args = {0};
......@@ -2446,7 +2425,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session,
if (save_path) {
switch_channel_set_variable(channel, "sound_prefix", save_path);
}
if (xml) {
switch_xml_free(xml);
}
return status;
}
......@@ -2463,9 +2446,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses
switch_say_interface_t *si;
switch_channel_t *channel = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
const char *save_path = NULL, *chan_lang = NULL, *lname = NULL, *sound_path = NULL;
const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
switch_event_t *hint_data;
switch_xml_t cfg, xml = NULL, language, macros;
switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
if (session) {
channel = switch_core_session_get_channel(session);
......@@ -2498,52 +2481,31 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses
switch_channel_event_set_data(channel, hint_data);
}
if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
goto done;
}
if (!(macros = switch_xml_child(cfg, "macros"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
goto done;
}
if (!(language = switch_xml_child(macros, "language"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
goto done;
}
while (language) {
if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
const char *tmp;
if ((tmp = switch_xml_attr(language, "module"))) {
module_name = tmp;
}
break;
}
language = language->next;
}
if (!language) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
goto done;
}
if (!module_name) {
if ((module_name = switch_xml_attr(language, "say-module"))) {
} else if ((module_name = switch_xml_attr(language, "module"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
} else {
module_name = chan_lang;
}
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
}
}
if (channel) {
save_path = switch_channel_get_variable(channel, "sound_prefix");
}
if (sound_path && channel) {
switch_channel_set_variable(channel, "sound_prefix", sound_path);
const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
if (!switch_true(p)) {
save_path = switch_channel_get_variable(channel, "sound_prefix");
if (sound_path) {
switch_channel_set_variable(channel, "sound_prefix", sound_path);
}
}
}
if ((si = switch_loadable_module_get_say_interface(module_name))) {
......
......@@ -28,6 +28,7 @@
* Neal Horman <neal at wanlink dot com>
* Matt Klein <mklein@nmedia.net>
* Michael Jerris <mike@jerris.com>
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
* switch_ivr_play_say.c -- IVR Library (functions to play or say audio)
*
......@@ -39,8 +40,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
switch_input_args_t *args)
{
switch_event_t *hint_data;
switch_xml_t cfg, xml = NULL, language, macros, macro, input, action;
char *lname = NULL, *mname = NULL;
switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action;
switch_status_t status = SWITCH_STATUS_GENERR;
const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
const char *module_name = NULL, *chan_lang = NULL;
......@@ -49,6 +49,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
int matches = 0;
const char *pause_val;
int pause = 100;
const char *group_macro_name = NULL;
const char *local_macro_name = macro_name;
switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
if (!macro_name) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
......@@ -65,8 +69,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
chan_lang = lang;
}
module_name = chan_lang;
switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(hint_data);
......@@ -82,40 +84,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
}
switch_channel_event_set_data(channel, hint_data);
if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
goto done;
}
if (!(macros = switch_xml_child(cfg, "macros"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
goto done;
}
if (!(language = switch_xml_child(macros, "language"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
goto done;
if ((module_name = switch_xml_attr(language, "say-module"))) {
} else if ((module_name = switch_xml_attr(language, "module"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n");
} else {
module_name = chan_lang;
}
while (language) {
if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
const char *tmp;
if ((tmp = switch_xml_attr(language, "module"))) {
module_name = tmp;
}
break;
if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
}
language = language->next;
}
if (!language) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
goto done;
}
if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
sound_path = (char *) switch_xml_attr(language, "sound_path");
}
if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) {
......@@ -126,31 +109,48 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
tts_voice = (char *) switch_xml_attr(language, "tts_voice");
}
if (sound_path) {
/* If we use the new structure, check for a group name */
if (language != macros) {
char *p;
old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
p = switch_core_session_strdup(session, old_sound_prefix);
old_sound_prefix = p;
switch_channel_set_variable(channel, "sound_prefix", sound_path);
}
char *macro_name_dup = switch_core_session_strdup(session, macro_name);
const char *group_sound_path;
const char *sound_prefix_enforced_str;
if (!(macro = switch_xml_child(language, "macro"))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any macro tags.\n");
goto done;
}
if ((p = strchr(macro_name_dup, '@'))) {
*p++ = '\0';
local_macro_name = macro_name_dup;
group_macro_name = p;
while (macro) {
if ((mname = (char *) switch_xml_attr(macro, "name")) && !strcasecmp(mname, macro_name)) {
break;
if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name);
goto done;
}
}
macro = macro->next;
/* Support override of certain language attribute */
if ((group_sound_path = (char *) switch_xml_attr(macros, "sound-prefix")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound-path")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound_path"))) {
sound_path = group_sound_path;
}
if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced"))
&& (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) {
switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str);
}
}
if (!macro) {
if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
goto done;
}
if (sound_path && sound_prefix_enforced == SWITCH_FALSE) {
char *p;
old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
p = switch_core_session_strdup(session, old_sound_prefix);
old_sound_prefix = p;
switch_channel_set_variable(channel, "sound_prefix", sound_path);
}
if ((pause_val = switch_xml_attr(macro, "pause"))) {
int tmp = atoi(pause_val);
if (tmp >= 0) {
......@@ -342,6 +342,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
if (old_sound_prefix) {
switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
}
if (local_sound_prefix_enforced == SWITCH_TRUE) {
switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
}
if (xml) {
switch_xml_free(xml);
}
......
......@@ -25,7 +25,7 @@
*
* Anthony Minessale II <anthm@freeswitch.org>
* Simon Capper <skyjunky@sbcglobal.net>
*
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
* switch_xml.c -- XML PARSER
*
......@@ -2785,6 +2785,62 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) {
return time_match;
}
SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language) {
switch_status_t status = SWITCH_STATUS_FALSE;
if (switch_xml_locate("languages", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
switch_xml_t sub_macros;
if (switch_xml_locate("phrases", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of languages and phrases failed.\n");
goto done;
}
if (!(sub_macros = switch_xml_child(*node, "macros"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
switch_xml_free(*root);
*root = NULL;
*node = NULL;
goto done;
}
if (!(*language = switch_xml_find_child(sub_macros, "language", "name", str_language))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
switch_xml_free(*root);
*root = NULL;
*node = NULL;
goto done;
}
*macros = *language;
} else {
if (!(*language = switch_xml_find_child(*node, "language", "name", str_language))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
switch_xml_free(*root);
*root = NULL;
goto done;
}
if (!(*phrases = switch_xml_child(*language, "phrases"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find phrases tag.\n");
switch_xml_free(*root);
*root = NULL;
*node = NULL;
*language = NULL;
goto done;
}
if (!(*macros = switch_xml_child(*phrases, "macros"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
switch_xml_free(*root);
*root = NULL;
*node = NULL;
*language = NULL;
*phrases = NULL;
goto done;
}
}
status = SWITCH_STATUS_SUCCESS;
done:
return status;
}
#ifdef WIN32
/*
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论