2 from datetime
import datetime
3 from couchdbkit
import ResourceNotFound
4 from couchdbkit
.ext
.django
.schema
import *
6 from mygpo
.core
.models
import Podcast
9 class Rating(DocumentSchema
):
10 rating
= IntegerProperty()
11 timestamp
= DateTimeProperty(default
=datetime
.utcnow
)
14 class Suggestions(Document
):
15 user
= StringProperty()
16 user_oldid
= IntegerProperty()
17 podcasts
= StringListProperty()
18 blacklist
= StringListProperty()
19 ratings
= SchemaListProperty(Rating
)
22 def for_user_oldid(cls
, oldid
):
23 r
= cls
.view('users/suggestions_by_user_oldid', key
=oldid
, \
33 def get_podcasts(self
):
34 from mygpo
.api
.models
import Subscription
35 subscriptions
= [x
.podcast
for x
in Subscription
.objects
.filter(user__id
=self
.user_oldid
)]
36 subscriptions
= [Podcast
.for_oldid(x
.id) for x
in subscriptions
]
37 subscriptions
= [x
._id
for x
in subscriptions
if x
]
39 for p
in self
.podcasts
:
40 if not p
in self
.blacklist
and not p
in subscriptions
:
42 podcast
= Podcast
.get(p
)
43 except ResourceNotFound
:
52 return super(Suggestions
, self
).__repr
__()
54 return '%d Suggestions for %s (%s)' % \
56 self
.user
[:10] if self
.user
else self
.user_oldid
,
60 class EpisodeAction(DocumentSchema
):
62 One specific action to an episode. Must
63 always be part of a EpisodeUserState
66 action
= StringProperty(required
=True)
67 timestamp
= DateTimeProperty(required
=True)
68 device_oldid
= IntegerProperty()
69 started
= IntegerProperty()
70 playmark
= IntegerProperty()
71 total
= IntegerProperty()
73 def __eq__(self
, other
):
74 if not isinstance(other
, EpisodeAction
):
76 vals
= ('action', 'timestamp', 'device_oldid', 'started', 'playmark',
78 return all([getattr(self
, v
, None) == getattr(other
, v
, None) for v
in vals
])
82 return '%s-Action on %s at %s (in %s)' % \
83 (self
.action
, self
.device_oldid
, self
.timestamp
, self
._id
)
86 class EpisodeUserState(Document
):
88 Contains everything a user has done with an Episode
91 episode_oldid
= IntegerProperty()
92 episode
= StringProperty(required
=True)
93 actions
= SchemaListProperty(EpisodeAction
)
94 settings
= DictProperty()
97 def add_actions(self
, actions
):
98 self
.actions
+= actions
99 self
.actions
= list(set(self
.actions
))
100 self
.actions
.sort(key
=lambda x
: x
.timestamp
)
103 def is_favorite(self
):
104 return self
.settings
.get('is_favorite', False)
107 def set_favorite(self
, set_to
=True):
108 self
.settings
['is_favorite'] = set_to
112 return 'Episode-State %s (in %s)' % \
113 (self
.episode
, self
._id
)
115 def __eq__(self
, other
):
116 if not isinstance(other
, EpisodeUserState
):
119 return (self
.episode_oldid
== other
.episode_oldid
and \
120 self
.episode
== other
.episode
and
121 self
.actions
== other
.actions
)
125 class SubscriptionAction(Document
):
126 action
= StringProperty()
127 timestamp
= DateTimeProperty(default
=datetime
.utcnow
)
128 device
= StringProperty()
130 def __eq__(self
, other
):
131 return self
.actions
== other
.action
and \
132 self
.timestamp
== other
.timestamp
and \
133 self
.device
== other
.device
136 class PodcastUserState(Document
):
138 Contains everything that a user has done
139 with a specific podcast and all its episodes
142 podcast
= StringProperty(required
=True)
143 episodes
= SchemaDictProperty(EpisodeUserState
)
144 user_oldid
= IntegerProperty()
145 settings
= DictProperty()
146 actions
= SchemaListProperty(SubscriptionAction
)
147 tags
= StringListProperty()
151 def for_user_podcast(cls
, user
, podcast
):
152 r
= PodcastUserState
.view('users/podcast_states_by_podcast', \
153 key
=[podcast
.get_id(), user
.id], limit
=1, include_docs
=True)
157 p
= PodcastUserState()
158 p
.podcast
= podcast
.get_id()
159 p
.user_oldid
= user
.id
164 def for_user(cls
, user
):
165 r
= PodcastUserState
.view('users/podcast_states_by_user',
166 startkey
=[user
.id, None], endkey
=[user
.id, 'ZZZZ'],
171 def get_episode(self
, e_id
):
172 if e_id
in self
.episodes
:
173 return self
.episodes
[e_id
]
175 e
= EpisodeUserState()
177 self
.episodes
[e_id
] = e
180 def add_actions(self
, actions
):
181 self
.actions
+= actions
182 self
.actions
= list(set(self
.actions
))
183 self
.actions
.sort(key
=lambda x
: x
.timestamp
)
186 def add_tags(self
, tags
):
187 self
.tags
= list(set(self
.tags
+ tags
))
190 def __eq__(self
, other
):
194 return self
.podcast
== other
.podcast
and \
195 self
.user_oldid
== other
.user_oldid
198 return 'Podcast %s for User %s (%s)' % \
199 (self
.podcast
, self
.user_oldid
, self
._id
)
202 class Device(Document
):
203 id = StringProperty(default
=lambda: uuid
.uuid4().hex)
204 oldid
= IntegerProperty()
205 uid
= StringProperty()
206 name
= StringProperty()
207 type = StringProperty()
208 settings
= DictProperty()
211 def for_user_uid(cls
, user
, uid
):
212 r
= cls
.view('users/devices_by_user_uid', key
=[user
.id, uid
], limit
=1)
213 return r
.one() if r
else None
216 class User(Document
):
217 oldid
= IntegerProperty()
218 settings
= DictProperty()
219 devices
= SchemaListProperty(Device
)
223 def for_oldid(cls
, oldid
):
224 r
= cls
.view('users/users_by_oldid', key
=oldid
, limit
=1, include_docs
=True)
225 return r
.one() if r
else None
228 def get_device(self
, uid
):
229 for device
in self
.devices
:
230 if device
.uid
== uid
:
236 def published_podcasts(self
):
238 Returns a list of the Ids (or full objects) of podcasts for which the
239 user has publisher permissions
242 r
= Podcast
.view('publisher/podcasts_by_publisher', key
=self
._id
)
243 return [x
['value'] for x
in r
]
247 return 'User %s' % self
._id