c60d669fc8d43b9be1601f4a72d03f8cf12271d9
[profile/tv/apps/web/browser.git] / services / HistoryService / HistoryService.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 <string>
18 #include <BrowserAssert.h>
19 #include <boost/date_time/posix_time/posix_time.hpp>
20 #include <boost/date_time/date.hpp>
21 #include <boost/date_time/date_defs.hpp>
22 #include <boost/date_time/gregorian/gregorian.hpp>
23
24 #include "ServiceManager.h"
25 #include "HistoryService.h"
26 #include "HistoryItem.h"
27 #include "AbstractWebEngine.h"
28 #include "EflTools.h"
29 #include "Tools/GeneralTools.h"
30
31
32
33
34 namespace tizen_browser
35 {
36 namespace services
37 {
38
39 EXPORT_SERVICE(HistoryService, DOMAIN_HISTORY_SERVICE)
40
41 const int SEARCH_LIKE = 1;
42
43 HistoryService::HistoryService() : m_testDbMod(false)
44 {
45     BROWSER_LOGD("HistoryService");
46 }
47
48 HistoryService::~HistoryService()
49 {
50 }
51
52 std::shared_ptr<tizen_browser::services::StorageService> HistoryService::getStorageManager()
53 {
54     if (!m_storageManager) {
55         m_storageManager = std::dynamic_pointer_cast <
56                            tizen_browser::services::StorageService,
57                            tizen_browser::core::AbstractService > (
58                                tizen_browser::core::ServiceManager::getInstance().getService(
59                                    DOMAIN_STORAGE_SERVICE));
60     }
61
62     M_ASSERT(m_storageManager);
63     m_storageManager->init(m_testDbMod);
64
65     return m_storageManager;
66 }
67
68 void HistoryService::setStorageServiceTestMode(bool testmode) {
69         m_testDbMod = testmode;
70 }
71
72 int HistoryService::getHistoryItemsCount(){
73     int *ids = nullptr;
74     int count=0;
75     bp_history_rows_cond_fmt conds;
76     conds.limit = 20;  //no of rows to get negative means no limitation
77     conds.offset = -1;   //the first row's index
78     conds.order_offset =BP_HISTORY_O_DATE_CREATED; // property to sort
79     conds.ordering = 1; //way of ordering 0 asc 1 desc
80     conds.period_offset = BP_HISTORY_O_DATE_CREATED;
81     conds.period_type = BP_HISTORY_DATE_TODAY;
82     int ret = bp_history_adaptor_get_cond_ids_p(&ids ,&count, &conds, 0, nullptr, 0);
83     if (ret<0){
84         BROWSER_LOGD("Error! Could not get ids!");
85     }
86
87     BROWSER_LOGD("[%s:%d] History Count %d", __PRETTY_FUNCTION__, __LINE__, count);
88     return count;
89 }
90
91 bool HistoryService::isDuplicate(const char* url) const
92 {
93     M_ASSERT(url);
94     int *ids=nullptr;
95     int count=0;
96     bp_history_rows_cond_fmt conds;
97     conds.limit = 20;  //no of rows to get negative means no limitation
98     conds.offset = -1;   //the first row's index
99     conds.order_offset =BP_HISTORY_O_DATE_CREATED; // property to sort
100     conds.ordering = 1; //way of ordering 0 asc 1 desc
101     conds.period_offset = BP_HISTORY_O_DATE_CREATED;
102     conds.period_type = BP_HISTORY_DATE_TODAY;
103     int ret = bp_history_adaptor_get_cond_ids_p(&ids ,&count, &conds, 0, nullptr, 0);
104     if (ret<0){
105         BROWSER_LOGD("Error! Could not get ids!");
106     }
107
108     bp_history_offset offset = (BP_HISTORY_O_URL | BP_HISTORY_O_DATE_CREATED);
109
110     for (int i = 0; i < count; i++) {
111         bp_history_info_fmt history_info;
112         bp_history_adaptor_get_info(ids[i], offset, &history_info);
113         if (!history_info.url) {
114             BROWSER_LOGD("Warning: history entry without url!");
115         } else if (!strcmp(history_info.url, url)) {
116             int freq;
117             bp_history_adaptor_get_frequency(ids[i], &freq);
118             bp_history_adaptor_set_frequency(ids[i], freq + 1);
119             bp_history_adaptor_set_date_visited(ids[i],-1);
120             return true;
121         }
122     }
123     return false;
124 }
125
126 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryAll()
127 {
128     return getHistoryItems(BP_HISTORY_DATE_ALL);
129 }
130
131 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryToday()
132 {
133     return getHistoryItems(BP_HISTORY_DATE_TODAY);
134 }
135
136 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryYesterday()
137 {
138     return getHistoryItems(BP_HISTORY_DATE_YESTERDAY);
139 }
140
141 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryLastWeek()
142 {
143     return getHistoryItems(BP_HISTORY_DATE_LAST_7_DAYS);
144 }
145
146 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryLastMonth()
147 {
148     return getHistoryItems(BP_HISTORY_DATE_LAST_MONTH);
149 }
150 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryOlder()
151 {
152     return getHistoryItems(BP_HISTORY_DATE_OLDER);
153 }
154
155 std::shared_ptr<HistoryItemVector> HistoryService::getMostVisitedHistoryItems()
156 {
157     std::shared_ptr<HistoryItemVector> ret_history_list(new HistoryItemVector);
158
159     int *ids=nullptr;
160     int count=-1;
161     bp_history_rows_cond_fmt conds;
162     conds.limit = 20;  //no of rows to get negative means no limitation
163     conds.offset = -1;   //the first row's index
164     conds.order_offset =BP_HISTORY_O_DATE_CREATED; // property to sort
165     conds.ordering = 1; //way of ordering 0 asc 1 desc
166     conds.period_offset = BP_HISTORY_O_DATE_CREATED;
167     conds.period_type = BP_HISTORY_DATE_TODAY;
168
169     int ret = bp_history_adaptor_get_cond_ids_p(&ids ,&count, &conds, 0, nullptr, 0);
170     if (ret<0){
171         BROWSER_LOGD("Error! Could not get ids!");
172     }
173
174     bp_history_offset offset = (BP_HISTORY_O_URL | BP_HISTORY_O_TITLE | BP_HISTORY_O_FAVICON | BP_HISTORY_O_DATE_CREATED | BP_HISTORY_O_THUMBNAIL);
175
176     int freq_arr[1000];
177     for(int i = 0; i< count; i++){
178         int freq;
179         if (0 == bp_history_adaptor_get_frequency(ids[i], &freq))
180         {
181             freq_arr[i] = freq;
182         }
183     }
184
185     int index_array[6];
186     int j=0;
187     int maximum = freq_arr[0];
188     int position = 0;
189
190     for(int k=1; k<=5;k++){
191         if(k > count || count == 0)
192             break;
193
194     maximum = freq_arr[0];
195     position = 0;
196
197     for(int i =1;i<count;i++){
198         if (freq_arr[i] > maximum)
199             {
200                 maximum  = freq_arr[i];
201                 position = i;
202             }
203          }
204         index_array[j++] = position;
205         freq_arr[position] = -1;
206     }
207
208     for(int i = 0; i < j; i++){
209         bp_history_info_fmt history_info;
210         bp_history_adaptor_get_info(ids[index_array[i]],offset,&history_info);
211
212         std::shared_ptr<HistoryItem> history = std::make_shared<HistoryItem>(std::string(history_info.url));
213         history->setUrl(std::string(history_info.url ? history_info.url : ""));
214         history->setTitle(std::string(history_info.title ? history_info.title : ""));
215
216         //thumbail
217         if (history_info.thumbnail_length != -1) {
218             std::shared_ptr<tizen_browser::tools::BrowserImage> hi = std::make_shared<tizen_browser::tools::BrowserImage>();
219             hi->imageType = tools::BrowserImage::ImageTypePNG;
220             hi->width = history_info.thumbnail_width;
221             hi->height = history_info.thumbnail_height;
222             hi->dataSize = history_info.thumbnail_length;
223             hi->imageData = (void*)malloc(history_info.thumbnail_length);
224             memcpy(hi->imageData, (void*)history_info.thumbnail, history_info.thumbnail_length);
225             history->setThumbnail(hi);
226         } else {
227             BROWSER_LOGD("history thumbnail lenght is -1");
228         }
229
230         ret_history_list->push_back(history);
231     }
232     free(ids);
233     return ret_history_list;
234 }
235
236 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryItemsByURL(const std::string& url, int maxItems)
237 {
238     std::string search("%" + tools::extractDomain(url) + "%");     // add SQL 'any character' signs
239
240     std::shared_ptr<HistoryItemVector> items(new HistoryItemVector);
241     int *ids=nullptr;
242     int count=-1;
243     bp_history_rows_cond_fmt conds;
244     conds.limit = maxItems;  //no of rows to get negative means no limitation
245     conds.offset = -1;   //the first row's index
246     conds.order_offset = BP_HISTORY_O_DATE_VISITED; // property to sort
247     conds.ordering = 1; //way of ordering 0 asc 1 desc
248     conds.period_offset = BP_HISTORY_O_DATE_VISITED;
249     conds.period_type = BP_HISTORY_DATE_ALL;
250
251     int ret = bp_history_adaptor_get_cond_ids_p(&ids ,&count, &conds, BP_HISTORY_O_URL, search.c_str(), SEARCH_LIKE);
252     if (ret < 0) {
253         BROWSER_LOGD("Error! Could not get ids!");
254         return items;
255     }
256
257     bp_history_offset offset = (BP_HISTORY_O_URL | BP_HISTORY_O_TITLE | BP_HISTORY_O_DATE_VISITED);
258     for(int i = 0; i < count; i++) {
259         bp_history_info_fmt history_info;
260         bp_history_adaptor_get_info(ids[i], offset, &history_info);
261
262         std::shared_ptr<HistoryItem> history = std::make_shared<HistoryItem>(std::string(history_info.url));
263         history->setTitle(std::string(history_info.title ? history_info.title : ""));
264
265         items->push_back(history);
266     }
267
268     free(ids);
269     return items;
270 }
271
272 void HistoryService::addHistoryItem(std::shared_ptr<HistoryItem> his,std::shared_ptr<tizen_browser::tools::BrowserImage> thumbnail){
273     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
274     his->setFavIcon(his->getFavIcon());
275     his->setThumbnail(thumbnail);
276
277     if (isDuplicate(his->getUrl().c_str()))
278         return;
279
280     int id = -1;
281     int ret = bp_history_adaptor_create(&id);
282     if (ret<0){
283         BROWSER_LOGE("Error! Could not create new bookmark!");
284     }
285
286     int *ids=nullptr;
287     int count=-1;
288     bp_history_rows_cond_fmt conds;
289     conds.limit = 20;  //no of rows to get negative means no limitation
290     conds.offset = -1;   //the first row's index
291     conds.order_offset =BP_HISTORY_O_DATE_CREATED; // property to sort
292     conds.ordering = 1; //way of ordering 0 asc 1 desc
293     conds.period_offset = BP_HISTORY_O_DATE_CREATED;
294     conds.period_type = BP_HISTORY_DATE_TODAY;
295
296     ret = bp_history_adaptor_get_cond_ids_p(&ids ,&count, &conds, 0, nullptr, 0);
297     if (ret<0){
298         BROWSER_LOGE("Error! Could not get ids!");
299     }
300
301     bp_history_adaptor_set_url(id, (his->getUrl()).c_str());
302     bp_history_adaptor_set_title(id, (his->getTitle()).c_str());
303     bp_history_adaptor_set_date_visited(id,-1);
304     bp_history_adaptor_set_frequency(id, 1);
305
306     if (thumbnail) {
307        std::unique_ptr<tizen_browser::tools::Blob> thumb_blob = tizen_browser::tools::EflTools::getBlobPNG(thumbnail);
308        unsigned char * thumb = std::move((unsigned char*)thumb_blob->getData());
309        bp_history_adaptor_set_snapshot(id, thumbnail->width, thumbnail->height, thumb, thumb_blob->getLength());
310     }
311
312     std::shared_ptr<tizen_browser::tools::BrowserImage> favicon = his->getFavIcon();
313     if (favicon) {
314        std::unique_ptr<tizen_browser::tools::Blob> favicon_blob = tizen_browser::tools::EflTools::getBlobPNG(favicon);
315        unsigned char * fav = std::move((unsigned char*)favicon_blob->getData());
316        bp_history_adaptor_set_icon(id, favicon->width, favicon->height, fav, favicon_blob->getLength());
317     }
318
319     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
320     historyAdded(his);
321 }
322
323 void HistoryService::clearAllHistory()
324 {
325     bp_history_adaptor_reset();
326     history_list.clear();
327     historyAllDeleted();
328 }
329
330 int HistoryService::getHistoryId(const std::string & url)
331 {
332     bp_history_rows_cond_fmt conds;
333     conds.limit = -1;
334     conds.offset = 0;
335     conds.order_offset = BP_HISTORY_O_DATE_CREATED;
336     conds.ordering = 0;
337     conds.period_offset = BP_HISTORY_O_DATE_CREATED;
338     conds.period_type = BP_HISTORY_DATE_ALL;
339     int *ids = nullptr;
340     int ids_count = 0;
341     int ret = bp_history_adaptor_get_cond_ids_p(&ids ,&ids_count, &conds, BP_HISTORY_O_URL, url.c_str(), 0);
342     if (ret < 0) {
343         BROWSER_LOGD("Error! Could not get ids!");
344     } else if (ids_count != 0) {
345         int i = *ids;
346         free(ids);
347         return i;
348     }
349     return 0;
350 }
351
352 void HistoryService::clearURLHistory(const std::string & url)
353 {
354     int id = getHistoryId(url);
355     if (id!=0)
356         bp_history_adaptor_delete(id);
357     if(0 == getHistoryItemsCount())
358         historyEmpty(true);
359     historyDeleted(url);
360 }
361
362 std::shared_ptr<HistoryItem> HistoryService::getHistoryItem(int * ids, int idNumber)
363 {
364     bp_history_offset offset = (BP_HISTORY_O_URL | BP_HISTORY_O_TITLE | BP_HISTORY_O_FAVICON | BP_HISTORY_O_DATE_VISITED);
365     bp_history_info_fmt history_info;
366     bp_history_adaptor_get_info(ids[idNumber], offset, &history_info);
367
368     int date;
369     bp_history_adaptor_get_date_created(ids[idNumber], &date);
370
371     struct tm *item_time_info;
372     time_t item_time = (time_t) date;
373     item_time_info = localtime(&item_time);
374
375     int m_year = item_time_info->tm_year;
376     int m_month = item_time_info->tm_mon + 1;
377     int m_month_day = item_time_info->tm_mday;
378     int min = item_time_info->tm_min;
379     int hour = item_time_info->tm_hour;
380     int sec = item_time_info->tm_sec;
381
382     m_year = 2000 + m_year % 100;
383
384     std::shared_ptr<HistoryItem> history = std::make_shared <HistoryItem> (std::string(history_info.url));
385     boost::gregorian::date d(m_year, m_month, m_month_day);
386     boost::posix_time::ptime t(d, boost::posix_time::time_duration(hour, min, sec));
387     history->setLastVisit(t);
388     history->setUrl(std::string(history_info.url ? history_info.url : ""));
389     history->setTitle(std::string(history_info.title ? history_info.title : ""));
390
391     //thumbail
392     std::shared_ptr<tizen_browser::tools::BrowserImage> hi = std::make_shared<tizen_browser::tools::BrowserImage>();
393     hi->imageType = tizen_browser::tools::BrowserImage::ImageType::ImageTypePNG;
394     hi->width = history_info.thumbnail_width;
395     hi->height = history_info.thumbnail_height;
396     hi->dataSize = history_info.thumbnail_length;
397     hi->imageData = (void*) malloc(history_info.thumbnail_length);
398     memcpy(hi->imageData, (void*) history_info.thumbnail, history_info.thumbnail_length);
399     history->setThumbnail(hi);
400
401     return history;
402 }
403
404 std::shared_ptr<HistoryItem> HistoryService::getCurrentTab()
405 {
406     int *ids=nullptr;
407     int count = -1;
408     bp_history_rows_cond_fmt conds;
409     conds.limit = 20;  //no of rows to get negative means no limitation
410     conds.offset = -1;   //the first row's index
411     conds.order_offset = BP_HISTORY_O_DATE_VISITED; // property to sort
412     conds.ordering = 1; //way of ordering 0 asc 1 desc
413     conds.period_offset = BP_HISTORY_O_DATE_VISITED;
414     conds.period_type = BP_HISTORY_DATE_TODAY;
415
416     int ret = bp_history_adaptor_get_cond_ids_p(&ids , &count, &conds, 0, nullptr, 0);
417     if (ret<0){
418         BROWSER_LOGD("Error! Could not get ids!");
419     }
420
421     return getHistoryItem(ids);
422 }
423
424 std::shared_ptr<HistoryItemVector> HistoryService::getHistoryItems(bp_history_date_defs period)
425 {
426     std::shared_ptr<HistoryItemVector> ret_history_list(new HistoryItemVector);
427
428     int *ids=nullptr;
429     int count=-1;
430     bp_history_rows_cond_fmt conds;
431     conds.limit = 20;  //no of rows to get negative means no limitation
432     conds.offset = -1;   //the first row's index
433     conds.order_offset = BP_HISTORY_O_DATE_VISITED; // property to sort
434     conds.ordering = 1; //way of ordering 0 asc 1 desc
435     conds.period_offset = BP_HISTORY_O_DATE_VISITED;
436     conds.period_type = period;
437
438     int ret = bp_history_adaptor_get_cond_ids_p(&ids ,&count, &conds, 0, nullptr, 0);
439     if (ret<0) {
440         BROWSER_LOGD("Error! Could not get ids!");
441     }
442
443     for(int i = 0; i< count; i++) {
444         ret_history_list->push_back(getHistoryItem(ids, i));
445     }
446     free(ids);
447     return ret_history_list;
448 }
449
450 }
451 }