Simplify/Robustify the thumbnail URL usage in templates
[mediagoblin.git] / mediagoblin / db / mixin.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
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
17 """
18 This module contains some Mixin classes for the db objects.
19
20 A bunch of functions on the db objects are really more like
21 "utility functions": They could live outside the classes
22 and be called "by hand" passing the appropiate reference.
23 They usually only use the public API of the object and
24 rarely use database related stuff.
25
26 These functions now live here and get "mixed in" into the
27 real objects.
28 """
29
30 import importlib
31
32 from mediagoblin import mg_globals
33 from mediagoblin.auth import lib as auth_lib
34 from mediagoblin.tools import common, licenses
35 from mediagoblin.tools.text import cleaned_markdown_conversion
36 from mediagoblin.tools.url import slugify
37
38
39 class UserMixin(object):
40 def check_login(self, password):
41 """
42 See if a user can login with this password
43 """
44 return auth_lib.bcrypt_check_password(
45 password, self.pw_hash)
46
47 @property
48 def bio_html(self):
49 return cleaned_markdown_conversion(self.bio)
50
51
52 class MediaEntryMixin(object):
53 def generate_slug(self):
54 # import this here due to a cyclic import issue
55 # (db.models -> db.mixin -> db.util -> db.models)
56 from mediagoblin.db.util import check_media_slug_used
57
58 self.slug = slugify(self.title)
59
60 duplicate = check_media_slug_used(mg_globals.database,
61 self.uploader, self.slug, self.id)
62
63 if duplicate:
64 if self.id is not None:
65 self.slug = u"%s-%s" % (self.id, self.slug)
66 else:
67 self.slug = None
68
69 @property
70 def description_html(self):
71 """
72 Rendered version of the description, run through
73 Markdown and cleaned with our cleaning tool.
74 """
75 return cleaned_markdown_conversion(self.description)
76
77 def get_display_media(self, media_map,
78 fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER):
79 """
80 Find the best media for display.
81
82 Args:
83 - media_map: a dict like
84 {u'image_size': [u'dir1', u'dir2', u'image.jpg']}
85 - fetch_order: the order we should try fetching images in
86
87 Returns:
88 (media_size, media_path)
89 """
90 media_sizes = media_map.keys()
91
92 for media_size in common.DISPLAY_IMAGE_FETCHING_ORDER:
93 if media_size in media_sizes:
94 return media_map[media_size]
95
96 def main_mediafile(self):
97 pass
98
99 @property
100 def slug_or_id(self):
101 return (self.slug or self._id)
102
103 def url_for_self(self, urlgen, **extra_args):
104 """
105 Generate an appropriate url for ourselves
106
107 Use a slug if we have one, else use our '_id'.
108 """
109 uploader = self.get_uploader
110
111 return urlgen(
112 'mediagoblin.user_pages.media_home',
113 user=uploader.username,
114 media=self.slug_or_id,
115 **extra_args)
116
117 @property
118 def thumb_url(self):
119 """Return the thumbnail URL (for usage in templates)
120 Will return either the real thumbnail or a default fallback icon."""
121 # TODO: implement generic fallback in case MEDIA_MANAGER does
122 # not specify one?
123 if u'thumb' in self.media_files:
124 thumb_url = mg_globals.app.public_store.file_url(
125 self.media_files[u'thumb'])
126 else:
127 # no thumbnail in media available. Get the media's
128 # MEDIA_MANAGER for the fallback icon and return static URL
129 manager = importlib.import_module(self.media_type)
130 thumb_url = manager.MEDIA_MANAGER[u'default_thumb']
131 thumb_url = mg_globals.app.staticdirector(thumb_url) # use static
132 return thumb_url
133
134 def get_fail_exception(self):
135 """
136 Get the exception that's appropriate for this error
137 """
138 if self.fail_error:
139 return common.import_component(self.fail_error)
140
141 def get_license_data(self):
142 """Return license dict for requested license"""
143 return licenses.SUPPORTED_LICENSES[self.license or ""]
144
145 def exif_display_iter(self):
146 from mediagoblin.tools.exif import USEFUL_TAGS
147
148 if not self.media_data:
149 return
150 exif_all = self.media_data.get("exif_all")
151
152 for key in USEFUL_TAGS:
153 if key in exif_all:
154 yield key, exif_all[key]
155
156
157 class MediaCommentMixin(object):
158 @property
159 def content_html(self):
160 """
161 the actual html-rendered version of the comment displayed.
162 Run through Markdown and the HTML cleaner.
163 """
164 return cleaned_markdown_conversion(self.content)
165
166
167 class CollectionMixin(object):
168 def generate_slug(self):
169 # import this here due to a cyclic import issue
170 # (db.models -> db.mixin -> db.util -> db.models)
171 from mediagoblin.db.util import check_collection_slug_used
172
173 self.slug = slugify(self.title)
174
175 duplicate = check_collection_slug_used(mg_globals.database,
176 self.creator, self.slug, self.id)
177
178 if duplicate:
179 if self.id is not None:
180 self.slug = u"%s-%s" % (self.id, self.slug)
181 else:
182 self.slug = None
183
184 @property
185 def description_html(self):
186 """
187 Rendered version of the description, run through
188 Markdown and cleaned with our cleaning tool.
189 """
190 return cleaned_markdown_conversion(self.description)
191
192 @property
193 def slug_or_id(self):
194 return (self.slug or self._id)
195
196 def url_for_self(self, urlgen, **extra_args):
197 """
198 Generate an appropriate url for ourselves
199
200 Use a slug if we have one, else use our '_id'.
201 """
202 creator = self.get_creator
203
204 return urlgen(
205 'mediagoblin.user_pages.user_collection',
206 user=creator.username,
207 collection=self.slug_or_id,
208 **extra_args)
209
210
211 class CollectionItemMixin(object):
212 @property
213 def note_html(self):
214 """
215 the actual html-rendered version of the note displayed.
216 Run through Markdown and the HTML cleaner.
217 """
218 return cleaned_markdown_conversion(self.note)