1 from hashlib
import sha1
2 from datetime
import datetime
4 from restkit
import RequestFailed
5 from couchdbkit
import MultipleResultsFound
7 from django
.core
.cache
import cache
9 from mygpo
.core
.models
import Podcast
, PodcastGroup
, PodcastSubscriberData
10 from mygpo
.core
.signals
import incomplete_obj
11 from mygpo
.decorators
import repeat_on_conflict
12 from mygpo
.cache
import cache_result
13 from mygpo
.utils
import get_timestamp
14 from mygpo
.db
.couchdb
import get_main_database
, get_userdata_database
, \
16 from mygpo
.db
import QueryParameterMissing
17 from mygpo
.db
.couchdb
import get_main_database
, get_single_result
18 from mygpo
.db
.couchdb
.utils
import multi_request_view
, is_couchdb_id
21 logger
= logging
.getLogger(__name__
)
24 def podcast_by_id_uncached(podcast_id
, current_id
=False):
27 raise QueryParameterMissing('podcast_id')
29 db
= get_main_database()
30 podcast
= get_single_result(db
, 'podcasts/by_id',
33 wrapper
= _wrap_podcast_group
,
39 if podcast
.needs_update
:
40 incomplete_obj
.send_robust(sender
=podcast
)
45 podcast_by_id
= cache_result(timeout
=60*60)(podcast_by_id_uncached
)
48 def podcasts_by_id(ids
):
51 raise QueryParameterMissing('ids')
56 r
= Podcast
.view('podcasts/by_id',
62 podcasts
= map(_wrap_podcast_group
, r
)
64 for podcast
in podcasts
:
65 if podcast
.needs_update
:
66 incomplete_obj
.send_robust(sender
=podcast
)
71 def podcasts_groups_by_id(ids
):
72 """ gets podcast groups and top-level podcasts for the given ids """
75 raise QueryParameterMissing('ids')
80 db
= get_main_database()
81 res
= db
.view('podcasts/podcasts_groups',
94 incomplete_obj
.send_robust(sender
=obj
)
106 if doc
['doc_type'] == 'Podcast':
107 return Podcast
.wrap(doc
)
109 elif doc
['doc_type'] == 'PodcastGroup':
110 return PodcastGroup
.wrap(doc
)
113 logger
.error('received unknown doc_type "%s"', doc
['doc_type'])
116 def podcasts_to_dict(ids
, use_cache
=False):
119 raise QueryParameterMissing('ids')
130 res
= cache
.get_many(ids
)
131 cache_objs
.extend(res
.values())
132 ids
= [x
for x
in ids
if x
not in res
.keys()]
134 db_objs
= podcasts_by_id(ids
)
136 for obj
in (cache_objs
+ db_objs
):
138 # get_multi returns dict {'key': _id, 'error': 'not found'}
139 # for non-existing objects
140 if isinstance(obj
, dict) and 'error' in obj
:
145 for i
in obj
.get_ids():
149 cache
.set_many(dict( (obj
.get_id(), obj
) for obj
in db_objs
))
154 def subscriberdata_for_podcast(podcast_id
):
157 raise QueryParameterMissing('podcast_id')
159 db
= get_main_database()
160 data
= get_single_result(db
, 'podcasts/subscriber_data',
163 schema
= PodcastSubscriberData
,
167 data
= PodcastSubscriberData()
168 data
.podcast
= podcast_id
174 def _wrap_podcast_group(res
):
175 if res
['doc']['doc_type'] == 'Podcast':
176 return Podcast
.wrap(res
['doc'])
178 pg
= PodcastGroup
.wrap(res
['doc'])
180 return pg
.get_podcast_by_id(id)
183 def search_wrapper(result
):
185 if doc
['doc_type'] == 'Podcast':
186 p
= Podcast
.wrap(doc
)
187 elif doc
['doc_type'] == 'PodcastGroup':
188 p
= PodcastGroup
.wrap(doc
)
193 @cache_result(timeout
=60*60)
194 def search(q
, offset
=0, num_results
=20):
199 db
= get_main_database()
201 FIELDS
= ['title', 'description']
202 q
= lucene_query(FIELDS
, q
)
205 res
= db
.search('podcasts/search',
206 wrapper
= search_wrapper
,
209 stale
= 'update_after',
216 for podcast
in podcasts
:
217 if podcast
.needs_update
:
218 incomplete_obj
.send_robust(sender
=podcast
)
220 return podcasts
, res
.total_rows
222 except RequestFailed
:
226 def reload_podcast(podcast
):
227 return podcast_by_id_uncached(podcast
.get_id())
230 @repeat_on_conflict(['podcast'], reload_f
=reload_podcast
)
231 def update_additional_data(podcast
, twitter
):
232 podcast
.twitter
= twitter
235 # clear the whole cache until we have a better invalidation mechanism
239 @repeat_on_conflict(['podcast'], reload_f
=reload_podcast
)
240 def update_related_podcasts(podcast
, related
):
241 if podcast
.related_podcasts
== related
:
244 podcast
.related_podcasts
= related
248 @repeat_on_conflict(['podcast'], reload_f
=reload_podcast
)
249 def delete_podcast(podcast
):