Merge branch 'master' into test_submission_views_365
[mediagoblin.git] / mediagoblin / db / models.py
CommitLineData
8e1e744d 1# GNU MediaGoblin -- federated, autonomous media hosting
e5572c60
ML
2# Copyright (C) 2011 Free Software Foundation, Inc
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
db1a438f 17import datetime, uuid
4ad5af85 18
d232e0f6 19from mongokit import Document, Set
4329be14 20
0546833c 21from mediagoblin import util
4ad5af85 22from mediagoblin.auth import lib as auth_lib
6e7ce8d1 23from mediagoblin import mg_globals
757f37a5 24from mediagoblin.db import migrations
7bd8197f
JW
25from mediagoblin.db.util import DESCENDING, ObjectId
26from mediagoblin.util import Pagination
d232e0f6 27
7bf3f5db
CAW
28###################
29# Custom validators
30###################
31
32########
33# Models
34########
35
36
d232e0f6 37class User(Document):
73a6e206
CAW
38 __collection__ = 'users'
39
d232e0f6
CAW
40 structure = {
41 'username': unicode,
24181820 42 'email': unicode,
d232e0f6
CAW
43 'created': datetime.datetime,
44 'plugin_data': dict, # plugins can dump stuff here.
45 'pw_hash': unicode,
24181820 46 'email_verified': bool,
4d75522b 47 'status': unicode,
18cf34d4
CAW
48 'verification_key': unicode,
49 'is_admin': bool,
630b57a3 50 'url' : unicode,
279d925e 51 'bio' : unicode
d232e0f6
CAW
52 }
53
db5912e3 54 required_fields = ['username', 'created', 'pw_hash', 'email']
fc9bb821
CAW
55
56 default_values = {
24181820 57 'created': datetime.datetime.utcnow,
4d75522b 58 'email_verified': False,
db1a438f 59 'status': u'needs_email_verification',
18cf34d4
CAW
60 'verification_key': lambda: unicode(uuid.uuid4()),
61 'is_admin': False}
0472653e 62
63 migration_handler = migrations.UserMigration
fc9bb821 64
4ad5af85
CAW
65 def check_login(self, password):
66 """
67 See if a user can login with this password
68 """
69 return auth_lib.bcrypt_check_password(
70 password, self['pw_hash'])
71
d232e0f6 72
4d75522b
CAW
73class MediaEntry(Document):
74 __collection__ = 'media_entries'
75
76 structure = {
757f37a5 77 'uploader': ObjectId,
4d75522b 78 'title': unicode,
1013bdaf 79 'slug': unicode,
4d75522b 80 'created': datetime.datetime,
44e2da2f
JW
81 'description': unicode, # May contain markdown/up
82 'description_html': unicode, # May contain plaintext, or HTML
4d75522b
CAW
83 'media_type': unicode,
84 'media_data': dict, # extra data relevant to this media_type
85 'plugin_data': dict, # plugins can dump stuff here.
74ae6b11
CAW
86 'tags': [unicode],
87 'state': unicode,
88
fa7f9c61
CAW
89 # For now let's assume there can only be one main file queued
90 # at a time
91 'queued_media_file': [unicode],
92
93 # A dictionary of logical names to filepaths
94 'media_files': dict,
95
74ae6b11
CAW
96 # The following should be lists of lists, in appropriate file
97 # record form
74ae6b11 98 'attachment_files': list,
74ae6b11
CAW
99
100 # This one should just be a single file record
101 'thumbnail_file': [unicode]}
4d75522b
CAW
102
103 required_fields = [
b1ae76ae 104 'uploader', 'created', 'media_type', 'slug']
4d75522b
CAW
105
106 default_values = {
74ae6b11
CAW
107 'created': datetime.datetime.utcnow,
108 'state': u'unprocessed'}
4d75522b 109
757f37a5
CAW
110 migration_handler = migrations.MediaEntryMigration
111
4d75522b
CAW
112 def main_mediafile(self):
113 pass
7bd8197f
JW
114
115 def get_comments(self, page):
116 cursor = self.db.MediaComment.find({
117 'media_entry': self['_id']}).sort('created', DESCENDING)
118
119 pagination = Pagination(page, cursor)
120 comments = pagination()
121
122 data = list()
123 for comment in comments:
124 comment['author'] = self.db.User.find_one({
125 '_id': comment['author']})
126 data.append(comment)
127
128 return (data, pagination)
129
0546833c
AW
130 def generate_slug(self):
131 self['slug'] = util.slugify(self['title'])
132
6e7ce8d1 133 duplicate = mg_globals.database.media_entries.find_one(
f0545dde 134 {'slug': self['slug']})
0546833c
AW
135
136 if duplicate:
137 self['slug'] = "%s-%s" % (self['_id'], self['slug'])
4d75522b 138
6926b23d
CAW
139 def url_for_self(self, urlgen):
140 """
141 Generate an appropriate url for ourselves
142
143 Use a slug if we have one, else use our '_id'.
144 """
16509be1
CAW
145 uploader = self.uploader()
146
6926b23d
CAW
147 if self.get('slug'):
148 return urlgen(
149 'mediagoblin.user_pages.media_home',
16509be1 150 user=uploader['username'],
6926b23d
CAW
151 media=self['slug'])
152 else:
153 return urlgen(
154 'mediagoblin.user_pages.media_home',
16509be1 155 user=uploader['username'],
6926b23d
CAW
156 media=unicode(self['_id']))
157
16509be1
CAW
158 def uploader(self):
159 return self.db.User.find_one({'_id': self['uploader']})
160
c11f21ab
JW
161class MediaComment(Document):
162 __collection__ = 'media_comments'
6926b23d 163
c11f21ab
JW
164 structure = {
165 'media_entry': ObjectId,
166 'author': ObjectId,
167 'created': datetime.datetime,
168 'content': unicode,
169 'content_html': unicode}
170
171 required_fields = [
7bd8197f 172 'media_entry', 'author', 'created', 'content']
c11f21ab
JW
173
174 default_values = {
175 'created': datetime.datetime.utcnow}
176
177 def media_entry(self):
7bd8197f 178 return self.db.MediaEntry.find_one({'_id': self['media_entry']})
c11f21ab
JW
179
180 def author(self):
181 return self.db.User.find_one({'_id': self['author']})
6926b23d 182
c11f21ab
JW
183REGISTER_MODELS = [
184 MediaEntry,
185 User,
186 MediaComment]
d232e0f6 187
4329be14 188
d232e0f6
CAW
189def register_models(connection):
190 """
191 Register all models in REGISTER_MODELS with this connection.
192 """
db61f7d1
CAW
193 connection.register(REGISTER_MODELS)
194