2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <dpl/log/log.h>
18 #include <dpl/scoped_ptr.h>
20 #include "Mediacontent.h"
21 #include "MediacontentManager.h"
22 #include "MediaFilterValidator.h"
23 #include "MediaSearchVisitor.h"
30 using namespace TizenApis::Api::Mediacontent;
31 using namespace WrtDeviceApis::Commons;
35 const string SELECT_FOLDER_QUERY =
36 "select uuid, path, title, storage_type,modified_date from (select uuid, path, folder_name as title, storage_type,modified_date from visual_folder where valid=1 union select _id, path, folder_name as title, storage_type,modified_date from audio_folder) where 1 ";
38 const string VIEW_MEDIA_QUERY_WITH_FOLDER =
39 "select media_uuid, folder_uuid, content_type, display_name, path, thumbnail_path,created_date, released_date, modified_date, description,rating, album, artist, last_played_time, played_count,longitude, latitude, width, height, orientation, genre, author, duration, folder_name, folder_path from \
40 (select media_uuid,folder_uuid, content_type, display_name, path, thumbnail_path,null as created_date, released_date, modified_date, description,rating, album, artist, last_played_time, null as played_count,longitude, latitude, width, height, orientation,null as genre, null as author, duration from visual_media join \
42 (select media_uuid, longitude, latitude, description, width, height, datetaken as released_date, orientation,null as album, null as artist, null as last_played_time,null as duration from image_meta \
44 select media_uuid, longitude, latitude, description, width, height, datetaken as released_date, null as orientation, album, artist, last_played_time,duration from video_meta)) \
47 select audio_id, folder_id as folder_uuid, content_type, title as display_name, path, thumbnail_path, added_time, year, modified_date, description, favourite, album, artist, last_played_time, played_count, null as longitude, null as latitude, null as width, null as height, null as orientation, genre, author, duration from audio_media) \
48 join ( select uuid as folder_id, path as folder_path, folder_name, modified_date as folder_modified_date, storage_type from visual_folder \
50 select _id as folder_id, path, folder_name, modified_date, storage_type from audio_folder) \
51 on folder_uuid=folder_id where 1 ";
53 const string SELECT_MEDIA_ID_WITH_FOLDER =
54 "select item_id from item_view where folder_uuid=";
55 const string SELECT_EXTRA_AUDIO =
56 "select copyright,bitrate,track_num,size from audio_media where audio_id=";
61 namespace Mediacontent{
63 Mediacontent::Mediacontent()
71 db_util_open(MEDIA_DB_PATH, &hDBCt, 0);
72 LogDebug("hDBCt:" << hDBCt);
75 Mediacontent::~Mediacontent()
80 if(db_connnect_count == 0)
82 ret = db_util_close(hDBCt);
90 tm Mediacontent::toDateTm(time_t date)
94 tm_date.tm_year = (date / 10000) - 1900;
95 tm_date.tm_mon = ((date - ((tm_date.tm_year + 1900) * 10000)) / 100) - 1;
96 tm_date.tm_mday = (date - ((tm_date.tm_year + 1900) * 10000) - tm_date.tm_mon * 100);
102 void Mediacontent::convertToPlatformFolder(folder_s &media_folder, MediacontentFolderPtr& newFolder)
104 if(media_folder.folder_uuid != NULL)
106 newFolder->setFolderUUID(media_folder.folder_uuid);
108 if(media_folder.folder_path != NULL)
110 newFolder->setFolderName(media_folder.folder_name);
112 if(media_folder.folder_name != NULL)
114 newFolder->setFolderPath(media_folder.folder_path);
117 newFolder->setFolderModifiedDate(toDateTm(media_folder.modified_date));
121 if(media_folder.storage_type == 0)
123 storageType = "INTERNAL";
125 else if( media_folder.storage_type == 1)
127 storageType = "EXTERNAL";
131 storageType = "UNKNOWN";
133 newFolder->setFolderStorageType(storageType);
138 string Mediacontent::makeQuerySortMode(SortModeArrayPtr attr)
143 SortModeArray::iterator it = attr->begin();
145 for (;it!=attr->end(); ++it)
147 attriName = (*it)->getAttributeName();
148 //convert to attribue's name
149 MediaSearchVisitor visitor;
150 attriName = visitor.getPlatformAttr(attriName);
151 if (attriName.compare("") != 0)
155 query.append(" ORDER BY ");
160 query.append(attriName);
162 if ((*it)->getOrder() == Api::Tizen::ASCENDING_SORT_ORDER)
164 query.append(" ASC");
168 query.append(" DESC");
179 void Mediacontent::OnRequestReceived(const IEventFindFolderPtr &eFolder)
187 string query(SELECT_FOLDER_QUERY);
190 MediaSearchVisitorPtr visitor(new MediaSearchVisitor());
192 if(eFolder->getFilterIsSet())
194 FilterPtr filter = eFolder->getFilter();
196 FilterValidatorPtr validator = MediaFilterValidatorFactory::getMediaFilterValidator(MediaFilterValidatorFactory::QUERY_FOLDER);
197 bool success = filter->validate(validator);
200 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
202 IFilterVisitorPtr IVisitor = DPL::StaticPointerCast<IFilterVisitor>(visitor);
204 visitor->setQueryType(MediaSearchVisitor::QUERY_FOLDER);
205 filter->travel(IVisitor);
206 condition = visitor->getResult();
208 query.append(" and ");
209 query.append(condition);
212 if(eFolder->getSortModesIsSet())
214 sortMode = makeQuerySortMode(eFolder->getSortModes());
216 query.append(sortMode);
220 if (eFolder->getLimitIsSet())
222 limitOffset.append(" LIMIT ");
223 std::stringstream limitStream;
224 limitStream << eFolder->getLimit();
225 limitOffset.append(limitStream.str());
226 if(eFolder->getOffsetIsSet())
228 limitOffset.append(" OFFSET ");
229 std::stringstream offsetStream;
230 offsetStream << eFolder->getOffset();
231 limitOffset.append(offsetStream.str());
234 query.append(limitOffset);
236 LogDebug("execute condition [" << condition << "]");
237 LogDebug("execute projection [" << projection << "]");
238 LogDebug("execute sortMode [" << sortMode << "]");
239 LogDebug("execute limitOffset [" << limitOffset << "]");
240 LogDebug("execute query [" << query << "]");
244 sqlite3_stmt* pStmt = NULL;
245 folder_s media_folder;
246 sqlite3_prepare_v2(hDBCt, (char *)(query.c_str()), strlen((char *)(query.c_str())), &pStmt, NULL);
247 while( sqlite3_step(pStmt) == SQLITE_ROW)
249 media_folder.folder_uuid = (char *)sqlite3_column_text(pStmt, 0);
250 media_folder.folder_path = (char *)sqlite3_column_text(pStmt, 1);
251 media_folder.folder_name = (char *)sqlite3_column_text(pStmt, 2);
252 media_folder.storage_type = sqlite3_column_int(pStmt, 3);
253 media_folder.modified_date = sqlite3_column_int(pStmt, 4);
255 MediacontentFolderPtr newFolder(new MediacontentFolder());
256 convertToPlatformFolder(media_folder, newFolder);
258 string queryMediaId(SELECT_MEDIA_ID_WITH_FOLDER);
259 queryMediaId.append("'");
260 queryMediaId.append(media_folder.folder_uuid);
261 queryMediaId.append("'");
262 sqlite3_stmt* pStmt1 = NULL;
263 if(sqlite3_prepare_v2(hDBCt, (char *)(queryMediaId.c_str()), strlen((char *)(queryMediaId.c_str())), &pStmt1, NULL) == SQLITE_OK)
265 MediaIdListPtr newMediaIdList(new MediaIdList());
266 //sqlite3_bind_text(pStmt1, 1, media_folder.folder_uuid,strlen(media_folder.folder_uuid), SQLITE_TRANSIENT);
267 LogDebug("execute 111111 [" << queryMediaId << "]");
268 while( sqlite3_step(pStmt1) == SQLITE_ROW)
270 string mediaId = (char *)sqlite3_column_text(pStmt1, 0);
271 LogDebug("execute mediaId [" << mediaId << "]");
272 newMediaIdList->push_back(mediaId);
274 newFolder->setMediaIdList(newMediaIdList);
275 sqlite3_finalize(pStmt1);
278 eFolder->addFolder(newFolder);
280 sqlite3_finalize(pStmt);
281 eFolder->setResult(true);
284 catch (const Exception &ex)
286 LogError("Exception: " << ex.DumpToString());
287 eFolder->setResult(false);
289 eFolder->setCancelAllowed(true);
293 void Mediacontent::OnRequestReceived(const IEventFindMediaPtr &eMedia)
295 LogDebug("OnRequestReceived::IEventFindMediaPtr entered");
302 string query(VIEW_MEDIA_QUERY_WITH_FOLDER);
304 MediaSearchVisitorPtr visitor(new MediaSearchVisitor());
306 if(eMedia->getFilterIsSet())
308 FilterPtr filter = eMedia->getFilter();
310 // FIXME validator have to be placed at JS binding.
311 FilterValidatorPtr validator = MediaFilterValidatorFactory::getMediaFilterValidator(MediaFilterValidatorFactory::QUERY_MEDIA);
312 bool success = filter->validate(validator);
315 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
317 IFilterVisitorPtr IVisitor = DPL::StaticPointerCast<IFilterVisitor>(visitor);
319 visitor->setQueryType(MediaSearchVisitor::QUERY_MEDIA);
320 filter->travel(IVisitor);
321 condition = visitor->getResult();
322 query.append(" and ");
323 query.append(condition);
326 if(eMedia->getSortModesIsSet())
328 sortMode = makeQuerySortMode(eMedia->getSortModes());
330 query.append(sortMode);
332 if (eMedia->getLimitIsSet())
334 limitOffset.append(" LIMIT ");
335 std::stringstream limitStream;
336 limitStream << eMedia->getLimit();
337 limitOffset.append(limitStream.str());
338 if(eMedia->getOffsetIsSet())
340 limitOffset.append(" OFFSET ");
341 std::stringstream offsetStream;
342 offsetStream << eMedia->getOffset();
343 limitOffset.append(offsetStream.str());
346 query.append(limitOffset);
349 LogDebug("execute condition [" << condition << "]");
350 LogDebug("execute projection [" << projection << "]");
351 LogDebug("execute sortMode [" << sortMode << "]");
352 LogDebug("execute limitOffset [" << limitOffset << "]");
353 LogDebug("execute query [" << query << "]");
360 sqlite3_stmt* pStmt = NULL;
362 ret = sqlite3_prepare_v2(hDBCt, (char *)(query.c_str()), query.length(), &pStmt, NULL);
364 while( sqlite3_step(pStmt) == SQLITE_ROW)
367 content_type = sqlite3_column_int(pStmt, 2);
369 if(content_type == MEDIA_TYPE_IMAGE)
372 MediacontentImage *newImage(new MediacontentImage());
373 readImageFromDB(pStmt,newImage);
374 eMedia->addMedia(newImage);
376 else if(content_type == MEDIA_TYPE_VIDEO)
378 MediacontentVideo *newVideo(new MediacontentVideo());
379 readVideoFromDB(pStmt,newVideo);
380 eMedia->addMedia(newVideo);
382 else if(content_type == MEDIA_TYPE_AUDIO)
384 MediacontentAudio *newVAudio(new MediacontentAudio());
385 readAudioFromDB(pStmt,newVAudio);
386 eMedia->addMedia(newVAudio);
391 sqlite3_finalize(pStmt);
392 eMedia->setResult(true);
395 catch (const Exception &ex)
397 LogError("Exception: " << ex.DumpToString());
398 eMedia->setResult(false);
401 eMedia->setCancelAllowed(true);
406 void Mediacontent::OnRequestReceived(const IEventUpdateMediaPtr &eMedia)
408 LogDebug("OnRequestReceived::IEventUpdateMediaPtr entered");
412 MediacontentMediaPtr mediaPtr = eMedia->getMediaItem();
413 string type = mediaPtr->getMediaType();
415 if(type.compare("IMAGE")==0)
418 MediacontentImagePtr imagePtr = DPL::DynamicPointerCast<MediacontentImage>(mediaPtr);
424 if(type.compare("VIDEO")==0)
427 MediacontentVideoPtr videoPtr = DPL::DynamicPointerCast<MediacontentVideo>(mediaPtr);
433 if(type.compare("AUDIO")==0)
436 MediacontentAudioPtr audioPtr = DPL::DynamicPointerCast<MediacontentAudio>(mediaPtr);
443 eMedia->setResult(true);
445 catch (const Exception &ex)
447 LogError("Exception: " << ex.DumpToString());
448 eMedia->setResult(false);
451 eMedia->setCancelAllowed(true);
457 void Mediacontent::readImageFromDB(sqlite3_stmt* pStmt, MediacontentImage* newImage)
463 tmp = (char*)sqlite3_column_text(pStmt,0);
465 newImage->setMediaUUID(tmp);
467 newImage->setMediaType("IMAGE");
470 tmp = (char*)sqlite3_column_text(pStmt,3);
472 newImage->setDisplayName(tmp);
474 tmp = (char*)sqlite3_column_text(pStmt,4);
476 newImage->setFilePath(tmp);
478 tmp = (char*)sqlite3_column_text(pStmt,5);
480 newImage->setThumbnailPath(tmp);
482 newImage->setCreatedDate(toDateTm(sqlite3_column_int(pStmt,6)));
483 newImage->setReleasedDate(toDateTm(sqlite3_column_int(pStmt,7)));
484 newImage->setModifiedDate(toDateTm(sqlite3_column_int(pStmt,8)));
486 tmp = (char*)sqlite3_column_text(pStmt,9);
488 newImage->setDescription(tmp);
490 newImage->setFavorite(sqlite3_column_int(pStmt,10));
491 newImage->setImageLatitude(sqlite3_column_double(pStmt,15));
492 newImage->setImageLongitude(sqlite3_column_double(pStmt,16));
493 newImage->setImageWidth(sqlite3_column_int(pStmt,17));
494 newImage->setImageHeight(sqlite3_column_int(pStmt,18));
495 int orientation = (sqlite3_column_int(pStmt,19));
496 string orientationStr;
500 orientationStr = "NORMAL";
503 orientationStr = "FLIP_HORIZONTAL";
506 orientationStr = "ROTATE_180";
509 orientationStr = "FLIP_VERTICAL";
512 orientationStr = "TRANSPOSE";
515 orientationStr = "ROTATE_90";
518 orientationStr = "TRANSVERSE";
521 orientationStr = "ROTATE_270";
524 newImage->setImageOrientation(orientationStr);
531 void Mediacontent::readVideoFromDB(sqlite3_stmt* pStmt, MediacontentVideo* newVideo)
537 tmp = (char*)sqlite3_column_text(pStmt,0);
539 newVideo->setMediaUUID(tmp);
541 newVideo->setMediaType("VIDEO");
544 tmp = (char*)sqlite3_column_text(pStmt,3);
546 newVideo->setDisplayName(tmp);
548 tmp = (char*)sqlite3_column_text(pStmt,4);
550 newVideo->setFilePath(tmp);
552 tmp = (char*)sqlite3_column_text(pStmt,5);
554 newVideo->setThumbnailPath(tmp);
556 newVideo->setCreatedDate(toDateTm(sqlite3_column_int(pStmt,6)));
557 newVideo->setReleasedDate(toDateTm(sqlite3_column_int(pStmt,7)));
558 newVideo->setModifiedDate(toDateTm(sqlite3_column_int(pStmt,8)));
560 tmp = (char*)sqlite3_column_text(pStmt,9);
562 newVideo->setDescription(tmp);
564 newVideo->setFavorite(sqlite3_column_int(pStmt,10));
566 tmp = (char*)sqlite3_column_text(pStmt,11);
568 newVideo->setVideoAlbum(tmp);
570 tmp = (char*)sqlite3_column_text(pStmt,12);
572 newVideo->setVideoArtist(tmp);
574 newVideo->setVideoPlayedTime(sqlite3_column_int(pStmt,13));
575 newVideo->setVideoPlayCount(sqlite3_column_int(pStmt,14));
577 newVideo->setVideoLongitude(sqlite3_column_double(pStmt,15));
578 newVideo->setVideoLatitude(sqlite3_column_double(pStmt,16));
580 newVideo->setVideoWidth(sqlite3_column_int(pStmt,17));
581 newVideo->setVideoHeight(sqlite3_column_int(pStmt,18));
583 newVideo->setVideoDuration(sqlite3_column_int(pStmt,22));
589 void Mediacontent::readAudioFromDB(sqlite3_stmt* pStmt, MediacontentAudio* newAudio)
595 tmp = (char*)sqlite3_column_text(pStmt,0);
597 newAudio->setMediaUUID(tmp);
599 newAudio->setMediaType("AUDIO");
602 tmp = (char*)sqlite3_column_text(pStmt,3);
604 newAudio->setDisplayName(tmp);
606 tmp = (char*)sqlite3_column_text(pStmt,4);
608 newAudio->setFilePath(tmp);
610 tmp = (char*)sqlite3_column_text(pStmt,5);
612 newAudio->setThumbnailPath(tmp);
614 newAudio->setCreatedDate(toDateTm(sqlite3_column_int(pStmt,6)));
615 newAudio->setReleasedDate(toDateTm(sqlite3_column_int(pStmt,7)));
616 newAudio->setModifiedDate(toDateTm(sqlite3_column_int(pStmt,8)));
618 tmp = (char*)sqlite3_column_text(pStmt,9);
620 newAudio->setDescription(tmp);
622 newAudio->setFavorite(sqlite3_column_int(pStmt,10));
624 tmp = (char*)sqlite3_column_text(pStmt,11);
626 newAudio->setAudioAlbum(tmp);
628 tmp = (char*)sqlite3_column_text(pStmt,12);
630 newAudio->setAudioArtist(tmp);
632 newAudio->setAudioPlayedTime(sqlite3_column_int(pStmt,13));
633 newAudio->setAudioPlayCount(sqlite3_column_int(pStmt,14));
635 tmp = (char*)sqlite3_column_text(pStmt,20);
637 newAudio->setAudioGenre(tmp);
639 tmp = (char*)sqlite3_column_text(pStmt,21);
641 newAudio->setAudioComposer(tmp);
643 newAudio->setAudioDuration(sqlite3_column_int(pStmt,22));
645 string queryExtraAudio(SELECT_EXTRA_AUDIO);
646 queryExtraAudio.append("'");
647 queryExtraAudio.append(newAudio->getMediaUUID());
648 queryExtraAudio.append("'");
649 sqlite3_stmt* pStmt1 = NULL;
650 //"select copyright,bitrate,track_num,size from audio_media where audio_id=";
651 if(sqlite3_prepare_v2(hDBCt, (char *)(queryExtraAudio.c_str()), strlen((char *)(queryExtraAudio.c_str())), &pStmt1, NULL) == SQLITE_OK)
653 while( sqlite3_step(pStmt1) == SQLITE_ROW)
655 tmp = (char*)sqlite3_column_text(pStmt,0);
657 newAudio->setAudioCopyright(tmp);
658 newAudio->setAudioBitrate(sqlite3_column_int(pStmt,1));
659 newAudio->setAudioTrackNum(sqlite3_column_int(pStmt,2));
660 newAudio->setAudioSize(sqlite3_column_int(pStmt,3));
662 sqlite3_finalize(pStmt1);
665 MMHandleType tag_attrs = 0;
666 LogDebug("AUDIO PATH: " << newAudio->getFilePath());
667 int ret = mm_file_create_tag_attrs(&tag_attrs, newAudio->getFilePath().c_str());
669 char *err_attr_name = NULL;
673 if (ret == MM_ERROR_NONE && tag_attrs)
675 ret = mm_file_get_attrs( tag_attrs,
677 MM_FILE_TAG_UNSYNCLYRICS, &unSyncText, &unSyncLen,
678 MM_FILE_TAG_SYNCLYRICS_NUM, &syncTextNum,
681 if (ret != MM_ERROR_NONE && err_attr_name)
683 MediacontentLyricsPtr lyricsPtr(new MediacontentLyrics());
686 lyricsPtr->setMediaLyricsType("SYNCHRONIZED");
687 for(int i=0; i < syncTextNum; i++)
689 unsigned long time_info = 0;
690 char * lyrics_info = NULL;
691 mm_file_get_synclyrics_info(tag_attrs,i,&time_info,&lyrics_info);
692 lyricsPtr->addMediaLyricsTimeStamp(time_info);
693 lyricsPtr->addMediaLyricsText(lyrics_info);
694 LogDebug("SYNCHRONIZED: " << lyrics_info);
699 LogDebug("UNSYNCHRONIZED: " << unSyncText);
700 lyricsPtr->setMediaLyricsType("UNSYNCHRONIZED");
701 lyricsPtr->addMediaLyricsTimeStamp(0);
702 lyricsPtr->addMediaLyricsText(unSyncText);
705 newAudio->setAudioLyrics(lyricsPtr);