cb244208fa9d562b4d54a69bec1a37685fbc3ff7
[apps/core/preloaded/calendar.git] / common / util.c
1 /*
2   *
3   *  Copyright 2012  Samsung Electronics Co., Ltd
4   *
5   *  Licensed under the Flora License, Version 1.0 (the "License");
6   *  you may not use this file except in compliance with the License.
7   *  You may obtain a copy of the License at
8   *
9   *       http://floralicense.org/license/
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17
18 #define _GNU_SOURCE
19
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <vconf.h>
23 #include <fcntl.h>
24 #include <string.h>
25 #include <media_content.h>
26 #include <sqlite3.h>
27
28 #include "cld.h"
29
30 #define LINEMAX 256
31 #define LOGFILE "/tmp/calendar.log"
32 #define SIN_TBL_S (sizeof(SIN_TBL)/sizeof(SIN_TBL[0]) - 1)
33 #define WORLDCLOCK_DB "/opt/dbspace/.worldclock.db"
34
35 static time_t cal_max;
36 static time_t cal_min;
37
38 static const float const SIN_TBL[] = {
39         0.0000f, 0.0174f, 0.0349f, 0.0523f, 0.0698f,
40         0.0872f, 0.1045f, 0.1219f, 0.1392f, 0.1564f,
41         0.1736f, 0.1908f, 0.2079f, 0.2249f, 0.2419f,
42         0.2588f, 0.2756f, 0.2924f, 0.3090f, 0.3256f,
43         0.3420f, 0.3584f, 0.3746f, 0.3907f, 0.4067f,
44         0.4226f, 0.4384f, 0.4540f, 0.4695f, 0.4848f,
45         0.5000f, 0.5150f, 0.5299f, 0.5446f, 0.5592f,
46         0.5736f, 0.5878f, 0.6018f, 0.6157f, 0.6293f,
47         0.6528f, 0.6561f, 0.6691f, 0.6820f, 0.6947f,
48         0.7071f, 0.7193f, 0.7314f, 0.7431f, 0.7547f,
49         0.7660f, 0.7772f, 0.7880f, 0.7986f, 0.8090f,
50         0.8191f, 0.8290f, 0.8387f, 0.8480f, 0.8571f,
51         0.8660f, 0.8746f, 0.8829f, 0.8910f, 0.8988f,
52         0.9063f, 0.9135f, 0.9205f, 0.9272f, 0.9336f,
53         0.9397f, 0.9455f, 0.9511f, 0.9563f, 0.9613f,
54         0.9659f, 0.9703f, 0.9744f, 0.9781f, 0.9816f,
55         0.9848f, 0.9877f, 0.9903f, 0.9926f, 0.9945f,
56         0.9962f, 0.9976f, 0.9986f, 0.9994f, 0.9998f,
57         1.0f
58 };
59
60
61 static int __cal_util_max_days[2][12] = {
62         { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
63         { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
64 };
65 int cal_util_get_max_days(int tm_year, int tm_mon)
66 {
67         while (tm_mon < 0) {
68                 tm_year -= 1;
69                 tm_mon += 12;
70         }
71
72         while (tm_mon > 11) {
73                 tm_year += 1;
74                 tm_mon -= 12;
75         }
76
77         tm_year = tm_year + 1900;
78
79         return __cal_util_max_days[(!(tm_year & 0x3) && (!(tm_year % 400)
80                                 || (tm_year % 100)))][tm_mon];
81 }
82
83 static int __cal_util_get_cal_min(void)
84 {
85         struct tm tm;
86         time_t t;
87
88         if (cal_min)
89                 return cal_min;
90
91         t = time(NULL);
92         localtime_r(&t, &tm);
93
94         // 1970-1-1 00:00:00
95         tm.tm_year = 70;
96         tm.tm_mon = 0;
97         tm.tm_mday = 1;
98         tm.tm_hour = 0;
99         tm.tm_min = 0;
100         tm.tm_sec = 0;
101
102         cal_min = mktime(&tm);
103         if(cal_min == -1)
104                 cal_min = 0;
105         c_retv_if(!cal_min, -1);
106
107         return cal_min;
108 }
109
110 static int __cal_util_get_cal_max(void)
111 {
112         struct tm tm;
113         time_t t;
114
115         if (cal_max)
116                 return cal_max;
117
118         t = time(NULL);
119         localtime_r(&t, &tm);
120
121         // 2036-12-31 23:59:59
122         tm.tm_year = 136;
123         tm.tm_mon = 11;
124         tm.tm_mday = 31;
125         tm.tm_hour = 23;
126         tm.tm_min = 59;
127         tm.tm_sec = 59;
128
129         cal_max = mktime(&tm);
130         if(cal_max == -1)
131                 cal_max = 0;
132         CAL_ASSERT(cal_max);
133
134         return cal_max;
135 }
136
137 time_t cal_util_get_max_time(void)
138 {
139         return __cal_util_get_cal_max();
140 }
141
142 time_t cal_util_get_min_time(void)
143 {
144         return __cal_util_get_cal_min();
145 }
146
147 time_t cal_util_update_tm_year(struct tm *t, int delta)
148 {
149         time_t r;
150         struct tm tmp;
151
152         tmp = *t;
153
154         tmp.tm_year += delta;
155         if (tmp.tm_mon == 1 && tmp.tm_mday == 29)
156                 tmp.tm_mday = cal_util_get_max_days(tmp.tm_year, tmp.tm_mon);
157
158         r = mktime(&tmp);
159         if (r == (time_t)-1)
160                 return -1;
161
162         if (r < __cal_util_get_cal_min() || r > __cal_util_get_cal_max())
163                 return -1;
164
165         *t = tmp;
166         return r;
167 }
168
169 time_t cal_util_update_tm_month(struct tm *t, int delta)
170 {
171         time_t r;
172         int max;
173         struct tm tmp;
174
175         tmp = *t;
176         tmp.tm_mon += delta;
177
178         while (tmp.tm_mon < 0) {
179                 tmp.tm_year -= 1;
180                 tmp.tm_mon += 12;
181         }
182
183         while (tmp.tm_mon > 11) {
184                 tmp.tm_year += 1;
185                 tmp.tm_mon -= 12;
186         }
187
188         max = cal_util_get_max_days(tmp.tm_year, tmp.tm_mon);
189         if (max < tmp.tm_mday)
190                 tmp.tm_mday = max;
191
192         r = mktime(&tmp);
193         if (r == (time_t)-1)
194                 return -1;
195
196         if (r < __cal_util_get_cal_min() || r > __cal_util_get_cal_max())
197                 return -1;
198
199         *t = tmp;
200         return r;
201 }
202
203 time_t cal_util_update_tm_day(struct tm *t, int delta)
204 {
205         time_t r;
206         struct tm tmp;
207
208         tmp = *t;
209         tmp.tm_mday += delta;
210
211         r = mktime(&tmp);
212         if (r == (time_t)-1)
213                 return -1;
214
215         if (r < __cal_util_get_cal_min() || r > __cal_util_get_cal_max())
216                 return -1;
217
218         *t = tmp;
219         return r;
220 }
221
222 time_t cal_util_update_tm_hour(struct tm* tm, int delta)
223 {
224         struct tm t;
225         struct tm* returned_tm = NULL;
226         time_t time = 0;
227
228         time = mktime(tm);
229         time = time + (delta * 60*60);
230
231         returned_tm = localtime_r(&time, &t);
232         if(!returned_tm)
233         {
234                 ERR("localtime is failed.");
235                 return -1;
236         }
237         CAL_MEMCPY(tm, &t, struct tm);
238
239         return time;
240 }
241
242 int cal_util_get_day_time_t(struct tm *t, time_t *st, time_t *et)
243 {
244         c_retvm_if(!t, -1 , "t is null");
245         c_retvm_if(!st, -1 , "st is null");
246         c_retvm_if(!et, -1 , "et is null");
247
248         time_t _t;
249         struct tm tm = *t;
250
251         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
252
253         _t = mktime(&tm);
254         if (_t == (time_t) -1)
255                 return -1;
256
257         *st = _t;
258         *et = _t + (24 * 60 * 60) - 1;
259
260         return 0;
261 }
262
263 int cal_util_get_week_time_t(struct tm *t, time_t *st, time_t *et, int start)
264 {
265         c_retvm_if(!t, -1 , "t is null");
266         c_retvm_if(!st, -1 , "st is null");
267         c_retvm_if(!et, -1 , "et is null");
268
269         time_t _t;
270         struct tm tm = *t;
271
272         tm.tm_mday -= CAL_UTIL_GET_WDAY(tm.tm_wday - start);
273
274         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
275
276         _t = mktime(&tm);
277         if (_t == (time_t) -1)
278                 return -1;
279
280         *st = _t;
281         *et = _t + (7 * 24 * 60 * 60) - 1;
282
283         return 0;
284 }
285
286 int cal_util_get_month_time_t(struct tm *t, time_t *st, time_t *et)
287 {
288         c_retvm_if(!t, -1 , "t is null");
289         c_retvm_if(!st, -1 , "st is null");
290         c_retvm_if(!et, -1 , "et is null");
291
292         time_t s, e;
293         struct tm tm = *t;
294
295         tm.tm_mday = 1;
296         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
297
298         s = mktime(&tm);
299         if (s == (time_t) -1)
300                 return -1;
301
302         tm.tm_mon++;
303         e = mktime(&tm);
304         if (e == (time_t) -1)
305                 return -1;
306
307         *st = s;
308         *et = e - 3600;
309         return 0;
310 }
311
312 int cal_util_get_year_time_t(struct tm *t, time_t *st, time_t *et)
313 {
314         c_retvm_if(!t, -1 , "t is null");
315         c_retvm_if(!st, -1 , "st is null");
316         c_retvm_if(!et, -1 , "et is null");
317
318         time_t s, e;
319         struct tm tm = *t;
320
321         tm.tm_mon = 0;
322         tm.tm_mday = 1;
323         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
324
325         s = mktime(&tm);
326         if (s == (time_t) -1)
327                 return -1;
328
329         tm.tm_year++;
330         e = mktime(&tm);
331         if (e == (time_t) -1)
332                 return -1;
333
334         *st = s;
335         *et = e - 1;
336
337         return 0;
338 }
339
340 void cal_svc_get_start_date(calendar_record_h record, struct tm* start_date)
341 {
342         calendar_time_s start_time;
343         _calendar_get_start_time(record, &start_time);
344         if (_calendar_is_allday_record(record)) {
345                 start_date->tm_year = start_time.time.date.year - 1900;
346                 start_date->tm_mon = start_time.time.date.month - 1;
347                 start_date->tm_mday = start_time.time.date.mday;
348         } else {
349                 cal_util_convert_lli_to_tm(NULL, start_time.time.utime, start_date);
350         }
351 }
352
353 void cal_svc_get_end_date(calendar_record_h record, struct tm* end_date)
354 {
355         calendar_time_s end_time;
356         _calendar_get_end_time(record, &end_time);
357         if (_calendar_is_allday_record(record)) {
358                 end_date->tm_year = end_time.time.date.year - 1900;
359                 end_date->tm_mon = end_time.time.date.month - 1;
360                 end_date->tm_mday = end_time.time.date.mday;
361         } else {
362                 cal_util_convert_lli_to_tm(NULL, end_time.time.utime, end_date);
363         }
364 }
365
366 inline void cal_util_set_time(struct tm* time, int hour, int min, int sec)
367 {
368         time->tm_hour = hour;
369         time->tm_min = min;
370         time->tm_sec = sec;
371 }
372
373 time_t cal_util_get_month_start_time(const struct tm* subject_date, struct tm* month_start_time)
374 {
375         *month_start_time = *subject_date;
376         month_start_time->tm_mday = 1;
377         cal_util_set_time(month_start_time, 0, 0, 0);
378         return mktime(month_start_time);        // normalize (fix broken wday and yday) & export time_t conversion
379 }
380
381 time_t cal_util_get_month_end_time(const struct tm* subject_date, struct tm* month_end_time)
382 {
383         *month_end_time = *subject_date;
384         month_end_time->tm_mday = 1;
385         cal_util_set_time(month_end_time, 23, 59, 59);
386         cal_util_update_tm_month(month_end_time, 1);
387         return cal_util_update_tm_day(month_end_time, -1);
388 }
389
390 static int __cal_util_get_wday_norm(int wday)
391 {
392         if (wday > 6)
393                 return wday - 7;
394
395         if (wday < 0)
396                 return wday + 7;
397
398         return wday;
399 }
400
401 time_t cal_util_get_week_start_time(const struct tm* subject_date, struct tm* week_start_time,
402                                                                         int start_wday)
403 {
404         *week_start_time = *subject_date;
405         cal_util_set_time(week_start_time, 0, 0, 0);
406
407         int diff = week_start_time->tm_wday - start_wday;
408         if (diff < 0)
409                 diff += 7;
410
411         return cal_util_update_tm_day(week_start_time, -diff);
412 }
413
414 time_t cal_util_get_week_end_time(const struct tm* subject_date, struct tm* week_end_time,
415                                                                   int start_wday)
416 {
417         *week_end_time = *subject_date;
418         cal_util_set_time(week_end_time, 23, 59, 59);
419
420         int end_wday = __cal_util_get_wday_norm(start_wday + 6);
421
422         int diff = end_wday - week_end_time->tm_wday;
423         if (diff < 0)
424                 diff += 7;
425
426         return cal_util_update_tm_day(week_end_time, diff);
427 }
428
429 int cal_util_get_day_diff(const struct tm* date1, const struct tm* date2)
430 {
431         struct tm d1 = *date1;
432         struct tm d2 = *date2;
433         cal_util_set_time(&d1, 0, 0, 0);
434         cal_util_set_time(&d2, 0, 0, 0);
435         time_t time1 = mktime(&d1);
436         time_t time2 = mktime(&d2);
437         return (time1 - time2) / (24 * 60 * 60);        // todo: a day is not always 24 * 60 * 60 seconds!
438 }
439
440 static inline int __cal_util_get_day_val(const struct tm* day)
441 {
442         return (day->tm_year << 9) | (day->tm_mon << 5) | day->tm_mday;
443 }
444
445 int cal_util_compare_day(const struct tm* date1, const struct tm* date2)
446 {
447         int diff = __cal_util_get_day_val(date2) - __cal_util_get_day_val(date1);
448
449         if (diff > 0)
450                 return 1;
451         else if (diff < 0)
452                 return -1;
453         else
454                 return 0;
455 }
456
457 const char* cal_util_print_day(const struct tm* day)
458 {
459         static char buffer[50];
460         sprintf(buffer, "%d/%d/%d", day->tm_year + 1900, day->tm_mon + 1, day->tm_mday);
461         return buffer;
462 }
463
464 float cal_util_nsin(float f)
465 {
466         if(f < 0.0 && f > 1.0)
467                 return 0.0;
468
469         return SIN_TBL[(int)(SIN_TBL_S * f)];
470 }
471
472 int cal_util_get_week_flag(char *week_s)
473 {
474         int i;
475         int flag;
476
477         flag = 0;
478         if (6 < CAL_STRLEN(week_s)) {
479                 for (i = 0; i < 7; i++) {
480                         if (week_s[i] == '1')
481                                 flag |= (1 << i);
482                 }
483         }
484
485         return flag;
486 }
487
488 static void __cal_util_get_timezone_id(char **timezone_id)
489 {
490         c_ret_if(!timezone_id);
491
492         int value = 0;
493
494         int ret = vconf_get_int(CAL_VCONFKEY_LOCK_TIMEZONE_ON_OFF, &value);
495         c_warn_if(ret, "vconf_get_int(CAL_VCONFKEY_LOCK_TIMEZONE_ON_OFF, &value) is failed");
496
497         char *text = NULL;
498
499         if (value) {
500                 text = vconf_get_str(CAL_VCONFKEY_LOCK_TIMEZONE_PATH);
501                 c_retm_if(!text, "vconf_get_str(CAL_VCONFKEY_LOCK_TIMEZONE_PATH) is failed");
502         } else {
503                 text = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
504                 c_retm_if(!text, "vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID) is failed");
505         }
506
507         *timezone_id = text;
508
509         c_warn_if(!CAL_STRLEN(text), "timezone_id is empty str");
510 }
511
512 void cal_util_get_timezone_id(int timezone_offset, char **timezone_id)
513 {
514         CAL_FN_START;
515
516         c_ret_if(!timezone_id);
517
518         sqlite3 *db_handler = NULL;
519         sqlite3_stmt *stmt = NULL;
520         char *error_message = NULL;
521         int ret = 0;
522
523         if (!db_handler) {
524                 ret = sqlite3_open( WORLDCLOCK_DB, &db_handler);
525                 c_retm_if(ret, "sqlite3_open() is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
526         }
527
528         char offset_hour[8];
529         int minutes_for_1_hour = 60;
530         int timezone_offset_hour = timezone_offset/minutes_for_1_hour;
531         int timezone_offset_minute = timezone_offset%minutes_for_1_hour;
532
533         if (0 <= timezone_offset_hour)
534                 snprintf(offset_hour, 8, "+%d", timezone_offset_hour);
535         else
536                 snprintf(offset_hour, 8, "%d", timezone_offset_hour);
537
538         char offset[16];
539         if (timezone_offset_minute)
540                 snprintf(offset, 16, "GMT%s:%d", offset_hour, timezone_offset_minute);
541         else
542                 snprintf(offset, 16, "GMT%s", offset_hour);
543
544         char query[256];
545         snprintf(query, 256, "SELECT tz_path FROM city_table where timezone=\"%s\" limit 1", offset);
546
547         ret = sqlite3_prepare_v2(db_handler, query, strlen(query), &stmt, NULL);
548         c_retm_if(ret, "sqlite3_prepare_v2(%s) failed(%d) : %s.", query, ret, sqlite3_errmsg(db_handler));
549
550         ret = sqlite3_step(stmt);
551         c_retm_if(ret != SQLITE_ROW
552                 && ret != SQLITE_OK
553                 && ret != SQLITE_DONE, "sqlite3_step is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
554
555         *timezone_id = CAL_STRDUP((char *)sqlite3_column_text(stmt, 0));
556
557         ret = sqlite3_finalize(stmt);
558         c_retm_if(ret, "sqlite3_finalize is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
559
560         sqlite3_free(error_message);
561
562         ret = sqlite3_close(db_handler);
563         c_retm_if(ret, "sqlite3_close is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
564 }
565
566 void cal_util_get_timezone(char **timezone_id, char **timezone_city, char **timezone_offset)
567 {
568         CAL_FN_START;
569
570         c_ret_if(!timezone_id);
571         c_ret_if(!timezone_city);
572         c_ret_if(!timezone_offset);
573
574         sqlite3 *db_handler = NULL;
575         sqlite3_stmt *stmt = NULL;
576         char *error_message = NULL;
577         int ret = 0;
578
579         if (!db_handler) {
580                 ret = sqlite3_open( WORLDCLOCK_DB, &db_handler);
581                 c_retm_if(ret, "sqlite3_open() is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
582         }
583
584         if (!*timezone_id)
585                 __cal_util_get_timezone_id(timezone_id);
586
587         char query[256];
588         snprintf(query, 256, "SELECT city, timezone FROM city_table where tz_path=\"%s\"", *timezone_id);
589
590         ret = sqlite3_prepare_v2(db_handler, query, strlen(query), &stmt, NULL);
591         c_retm_if(ret, "sqlite3_prepare_v2(%s) failed(%d) : %s.", query, ret, sqlite3_errmsg(db_handler));
592
593         ret = sqlite3_step(stmt);
594         c_retm_if(ret != SQLITE_ROW
595                 && ret != SQLITE_OK
596                 && ret != SQLITE_DONE, "sqlite3_step is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
597
598         *timezone_city = CAL_STRDUP((char *)sqlite3_column_text(stmt, 0));
599         *timezone_offset = CAL_STRDUP((char *)sqlite3_column_text(stmt, 1));
600
601         ret = sqlite3_finalize(stmt);
602         c_retm_if(ret, "sqlite3_finalize is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
603
604         sqlite3_free(error_message);
605
606         ret = sqlite3_close(db_handler);
607         c_retm_if(ret, "sqlite3_close is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
608 }
609
610 char *cal_util_get_search_color_text( const char *search_str, const char *input_str)
611 {
612         c_retv_if(!CAL_STRLEN(search_str), NULL);
613         c_retv_if(!CAL_STRLEN(input_str), NULL);
614
615         char *color_str = NULL;
616         const char *color_start_str = "<match>";
617         const char *color_end_str = "</>";
618         char* sub_str = NULL;
619
620         int color_start_str_sz = CAL_STRLEN(color_start_str);
621         int color_end_str_sz = CAL_STRLEN(color_end_str);
622         int input_str_sz = CAL_STRLEN(input_str);
623         int search_str_sz = CAL_STRLEN(search_str);
624
625         sub_str= strcasestr(input_str, search_str);
626         int sub_str_sz = CAL_STRLEN(sub_str);
627
628         c_retv_if(!sub_str_sz, NULL);
629
630         color_str = calloc(1, color_start_str_sz+color_end_str_sz+input_str_sz+1);
631         c_retv_if(!color_str, NULL);
632
633         int head_str_sz = sub_str - input_str;
634
635         CAL_STRNCPY(color_str, input_str, head_str_sz);
636         CAL_STRNCPY(color_str + head_str_sz, color_start_str, color_start_str_sz);
637         CAL_STRNCPY(color_str + head_str_sz + color_start_str_sz, sub_str, search_str_sz);
638         CAL_STRNCPY(color_str + head_str_sz + color_start_str_sz + search_str_sz, color_end_str, color_end_str_sz);
639         CAL_STRNCPY(color_str + head_str_sz + color_start_str_sz + search_str_sz + color_end_str_sz, sub_str + search_str_sz, sub_str_sz - search_str_sz);
640
641         return color_str;
642 }
643
644 void cal_util_update_media_db(const char *file_path)
645 {
646         c_ret_if(!CAL_STRLEN(file_path));
647
648         int error = media_content_connect();
649         c_warn_if(error != MEDIA_CONTENT_ERROR_NONE, "media_content_connect() is failed(%x)", error);
650
651         error = media_content_scan_file(file_path);
652         c_warn_if(error != MEDIA_CONTENT_ERROR_NONE, "media_content_scan_file(%s) is failed(%x)", file_path, error);
653
654         error = media_content_disconnect();
655         c_warn_if(error != MEDIA_CONTENT_ERROR_NONE, "media_content_disconnect() is failed(%x)", error);
656 }
657
658 int cal_util_get_flick_distance_threshold()
659 {
660         return 40;
661 }