1 from itertools
import count
3 from couchdbkit
.ext
.django
.schema
import *
5 from django
.utils
.text
import slugify
7 from mygpo
.decorators
import repeat_on_conflict
10 def assign_slug(obj
, generator
):
14 slug
= generator(obj
).get_slug()
15 _set_slug(obj
=obj
, slug
=slug
)
18 def assign_missing_episode_slugs(podcast
):
19 common_title
= podcast
.get_common_episode_title()
21 episodes
= EpisodesMissingSlugs(podcast
.get_id())
24 for episode
in episodes
:
25 slug
= EpisodeSlug(episode
, common_title
).get_slug()
26 _set_slug(obj
=episode
, slug
=slug
)
29 @repeat_on_conflict(['obj'])
30 def _set_slug(obj
, slug
):
37 class SlugGenerator(object):
38 """ Generates a unique slug for an object """
41 def __init__(self
, obj
):
43 raise ValueError('%(obj)s already has slug %(slug)s' % \
44 dict(obj
=obj
, slug
=obj
.slug
))
46 self
.base_slug
= self
._get
_base
_slug
(obj
)
50 def _get_base_slug(obj
):
53 base_slug
= slugify(obj
.title
)
58 def _get_existing_slugs():
63 """ Gets existing slugs and appends numbers until slug is unique """
64 if not self
.base_slug
:
67 existing_slugs
= self
._get
_existing
_slugs
()
69 if not self
.base_slug
in existing_slugs
:
70 return str(self
.base_slug
)
73 tmp_slug
= '%s-%d' % (self
.base_slug
, n
)
74 if not tmp_slug
in existing_slugs
:
75 # slugify returns SafeUnicode, we need a plain string
80 class PodcastGroupSlug(SlugGenerator
):
81 """ Generates slugs for Podcast Groups """
83 def _get_existing_slugs(self
):
84 from mygpo
.db
.couchdb
.podcast
import podcast_slugs
85 return podcast_slugs(self
.base_slug
)
89 class PodcastSlug(PodcastGroupSlug
):
90 """ Generates slugs for Podcasts """
93 def _get_base_slug(podcast
):
94 base_slug
= SlugGenerator
._get
_base
_slug
(podcast
)
99 # append group_member_name to slug
100 if podcast
.group_member_name
:
101 member_slug
= slugify(podcast
.group_member_name
)
102 if member_slug
and not member_slug
in base_slug
:
103 base_slug
= '%s-%s' % (base_slug
, member_slug
)
109 class EpisodeSlug(SlugGenerator
):
110 """ Generates slugs for Episodes """
112 def __init__(self
, episode
, common_title
):
113 self
.common_title
= common_title
114 super(EpisodeSlug
, self
).__init
__(episode
)
115 self
.podcast_id
= episode
.podcast
118 def _get_base_slug(self
, obj
):
120 number
= obj
.get_episode_number(self
.common_title
)
124 short_title
= obj
.get_short_title(self
.common_title
)
126 return slugify(short_title
)
129 return slugify(obj
.title
)
134 def _get_existing_slugs(self
):
135 """ Episode slugs have to be unique within the Podcast """
136 from mygpo
.db
.couchdb
.episode
import episode_slugs_per_podcast
137 return episode_slugs_per_podcast(self
.podcast_id
, self
.base_slug
)
140 class ObjectsMissingSlugs(object):
141 """ A collections of objects missing a slug """
143 def __init__(self
, cls
, wrapper
=None, start
=[None], end
=[{}]):
145 self
.doc_type
= cls
._doc
_type
146 self
.wrapper
= wrapper
153 from mygpo
.db
.couchdb
.common
import missing_slug_count
154 return missing_slug_count(self
.doc_type
, self
.start
, self
.end
)
158 from mygpo
.db
.couchdb
.common
import missing_slugs
159 return missing_slugs(self
.doc_type
, self
.start
, self
.end
, self
.wrapper
, **self
.kwargs
)
163 class PodcastsMissingSlugs(ObjectsMissingSlugs
):
164 """ Podcasts that don't have a slug (but could have one) """
167 from mygpo
.core
.models
import Podcast
168 super(PodcastsMissingSlugs
, self
).__init
__(Podcast
, self
._podcast
_wrapper
)
169 self
.kwargs
= {'wrap': False}
172 def _podcast_wrapper(r
):
173 from mygpo
.core
.models
import Podcast
, PodcastGroup
177 if doc
['doc_type'] == 'Podcast':
178 return Podcast
.wrap(doc
)
181 pg
= PodcastGroup
.wrap(doc
)
182 return pg
.get_podcast_by_id(pid
)
185 for r
in super(PodcastsMissingSlugs
, self
).__iter
__():
186 yield self
._podcast
_wrapper
(r
)
189 class EpisodesMissingSlugs(ObjectsMissingSlugs
):
190 """ Episodes that don't have a slug (but could have one) """
192 def __init__(self
, podcast_id
=None):
193 from mygpo
.core
.models
import Episode
196 start
= [podcast_id
, None]
197 end
= [podcast_id
, {}]
202 super(EpisodesMissingSlugs
, self
).__init
__(Episode
,
203 self
._episode
_wrapper
, start
, end
)
206 def _episode_wrapper(doc
):
207 from mygpo
.core
.models
import Episode
209 return Episode
.wrap(doc
)
212 class PodcastGroupsMissingSlugs(ObjectsMissingSlugs
):
213 """ Podcast Groups that don't have a slug (but could have one) """
216 from mygpo
.core
.models
import PodcastGroup
217 super(PodcastGroupsMissingSlugs
, self
).__init
__(PodcastGroup
,
221 def _group_wrapper(doc
):
222 from mygpo
.core
.models
import PodcastGroup
223 return PodcastGroup
.wrap(doc
)
226 class SlugMixin(DocumentSchema
):
227 slug
= StringProperty()
228 merged_slugs
= StringListProperty()
230 def set_slug(self
, slug
):
231 """ Set the main slug of the object """
234 self
.merged_slugs
.append(self
.slug
)
236 self
.merged_slugs
= list(set(self
.merged_slugs
) - set([slug
]))
241 def remove_slug(self
, slug
):
242 """ Removes the slug from the object """
245 if self
.slug
== slug
:
248 # remove from merged slugs
249 self
.merged_slugs
= list(set(self
.merged_slugs
) - set([slug
]))