2.0 alpha
[apps/home/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://www.tizenopensource.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
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <vconf.h>
22 #include <fcntl.h>
23
24 #include "cld.h"
25 #define LINEMAX 256
26 #define LOGFILE "/tmp/calendar.log"
27 #define SIN_TBL_S (sizeof(SIN_TBL)/sizeof(SIN_TBL[0]) - 1)
28 #define WORLDCLOCK_DB "/opt/dbspace/.worldclock.db"
29
30 static time_t cal_max;
31 static time_t cal_min;
32
33 static const float const SIN_TBL[] = {
34         0.0000f, 0.0174f, 0.0349f, 0.0523f, 0.0698f,
35         0.0872f, 0.1045f, 0.1219f, 0.1392f, 0.1564f,
36         0.1736f, 0.1908f, 0.2079f, 0.2249f, 0.2419f,
37         0.2588f, 0.2756f, 0.2924f, 0.3090f, 0.3256f,
38         0.3420f, 0.3584f, 0.3746f, 0.3907f, 0.4067f,
39         0.4226f, 0.4384f, 0.4540f, 0.4695f, 0.4848f,
40         0.5000f, 0.5150f, 0.5299f, 0.5446f, 0.5592f,
41         0.5736f, 0.5878f, 0.6018f, 0.6157f, 0.6293f,
42         0.6528f, 0.6561f, 0.6691f, 0.6820f, 0.6947f,
43         0.7071f, 0.7193f, 0.7314f, 0.7431f, 0.7547f,
44         0.7660f, 0.7772f, 0.7880f, 0.7986f, 0.8090f,
45         0.8191f, 0.8290f, 0.8387f, 0.8480f, 0.8571f,
46         0.8660f, 0.8746f, 0.8829f, 0.8910f, 0.8988f,
47         0.9063f, 0.9135f, 0.9205f, 0.9272f, 0.9336f,
48         0.9397f, 0.9455f, 0.9511f, 0.9563f, 0.9613f,
49         0.9659f, 0.9703f, 0.9744f, 0.9781f, 0.9816f,
50         0.9848f, 0.9877f, 0.9903f, 0.9926f, 0.9945f,
51         0.9962f, 0.9976f, 0.9986f, 0.9994f, 0.9998f,
52         1.0f
53 };
54
55
56 static int __cal_util_max_days[2][12] = {
57         { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
58         { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
59 };
60 int cal_util_get_max_days(int tm_year, int tm_mon)
61 {
62         while (tm_mon < 0) {
63                 tm_year -= 1;
64                 tm_mon += 12;
65         }
66
67         while (tm_mon > 11) {
68                 tm_year += 1;
69                 tm_mon -= 12;
70         }
71
72         tm_year = tm_year + 1900;
73
74         return __cal_util_max_days[(!(tm_year & 0x3) && (!(tm_year % 400)
75                                 || (tm_year % 100)))][tm_mon];
76 }
77
78 static int __cal_util_get_cal_min(void)
79 {
80         struct tm tm;
81         time_t t;
82
83         if (cal_min)
84                 return cal_min;
85
86         t = time(NULL);
87         localtime_r(&t, &tm);
88
89         // 1970-1-1 00:00:00
90         tm.tm_year = 70;
91         tm.tm_mon = 0;
92         tm.tm_mday = 1;
93         tm.tm_hour = 0;
94         tm.tm_min = 0;
95         tm.tm_sec = 0;
96
97         cal_min = mktime(&tm);
98         if(cal_min == -1)
99                 cal_min = 0;
100         c_retv_if(!cal_min, -1);
101
102         return cal_min;
103 }
104
105 static int __cal_util_get_cal_max(void)
106 {
107         struct tm tm;
108         time_t t;
109
110         if (cal_max)
111                 return cal_max;
112
113         t = time(NULL);
114         localtime_r(&t, &tm);
115
116         // 2037-12-31 23:59:59
117         tm.tm_year = 137;
118         tm.tm_mon = 11;
119         tm.tm_mday = 31;
120         tm.tm_hour = 23;
121         tm.tm_min = 59;
122         tm.tm_sec = 59;
123
124         cal_max = mktime(&tm);
125         if(cal_max == -1)
126                 cal_max = 0;
127         CAL_ASSERT(cal_max);
128
129         return cal_max;
130 }
131
132 time_t cal_util_get_max_time(void)
133 {
134         return __cal_util_get_cal_max();
135 }
136
137 time_t cal_util_get_min_time(void)
138 {
139         return __cal_util_get_cal_min();
140 }
141
142 int cal_util_update_tm_year(struct tm *t, int delta)
143 {
144         time_t r;
145         struct tm tmp;
146
147         tmp = *t;
148
149         tmp.tm_year += delta;
150         if (tmp.tm_mon == 1 && tmp.tm_mday == 29)
151                 tmp.tm_mday = cal_util_get_max_days(tmp.tm_year, tmp.tm_mon);
152
153         r = mktime(&tmp);
154         if (r == (time_t)-1)
155                 return -1;
156
157         if (r < __cal_util_get_cal_min() || r > __cal_util_get_cal_max())
158                 return -1;
159
160         *t = tmp;
161         return 0;
162 }
163
164 int cal_util_update_tm_month(struct tm *t, int delta)
165 {
166         time_t r;
167         int max;
168         struct tm tmp;
169
170         tmp = *t;
171         tmp.tm_mon += delta;
172
173         while (tmp.tm_mon < 0) {
174                 tmp.tm_year -= 1;
175                 tmp.tm_mon += 12;
176         }
177
178         while (tmp.tm_mon > 11) {
179                 tmp.tm_year += 1;
180                 tmp.tm_mon -= 12;
181         }
182
183         max = cal_util_get_max_days(tmp.tm_year, tmp.tm_mon);
184         if (max < tmp.tm_mday)
185                 tmp.tm_mday = max;
186
187         r = mktime(&tmp);
188         if (r == (time_t)-1)
189                 return -1;
190
191         if (r < __cal_util_get_cal_min() || r > __cal_util_get_cal_max())
192                 return -1;
193
194         *t = tmp;
195         return 0;
196 }
197
198 int cal_util_update_tm_day(struct tm *t, int delta)
199 {
200         time_t r;
201         struct tm tmp;
202
203         tmp = *t;
204         tmp.tm_mday += delta;
205
206         r = mktime(&tmp);
207         if (r == (time_t)-1)
208                 return -1;
209
210         if (r < __cal_util_get_cal_min() || r > __cal_util_get_cal_max())
211                 return -1;
212
213         *t = tmp;
214         return 0;
215 }
216
217 int cal_util_update_tm_hour(struct tm* tm, int delta)
218 {
219         struct tm t;
220         struct tm* returned_tm = NULL;
221         time_t time = 0;
222
223         time = mktime(tm);
224         time = time + (delta * 60*60);
225
226         returned_tm = localtime_r(&time, &t);
227         if(!returned_tm)
228         {
229                 ERR("localtime is failed.");
230                 return -1;
231         }
232         CAL_MEMCPY(tm, &t, struct tm);
233
234         return 0;
235 }
236
237 int cal_util_get_day_time_t(struct tm *t, time_t *st, time_t *et)
238 {
239         c_retvm_if(!t, -1 , "t is null");
240         c_retvm_if(!st, -1 , "st is null");
241         c_retvm_if(!et, -1 , "et is null");
242
243         time_t _t;
244         struct tm tm = *t;
245
246         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
247
248         _t = mktime(&tm);
249         if (_t == (time_t) -1)
250                 return -1;
251
252         *st = _t;
253         *et = _t + (24 * 60 * 60) - 1;
254
255         return 0;
256 }
257
258 int cal_util_get_week_time_t(struct tm *t, time_t *st, time_t *et, int start)
259 {
260         c_retvm_if(!t, -1 , "t is null");
261         c_retvm_if(!st, -1 , "st is null");
262         c_retvm_if(!et, -1 , "et is null");
263
264         time_t _t;
265         struct tm tm = *t;
266
267         tm.tm_mday -= CAL_UTIL_GET_WDAY(tm.tm_wday - start);
268
269         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
270
271         _t = mktime(&tm);
272         if (_t == (time_t) -1)
273                 return -1;
274
275         *st = _t;
276         *et = _t + (7 * 24 * 60 * 60) - 1;
277
278         return 0;
279 }
280
281 int cal_util_get_month_time_t(struct tm *t, time_t *st, time_t *et)
282 {
283         c_retvm_if(!t, -1 , "t is null");
284         c_retvm_if(!st, -1 , "st is null");
285         c_retvm_if(!et, -1 , "et is null");
286
287         time_t s, e;
288         struct tm tm = *t;
289
290         tm.tm_mday = 1;
291         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
292
293         s = mktime(&tm);
294         if (s == (time_t) -1)
295                 return -1;
296
297         tm.tm_mon++;
298         e = mktime(&tm);
299         if (e == (time_t) -1)
300                 return -1;
301
302         *st = s;
303         *et = e - 3600;
304         return 0;
305 }
306
307 int cal_util_get_year_time_t(struct tm *t, time_t *st, time_t *et)
308 {
309         c_retvm_if(!t, -1 , "t is null");
310         c_retvm_if(!st, -1 , "st is null");
311         c_retvm_if(!et, -1 , "et is null");
312
313         time_t s, e;
314         struct tm tm = *t;
315
316         tm.tm_mon = 0;
317         tm.tm_mday = 1;
318         tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
319
320         s = mktime(&tm);
321         if (s == (time_t) -1)
322                 return -1;
323
324         tm.tm_year++;
325         e = mktime(&tm);
326         if (e == (time_t) -1)
327                 return -1;
328
329         *st = s;
330         *et = e - 1;
331
332         return 0;
333 }
334
335 float cal_util_nsin(float f)
336 {
337         if(f < 0.0 && f > 1.0)
338                 return 0.0;
339
340         return SIN_TBL[(int)(SIN_TBL_S * f)];
341 }
342
343 int cal_util_get_week_flag(char *week_s)
344 {
345         int i;
346         int flag;
347
348         flag = 0;
349         if (6 < CAL_STRLEN(week_s)) {
350                 for (i = 0; i < 7; i++) {
351                         if (week_s[i] == '1')
352                                 flag |= (1 << i);
353                 }
354         }
355
356         return flag;
357 }
358
359 int cal_util_create_vcs_file_from_cs(cal_struct *cs, const char *filename)
360 {
361         c_retvm_if(!cs || !filename, CAL_ERR_FAIL,  "input param is wrong");
362
363         int r;
364         int fd;
365         char *stream = NULL;
366         GList *schedules = NULL;
367
368         schedules = g_list_append(schedules, cs);
369         c_retvm_if(!schedules, CAL_ERR_FAIL, "g_list_append return null");
370
371         r = calendar_svc_write_schedules(schedules, &stream);
372         if (r < 0) {
373                 ERR("Failed to write schedules(errno:%d)", r);
374                 return CAL_ERR_FAIL;
375         }
376         g_list_free(schedules);
377         schedules = NULL;
378
379         if (NULL == stream) {
380                 ERR("stream is NULL");
381                 return CAL_ERR_FAIL;
382         }
383
384         fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0660);
385         if (fd < 0) {
386                 ERR("Failed to open path(%s)\n", filename);
387                 free(stream);
388                 return CAL_ERR_IO_ERR;
389         }
390
391         r = write(fd, stream, strlen(stream));
392         free(stream);
393         close(fd);
394
395         if (r < 0) {
396                 ERR("Failed to write stream(errno:%d)\n", r);
397                 return CAL_ERR_IO_ERR;
398         }
399
400         return CAL_SUCCESS;
401 }
402
403 static void __cal_util_get_timezone_id(char **timezone_id)
404 {
405         c_ret_if(!timezone_id);
406
407         int value = 0;
408
409         int ret = vconf_get_int(CAL_VCONFKEY_LOCK_TIMEZONE_ON_OFF, &value);
410         c_warn_if(ret, "vconf_get_int(CAL_VCONFKEY_LOCK_TIMEZONE_ON_OFF, &value) is failed");
411
412         char *text = NULL;
413
414         if (value) {
415                 text = vconf_get_str(CAL_VCONFKEY_LOCK_TIMEZONE_PATH);
416                 c_retm_if(!text, "vconf_get_str(CAL_VCONFKEY_LOCK_TIMEZONE_PATH) is failed");
417         } else {
418                 text = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
419                 c_retm_if(!text, "vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID) is failed");
420         }
421
422         *timezone_id = text;
423
424         c_warn_if(!CAL_STRLEN(text), "timezone_id is empty str");
425 }
426
427 void cal_util_get_timezone_id(int timezone_offset, char **timezone_id)
428 {
429         CAL_FN_START;
430
431         c_ret_if(!timezone_id);
432
433         sqlite3 *db_handler = NULL;
434         sqlite3_stmt *stmt = NULL;
435         char *error_message = NULL;
436         int ret = 0;
437
438         if (!db_handler) {
439                 ret = sqlite3_open( WORLDCLOCK_DB, &db_handler);
440                 c_retm_if(ret, "sqlite3_open() is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
441         }
442
443         char offset_hour[8];
444         int minutes_for_1_hour = 60;
445         int timezone_offset_hour = timezone_offset/minutes_for_1_hour;
446         int timezone_offset_minute = timezone_offset%minutes_for_1_hour;
447
448         if (0 <= timezone_offset_hour)
449                 snprintf(offset_hour, 8, "+%d", timezone_offset_hour);
450         else
451                 snprintf(offset_hour, 8, "%d", timezone_offset_hour);
452
453         char offset[16];
454         if (timezone_offset_minute)
455                 snprintf(offset, 16, "GMT%s:%d", offset_hour, timezone_offset_minute);
456         else
457                 snprintf(offset, 16, "GMT%s", offset_hour);
458
459         char query[256];
460         snprintf(query, 256, "SELECT tz_path FROM city_table where timezone=\"%s\" limit 1", offset);
461
462         ret = sqlite3_prepare_v2(db_handler, query, strlen(query), &stmt, NULL);
463         c_retm_if(ret, "sqlite3_prepare_v2(%s) failed(%d) : %s.", query, ret, sqlite3_errmsg(db_handler));
464
465         ret = sqlite3_step(stmt);
466         c_retm_if(ret != SQLITE_ROW
467                 && ret != SQLITE_OK
468                 && ret != SQLITE_DONE, "sqlite3_step is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
469
470         *timezone_id = CAL_STRDUP((char *)sqlite3_column_text(stmt, 0));
471
472         ret = sqlite3_finalize(stmt);
473         c_retm_if(ret, "sqlite3_finalize is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
474
475         sqlite3_free(error_message);
476
477         ret = sqlite3_close(db_handler);
478         c_retm_if(ret, "sqlite3_close is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
479 }
480
481 void cal_util_get_timezone(char **timezone_id, char **timezone_city, char **timezone_offset)
482 {
483         CAL_FN_START;
484
485         c_ret_if(!timezone_id);
486         c_ret_if(!timezone_city);
487         c_ret_if(!timezone_offset);
488
489         sqlite3 *db_handler = NULL;
490         sqlite3_stmt *stmt = NULL;
491         char *error_message = NULL;
492         int ret = 0;
493
494         if (!db_handler) {
495                 ret = sqlite3_open( WORLDCLOCK_DB, &db_handler);
496                 c_retm_if(ret, "sqlite3_open() is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
497         }
498
499         if (!*timezone_id)
500                 __cal_util_get_timezone_id(timezone_id);
501
502         char query[256];
503         snprintf(query, 256, "SELECT city, timezone FROM city_table where tz_path=\"%s\"", *timezone_id);
504
505         ret = sqlite3_prepare_v2(db_handler, query, strlen(query), &stmt, NULL);
506         c_retm_if(ret, "sqlite3_prepare_v2(%s) failed(%d) : %s.", query, ret, sqlite3_errmsg(db_handler));
507
508         ret = sqlite3_step(stmt);
509         c_retm_if(ret != SQLITE_ROW
510                 && ret != SQLITE_OK
511                 && ret != SQLITE_DONE, "sqlite3_step is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
512
513         *timezone_city = CAL_STRDUP((char *)sqlite3_column_text(stmt, 0));
514         *timezone_offset = CAL_STRDUP((char *)sqlite3_column_text(stmt, 1));
515
516         ret = sqlite3_finalize(stmt);
517         c_retm_if(ret, "sqlite3_finalize is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
518
519         sqlite3_free(error_message);
520
521         ret = sqlite3_close(db_handler);
522         c_retm_if(ret, "sqlite3_close is failed(%d) : %s", ret, sqlite3_errmsg(db_handler));
523 }
524
525 char *cal_util_get_search_color_text( const char *search_str, const char *input_str)
526 {
527         c_retv_if(!CAL_STRLEN(search_str), NULL);
528         c_retv_if(!CAL_STRLEN(input_str), NULL);
529
530         char *color_str = NULL;
531         const char *color_start_str = "<color=#2A89C2FF>";
532         const char *color_end_str = "</color>";
533         char* sub_str = NULL;
534
535         int color_start_str_sz = CAL_STRLEN(color_start_str);
536         int color_end_str_sz = CAL_STRLEN(color_end_str);
537         int input_str_sz = CAL_STRLEN(input_str);
538         int search_str_sz = CAL_STRLEN(search_str);
539
540         sub_str= strcasestr(input_str, search_str);
541         int sub_str_sz = CAL_STRLEN(sub_str);
542
543         c_retv_if(!sub_str_sz, NULL);
544
545         color_str = calloc(1, color_start_str_sz+color_end_str_sz+input_str_sz+1);
546         c_retv_if(!color_str, NULL);
547
548         int head_str_sz = sub_str - input_str;
549
550         CAL_STRNCPY(color_str, input_str, head_str_sz);
551         CAL_STRNCPY(color_str + head_str_sz, color_start_str, color_start_str_sz);
552         CAL_STRNCPY(color_str + head_str_sz + color_start_str_sz, sub_str, search_str_sz);
553         CAL_STRNCPY(color_str + head_str_sz + color_start_str_sz + search_str_sz, color_end_str, color_end_str_sz);
554         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);
555
556         return color_str;
557 }