4a900e321baed18c3a8a0bd3ee41ce840385fa4e
[apps/core/preloaded/email.git] / common / src / email-utils.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sys/time.h>
18 #include <glib.h>
19 #include <glib/gprintf.h>
20 #include <appcore-common.h>
21 #include <vconf.h>
22 #include <stdlib.h>
23 #include <regex.h>
24 #include <errno.h>
25 #include <drm_client.h>
26 #include <drm_client_types.h>
27 #include <pthread.h>
28 #include <media_content.h>
29
30 #include "email-utils.h"
31
32 static pthread_mutex_t icu_mutex = PTHREAD_MUTEX_INITIALIZER;
33 char *icu_locale = NULL;
34 static UDateTimePatternGenerator *icu_pattern_generator = NULL;
35 static UDateFormat *icu_formatter_hmm = NULL;
36 static UDateFormat *icu_formatter_Hmm = NULL;
37 static UDateFormat *icu_formatter_MMMyyyy = NULL;
38 static UDateFormat *icu_formatter_MMMd = NULL;
39 static UDateFormat *icu_formatter_EEEMMMd = NULL;
40 enum appcore_time_format icu_timeformat;
41
42
43 enum {
44         EMAIL_GROUP_UNKNOWN = -1,
45         EMAIL_GROUP_TODAY,
46         EMAIL_GROUP_YESTERDAY,
47         EMAIL_GROUP_SUN,
48         EMAIL_GROUP_MON,
49         EMAIL_GROUP_TUE,
50         EMAIL_GROUP_WED,
51         EMAIL_GROUP_THU,
52         EMAIL_GROUP_LASTWEEK,
53         EMAIL_GROUP_TWOWEEKS_AGO,
54         EMAIL_GROUP_THREEWEEKS_AGO,
55         EMAIL_GROUP_EARLIER_THISMONTH,
56         EMAIL_GROUP_LASTMONTH,
57         EMAIL_GROUP_OLDER,
58         EMAIL_GROUP_UNREAD,
59         EMAIL_GROUP_READ,
60         EMAIL_GROUP_FAVORITES,
61         EMAIL_GROUP_ATTACHMENTS,
62         EMAIL_GROUP_OTHER,
63         EMAIL_GROUP_PRIORITY_HIGH,
64         EMAIL_GROUP_PRIORITY_NORMAL,
65         EMAIL_GROUP_PRIORITY_LOW,
66         EMAIL_GROUP_MAX,
67 };
68
69
70 static gboolean _copy_actual_file(const char *src_full_path, const char *dest_full_path, gboolean(*copy_file_cb) (float percentage));
71 static void _generate_best_pattern(const char *locale, UChar * customSkeleton, char *formattedString, void *time);
72 static int _open_icu_pattern_n_formatter(const char *locale, char *skeleton, UDateFormat **formatter);
73 static int _close_icu_pattern_n_formatter(UDateFormat *formatter);
74
75 /*
76  * Function implementation
77  */
78 char *email_get_current_theme_name(void)
79 {
80         char *theme_name = NULL;
81         char *save_ptr = NULL;
82
83         /* Get current theme path. Return value is a full path of theme file. ex) blue-hd:default */
84         const char *current_theme_path = elm_theme_get(NULL);
85         debug_log("current_theme_path [%s]", current_theme_path);
86
87         if (current_theme_path == NULL) {
88                 debug_log("current_theme_path is NULL !!");
89                 return NULL;
90         }
91
92         theme_name = strdup(current_theme_path);
93         if (theme_name == NULL) {
94                 debug_log("theme_name is NULL !!");
95                 return NULL;
96         }
97
98         theme_name = strtok_r(theme_name, ":", &save_ptr);
99         if (theme_name == NULL) {
100                 debug_log("theme_name is NULL !!");
101                 return NULL;
102         }
103
104         debug_log("theme_name [%s]", theme_name);
105
106         return theme_name;
107 }
108
109 gboolean email_check_file_exist(const gchar *path)
110 {
111         debug_log("");
112         RETURN_VAL_IF_FAIL(STR_VALID(path), FALSE);
113
114         if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
115                 return FALSE;
116         }
117         return TRUE;
118 }
119
120 gboolean email_check_dir_exist(const gchar *path)
121 {
122         debug_log("");
123         RETURN_VAL_IF_FAIL(STR_VALID(path), FALSE);
124
125         if (!g_file_test(path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
126                 return FALSE;
127         }
128         return TRUE;
129 }
130
131 gchar *email_parse_get_filename_from_path(const gchar *path)
132 {
133         debug_log("");
134         RETURN_VAL_IF_FAIL(STR_VALID(path), NULL);
135
136         guint index = 0;
137
138         gchar *file_path = g_strdup(path);
139         file_path = g_strstrip(file_path);
140         gchar **token_list = g_strsplit_set(file_path, "/", -1);
141         g_free(file_path);      /* MUST BE. */
142
143         RETURN_VAL_IF_FAIL(token_list != NULL, NULL);
144
145         while (token_list[index] != NULL) {
146                 index++;
147         }
148
149         gchar *file_name = g_strdup(token_list[index - 1]);
150
151         g_strfreev(token_list); /* MUST BE. */
152
153         int len = 0;
154         if (file_name)
155                 len = strlen(file_name);
156
157         gchar *ext = g_strrstr(file_name, ".");
158         if (ext)
159                 len = len - strlen(ext);
160
161         gchar *file_name_without_ext = g_strndup(file_name, len);
162
163         g_free(file_name);      /* MUST BE. */
164
165         debug_log("file name (%s)", file_name_without_ext);
166
167         return file_name_without_ext;
168 }
169
170 void email_parse_get_filename_n_ext_from_path(const gchar *path, gchar **ret_file_name, gchar **ret_ext)
171 {
172         debug_log("");
173         RETURN_IF_FAIL(STR_VALID(path));
174
175         guint index = 0;
176
177         gchar *file_path = g_strdup(path);
178         file_path = g_strstrip(file_path);
179         gchar **token_list = g_strsplit_set(file_path, "/", -1);
180         g_free(file_path);      /* MUST BE. */
181
182         RETURN_IF_FAIL(token_list != NULL);
183
184         while (token_list[index] != NULL) {
185                 index++;
186         }
187
188         gchar *file_name = g_strdup(token_list[index - 1]);
189
190         g_strfreev(token_list); /* MUST BE. */
191
192         int len = 0;
193         if (file_name)
194                 len = strlen(file_name);
195
196         gchar *ext = g_strrstr(file_name, ".");
197         if (ext)
198                 len = len - strlen(ext);
199
200         *ret_file_name = g_strndup(file_name, len);
201
202         *ret_ext = g_strdup(ext);
203
204         g_free(file_name);
205 }
206
207 gchar *email_parse_get_filepath_from_path(const gchar *path)
208 {
209         debug_log("");
210         RETURN_VAL_IF_FAIL(STR_VALID(path), NULL);
211
212         gchar *file_path = NULL;
213         gint i = 0;
214         gint size = STR_LEN((gchar *)path);
215
216         for (i = (size - 1); i >= 0; --i) {
217                 if (path[i] == '/') {
218                         file_path = g_strndup(path, i + 1);
219                         break;
220                 }
221         }
222
223         debug_log("file path (%s)", file_path);
224
225         return file_path;
226 }
227
228 void email_save_file(const gchar *path, const gchar *buf, gsize len)
229 {
230         debug_log("");
231         if (STR_LEN((gchar *)buf) > 0 && len > 0) {
232                 int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
233                 if (fd != -1) {
234                         int size = write(fd, (const void *)buf, (size_t) len);
235                         debug_log("size:%d", size);
236                         close(fd);
237                 }
238         }
239 }
240
241 gchar *email_get_buff_from_file(const gchar *path, guint max_kbyte)
242 {
243         debug_log("");
244         RETURN_VAL_IF_FAIL(STR_VALID(path), NULL);
245
246         debug_log("path (%s)", path);
247
248         FILE *fp = fopen(path, "r");
249
250         if (fp) {
251
252                 char body[MAX_STR_LEN + 1] = { 0, };
253                 size_t size = 0;
254                 guint kbyte = 0;
255                 gchar *buff = NULL;
256                 gchar *temp = NULL;
257
258                 while (1) {
259
260                         memset(body, 0, sizeof(body));
261
262                         size = fread(body, sizeof(unsigned char), MAX_STR_LEN, fp);
263                         body[MAX_STR_LEN] = '\0';
264
265                         if (size <= 0 || STR_LEN(body) == 0)
266                                 break;
267
268                         if (max_kbyte > 0 && kbyte > max_kbyte)
269                                 break;
270
271                         if (STR_VALID(buff)) {
272                                 temp = g_strconcat(buff, body, NULL);
273                                 g_free(buff);
274                                 buff = temp;
275                                 temp = NULL;
276                         } else {
277                                 buff = g_strdup(body);
278                         }
279
280                         ++kbyte;
281                 }
282
283                 fclose(fp);
284
285                 /*
286                 debug_log("buff [%s]", buff);
287                 */
288
289                 return buff;
290         }
291
292         return NULL;
293 }
294
295 gchar *email_get_file_size_string(guint64 size)
296 {
297         debug_log("");
298         gchar str_buf[16] = "\0";
299
300         if (size < 1024) {
301                 g_sprintf(str_buf, "%d %s", (gint) size, dgettext("sys_string", "IDS_COM_BODY_B"));
302         } else {
303                 gdouble tmpsize = (gdouble) (size / 1024.);
304
305                 if (tmpsize < 1024) {
306                         g_sprintf(str_buf, "%.2f %s", tmpsize, dgettext("sys_string", "IDS_COM_BODY_KB"));
307                 } else {
308                         tmpsize /= 1024.;
309
310                         if (tmpsize < 1024) {
311                                 g_sprintf(str_buf, "%.2f %s", tmpsize, dgettext("sys_string", "IDS_COM_BODY_MB"));
312                         } else {
313                                 tmpsize /= 1024.;
314                                 g_sprintf(str_buf, "%.2f %s", tmpsize, dgettext("sys_string", "IDS_COM_BODY_GB"));
315                         }
316                 }
317         }
318         return STR_LEN(str_buf) > 0 ? g_strdup(str_buf) : NULL;
319 }
320
321 guint64 email_get_file_size(const gchar *path)
322 {
323         debug_log("");
324         guint64 size = 0;
325         struct stat st;
326         memset(&st, 0, sizeof(struct stat));
327
328         if (stat(path, &st) == 0) {
329                 if (S_ISREG(st.st_mode)) {
330                         size = (guint64) st.st_size;
331                         debug_log("size (%llu)", size);
332                 }
333         } else {
334                 size = 0;
335         }
336         return size;
337 }
338
339 #define EMAIL_ACCOUNT_RGEX              "([a-z0-9!#$%&'*+/=?^_`{|}~-]+[.])*[a-z0-9!#$%&'*+/=?^_`{|}~-]+"
340 #define EMAIL_DOMAIN_RGEX               "([a-z0-9!#$%&'*+/=?^_`{|}~-]+[.])+[a-z0-9!#$%&'*+/=?^_`{|}~-]+"
341 #define EMAIL_ADDR_RGEX         EMAIL_ACCOUNT_RGEX"@"EMAIL_DOMAIN_RGEX
342
343 gboolean email_get_address_validation(const char *address)
344 {
345         debug_log("");
346         /* this following code verfies the email alias string using reg. exp. */
347         regex_t alias_list_regex;
348         int ret = FALSE;
349
350         if (regcomp(&alias_list_regex, EMAIL_ADDR_RGEX, REG_ICASE | REG_EXTENDED)) {
351                 debug_log("email alias regex unrecognized");
352                 return FALSE;
353         }
354
355         int nsub = alias_list_regex.re_nsub + 1;        /* should be the number of parenthesized subexpressions (+1) */
356         regmatch_t pmatch[nsub];
357         memset(pmatch, 0, sizeof(regmatch_t) * nsub);
358
359         if (regexec(&alias_list_regex, address, nsub, pmatch, 0) == REG_NOMATCH)
360                 debug_log("failed : [%s]", address);
361         else {
362                 debug_log("success : [%s]", address);
363
364                 /*
365                  * remove sub-string match
366                  */
367                 if ((int)(pmatch[0].rm_eo - pmatch[0].rm_so) == strlen(address))
368                         ret = TRUE;
369         }
370
371         regfree(&alias_list_regex);
372
373         return ret;
374 }
375
376 gchar *email_cut_text_by_byte_len(const gchar *text, gint len)
377 {
378         debug_log("");
379         RETURN_VAL_IF_FAIL(STR_VALID(text), NULL);
380         RETURN_VAL_IF_FAIL(len > 0, NULL);
381
382         gint char_len2 = g_utf8_strlen(text, len);
383         gchar *offset = g_utf8_offset_to_pointer(text, char_len2);
384
385         gchar *ret_text = (gchar *)g_malloc0(offset - text + 1);
386
387         STR_NCPY(ret_text, (gchar *)text, offset - text);
388
389         return ret_text;
390 }
391
392 static int is_yesterday(struct tm *req_tm, struct tm *now_tm)
393 {
394         if (now_tm->tm_yday == 0) { /* It is the first day of year */
395                 if (req_tm->tm_year == now_tm->tm_year-1 && req_tm->tm_mon == 12 && req_tm->tm_mday == 31)
396                         return 1;
397                 else
398                         return 0;
399         } else {
400                 if (req_tm->tm_year == now_tm->tm_year && req_tm->tm_yday == now_tm->tm_yday - 1)
401                         return 1;
402                 else
403                         return 0;
404         }
405 }
406
407 static int is_today(struct tm *req_tm, struct tm *now_tm)
408 {
409         if (req_tm->tm_year == now_tm->tm_year && req_tm->tm_yday == now_tm->tm_yday)
410                 return 1;
411         else
412                 return 0;
413 }
414
415 static int is_nth_weeks_ago(struct tm *req_tm, struct tm *now_tm, int num)
416 {
417         time_t req = mktime(req_tm);
418         time_t now = mktime(now_tm);
419         time_t nth_begin = 0, nth_end = 0;
420         nth_end = now - (now_tm->tm_wday * 3600 * 24 + now_tm->tm_hour * 3600 + now_tm->tm_min * 60 + now_tm->tm_sec) - ((num - 1) * 7 * 3600 * 24);
421         nth_begin = now - (now_tm->tm_wday * 3600 * 24 + now_tm->tm_hour * 3600 + now_tm->tm_min * 60 + now_tm->tm_sec) - (num * 7 * 3600 * 24);
422
423         if(req > nth_begin && req < nth_end)
424                 return 1;
425         else
426                 return 0;
427 }
428
429 static int is_lastmonth(struct tm *req_tm, struct tm *now_tm)
430 {
431         if((req_tm->tm_year == now_tm->tm_year - 1) && (req_tm->tm_mon == 11) && (now_tm->tm_mon == 0))
432                 return 1;
433         else if((req_tm->tm_year == now_tm->tm_year) && (req_tm->tm_mon == now_tm->tm_mon - 1))
434                 return 1;
435         else
436                 return 0;
437 }
438
439 int email_get_group_title_str(const time_t req_time, gchar **group_title,
440                                                                                 gchar **group_date)
441 {
442         debug_log("");
443         RETURN_VAL_IF_FAIL(group_title != NULL, 0);
444         RETURN_VAL_IF_FAIL(group_date != NULL, 0);
445
446         int groupIndex = EMAIL_GROUP_UNKNOWN;
447         tzset();                /* MUST BE. */
448
449         time_t now_time = time(NULL);
450
451         struct tm *dummy = localtime(&now_time);
452         struct tm now_tm;
453         memcpy(&now_tm, dummy, sizeof(struct tm));
454
455         dummy = localtime(&req_time);
456         struct tm req_tm;
457         memcpy(&req_tm, dummy, sizeof(struct tm));
458
459         email_icu_mutex_lock();
460
461         if (is_today(&req_tm, &now_tm) || req_time > now_time /*future mail :)*/) {
462                 *group_title = g_strdup(dgettext("sys_string", "IDS_COM_BODY_TODAY"));
463                 *group_date = email_get_date_text_with_formatter(icu_formatter_EEEMMMd, (void *)&req_time);
464                 groupIndex = EMAIL_GROUP_TODAY;
465         }
466         else if (is_yesterday(&req_tm, &now_tm)) {
467                 *group_title = g_strdup(dgettext("sys_string", "IDS_COM_BODY_YESTERDAY"));
468                 *group_date = email_get_date_text_with_formatter(icu_formatter_EEEMMMd, (void *)&req_time);
469                 groupIndex = EMAIL_GROUP_YESTERDAY;
470         }
471         else if (is_nth_weeks_ago(&req_tm, &now_tm, 0)) {
472                 switch(req_tm.tm_wday)
473                 {
474                 case 0:
475                         *group_title = g_strdup(_("IDS_EMAIL_BODY_SUNDAY"));
476                         groupIndex = EMAIL_GROUP_SUN;
477                         break;
478                 case 1:
479                         *group_title = g_strdup(_("IDS_EMAIL_BODY_MONDAY"));
480                         groupIndex = EMAIL_GROUP_MON;
481                         break;
482                 case 2:
483                         *group_title = g_strdup(_("IDS_EMAIL_BODY_TUESDAY"));
484                         groupIndex = EMAIL_GROUP_TUE;
485                         break;
486                 case 3:
487                         *group_title = g_strdup(_("IDS_EMAIL_BODY_WEDNESDAY"));
488                         groupIndex = EMAIL_GROUP_WED;
489                         break;
490                 case 4:
491                         *group_title = g_strdup(_("IDS_EMAIL_BODY_THURSDAY"));
492                         groupIndex = EMAIL_GROUP_THU;
493                         break;
494                 case 5:
495                         *group_title = g_strdup(_("IDS_EMAIL_BODY_FRIDAY"));
496                         groupIndex = EMAIL_GROUP_THU;
497                         break;
498                 case 6:
499                         *group_title = g_strdup(_("IDS_EMAIL_BODY_SATURDAY"));
500                         groupIndex = EMAIL_GROUP_THU;
501                         break;
502                 default:
503                         debug_log("invalid date");
504                         break;
505                 }
506                 *group_date = email_get_date_text_with_formatter(icu_formatter_EEEMMMd, (void *)&req_time);
507         }
508         else if(is_nth_weeks_ago(&req_tm, &now_tm, 1)) {
509                 *group_title = g_strdup(_("IDS_EMAIL_BODY_LAST_WEEK"));
510                 groupIndex = EMAIL_GROUP_LASTWEEK;
511                 *group_date = NULL;
512         }
513         else if(is_nth_weeks_ago(&req_tm, &now_tm, 2)) {
514                 char str[MAX_STR_LEN] = { 0, };
515                 snprintf(str, sizeof(str), _("IDS_EMAIL_BODY_PD_WEEKS_AGO"), 2);
516                 *group_title = g_strdup(str);
517                 groupIndex = EMAIL_GROUP_TWOWEEKS_AGO;
518                 *group_date = NULL;
519         }
520         else if(is_nth_weeks_ago(&req_tm, &now_tm, 3)) {
521                 char str[MAX_STR_LEN] = { 0, };
522                 snprintf(str, sizeof(str), _("IDS_EMAIL_BODY_PD_WEEKS_AGO"), 3);
523                 *group_title = g_strdup(str);
524                 groupIndex = EMAIL_GROUP_THREEWEEKS_AGO;
525                 *group_date = NULL;
526         }
527         else if((req_tm.tm_year == now_tm.tm_year) && (req_tm.tm_mon == now_tm.tm_mon)) {
528                 *group_title = g_strdup(N_("Earlier this Month"));
529                 groupIndex = EMAIL_GROUP_EARLIER_THISMONTH;
530                 *group_date = NULL;
531         }
532         else if(is_lastmonth(&req_tm, &now_tm)) {
533                 *group_title = g_strdup(_("IDS_EMAIL_BODY_LAST_MONTH"));
534                 groupIndex = EMAIL_GROUP_LASTMONTH;
535                 *group_date = NULL;
536         }
537         else {
538                 *group_title = g_strdup(_("IDS_EMAIL_BODY_OLDER_M_HISTORY"));
539                 groupIndex = EMAIL_GROUP_OLDER;
540                 *group_date = NULL;
541         }
542         email_icu_mutex_unlock();
543         /*debug_log("-now : %d.%d (%d)", now_tm.tm_year + 1900, now_tm.tm_yday, now_time);
544         debug_log("-req : %d.%d (%d)", req_tm.tm_year + 1900, req_tm.tm_yday, req_time);
545         debug_log("(%s) (%s)", *group_title, *group_date);*/
546
547         return groupIndex;
548 }
549
550 char *email_get_str_datetime(const time_t req_time)
551 {
552         debug_log("");
553
554         tzset(); /* MUST BE. */
555
556         time_t now_time = time(NULL);
557
558         struct tm *dummy = localtime(&now_time);
559         struct tm now_tm;
560         memcpy(&now_tm, dummy, sizeof(struct tm));
561
562         dummy = localtime(&req_time);
563         struct tm req_tm;
564         memcpy(&req_tm, dummy, sizeof(struct tm));
565
566         /*debug_log("*now : %d.%d.%d", now_tm.tm_year + 1900, now_tm.tm_mon, now_tm.tm_mday);
567         debug_log("*req : %d.%d.%d", req_tm.tm_year + 1900, req_tm.tm_mon, req_tm.tm_mday);*/
568         email_icu_mutex_lock();
569
570         char *datetime = ({
571                         char *_ret_str = NULL;
572                         if (is_today(&req_tm, &now_tm) || is_yesterday(&req_tm, &now_tm) ||
573                                         req_time > now_time) /* sometimes, future mail arrives :) */ {
574                                 /* today or yesterday */
575                                 _ret_str = (icu_timeformat == APPCORE_TIME_FORMAT_12)?
576                                         email_get_date_text_with_formatter(icu_formatter_hmm, (void *)&req_time):
577                                         email_get_date_text_with_formatter(icu_formatter_Hmm, (void *)&req_time);
578                         } else if (req_tm.tm_year < now_tm.tm_year) /* previous year */
579                                 _ret_str = email_get_date_text_with_formatter(icu_formatter_MMMyyyy, (void *)&req_time);
580                         else /* days before yesterday in this year */
581                                 _ret_str = email_get_date_text_with_formatter(icu_formatter_MMMd, (void *)&req_time);
582                         _ret_str;
583                 });
584         email_icu_mutex_unlock();
585
586         return datetime;
587 }
588
589 char *email_get_date_text(const char *locale, char *skeleton, void *time)
590 {
591         debug_log("");
592         char formattedString[128] = { 0, };
593         UChar customSkeleton[64] = { 0, };
594         int skeletonLength = strlen(skeleton);
595
596         email_icu_mutex_lock();
597         u_uastrncpy(customSkeleton, skeleton, skeletonLength);
598         _generate_best_pattern(locale, customSkeleton, formattedString, time);
599         email_icu_mutex_unlock();
600         return g_strdup(formattedString);
601 }
602
603 char *email_get_date_text_with_formatter(UDateFormat *formatter, void *time)
604 {
605         debug_log("");
606         char formattedString[128] = { 0, };
607
608         UErrorCode status = U_ZERO_ERROR;
609         UDate date = 0;
610         UChar formatted[64] = { 0, };
611         int32_t formattedCapacity;
612         int32_t formattedLength;
613
614         formattedCapacity = (int32_t) (sizeof(formatted) / sizeof(formatted[0]));
615         if (time) {
616                 time_t msg_time = *(time_t *)time;
617                 date = (UDate)msg_time * 1000;  /* Equivalent to Date = ucal_getNow() in Milliseconds */
618         }
619         formattedLength = udat_format(formatter, date, formatted, formattedCapacity, NULL, &status);
620         u_austrncpy(formattedString, formatted, 128);
621         return g_strdup(formattedString);
622 }
623 void email_icu_mutex_init(void)
624 {
625         debug_log("");
626         pthread_mutex_init(&icu_mutex, NULL);
627
628 }
629 void email_icu_mutex_lock(void)
630 {
631         debug_log("");
632         pthread_mutex_lock(&icu_mutex);
633
634 }
635 void email_icu_mutex_unlock(void)
636 {
637         debug_log("");
638         pthread_mutex_unlock(&icu_mutex);
639
640 }
641 void email_icu_mutex_destroy(void)
642 {
643         debug_log("");
644         pthread_mutex_destroy(&icu_mutex);
645
646 }
647 int email_open_icu_pattern_generator(void)
648 {
649         debug_log("");
650         UErrorCode status = U_ZERO_ERROR;
651
652         uloc_setDefault(getenv("LC_TIME"), &status);
653         if (U_FAILURE(status)) {
654                 debug_critical("uloc_setDefault() failed: %s\n", u_errorName(status));
655                 return -1;
656         }
657
658         status = U_ZERO_ERROR;
659         icu_locale = (char *)uloc_getDefault();
660         debug_log("uloc_getDefault: %s", icu_locale);
661         appcore_get_timeformat(&icu_timeformat);
662         icu_pattern_generator = udatpg_open(icu_locale, &status);
663
664         if (!icu_pattern_generator) {
665                 debug_log("udatpg_open() failed: %s", u_errorName(status));
666                 return -1;
667         }
668
669         _open_icu_pattern_n_formatter(icu_locale, "hmm", &icu_formatter_hmm);
670         _open_icu_pattern_n_formatter(icu_locale, "Hmm", &icu_formatter_Hmm);
671         _open_icu_pattern_n_formatter(icu_locale, "MMMyyyy", &icu_formatter_MMMyyyy);
672         _open_icu_pattern_n_formatter(icu_locale, "MMMd", &icu_formatter_MMMd);
673         _open_icu_pattern_n_formatter(icu_locale, "EEEMMMd", &icu_formatter_EEEMMMd);
674
675         return 0;
676 }
677
678 int email_close_icu_pattern_generator(void)
679 {
680         debug_log("");
681
682         if (icu_pattern_generator) {
683                 udatpg_close(icu_pattern_generator);
684                 icu_pattern_generator = NULL;
685         }
686
687         _close_icu_pattern_n_formatter(icu_formatter_hmm);
688         _close_icu_pattern_n_formatter(icu_formatter_Hmm);
689         _close_icu_pattern_n_formatter(icu_formatter_MMMyyyy);
690         _close_icu_pattern_n_formatter(icu_formatter_MMMd);
691         _close_icu_pattern_n_formatter(icu_formatter_EEEMMMd);
692
693         return 0;
694 }
695
696 static int _open_icu_pattern_n_formatter(const char *locale, char *skeleton, UDateFormat **formatter)
697 {
698         debug_log("");
699         UErrorCode status = U_ZERO_ERROR;
700         UChar bestPattern[64] = { 0, };
701         UChar customSkeleton[64] = { 0, };
702         int32_t bestPatternCapacity;
703         int32_t bestPatternLength;
704         int skeletonLength = strlen(skeleton);
705
706         u_uastrncpy(customSkeleton, skeleton, skeletonLength);
707
708         bestPatternCapacity = (int32_t) (sizeof(bestPattern) / sizeof(bestPattern[0]));
709         bestPatternLength = udatpg_getBestPattern(icu_pattern_generator, customSkeleton, u_strlen(customSkeleton), bestPattern, bestPatternCapacity, &status);
710         *formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status);
711
712         return 0;
713 }
714
715 static int _close_icu_pattern_n_formatter(UDateFormat *formatter)
716 {
717         debug_log("");
718
719         udat_close(formatter);
720
721         return 0;
722 }
723
724 static void _generate_best_pattern(const char *locale, UChar * customSkeleton, char *formattedString, void *time)
725 {
726         debug_log("");
727         UErrorCode status = U_ZERO_ERROR;
728         UDateFormat *formatter;
729         UDate date = 0;
730         UChar bestPattern[64] = { 0, };
731         UChar formatted[64] = { 0, };
732         int32_t bestPatternCapacity, formattedCapacity;
733         int32_t bestPatternLength, formattedLength;
734
735         bestPatternCapacity = (int32_t) (sizeof(bestPattern) / sizeof(bestPattern[0]));
736         bestPatternLength = udatpg_getBestPattern(icu_pattern_generator, customSkeleton, u_strlen(customSkeleton), bestPattern, bestPatternCapacity, &status);
737
738         formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status);
739         formattedCapacity = (int32_t) (sizeof(formatted) / sizeof(formatted[0]));
740         if (time) {
741                 time_t msg_time = *(time_t *)time;
742                 date = (UDate)msg_time * 1000;  /* Equivalent to Date = ucal_getNow() in Milliseconds */
743         }
744         formattedLength = udat_format(formatter, date, formatted, formattedCapacity, NULL, &status);
745         u_austrncpy(formattedString, formatted, 128);
746         udat_close(formatter);
747 }
748
749 void _create_download_folder()
750 {
751         debug_log("");
752
753         if (!email_check_dir_exist(DIR_DEFAULT_MEDIA_PHONE"/Downloads")) {
754                 int nErr = -1;
755                 nErr = mkdir(DIR_DEFAULT_MEDIA_PHONE"/Downloads", 0755);
756                 debug_log("errno: %d", nErr);
757                 if (nErr == -1)
758                         debug_log("Downloads folder creation failed");
759         } else
760                 debug_log("Downloads folder already exists.");
761 }
762
763 int email_attachments_save_file(const gchar *path, gchar *newpath, gboolean(*copy_file_cb) (float percentage))
764 {
765         debug_log("");
766         RETURN_VAL_IF_FAIL(STR_VALID(path), EMAIL_EXT_SAVE_ERR_UNKNOWN);
767         int ret = 0;
768         gchar new_path[MAX_PATH_LEN] = { 0, };
769         gchar tmp_path[MAX_PATH_LEN] = { 0, };
770         gchar new_filename[MAX_PATH_LEN] = { 0, };
771         gchar prefix[MAX_PATH_LEN] = { 0, };
772         gboolean saved = FALSE;
773         gint err = 0;
774         gint max_length = MAX_PATH_LEN;
775
776         snprintf(prefix, sizeof(prefix), "%s", DIR_DEFAULT_MEDIA_PHONE"/Downloads");
777
778         debug_log("prefix:%s", prefix);
779
780         memset(new_path, 0, sizeof(MAX_PATH_LEN));
781         memset(tmp_path, 0, sizeof(MAX_PATH_LEN));
782
783         if (STR_LEN(tmp_path) == 0) {
784                 g_sprintf(tmp_path, "%s", path);
785         }
786
787         gchar *file_name = NULL;
788         gchar *file_ext = NULL;
789         gchar *file_path = email_parse_get_filepath_from_path(tmp_path);
790         email_parse_get_filename_n_ext_from_path(tmp_path, &file_name, &file_ext);
791
792         debug_log("file_name:%s", file_name);
793         debug_log("file_ext:%s", file_ext);
794
795         if (file_ext == NULL)
796                 file_ext = "";
797
798         if (file_name != NULL) {
799                 debug_log("");
800                 if (strlen(file_name) + strlen(file_ext) > max_length - STR_LEN(prefix)) {
801                         gint available_len = max_length - STR_LEN(prefix);
802
803                         if (strlen(file_ext) > 0) {
804                                 available_len -= strlen(file_ext);
805                         }
806
807                         gchar *new_name = email_cut_text_by_byte_len(file_name, available_len);
808
809                         if (STR_VALID(new_name)) {
810                                 g_sprintf(new_path, "%s/%s%s", prefix, new_name, file_ext);
811                                 g_sprintf(new_filename, "%s%s", new_name, file_ext);
812                                 g_free(new_name);       /* MUST BE. */
813                         }
814                 } else {
815                         g_sprintf(new_path, "%s/%s%s", prefix, file_name, file_ext);
816                 }
817         }
818
819         if (STR_VALID(file_path)) {
820                 g_free(file_path);      /* MUST BE. */
821         }
822
823         if (STR_VALID(file_name)) {
824                 g_free(file_name);      /* MUST BE. */
825         }
826
827         if (STR_VALID(file_ext)) {
828                 g_free(file_ext);       /* MUST BE. */
829         }
830
831         debug_log("new_path:%s", new_path);
832
833         /* Move for DRM file */
834
835         ret = media_content_connect();
836         if (!ret) {
837                 _create_download_folder();
838
839                 /* Copy for non-DRM */
840                 if (access(new_path, F_OK) != -1) {
841                         debug_log("file existed");
842                         err = EMAIL_EXT_SAVE_ERR_ALREADY_EXIST;
843                 } else {
844                         saved = _copy_actual_file(path, new_path, copy_file_cb);
845                         debug_log("saved(%d), err(%d), errno(%d)", saved, err, errno);
846
847                         if (saved)
848                                 err = EMAIL_EXT_SAVE_ERR_NONE;
849                         else
850                                 err = EMAIL_EXT_SAVE_ERR_UNKNOWN;
851                         ret = media_content_scan_file(new_path);
852                         debug_log("media_content_scan_file: %d", ret);
853                 }
854
855                 snprintf(newpath, MAX_PATH_LEN, "%s", new_path);
856                 ret = media_content_disconnect();
857                 if (ret) {
858                         debug_log("media_content_disconnect() is failed!");
859                 }
860         } else {
861                 debug_log("media_content_connect() is failed!");
862         }
863         return err;
864 }
865
866 static gboolean _copy_actual_file(const char *src_full_path, const char *dest_full_path, gboolean(*copy_file_cb) (float percentage))
867 {
868         debug_log("");
869         FILE *fs = NULL;
870         FILE *fd = NULL;
871         char buff[4096] = { 0, };
872         int n = 0;
873         gboolean result = FALSE;
874         gboolean stop_copying = FALSE;
875         int m = 0;
876         int cnt = 0;
877         struct stat statbuf = { 0 };
878         int ret = 0;
879         int total_size = 0;
880         int copied_size = 0;
881         gboolean remove_dest = FALSE;
882         clock_t begin;
883         clock_t finish;         /* consumed time to copy whole file */
884         double totaltime;
885         float percentage = 0.0;
886
887         fs = fopen(src_full_path, "rb");
888         if (fs == NULL) {
889                 int err = errno;
890                 debug_log("fopen error(%d)", err);
891                 return FALSE;
892         }
893
894         ret = fstat(fileno(fs), &statbuf);
895         if (ret != 0) {
896                 debug_log("fstat error");
897                 fclose(fs);
898                 return FALSE;
899         }
900
901         total_size = (int)statbuf.st_size;
902
903         fseek(fs, 0, SEEK_SET);
904
905         fd = fopen(dest_full_path, "wb");
906
907         remove_dest = TRUE;
908
909         if (fd == NULL) {
910                 int err = errno;
911                 debug_log("fopen error(%d)", err);
912                 fclose(fs);
913                 return FALSE;
914         }
915
916         fseek(fd, 0, SEEK_SET);
917
918         copied_size = 0;
919
920         begin = clock();
921
922         while (1) {
923                 result = feof(fs);
924                 if (!result) {
925                         n = fread(buff, sizeof(char), sizeof(buff), fs);
926                         if (n > 0) {
927                                 m = fwrite(buff, sizeof(char), n, fd);
928                                 if (m <= 0) {
929                                         debug_log("fwrite = %d", m);
930                                         result = FALSE;
931                                         goto CATCH;
932                                 }
933
934                                 cnt++;
935                                 copied_size += m;
936
937                                 if (cnt > 100) {
938                                         percentage = ((float)(total_size - copied_size) / (float)total_size) * 100.0;
939                                         if (copy_file_cb)
940                                                 stop_copying = copy_file_cb(percentage);
941
942                                         if (stop_copying) {
943                                                 result = FALSE;
944                                                 remove_dest = TRUE;
945                                                 goto CATCH;
946                                         }
947
948                                         cnt = 0;
949                                 }
950                         } else {
951                                 result = TRUE;
952                                 goto CATCH;
953                         }
954                 } else {
955                         result = TRUE;
956                         goto CATCH;
957                 }
958         }
959
960  CATCH:
961         fflush(fd);
962         fsync(fileno(fd));
963         fclose(fd);
964         fclose(fs);
965
966         if (remove_dest && result == FALSE) {
967                 if (-1 == remove(dest_full_path)) {
968                         debug_log("Failed to remove dest_full_path");
969                 }
970                 sync();
971         }
972
973         if (result) {
974                 finish = clock();
975                 totaltime = (double)(finish - begin) / CLOCKS_PER_SEC;
976                 debug_log("takes %f s to copy %s", totaltime, src_full_path);
977         }
978
979         return result;
980 }
981
982 gboolean email_drm_file_is_right(const gchar *path)
983 {
984         RETURN_VAL_IF_FAIL(STR_VALID(path), FALSE);
985
986         debug_log("");
987
988         drm_bool_type_e is_drm_file = FALSE;
989
990         if (drm_is_drm_file(path, &is_drm_file) != DRM_RETURN_SUCCESS) {
991                 debug_log("drm_is_drm_file is failed");
992                 return FALSE;
993         }
994
995         return is_drm_file;
996 }
997
998 gboolean email_drm_file_forward_lock_check(const gchar *path)
999 {
1000         RETURN_VAL_IF_FAIL(STR_VALID(path), FALSE);
1001         RETURN_VAL_IF_FAIL(email_drm_file_is_right(path), FALSE);
1002
1003         debug_log("");
1004
1005         drm_file_info_s drm_info;
1006
1007         if (drm_get_file_info(path, &drm_info)) {
1008                 debug_log("drm_info.oma_info.method (%d)", drm_info.oma_info.method);
1009                 if (drm_info.oma_info.method == DRM_METHOD_TYPE_FORWARD_LOCK || drm_info.oma_info.method == DRM_METHOD_TYPE_COMBINED_DELIVERY) {
1010                         debug_log("Forward Lock");
1011                         return TRUE;
1012                 }
1013         }
1014
1015         return FALSE;
1016 }
1017
1018
1019 static int termination_flag = 0;
1020 static int pause_flag = 0;
1021
1022 void set_app_terminated()
1023 {
1024         termination_flag = 1;
1025 }
1026
1027 int get_app_terminated()
1028 {
1029         return termination_flag;
1030 }
1031
1032 void set_app_paused()
1033 {
1034         pause_flag = 1;
1035 }
1036
1037 void reset_app_paused()
1038 {
1039         pause_flag = 0;
1040 }
1041
1042 int get_app_paused()
1043 {
1044         return pause_flag;
1045 }
1046
1047 char* email_util_strrtrim(char* s)
1048 {
1049         char *end;
1050
1051         end = s + strlen(s) - 1;
1052         while (end != s && isspace(*end))
1053         {
1054                 end--;
1055         }
1056         *(end + 1) = '\0';
1057
1058         debug_log("result [%s]", s);
1059         return s;
1060 }
1061
1062 char* email_util_strltrim(char* s)
1063 {
1064         char* begin;
1065         begin = s;
1066
1067         while (*begin != '\0') {
1068                 if (isspace(*begin))
1069                         begin++;
1070                 else {
1071                         s = begin;
1072                         break;
1073                 }
1074         }
1075
1076         debug_log("result [%s]", s);
1077         return s;
1078 }
1079
1080 char* email_util_get_parent_folder(char *s)
1081 {
1082         gchar **vector = NULL;
1083         vector = g_strsplit_set(s, "/", -1);
1084         int vlen = g_strv_length(vector);
1085         gchar *foler_name = g_strdup(vector[vlen-1]);
1086         gchar* retval = g_strdup(s);
1087         gchar* ptr = NULL;
1088         ptr = g_strstr_len(retval, -1, foler_name);
1089
1090         debug_log("input [%s], vlen(%d)", s, vlen);
1091
1092         if (ptr != NULL && vlen > 1){
1093                 gchar* temp = g_strndup(retval, ptr-retval-1);
1094                 g_free(retval);
1095                 retval = g_strdup(temp);
1096                 g_free(temp);
1097
1098                 debug_log("foler_name [%s], retval[%s]", foler_name, retval);
1099
1100                 g_free(foler_name);
1101                 return retval;
1102         }
1103         else
1104         {
1105                 debug_log("foler_name [%s]: parent == root. ", foler_name);
1106                 g_free(foler_name);
1107                 return NULL;
1108         }
1109 }
1110
1111 int email_register_timezone_changed_callback(void *func, void *data)
1112 {
1113         debug_log("");
1114         if (vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, func, data) < 0) {
1115                 debug_log("vconf callback registration(VCONFKEY_SYSTEM_TIME_CHANGED) is failed");
1116                 return -1;
1117         }
1118
1119         return 0;
1120 }
1121
1122 int email_deregister_timezone_changed_callback(void *func)
1123 {
1124         debug_log("");
1125         if (vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, func) < 0) {
1126                 debug_log("vconf callback removal(VCONFKEY_SYSTEM_TIME_CHANGED) is failed");
1127                 return -1;
1128         }
1129         return 0;
1130 }
1131
1132 /* Contact service2 */
1133 int email_get_contacts_list(contacts_match_str_flag_e match, contacts_list_h *list, const char *search_word)
1134 {
1135         debug_log("");
1136
1137         int ct_ret = CONTACTS_ERROR_NONE;
1138
1139         contacts_query_h query = NULL;
1140         contacts_filter_h filter = NULL;
1141         debug_log("search_word = %s", search_word);
1142
1143         /* get number list first */
1144         ct_ret = contacts_query_create(_contacts_contact_email._uri, &query);
1145         ct_ret = contacts_filter_create(_contacts_contact_email._uri, &filter);
1146         ct_ret = contacts_filter_add_str(filter, _contacts_contact_email.email, match, search_word);
1147         ct_ret = contacts_query_set_filter(query, filter);
1148
1149         ct_ret = contacts_db_get_records_with_query(query, 0, 0, list);
1150         ct_ret = contacts_filter_destroy(filter);
1151         ct_ret = contacts_query_destroy(query);
1152
1153         if (ct_ret != CONTACTS_ERROR_NONE) {
1154                 debug_log("contacts_db_get_records_with_query is failed error_code = %d", ct_ret);
1155         }
1156         return ct_ret;
1157 }
1158
1159 int email_get_contacts_index(contacts_record_h record, int *index)
1160 {
1161         debug_log("");
1162         int ct_ret = CONTACTS_ERROR_NONE;
1163         ct_ret = contacts_record_get_int(record, _contacts_contact_email.contact_id, index);
1164         return ct_ret;
1165 }
1166
1167 int email_get_contacts_display_name(contacts_record_h record, char *display_name)
1168 {
1169         debug_log("");
1170         int ct_ret = CONTACTS_ERROR_NONE;
1171         ct_ret = contacts_record_get_str_p(record, _contacts_contact_email.display_name, &display_name);
1172 //      contacts_list_item->display = g_strdup(display_name);
1173         return ct_ret;
1174 }
1175
1176 int email_get_contacts_email_address(contacts_record_h record, char *email_addr)
1177 {
1178         debug_log("");
1179         int ct_ret = CONTACTS_ERROR_NONE;
1180         ct_ret = contacts_record_get_str_p(record, _contacts_contact_email.email, &email_addr);
1181         return ct_ret;
1182 }
1183
1184 int email_get_contacts_image_thumbnail_path(contacts_record_h record, char *image_thumbnail_path)
1185 {
1186         debug_log("");
1187         int ct_ret = CONTACTS_ERROR_NONE;
1188         ct_ret = contacts_record_get_str_p(record, _contacts_contact_email.image_thumbnail_path, &image_thumbnail_path);
1189         return ct_ret;
1190 }
1191
1192 int email_get_contacts_first_name(contacts_record_h record, char *first_name)
1193 {
1194         debug_log("");
1195         int ct_ret = CONTACTS_ERROR_NONE;
1196         ct_ret = contacts_record_get_str_p(record, _contacts_name.first, &first_name);
1197         return ct_ret;
1198 }
1199
1200 int email_get_contacts_last_name(contacts_record_h record, char *last_name)
1201 {
1202         debug_log("");
1203         int ct_ret = CONTACTS_ERROR_NONE;
1204         ct_ret = contacts_record_get_str_p(record, _contacts_name.last, &last_name);
1205         return ct_ret;
1206 }
1207
1208 int email_get_contacts_list_info(contacts_list_h list, EMAIL_CONTACT_LIST_INFO_S *ct_list_info)
1209 {
1210         debug_log("");
1211         int index = 0;
1212         int ct_ret = CONTACTS_ERROR_NONE;
1213
1214         while (CONTACTS_ERROR_NONE == ct_ret) {
1215                 contacts_record_h ct_value = NULL;
1216                 contacts_list_get_current_record_p(list, &ct_value);
1217                 debug_log("ct_ret = %d", ct_ret);
1218                 debug_log("ct_value = %d", (ct_value == NULL));
1219                 if (ct_value) {
1220                         ct_ret = contacts_record_get_int(ct_value, _contacts_contact_email.contact_id, &index);
1221                         if (index > 0) {
1222                                 char *display_name = NULL;
1223                                 char *image_path = NULL;
1224                                 char *email_addr = NULL;
1225
1226                                 ct_list_info->index = index;
1227                                 if ((ct_ret = contacts_record_get_str_p(ct_value, _contacts_contact_email.display_name, &display_name)) == CONTACTS_ERROR_NONE) {
1228                                         if (display_name != NULL) {
1229                                                 ct_list_info->display = g_strdup(display_name);
1230                                         }
1231                                 } else {
1232                                         debug_log("email_get_contacts_display_name is failed error_code = %d", ct_ret);
1233                                 }
1234
1235                                 if ((ct_ret = contacts_record_get_str_p(ct_value, _contacts_contact_email.image_thumbnail_path, &image_path)) == CONTACTS_ERROR_NONE) {
1236                                         if (image_path != NULL) {
1237                                                 ct_list_info->image_path = g_strdup(image_path);
1238                                         }
1239                                 } else {
1240                                         debug_log("email_get_contacts_image_thumbnail_path is failed error_code = %d", ct_ret);
1241                                 }
1242
1243                                 if ((ct_ret = contacts_record_get_str_p(ct_value, _contacts_contact_email.email, &email_addr)) == CONTACTS_ERROR_NONE){
1244                                         if (email_addr != NULL) {
1245                                                 ct_list_info->email_address = g_strdup(email_addr);
1246                                         }
1247                                 } else {
1248                                         debug_log("email_get_contacts_email_address is failed error_code = %d", ct_ret);
1249                                 }
1250
1251                                 if (!ct_list_info->display && email_addr) {
1252                                         strncpy(ct_list_info->display_name, email_addr, sizeof(ct_list_info->display_name) - 1);
1253                                 } else {
1254                                         if (strlen(ct_list_info->display) > 0) {
1255                                                 snprintf(ct_list_info->display_name, sizeof(ct_list_info->display_name), "%s", ct_list_info->display);
1256                                         }
1257                                 }
1258
1259                                 debug_log("index(%d), display(%s), image_path(%s), email(%s), display_name(%s)",
1260                                         index, ct_list_info->display, ct_list_info->image_path, ct_list_info->email_address, ct_list_info->display_name);
1261
1262                                 return ct_ret;
1263                         }
1264                 }
1265                 ct_ret = contacts_list_next(list);
1266         }
1267         return ct_ret;
1268 }
1269
1270 int email_num_id_get_contacts_record(int num_id, contacts_record_h* out_record)
1271 {
1272         debug_log("");
1273         int ct_ret = CONTACTS_ERROR_NONE;
1274
1275         /* get record email */
1276         ct_ret = contacts_db_get_record(_contacts_contact_email._uri, num_id, out_record);
1277         if (ct_ret != CONTACTS_ERROR_NONE) {
1278                 debug_log("_contacts_number, db_get_record is failed : ct_ret = [%d]", ct_ret);
1279                 return ct_ret;
1280         }
1281         return ct_ret;
1282 }
1283
1284 /* EOF */