Review Board 1.7.16


Add aliases for Directory

Review Request #2244 - Created Dec. 12, 2012 and submitted

Tilghman Lesher
Reviewers
asterisk-dev
Asterisk
This patch adds extra strings for comparison in the Directory application.  The purpose of this is to enable nicknames that otherwise would not be compared.  For example, Bob "Bongo Boy" Berman might have an alias of "Bongo", for which he would be searchable, even though his name would not normally include it.
Deployed and working on a production machine.

Diff revision 3 (Latest)

1 2 3
1 2 3

  1. /trunk/apps/app_directory.c: Loading...
  2. /trunk/configs/voicemail.conf.sample: Loading...
  3. /trunk/contrib/realtime/mysql/voicemail.sql: Loading...
/trunk/apps/app_directory.c
Revision 377511 New Change
[20] 84 lines
[+20] [+] ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
85
						<para> Allow the caller to enter either the first or the last name
85
						<para> Allow the caller to enter either the first or the last name
86
						of a user in the directory.  If specified, the optional number
86
						of a user in the directory.  If specified, the optional number
87
						argument will be used for the number of characters the user should enter.</para>
87
						argument will be used for the number of characters the user should enter.</para>
88
						<argument name="n" required="true" />
88
						<argument name="n" required="true" />
89
					</option>
89
					</option>

    
   
90
					<option name="a">

    
   
91
						<para>Allow the caller to additionally enter an alias for a user in the

    
   
92
						directory.  This option must be specified in addition to the

    
   
93
						<literal>f</literal>, <literal>l</literal>, or <literal>b</literal>

    
   
94
						option.</para>

    
   
95
					</option>
90
					<option name="m">
96
					<option name="m">
91
						<para>Instead of reading each name sequentially and asking for
97
						<para>Instead of reading each name sequentially and asking for
92
						confirmation, create a menu of up to 8 names.</para>
98
						confirmation, create a menu of up to 8 names.</para>
93
					</option>
99
					</option>
94
					<option name="n">
100
					<option name="n">
[+20] [20] 38 lines
[+20] [+] enum {
133
	OPT_SELECTFROMMENU =  (1 << 3),
139
	OPT_SELECTFROMMENU =  (1 << 3),
134
	OPT_LISTBYLASTNAME =  (1 << 4),
140
	OPT_LISTBYLASTNAME =  (1 << 4),
135
	OPT_LISTBYEITHER =    OPT_LISTBYFIRSTNAME | OPT_LISTBYLASTNAME,
141
	OPT_LISTBYEITHER =    OPT_LISTBYFIRSTNAME | OPT_LISTBYLASTNAME,
136
	OPT_PAUSE =           (1 << 5),
142
	OPT_PAUSE =           (1 << 5),
137
	OPT_NOANSWER =        (1 << 6),
143
	OPT_NOANSWER =        (1 << 6),

    
   
144
	OPT_ALIAS =           (1 << 7),
138
};
145
};
139

    
   
146

   
140
enum {
147
enum {
141
	OPT_ARG_FIRSTNAME =   0,
148
	OPT_ARG_FIRSTNAME =   0,
142
	OPT_ARG_LASTNAME =    1,
149
	OPT_ARG_LASTNAME =    1,
[+20] [20] 19 lines
[+20] [+] AST_APP_OPTIONS(directory_app_options, {
162
	AST_APP_OPTION_ARG('p', OPT_PAUSE, OPT_ARG_PAUSE),
169
	AST_APP_OPTION_ARG('p', OPT_PAUSE, OPT_ARG_PAUSE),
163
	AST_APP_OPTION('e', OPT_SAYEXTENSION),
170
	AST_APP_OPTION('e', OPT_SAYEXTENSION),
164
	AST_APP_OPTION('v', OPT_FROMVOICEMAIL),
171
	AST_APP_OPTION('v', OPT_FROMVOICEMAIL),
165
	AST_APP_OPTION('m', OPT_SELECTFROMMENU),
172
	AST_APP_OPTION('m', OPT_SELECTFROMMENU),
166
	AST_APP_OPTION('n', OPT_NOANSWER),
173
	AST_APP_OPTION('n', OPT_NOANSWER),

    
   
174
	AST_APP_OPTION('a', OPT_ALIAS),
167
});
175
});
168

    
   
176

   
169
static int compare(const char *text, const char *template)
177
static int compare(const char *text, const char *template)
170
{
178
{
171
	char digit;
179
	char digit;
[+20] [20] 253 lines
[+20] [+] static int select_item_menu(struct ast_channel *chan, struct directory_item **items, int count, const char *dialcontext, struct ast_flags *flags, char *opts[])
425

    
   
433

   
426
	/* Nothing was selected */
434
	/* Nothing was selected */
427
	return 0;
435
	return 0;
428
}
436
}
429

    
   
437

   

    
   
438
AST_THREADSTORAGE(commonbuf);

    
   
439

   
430
static struct ast_config *realtime_directory(char *context)
440
static struct ast_config *realtime_directory(char *context)
431
{
441
{
432
	struct ast_config *cfg;
442
	struct ast_config *cfg;
433
	struct ast_config *rtdata;
443
	struct ast_config *rtdata;
434
	struct ast_category *cat;
444
	struct ast_category *cat;
435
	struct ast_variable *var;
445
	struct ast_variable *var;
436
	char *mailbox;
446
	char *mailbox;
437
	const char *fullname;
447
	const char *fullname;
438
	const char *hidefromdir, *searchcontexts = NULL;
448
	const char *hidefromdir, *searchcontexts = NULL;
439
	char tmp[100];

   
440
	struct ast_flags config_flags = { 0 };
449
	struct ast_flags config_flags = { 0 };

    
   
450
	struct ast_str *tmp = ast_str_thread_get(&commonbuf, 100);

    
   
451

   

    
   
452
	if (!tmp) {

    
   
453
		return NULL;

    
   
454
	}
441

    
   
455

   
442
	/* Load flat file config. */
456
	/* Load flat file config. */
443
	cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
457
	cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
444

    
   
458

   
445
	if (!cfg) {
459
	if (!cfg) {
[+20] [20] 24 lines
[+20] static struct ast_config *realtime_directory(char *context)
470
		return cfg;
484
		return cfg;
471
	}
485
	}
472

    
   
486

   
473
	mailbox = NULL;
487
	mailbox = NULL;
474
	while ( (mailbox = ast_category_browse(rtdata, mailbox)) ) {
488
	while ( (mailbox = ast_category_browse(rtdata, mailbox)) ) {

    
   
489
		struct ast_variable *alias;
475
		const char *ctx = ast_variable_retrieve(rtdata, mailbox, "context");
490
		const char *ctx = ast_variable_retrieve(rtdata, mailbox, "context");
476

    
   
491

   
477
		fullname = ast_variable_retrieve(rtdata, mailbox, "fullname");
492
		fullname = ast_variable_retrieve(rtdata, mailbox, "fullname");
478
		hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir");
493
		hidefromdir = ast_variable_retrieve(rtdata, mailbox, "hidefromdir");
479
		if (ast_true(hidefromdir)) {
494
		if (ast_true(hidefromdir)) {
480
			/* Skip hidden */
495
			/* Skip hidden */
481
			continue;
496
			continue;
482
		}
497
		}
483
		snprintf(tmp, sizeof(tmp), "no-password,%s", S_OR(fullname, ""));
498
		ast_str_set(&tmp, 0, "no-password,%s", S_OR(fullname, ""));

    
   
499
		if (ast_variable_retrieve(rtdata, mailbox, "alias")) {

    
   
500
			for (alias = ast_variable_browse(rtdata, mailbox); alias; alias = alias->next) {

    
   
501
				if (!strcasecmp(alias->name, "alias")) {

    
   
502
					ast_str_append(&tmp, 0, "|alias=%s", alias->value);

    
   
503
				}

    
   
504
			}

    
   
505
		}
484

    
   
506

   
485
		/* Does the context exist within the config file? If not, make one */
507
		/* Does the context exist within the config file? If not, make one */
486
		if (!(cat = ast_category_get(cfg, ctx))) {
508
		if (!(cat = ast_category_get(cfg, ctx))) {
487
			if (!(cat = ast_category_new(ctx, "", 99999))) {
509
			if (!(cat = ast_category_new(ctx, "", 99999))) {
488
				ast_log(LOG_WARNING, "Out of memory\n");
510
				ast_log(LOG_WARNING, "Out of memory\n");
[+20] [20] 4 lines
[+20] static struct ast_config *realtime_directory(char *context)
493
				return NULL;
515
				return NULL;
494
			}
516
			}
495
			ast_category_append(cfg, cat);
517
			ast_category_append(cfg, cat);
496
		}
518
		}
497

    
   
519

   
498
		if ((var = ast_variable_new(mailbox, tmp, ""))) {
520
		if ((var = ast_variable_new(mailbox, ast_str_buffer(tmp), ""))) {
499
			ast_variable_append(cat, var);
521
			ast_variable_append(cat, var);
500
		} else {
522
		} else {
501
			ast_log(LOG_WARNING, "Out of memory adding mailbox '%s'\n", mailbox);
523
			ast_log(LOG_WARNING, "Out of memory adding mailbox '%s'\n", mailbox);
502
		}
524
		}
503
	}
525
	}
[+20] [20] 50 lines
[+20] [+] static int check_match(struct directory_item **result, const char *item_context, const char *item_fullname, const char *item_ext, const char *pattern_ext, int use_first_name)
554
typedef AST_LIST_HEAD_NOLOCK(, directory_item) itemlist;
576
typedef AST_LIST_HEAD_NOLOCK(, directory_item) itemlist;
555

    
   
577

   
556
static int search_directory_sub(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
578
static int search_directory_sub(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
557
{
579
{
558
	struct ast_variable *v;
580
	struct ast_variable *v;
559
	char buf[AST_MAX_EXTENSION + 1], *pos, *bufptr, *cat;
581
	struct ast_str *buf = ast_str_thread_get(&commonbuf, 100);

    
   
582
	char *pos, *bufptr, *cat, *alias;
560
	struct directory_item *item;
583
	struct directory_item *item;
561
	int res;
584
	int res;
562

    
   
585

   

    
   
586
	if (!buf) {

    
   
587
		return -1;

    
   
588
	}

    
   
589

   
563
	ast_debug(2, "Pattern: %s\n", ext);
590
	ast_debug(2, "Pattern: %s\n", ext);
564

    
   
591

   
565
	for (v = ast_variable_browse(vmcfg, context); v; v = v->next) {
592
	for (v = ast_variable_browse(vmcfg, context); v; v = v->next) {
566

    
   
593

   
567
		/* Ignore hidden */
594
		/* Ignore hidden */
568
		if (strcasestr(v->value, "hidefromdir=yes"))
595
		if (strcasestr(v->value, "hidefromdir=yes")) {
569
			continue;
596
			continue;

    
   
597
		}
570

    
   
598

   
571
		ast_copy_string(buf, v->value, sizeof(buf));
599
		ast_str_set(&buf, 0, "%s", v->value);
572
		bufptr = buf;
600
		bufptr = ast_str_buffer(buf);
573

    
   
601

   
574
		/* password,Full Name,email,pager,options */
602
		/* password,Full Name,email,pager,options */
575
		strsep(&bufptr, ",");
603
		strsep(&bufptr, ",");
576
		pos = strsep(&bufptr, ",");
604
		pos = strsep(&bufptr, ",");
577

    
   
605

   
[+20] [20] 7 lines
[+20] static int search_directory_sub(const char *context, struct ast_config *vmcfg, struct ast_config *ucfg, const char *ext, struct ast_flags flags, itemlist *alist)
585
			res = check_match(&item, context, pos, v->name, ext, 0 /* use_first_name */);
613
			res = check_match(&item, context, pos, v->name, ext, 0 /* use_first_name */);
586
		}
614
		}
587
		if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
615
		if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
588
			res = check_match(&item, context, pos, v->name, ext, 1 /* use_first_name */);
616
			res = check_match(&item, context, pos, v->name, ext, 1 /* use_first_name */);
589
		}
617
		}

    
   
618
		if (!res && ast_test_flag(&flags, OPT_ALIAS) && (alias = strcasestr(bufptr, "alias="))) {

    
   
619
			char *a;

    
   
620
			ast_debug(1, "Found alias: %s\n", alias);

    
   
621
			while ((a = strsep(&alias, "|"))) {

    
   
622
				if (!strncasecmp(a, "alias=", 6)) {

    
   
623
					if ((res = check_match(&item, context, a + 6, v->name, ext, 1))) {

    
   
624
						break;

    
   
625
					}

    
   
626
				}

    
   
627
			}

    
   
628
		}
590

    
   
629

   
591
		if (!res)
630
		if (!res) {
592
			continue;
631
			continue;
593
		else if (res < 0)
632
		} else if (res < 0) {
594
			return -1;
633
			return -1;

    
   
634
		}
595

    
   
635

   
596
		AST_LIST_INSERT_TAIL(alist, item, entry);
636
		AST_LIST_INSERT_TAIL(alist, item, entry);
597
	}
637
	}
598

    
   
638

   
599
	if (ucfg) {
639
	if (ucfg) {
600
		for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
640
		for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
601
			const char *position;
641
			const char *position;
602
			if (!strcasecmp(cat, "general"))
642

   

    
   
643
			if (!strcasecmp(cat, "general")) {
603
				continue;
644
				continue;
604
			if (!ast_true(ast_config_option(ucfg, cat, "hasdirectory")))
645
			}

    
   
646
			if (!ast_true(ast_config_option(ucfg, cat, "hasdirectory"))) {
605
				continue;
647
				continue;

    
   
648
			}
606

    
   
649

   
607
			/* Find all candidate extensions */
650
			/* Find all candidate extensions */
608
			position = ast_variable_retrieve(ucfg, cat, "fullname");
651
			if (!(position = ast_variable_retrieve(ucfg, cat, "fullname"))) {
609
			if (!position)

   
610
				continue;
652
				continue;

    
   
653
			}
611

    
   
654

   
612
			res = 0;
655
			res = 0;
613
			if (ast_test_flag(&flags, OPT_LISTBYLASTNAME)) {
656
			if (ast_test_flag(&flags, OPT_LISTBYLASTNAME)) {
614
				res = check_match(&item, context, position, cat, ext, 0 /* use_first_name */);
657
				res = check_match(&item, context, position, cat, ext, 0 /* use_first_name */);
615
			}
658
			}
616
			if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
659
			if (!res && ast_test_flag(&flags, OPT_LISTBYFIRSTNAME)) {
617
				res = check_match(&item, context, position, cat, ext, 1 /* use_first_name */);
660
				res = check_match(&item, context, position, cat, ext, 1 /* use_first_name */);
618
			}
661
			}

    
   
662
			if (!res && ast_test_flag(&flags, OPT_ALIAS)) {

    
   
663
				struct ast_variable *alias;

    
   
664
				for (alias = ast_variable_browse(ucfg, cat); alias; alias = alias->next) {

    
   
665
					if (!strcasecmp(v->name, "alias") && (res = check_match(&item, context, v->value, cat, ext, 1))) {

    
   
666
						break;

    
   
667
					}

    
   
668
				}

    
   
669
			}
619

    
   
670

   
620
			if (!res)
671
			if (!res) {
621
				continue;
672
				continue;
622
			else if (res < 0)
673
			} else if (res < 0) {
623
				return -1;
674
				return -1;

    
   
675
			}
624

    
   
676

   
625
			AST_LIST_INSERT_TAIL(alist, item, entry);
677
			AST_LIST_INSERT_TAIL(alist, item, entry);
626
		}
678
		}
627
	}
679
	}
628
	return 0;
680
	return 0;
[+20] [20] 265 lines
/trunk/configs/voicemail.conf.sample
Revision 377511 New Change
 
/trunk/contrib/realtime/mysql/voicemail.sql
Revision 377511 New Change
 
  1. /trunk/apps/app_directory.c: Loading...
  2. /trunk/configs/voicemail.conf.sample: Loading...
  3. /trunk/contrib/realtime/mysql/voicemail.sql: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.