@@ -3,7 +3,9 @@ use pyo3::prelude::*;
33
44use super :: common:: { PyContent , PyEnclosure , PyLink , PyPerson , PySource , PyTag , PyTextConstruct } ;
55use super :: datetime:: optional_datetime_to_struct_time;
6- use super :: podcast:: { PyItunesEntryMeta , PyPodcastPerson , PyPodcastTranscript } ;
6+ use super :: geo:: PyGeoLocation ;
7+ use super :: media:: { PyMediaContent , PyMediaThumbnail } ;
8+ use super :: podcast:: { PyItunesEntryMeta , PyPodcastEntryMeta , PyPodcastPerson , PyPodcastTranscript } ;
79
810#[ pyclass( name = "Entry" , module = "feedparser_rs" ) ]
911#[ derive( Clone ) ]
@@ -196,6 +198,13 @@ impl PyEntry {
196198 . map ( |i| PyItunesEntryMeta :: from_core ( i. clone ( ) ) )
197199 }
198200
201+ /// Returns podcast transcripts for this entry.
202+ ///
203+ /// Dual access pattern for feedparser compatibility:
204+ /// - `entry.podcast_transcripts` - Direct access (this method)
205+ /// - `entry.podcast.transcript` - Nested access via PodcastEntryMeta
206+ ///
207+ /// Both provide the same data. Use whichever pattern matches your code style.
199208 #[ getter]
200209 fn podcast_transcripts ( & self ) -> Vec < PyPodcastTranscript > {
201210 self . inner
@@ -205,6 +214,13 @@ impl PyEntry {
205214 . collect ( )
206215 }
207216
217+ /// Returns podcast persons for this entry.
218+ ///
219+ /// Dual access pattern for feedparser compatibility:
220+ /// - `entry.podcast_persons` - Direct access (this method)
221+ /// - `entry.podcast.person` - Nested access via PodcastEntryMeta
222+ ///
223+ /// Both provide the same data. Use whichever pattern matches your code style.
208224 #[ getter]
209225 fn podcast_persons ( & self ) -> Vec < PyPodcastPerson > {
210226 self . inner
@@ -219,6 +235,65 @@ impl PyEntry {
219235 self . inner . license . as_deref ( )
220236 }
221237
238+ #[ getter]
239+ fn geo ( & self ) -> Option < PyGeoLocation > {
240+ self . inner
241+ . geo
242+ . as_ref ( )
243+ . map ( |g| PyGeoLocation :: from_core ( g. clone ( ) ) )
244+ }
245+
246+ #[ getter]
247+ fn dc_creator ( & self ) -> Option < & str > {
248+ self . inner . dc_creator . as_deref ( )
249+ }
250+
251+ #[ getter]
252+ fn dc_date ( & self ) -> Option < String > {
253+ self . inner . dc_date . map ( |dt| dt. to_rfc3339 ( ) )
254+ }
255+
256+ #[ getter]
257+ fn dc_date_parsed ( & self , py : Python < ' _ > ) -> PyResult < Option < Py < PyAny > > > {
258+ optional_datetime_to_struct_time ( py, & self . inner . dc_date )
259+ }
260+
261+ #[ getter]
262+ fn dc_rights ( & self ) -> Option < & str > {
263+ self . inner . dc_rights . as_deref ( )
264+ }
265+
266+ #[ getter]
267+ fn dc_subject ( & self ) -> Vec < String > {
268+ self . inner . dc_subject . clone ( )
269+ }
270+
271+ #[ getter]
272+ fn media_thumbnails ( & self ) -> Vec < PyMediaThumbnail > {
273+ self . inner
274+ . media_thumbnails
275+ . iter ( )
276+ . map ( |t| PyMediaThumbnail :: from_core ( t. clone ( ) ) )
277+ . collect ( )
278+ }
279+
280+ #[ getter]
281+ fn media_content ( & self ) -> Vec < PyMediaContent > {
282+ self . inner
283+ . media_content
284+ . iter ( )
285+ . map ( |c| PyMediaContent :: from_core ( c. clone ( ) ) )
286+ . collect ( )
287+ }
288+
289+ #[ getter]
290+ fn podcast ( & self ) -> Option < PyPodcastEntryMeta > {
291+ self . inner
292+ . podcast
293+ . as_ref ( )
294+ . map ( |p| PyPodcastEntryMeta :: from_core ( p. clone ( ) ) )
295+ }
296+
222297 fn __repr__ ( & self ) -> String {
223298 format ! (
224299 "Entry(title='{}', id='{}')" ,
0 commit comments