Commit | Line | Data |
---|---|---|
41f446f4 | 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
cf29e8a8 | 2 | # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. |
41f446f4 CAW |
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 | ||
64da09e8 JW |
17 | import logging |
18 | ||
2e5ea6b9 | 19 | from celery.task import Task |
41f446f4 | 20 | |
82cd9683 | 21 | from mediagoblin.db.util import ObjectId, atomic_update |
4a477e24 | 22 | from mediagoblin import mg_globals as mgg |
8e5f9746 | 23 | |
6506b1e2 | 24 | from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ |
8e5f9746 JW |
25 | |
26 | from mediagoblin.media_types import get_media_manager | |
4b860cb8 | 27 | |
64da09e8 | 28 | _log = logging.getLogger(__name__) |
41f446f4 | 29 | |
24eaf0fd | 30 | THUMB_SIZE = 180, 180 |
93214d8e | 31 | MEDIUM_SIZE = 640, 640 |
41f446f4 CAW |
32 | |
33 | ||
180bdbde | 34 | def create_pub_filepath(entry, filename): |
48a7ba1e | 35 | return mgg.public_store.get_unique_filepath( |
180bdbde | 36 | ['media_entries', |
eabe6b67 | 37 | unicode(entry._id), |
180bdbde E |
38 | filename]) |
39 | ||
4a477e24 | 40 | |
4a477e24 CAW |
41 | ################################ |
42 | # Media processing initial steps | |
43 | ################################ | |
44 | ||
45 | class ProcessMedia(Task): | |
46 | """ | |
8e5f9746 JW |
47 | DEPRECATED -- This now resides in the individual media plugins |
48 | ||
4a477e24 CAW |
49 | Pass this entry off for processing. |
50 | """ | |
51 | def run(self, media_id): | |
52 | """ | |
53 | Pass the media entry off to the appropriate processing function | |
54 | (for now just process_image...) | |
55 | """ | |
56 | entry = mgg.database.MediaEntry.one( | |
57 | {'_id': ObjectId(media_id)}) | |
6788b412 CAW |
58 | |
59 | # Try to process, and handle expected errors. | |
60 | try: | |
f4ee8399 E |
61 | #__import__(entry.media_type) |
62 | manager = get_media_manager(entry.media_type) | |
64da09e8 | 63 | _log.debug('Processing {0}'.format(entry)) |
8e5f9746 | 64 | manager['processor'](entry) |
6788b412 | 65 | except BaseProcessingFail, exc: |
eabe6b67 | 66 | mark_entry_failed(entry._id, exc) |
6788b412 | 67 | return |
a63b640f | 68 | except ImportError, exc: |
64da09e8 JW |
69 | _log.error( |
70 | 'Entry {0} failed to process due to an import error: {1}'\ | |
71 | .format( | |
72 | entry.title, | |
73 | exc)) | |
74 | ||
75 | mark_entry_failed(entry._id, exc) | |
c2b862d1 | 76 | |
049284b1 | 77 | entry.state = u'processed' |
4a477e24 CAW |
78 | entry.save() |
79 | ||
80 | def on_failure(self, exc, task_id, args, kwargs, einfo): | |
81 | """ | |
82 | If the processing failed we should mark that in the database. | |
83 | ||
243c3843 NY |
84 | Assuming that the exception raised is a subclass of |
85 | BaseProcessingFail, we can use that to get more information | |
86 | about the failure and store that for conveying information to | |
87 | users about the failure, etc. | |
4a477e24 | 88 | """ |
6788b412 CAW |
89 | entry_id = args[0] |
90 | mark_entry_failed(entry_id, exc) | |
4a477e24 | 91 | |
4a477e24 | 92 | |
6788b412 | 93 | def mark_entry_failed(entry_id, exc): |
2e5ea6b9 CAW |
94 | """ |
95 | Mark a media entry as having failed in its conversion. | |
96 | ||
243c3843 NY |
97 | Uses the exception that was raised to mark more information. If |
98 | the exception is a derivative of BaseProcessingFail then we can | |
99 | store extra information that can be useful for users telling them | |
100 | why their media failed to process. | |
2e5ea6b9 CAW |
101 | |
102 | Args: | |
103 | - entry_id: The id of the media entry | |
104 | ||
105 | """ | |
6788b412 CAW |
106 | # Was this a BaseProcessingFail? In other words, was this a |
107 | # type of error that we know how to handle? | |
108 | if isinstance(exc, BaseProcessingFail): | |
109 | # Looks like yes, so record information about that failure and any | |
110 | # metadata the user might have supplied. | |
82cd9683 | 111 | atomic_update(mgg.database.MediaEntry, |
6788b412 | 112 | {'_id': entry_id}, |
82cd9683 E |
113 | {u'state': u'failed', |
114 | u'fail_error': exc.exception_path, | |
115 | u'fail_metadata': exc.metadata}) | |
6788b412 | 116 | else: |
baae1578 | 117 | _log.warn("No idea what happened here, but it failed: %r", exc) |
6788b412 CAW |
118 | # Looks like no, so just mark it as failed and don't record a |
119 | # failure_error (we'll assume it wasn't handled) and don't record | |
120 | # metadata (in fact overwrite it if somehow it had previous info | |
121 | # here) | |
82cd9683 | 122 | atomic_update(mgg.database.MediaEntry, |
6788b412 | 123 | {'_id': entry_id}, |
82cd9683 E |
124 | {u'state': u'failed', |
125 | u'fail_error': None, | |
126 | u'fail_metadata': {}}) | |
4a477e24 CAW |
127 | |
128 | ||
8e5f9746 JW |
129 | class BaseProcessingFail(Exception): |
130 | """ | |
131 | Base exception that all other processing failure messages should | |
132 | subclass from. | |
133 | ||
134 | You shouldn't call this itself; instead you should subclass it | |
135 | and provid the exception_path and general_message applicable to | |
136 | this error. | |
137 | """ | |
138 | general_message = u'' | |
139 | ||
140 | @property | |
141 | def exception_path(self): | |
142 | return u"%s:%s" % ( | |
143 | self.__class__.__module__, self.__class__.__name__) | |
144 | ||
145 | def __init__(self, **metadata): | |
146 | self.metadata = metadata or {} | |
147 | ||
148 | ||
149 | class BadMediaFail(BaseProcessingFail): | |
4a477e24 | 150 | """ |
8e5f9746 JW |
151 | Error that should be raised when an inappropriate file was given |
152 | for the media type specified. | |
4a477e24 | 153 | """ |
8e5f9746 | 154 | general_message = _(u'Invalid file given for media type.') |