2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include "XBDateTime.h"
12 #include "addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr/pvr_epg.h"
13 #include "pvr/epg/EpgTagsContainer.h"
14 #include "threads/CriticalSection.h"
15 #include "utils/EventStream.h"
27 class CPVREpgChannelData
;
28 class CPVREpgDatabase
;
33 friend class CPVREpgDatabase
;
37 * @brief Create a new EPG instance.
38 * @param iEpgID The ID of this table or <= 0 to create a new ID.
39 * @param strName The name of this table.
40 * @param strScraperName The name of the scraper to use.
41 * @param database The EPG database
44 const std::string
& strName
,
45 const std::string
& strScraperName
,
46 const std::shared_ptr
<CPVREpgDatabase
>& database
);
49 * @brief Create a new EPG instance.
50 * @param iEpgID The ID of this table or <= 0 to create a new ID.
51 * @param strName The name of this table.
52 * @param strScraperName The name of the scraper to use.
53 * @param channelData The channel data.
54 * @param database The EPG database
57 const std::string
& strName
,
58 const std::string
& strScraperName
,
59 const std::shared_ptr
<CPVREpgChannelData
>& channelData
,
60 const std::shared_ptr
<CPVREpgDatabase
>& database
);
63 * @brief Destroy this EPG instance.
68 * @brief Get data for the channel associated with this EPG.
71 std::shared_ptr
<CPVREpgChannelData
> GetChannelData() const;
74 * @brief Set data for the channel associated with this EPG.
75 * @param data The data.
77 void SetChannelData(const std::shared_ptr
<CPVREpgChannelData
>& data
);
80 * @brief The id of the channel associated with this EPG.
81 * @return The channel id or -1 if no channel is associated
83 int ChannelID() const;
86 * @brief Get the name of the scraper to use for this table.
87 * @return The name of the scraper to use for this table.
89 const std::string
& ScraperName() const;
92 * @brief Returns if there is a manual update pending for this EPG
93 * @return True if there is a manual update pending, false otherwise
95 bool UpdatePending() const;
98 * @brief Clear the current tags and schedule manual update
103 * @brief Get the name of this table.
104 * @return The name of this table.
106 const std::string
& Name() const;
109 * @brief Get the database ID of this table.
110 * @return The database ID of this table.
115 * @brief Remove all entries from this EPG that finished before the given time.
116 * @param time Delete entries with an end time before this time in UTC.
118 void Cleanup(const CDateTime
& time
);
121 * @brief Remove all entries from this EPG.
126 * @brief Get the event that is occurring now
127 * @return The current event or NULL if it wasn't found.
129 std::shared_ptr
<CPVREpgInfoTag
> GetTagNow() const;
132 * @brief Get the event that will occur next
133 * @return The next event or NULL if it wasn't found.
135 std::shared_ptr
<CPVREpgInfoTag
> GetTagNext() const;
138 * @brief Get the event that occurred previously
139 * @return The previous event or NULL if it wasn't found.
141 std::shared_ptr
<CPVREpgInfoTag
> GetTagPrevious() const;
144 * @brief Get the event that occurs between the given begin and end time.
145 * @param beginTime Minimum start time in UTC of the event.
146 * @param endTime Maximum end time in UTC of the event.
147 * @param bUpdateFromClient if true, try to fetch the event from the client if not found locally.
148 * @return The found tag or NULL if it wasn't found.
150 std::shared_ptr
<CPVREpgInfoTag
> GetTagBetween(const CDateTime
& beginTime
, const CDateTime
& endTime
, bool bUpdateFromClient
= false);
153 * @brief Get the event matching the given unique broadcast id
154 * @param iUniqueBroadcastId The uid to look up
155 * @return The matching event or NULL if it wasn't found.
157 std::shared_ptr
<CPVREpgInfoTag
> GetTagByBroadcastId(unsigned int iUniqueBroadcastId
) const;
160 * @brief Get the event matching the given database id
161 * @param iDatabaseId The id to look up
162 * @return The matching event or NULL if it wasn't found.
164 std::shared_ptr
<CPVREpgInfoTag
> GetTagByDatabaseId(int iDatabaseId
) const;
167 * @brief Update an entry in this EPG.
168 * @param data The tag to update.
169 * @param iClientId The id of the pvr client this event belongs to.
170 * @return True if it was updated successfully, false otherwise.
172 bool UpdateEntry(const EPG_TAG
* data
, int iClientId
);
175 * @brief Update an entry in this EPG.
176 * @param tag The tag to update.
177 * @param newState the new state of the event.
178 * @return True if it was updated successfully, false otherwise.
180 bool UpdateEntry(const std::shared_ptr
<CPVREpgInfoTag
>& tag
, EPG_EVENT_STATE newState
);
183 * @brief Update the EPG from 'start' till 'end'.
184 * @param start The start time.
185 * @param end The end time.
186 * @param iUpdateTime Update the table after the given amount of time has passed.
187 * @param iPastDays Amount of past days from now on, for which past entries are to be kept.
188 * @param database If given, the database to store the data.
189 * @param bForceUpdate Force update from client even if it's not the time to
190 * @return True if the update was successful, false otherwise.
192 bool Update(time_t start
, time_t end
, int iUpdateTime
, int iPastDays
, const std::shared_ptr
<CPVREpgDatabase
>& database
, bool bForceUpdate
= false);
195 * @brief Get all EPG tags.
198 std::vector
<std::shared_ptr
<CPVREpgInfoTag
>> GetTags() const;
201 * @brief Get all EPG tags for the given time frame, including "gap" tags.
202 * @param timelineStart Start of time line
203 * @param timelineEnd End of time line
204 * @param minEventEnd The minimum end time of the events to return
205 * @param maxEventStart The maximum start time of the events to return
206 * @return The matching tags.
208 std::vector
<std::shared_ptr
<CPVREpgInfoTag
>> GetTimeline(const CDateTime
& timelineStart
,
209 const CDateTime
& timelineEnd
,
210 const CDateTime
& minEventEnd
,
211 const CDateTime
& maxEventStart
) const;
214 * @brief Write the query to persist data into given database's queue
215 * @param database The database.
216 * @return True on success, false otherwise.
218 bool QueuePersistQuery(const std::shared_ptr
<CPVREpgDatabase
>& database
);
221 * @brief Write the delete queries into the given database's queue
222 * @param database The database.
223 * @return True on success, false otherwise.
225 bool QueueDeleteQueries(const std::shared_ptr
<CPVREpgDatabase
>& database
);
228 * @brief Get the start and end time of the last not yet committed entry in this table.
229 * @return The times; first: start time, second: end time.
231 std::pair
<CDateTime
, CDateTime
> GetFirstAndLastUncommitedEPGDate() const;
234 * @brief Notify observers when the currently active tag changed.
235 * @return True if the playing tag has changed, false otherwise.
237 bool CheckPlayingEvent();
240 * @brief Convert a genre id and subid to a human readable name.
241 * @param iID The genre ID.
242 * @param iSubID The genre sub ID.
243 * @return A human readable name.
245 static const std::string
& ConvertGenreIdToString(int iID
, int iSubID
);
248 * @brief Check whether this EPG has unsaved data.
249 * @return True if this EPG contains unsaved data, false otherwise.
251 bool NeedsSave() const;
254 * @brief Check whether this EPG is valid.
255 * @return True if this EPG is valid and can be updated, false otherwise.
257 bool IsValid() const;
260 * @brief Query the events available for CEventStream
262 CEventStream
<PVREvent
>& Events() { return m_events
; }
265 * @brief Lock the instance. No other thread gets access to this EPG until Unlock was called.
267 void Lock() { m_critSection
.lock(); }
270 * @brief Unlock the instance. Other threads may get access to this EPG again.
272 void Unlock() { m_critSection
.unlock(); }
275 * @brief Called to inform the EPG that it has been removed from the EPG container.
277 void RemovedFromContainer();
280 * @brief Erase stale texture db entries and image files.
281 * @param database The EPG database
282 * @return number of cleaned up images.
284 int CleanupCachedImages(const std::shared_ptr
<const CPVREpgDatabase
>& database
);
288 CPVREpg(const CPVREpg
&) = delete;
289 CPVREpg
& operator =(const CPVREpg
&) = delete;
292 * @brief Update the EPG from a scraper set in the channel tag.
293 * @todo not implemented yet for non-pvr EPGs
294 * @param start Get entries with a start date after this time.
295 * @param end Get entries with an end date before this time.
296 * @param bForceUpdate Force update from client even if it's not the time to
297 * @return True if the update was successful, false otherwise.
299 bool UpdateFromScraper(time_t start
, time_t end
, bool bForceUpdate
);
302 * @brief Update the contents of this table with the contents provided in "epg"
303 * @param epg The updated contents.
304 * @return True if the update was successful, false otherwise.
306 bool UpdateEntries(const CPVREpg
& epg
);
309 * @brief Remove all entries from this EPG that finished before the given amount of days.
310 * @param iPastDays Delete entries with an end time before the given amount of days from now on.
312 void Cleanup(int iPastDays
);
314 bool m_bChanged
= false; /*!< true if anything changed that needs to be persisted, false otherwise */
315 std::atomic
<bool> m_bUpdatePending
= {false}; /*!< true if manual update is pending */
316 int m_iEpgID
= 0; /*!< the database ID of this table */
317 std::string m_strName
; /*!< the name of this table */
318 std::string m_strScraperName
; /*!< the name of the scraper to use */
319 CDateTime m_lastScanTime
; /*!< the last time the EPG has been updated */
320 mutable CCriticalSection m_critSection
; /*!< critical section for changes in this table */
321 bool m_bUpdateLastScanTime
= false;
322 std::shared_ptr
<CPVREpgChannelData
> m_channelData
;
323 CPVREpgTagsContainer m_tags
;
325 CEventSource
<PVREvent
> m_events
;