Newer
Older
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
return res;
}
/*
* A list of the files that you need to create
-> digits/xilia = "xilia"
-> digits/myrio = "ekatomyrio"
-> digits/thousands = "xiliades"
-> digits/millions = "ektatomyria"
-> digits/[1..12] :: A pronunciation of th digits form 1 to 12 e.g. "tria"
-> digits/[10..100] :: A pronunciation of the tens from 10 to 90
e,g 80 = "ogdonta"
Here we must note that we use digits/tens/100 to utter "ekato"
and digits/hundred-100 to utter "ekaton"
-> digits/hundred-[100...1000] :: A pronunciation of hundreds from 100 to 1000 e.g 400 =
"terakosia". Here again we use hundreds/1000 for "xilia"
and digits/thousnds for "xiliades"
*/
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language,int audiofd, int ctrlfd)
{
int res = 0;
char fn[256] = "";
int i=0;
if (!num) {
snprintf(fn, sizeof(fn), "digits/0");
res = ast_streamfile(chan, fn, chan->language);
if (!res)
return ast_waitstream(chan, ints);
}
while(!res && num ) {
i++;
if (num < 13) {
snprintf(fn, sizeof(fn), "digits/%d", num);
num = 0;
} else if (num <= 100) {
/* 13 < num <= 100 */
snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
num -= ((num / 10) * 10);
} else if (num < 200) {
/* 100 < num < 200 */
snprintf(fn, sizeof(fn), "digits/hundred-100");
num -= ((num / 100) * 100);
}else if (num < 1000) {
/* 200 < num < 1000 */
snprintf(fn, sizeof(fn), "digits/hundred-%d", (num/100)*100);
num -= ((num / 100) * 100);
}else if (num < 2000){
snprintf(fn, sizeof(fn), "digits/xilia");
num -= ((num / 1000) * 1000);
}
else {
/* num > 1000 */
if (num < 1000000) {
res = ast_say_number_full_gr(chan, (num / 1000), ints, chan->language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousands");
} else {
if (num < 1000000000) { /* 1,000,000,000 */
res = ast_say_number_full_gr(chan, (num / 1000000), ints, chan->language ,audiofd, ctrlfd);
if (res)
return res;
num = num % 1000000;
snprintf(fn, sizeof(fn), "digits/millions");
} else {
ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
res = -1;
}
}
}
if (!res) {
if(!ast_streamfile(chan, fn, language)) {
if ((audiofd > -1) && (ctrlfd > -1))
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
}
}
return res;
}
/*
* The format is weekday - day - month -year
*
* A list of the files that you need to create
* digits/day-[1..7] : "Deytera .. Paraskeyh"
* digits/months/1..12 : "Ianouariou .. Dekembriou"
Attention the months are in
"gekinh klhsh"
*/
static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
struct tm tm;
char fn[256];
int res = 0;
ast_localtime(&t,&tm,NULL);
/* W E E K - D A Y */
if (!res) {
snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
/* D A Y */
if (!res) {
gr_say_number_female(tm.tm_mday, chan, ints, lang);
}
/* M O N T H */
if (!res) {
snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
/* Y E A R */
if (!res)
res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
return res;
}
/* A list of the files that you need to create
* digits/female/1..4 : "Mia, dyo , treis, tesseris "
* digits/kai : "KAI"
* didgits : "h wra"
* digits/p-m : "meta meshmbrias"
* digits/a-m : "pro meshmbrias"
*/
static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
struct tm tm;
int res = 0;
int hour, pm=0;
localtime_r(&t,&tm);
hour = tm.tm_hour;
if (!hour)
hour = 12;
else if (hour == 12)
pm = 1;
else if (hour > 12) {
hour -= 12;
pm = 1;
}
res = gr_say_number_female(hour, chan, ints, lang);
if (tm.tm_min) {
if (!res)
res = ast_streamfile(chan, "digits/kai", lang);
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else {
if (!res)
res = ast_streamfile(chan, "digits/hwra", lang);
if (!res)
res = ast_waitstream(chan, ints);
}
if (pm) {
if (!res)
res = ast_streamfile(chan, "digits/p-m", lang);
} else {
if (!res)
res = ast_streamfile(chan, "digits/a-m", lang);
}
if (!res)
res = ast_waitstream(chan, ints);
return res;
}
static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
struct tm tm;
char fn[256];
int res = 0;
localtime_r(&t,&tm);
/* W E E K - D A Y */
if (!res) {
snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
/* D A Y */
if (!res) {
gr_say_number_female(tm.tm_mday, chan, ints, lang);
}
/* M O N T H */
if (!res) {
snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
res = ast_say_time_gr(chan, t, ints, lang);
return res;
}
static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
{
struct tm tm;
int res=0, offset, sndoffset;
char sndfile[256], nextmsg[256];
Tilghman Lesher
committed
if (!format)
format = "AdBY 'digits/at' IMp";
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
ast_localtime(&time,&tm,timezone);
for (offset=0 ; format[offset] != '\0' ; offset++) {
ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
switch (format[offset]) {
/* NOTE: if you add more options here, please try to be consistent with strftime(3) */
case '\'':
/* Literal name of a sound file */
sndoffset=0;
for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
sndfile[sndoffset] = format[offset];
sndfile[sndoffset] = '\0';
res = wait_file(chan,ints,sndfile,lang);
break;
case 'A':
case 'a':
/* Sunday - Saturday */
snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
res = wait_file(chan,ints,nextmsg,lang);
break;
case 'B':
case 'b':
case 'h':
/* January - December */
snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
res = wait_file(chan,ints,nextmsg,lang);
break;
case 'd':
case 'e':
/* first - thirtyfirst */
gr_say_number_female(tm.tm_mday, chan, ints, lang);
break;
case 'Y':
/* Year */
ast_say_number_full_gr(chan, 1900+tm.tm_year, ints, chan->language, -1, -1);
break;
case 'I':
case 'l':
/* 12-Hour */
if (tm.tm_hour == 0)
gr_say_number_female(12, chan, ints, lang);
else if (tm.tm_hour > 12)
gr_say_number_female(tm.tm_hour - 12, chan, ints, lang);
else
gr_say_number_female(tm.tm_hour, chan, ints, lang);
break;
case 'H':
case 'k':
/* 24-Hour */
gr_say_number_female(tm.tm_hour, chan, ints, lang);
break;
case 'M':
/* Minute */
if (tm.tm_min) {
if (!res)
res = ast_streamfile(chan, "digits/kai", lang);
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
res = ast_say_number_full_gr(chan, tm.tm_min, ints, lang, -1, -1);
} else {
if (!res)
res = ast_streamfile(chan, "digits/oclock", lang);
if (!res)
res = ast_waitstream(chan, ints);
}
break;
case 'P':
case 'p':
/* AM/PM */
if (tm.tm_hour > 11)
snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
else
snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
res = wait_file(chan,ints,nextmsg,lang);
break;
case 'Q':
/* Shorthand for "Today", "Yesterday", or ABdY */
Tilghman Lesher
committed
/* XXX As emphasized elsewhere, this should the native way in your
* language to say the date, with changes in what you say, depending
* upon how recent the date is. XXX */
{
struct timeval now;
struct tm tmnow;
Kevin P. Fleming
committed
time_t beg_today, tt;
Kevin P. Fleming
committed
tt = now.tv_sec;
ast_localtime(&tt,&tmnow,timezone);
/* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
/* In any case, it saves not having to do ast_mktime() */
Kevin P. Fleming
committed
beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
if (beg_today < time) {
/* Today */
res = wait_file(chan,ints, "digits/today",lang);
} else if (beg_today - 86400 < time) {
/* Yesterday */
res = wait_file(chan,ints, "digits/yesterday",lang);
} else {
Tilghman Lesher
committed
res = ast_say_date_with_format_gr(chan, time, ints, lang, "AdBY", timezone);
}
}
break;
case 'q':
/* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
Tilghman Lesher
committed
/* XXX As emphasized elsewhere, this should the native way in your
* language to say the date, with changes in what you say, depending
* upon how recent the date is. XXX */
{
struct timeval now;
struct tm tmnow;
Kevin P. Fleming
committed
time_t beg_today, tt;
Kevin P. Fleming
committed
tt = now.tv_sec;
ast_localtime(&tt,&tmnow,timezone);
/* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
/* In any case, it saves not having to do ast_mktime() */
Kevin P. Fleming
committed
beg_today = tt - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
if (beg_today < time) {
/* Today */
} else if ((beg_today - 86400) < time) {
/* Yesterday */
res = wait_file(chan,ints, "digits/yesterday",lang);
} else if (beg_today - 86400 * 6 < time) {
/* Within the last week */
Tilghman Lesher
committed
res = ast_say_date_with_format_gr(chan, time, ints, lang, "A", timezone);
Tilghman Lesher
committed
res = ast_say_date_with_format_gr(chan, time, ints, lang, "AdBY", timezone);
}
}
break;
case 'R':
Tilghman Lesher
committed
res = ast_say_date_with_format_gr(chan, time, ints, lang, "HM", timezone);
break;
case 'S':
/* Seconds */
snprintf(nextmsg,sizeof(nextmsg), "digits/kai");
res = wait_file(chan,ints,nextmsg,lang);
if (!res)
res = ast_say_number_full_gr(chan, tm.tm_sec, ints, lang, -1, -1);
if (!res)
snprintf(nextmsg,sizeof(nextmsg), "digits/seconds");
res = wait_file(chan,ints,nextmsg,lang);
break;
case 'T':
Tilghman Lesher
committed
res = ast_say_date_with_format_gr(chan, time, ints, lang, "HMS", timezone);
break;
case ' ':
case ' ':
/* Just ignore spaces and tabs */
break;
default:
/* Unknown character */
ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
}
/* Jump out on DTMF */
if (res) {
break;
}
}
return res;
}
/*
* remap the 'say' functions to use those in this file
*/
static void __attribute__((constructor)) __say_init(void)
{
ast_say_number_full = say_number_full;
ast_say_enumeration_full = say_enumeration_full;
ast_say_digit_str_full = say_digit_str_full;
ast_say_character_str_full = say_character_str_full;
ast_say_phonetic_str_full = say_phonetic_str_full;
ast_say_datetime = say_datetime;
ast_say_time = say_time;
ast_say_date = say_date;
ast_say_datetime_from_now = say_datetime_from_now;
ast_say_date_with_format = say_date_with_format;
}