2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
21 #include "AnnouncementManager.h"
22 #include "threads/SingleLock.h"
24 #include "utils/log.h"
25 #include "utils/Variant.h"
26 #include "utils/StringUtils.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"
34 #define LOOKUP_PROPERTY "database-lookup"
37 using namespace ANNOUNCEMENT;
39 #define m_announcers XBMC_GLOBAL_USE(ANNOUNCEMENT::CAnnouncementManager::Globals).m_announcers
40 #define m_critSection XBMC_GLOBAL_USE(ANNOUNCEMENT::CAnnouncementManager::Globals).m_critSection
42 void CAnnouncementManager::Deinitialize()
44 CSingleLock lock (m_critSection);
48 void CAnnouncementManager::AddAnnouncer(IAnnouncer *listener)
53 CSingleLock lock (m_critSection);
54 m_announcers.push_back(listener);
57 void CAnnouncementManager::RemoveAnnouncer(IAnnouncer *listener)
62 CSingleLock lock (m_critSection);
63 for (unsigned int i = 0; i < m_announcers.size(); i++)
65 if (m_announcers[i] == listener)
67 m_announcers.erase(m_announcers.begin() + i);
73 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message)
76 Announce(flag, sender, message, data);
79 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CVariant &data)
81 CLog::Log(LOGDEBUG, "CAnnouncementManager - Announcement: %s from %s", message, sender);
82 CSingleLock lock (m_critSection);
83 for (unsigned int i = 0; i < m_announcers.size(); i++)
84 m_announcers[i]->Announce(flag, sender, message, data);
87 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item)
90 Announce(flag, sender, message, item, data);
93 void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data)
97 Announce(flag, sender, message, data);
101 // Extract db id of item
102 CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject;
106 if(item->HasPVRChannelInfoTag())
108 const PVR::CPVRChannel *channel = item->GetPVRChannelInfoTag();
109 id = channel->ChannelID();
112 object["item"]["title"] = channel->ChannelName();
113 object["item"]["channeltype"] = channel->IsRadio() ? "radio" : "tv";
115 if (data.isMember("player") && data["player"].isMember("playerid"))
116 object["player"]["playerid"] = channel->IsRadio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
118 else if (item->HasVideoInfoTag())
120 id = item->GetVideoInfoTag()->m_iDbId;
122 // TODO: Can be removed once this is properly handled when starting playback of a file
123 if (id <= 0 && !item->GetPath().empty() &&
124 (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean()))
126 CVideoDatabase videodatabase;
127 if (videodatabase.Open())
129 CStdString path = item->GetPath();
130 CStdString videoInfoTagPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
131 if (StringUtils::StartsWith(videoInfoTagPath, "removable://"))
132 path = videoInfoTagPath;
133 if (videodatabase.LoadVideoInfo(path, *item->GetVideoInfoTag()))
134 id = item->GetVideoInfoTag()->m_iDbId;
136 videodatabase.Close();
140 if (!item->GetVideoInfoTag()->m_type.empty())
141 type = item->GetVideoInfoTag()->m_type;
143 CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type);
147 // TODO: Can be removed once this is properly handled when starting playback of a file
148 item->SetProperty(LOOKUP_PROPERTY, false);
150 CStdString title = item->GetVideoInfoTag()->m_strTitle;
152 title = item->GetLabel();
153 object["item"]["title"] = title;
155 switch (item->GetVideoContentType())
157 case VIDEODB_CONTENT_MOVIES:
158 if (item->GetVideoInfoTag()->m_iYear > 0)
159 object["item"]["year"] = item->GetVideoInfoTag()->m_iYear;
161 case VIDEODB_CONTENT_EPISODES:
162 if (item->GetVideoInfoTag()->m_iEpisode >= 0)
163 object["item"]["episode"] = item->GetVideoInfoTag()->m_iEpisode;
164 if (item->GetVideoInfoTag()->m_iSeason >= 0)
165 object["item"]["season"] = item->GetVideoInfoTag()->m_iSeason;
166 if (!item->GetVideoInfoTag()->m_strShowTitle.empty())
167 object["item"]["showtitle"] = item->GetVideoInfoTag()->m_strShowTitle;
169 case VIDEODB_CONTENT_MUSICVIDEOS:
170 if (!item->GetVideoInfoTag()->m_strAlbum.empty())
171 object["item"]["album"] = item->GetVideoInfoTag()->m_strAlbum;
172 if (!item->GetVideoInfoTag()->m_artist.empty())
173 object["item"]["artist"] = StringUtils::Join(item->GetVideoInfoTag()->m_artist, " / ");
178 else if (item->HasMusicInfoTag())
180 id = item->GetMusicInfoTag()->GetDatabaseId();
183 // TODO: Can be removed once this is properly handled when starting playback of a file
184 if (id <= 0 && !item->GetPath().empty() &&
185 (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean()))
187 CMusicDatabase musicdatabase;
188 if (musicdatabase.Open())
191 if (musicdatabase.GetSongByFileName(item->GetPath(), song, item->m_lStartOffset))
193 item->GetMusicInfoTag()->SetSong(song);
194 id = item->GetMusicInfoTag()->GetDatabaseId();
197 musicdatabase.Close();
203 // TODO: Can be removed once this is properly handled when starting playback of a file
204 item->SetProperty(LOOKUP_PROPERTY, false);
206 CStdString title = item->GetMusicInfoTag()->GetTitle();
208 title = item->GetLabel();
209 object["item"]["title"] = title;
211 if (item->GetMusicInfoTag()->GetTrackNumber() > 0)
212 object["item"]["track"] = item->GetMusicInfoTag()->GetTrackNumber();
213 if (!item->GetMusicInfoTag()->GetAlbum().empty())
214 object["item"]["album"] = item->GetMusicInfoTag()->GetAlbum();
215 if (!item->GetMusicInfoTag()->GetArtist().empty())
216 object["item"]["artist"] = item->GetMusicInfoTag()->GetArtist();
219 else if (item->IsVideo())
221 // video item but has no video info tag.
223 object["item"]["title"] = item->GetLabel();
225 else if (item->HasPictureInfoTag())
228 object["item"]["file"] = item->GetPath();
233 object["item"]["type"] = type;
235 object["item"]["id"] = id;
237 Announce(flag, sender, message, object);