Merge pull request #2948 from ace20022/blu_lang_fix
[vuplus_xbmc] / xbmc / interfaces / AnnouncementManager.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "AnnouncementManager.h"
22 #include "threads/SingleLock.h"
23 #include <stdio.h>
24 #include "utils/log.h"
25 #include "utils/Variant.h"
26 #include "utils/StringUtils.h"
27 #include "FileItem.h"
28 #include "music/tags/MusicInfoTag.h"
29 #include "music/MusicDatabase.h"
30 #include "video/VideoDatabase.h"
31 #include "pvr/channels/PVRChannel.h"
32 #include "PlayListPlayer.h"
33
34 #define LOOKUP_PROPERTY "database-lookup"
35
36 using namespace std;
37 using namespace ANNOUNCEMENT;
38
39 #define m_announcers XBMC_GLOBAL_USE(ANNOUNCEMENT::CAnnouncementManager::Globals).m_announcers
40 #define m_critSection XBMC_GLOBAL_USE(ANNOUNCEMENT::CAnnouncementManager::Globals).m_critSection
41
42 void CAnnouncementManager::AddAnnouncer(IAnnouncer *listener)
43 {
44   if (!listener)
45     return;
46
47   CSingleLock lock (m_critSection);
48   m_announcers.push_back(listener);
49 }
50
51 void CAnnouncementManager::RemoveAnnouncer(IAnnouncer *listener)
52 {
53   if (!listener)
54     return;
55
56   CSingleLock lock (m_critSection);
57   for (unsigned int i = 0; i < m_announcers.size(); i++)
58   {
59     if (m_announcers[i] == listener)
60     {
61       m_announcers.erase(m_announcers.begin() + i);
62       return;
63     }
64   }
65 }
66
67 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message)
68 {
69   CVariant data;
70   Announce(flag, sender, message, data);
71 }
72
73 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CVariant &data)
74 {
75   CLog::Log(LOGDEBUG, "CAnnouncementManager - Announcement: %s from %s", message, sender);
76   CSingleLock lock (m_critSection);
77   for (unsigned int i = 0; i < m_announcers.size(); i++)
78     m_announcers[i]->Announce(flag, sender, message, data);
79 }
80
81 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item)
82 {
83   CVariant data;
84   Announce(flag, sender, message, item, data);
85 }
86
87 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data)
88 {
89   if (!item.get())
90   {
91     Announce(flag, sender, message, data);
92     return;
93   }
94
95   // Extract db id of item
96   CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject;
97   CStdString type;
98   int id = 0;
99   
100   if(item->HasPVRChannelInfoTag())
101   {
102     const PVR::CPVRChannel *channel = item->GetPVRChannelInfoTag();
103     id = channel->ChannelID();
104     type = "channel";
105
106     object["item"]["title"] = channel->ChannelName();
107     object["item"]["channeltype"] = channel->IsRadio() ? "radio" : "tv";
108
109     if (data.isMember("player") && data["player"].isMember("playerid"))
110       object["player"]["playerid"] = channel->IsRadio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
111   }
112   else if (item->HasVideoInfoTag())
113   {
114     id = item->GetVideoInfoTag()->m_iDbId;
115
116     // TODO: Can be removed once this is properly handled when starting playback of a file
117     if (id <= 0 && !item->GetPath().empty() &&
118        (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean()))
119     {
120       CVideoDatabase videodatabase;
121       if (videodatabase.Open())
122       {
123         CStdString path = item->GetPath();
124         CStdString videoInfoTagPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
125         if (videoInfoTagPath.Find("removable://") == 0)
126           path = videoInfoTagPath;
127         if (videodatabase.LoadVideoInfo(path, *item->GetVideoInfoTag()))
128           id = item->GetVideoInfoTag()->m_iDbId;
129
130         videodatabase.Close();
131       }
132     }
133
134     if (!item->GetVideoInfoTag()->m_type.empty())
135       type = item->GetVideoInfoTag()->m_type;
136     else
137       CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type);
138
139     if (id <= 0)
140     {
141       // TODO: Can be removed once this is properly handled when starting playback of a file
142       item->SetProperty(LOOKUP_PROPERTY, false);
143
144       CStdString title = item->GetVideoInfoTag()->m_strTitle;
145       if (title.IsEmpty())
146         title = item->GetLabel();
147       object["item"]["title"] = title;
148
149       switch (item->GetVideoContentType())
150       {
151       case VIDEODB_CONTENT_MOVIES:
152         if (item->GetVideoInfoTag()->m_iYear > 0)
153           object["item"]["year"] = item->GetVideoInfoTag()->m_iYear;
154         break;
155       case VIDEODB_CONTENT_EPISODES:
156         if (item->GetVideoInfoTag()->m_iEpisode >= 0)
157           object["item"]["episode"] = item->GetVideoInfoTag()->m_iEpisode;
158         if (item->GetVideoInfoTag()->m_iSeason >= 0)
159           object["item"]["season"] = item->GetVideoInfoTag()->m_iSeason;
160         if (!item->GetVideoInfoTag()->m_strShowTitle.empty())
161           object["item"]["showtitle"] = item->GetVideoInfoTag()->m_strShowTitle;
162         break;
163       case VIDEODB_CONTENT_MUSICVIDEOS:
164         if (!item->GetVideoInfoTag()->m_strAlbum.empty())
165           object["item"]["album"] = item->GetVideoInfoTag()->m_strAlbum;
166         if (!item->GetVideoInfoTag()->m_artist.empty())
167           object["item"]["artist"] = StringUtils::Join(item->GetVideoInfoTag()->m_artist, " / ");
168         break;
169       }
170     }
171   }
172   else if (item->HasMusicInfoTag())
173   {
174     id = item->GetMusicInfoTag()->GetDatabaseId();
175     type = "song";
176
177     // TODO: Can be removed once this is properly handled when starting playback of a file
178     if (id <= 0 && !item->GetPath().empty() &&
179        (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean()))
180     {
181       CMusicDatabase musicdatabase;
182       if (musicdatabase.Open())
183       {
184         CSong song;
185         if (musicdatabase.GetSongByFileName(item->GetPath(), song, item->m_lStartOffset))
186         {
187           item->GetMusicInfoTag()->SetSong(song);
188           id = item->GetMusicInfoTag()->GetDatabaseId();
189         }
190
191         musicdatabase.Close();
192       }
193     }
194
195     if (id <= 0)
196     {
197       // TODO: Can be removed once this is properly handled when starting playback of a file
198       item->SetProperty(LOOKUP_PROPERTY, false);
199
200       CStdString title = item->GetMusicInfoTag()->GetTitle();
201       if (title.IsEmpty())
202         title = item->GetLabel();
203       object["item"]["title"] = title;
204
205       if (item->GetMusicInfoTag()->GetTrackNumber() > 0)
206         object["item"]["track"] = item->GetMusicInfoTag()->GetTrackNumber();
207       if (!item->GetMusicInfoTag()->GetAlbum().empty())
208         object["item"]["album"] = item->GetMusicInfoTag()->GetAlbum();
209       if (!item->GetMusicInfoTag()->GetArtist().empty())
210         object["item"]["artist"] = item->GetMusicInfoTag()->GetArtist();
211     }
212   }
213   else if (item->IsVideo())
214   {
215     // video item but has no video info tag.
216     type = "movies";
217     object["item"]["title"] = item->GetLabel();
218   }
219   else if (item->HasPictureInfoTag())
220   {
221     type = "picture";
222     object["item"]["file"] = item->GetPath();
223   }
224   else
225     type = "unknown";
226
227   object["item"]["type"] = type;
228   if (id > 0)
229     object["item"]["id"] = id;
230
231   Announce(flag, sender, message, object);
232 }