b7e761f252386ddb25acf7fbcc589f2b792fe369
[mediagoblin.git] / mediagoblin / processing / task.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 import logging
18
19 from celery.task import Task
20
21 from mediagoblin import mg_globals as mgg
22 from mediagoblin.db.sql.models import MediaEntry
23 from mediagoblin.processing import mark_entry_failed, BaseProcessingFail
24 from mediagoblin.tools.processing import json_processing_callback
25
26 _log = logging.getLogger(__name__)
27 logging.basicConfig()
28 _log.setLevel(logging.DEBUG)
29
30
31 ################################
32 # Media processing initial steps
33 ################################
34
35 class ProcessMedia(Task):
36 """
37 Pass this entry off for processing.
38 """
39 def run(self, media_id):
40 """
41 Pass the media entry off to the appropriate processing function
42 (for now just process_image...)
43 """
44 entry = MediaEntry.query.get(media_id)
45
46 # Try to process, and handle expected errors.
47 try:
48 entry.state = u'processing'
49 entry.save()
50
51 _log.debug('Processing {0}'.format(entry))
52
53 # run the processing code
54 entry.media_manager['processor'](entry)
55
56 # We set the state to processed and save the entry here so there's
57 # no need to save at the end of the processing stage, probably ;)
58 entry.state = u'processed'
59 entry.save()
60
61 json_processing_callback(entry)
62 except BaseProcessingFail as exc:
63 mark_entry_failed(entry.id, exc)
64 json_processing_callback(entry)
65 return
66
67 except ImportError as exc:
68 _log.error(
69 'Entry {0} failed to process due to an import error: {1}'\
70 .format(
71 entry.title,
72 exc))
73
74 mark_entry_failed(entry.id, exc)
75 json_processing_callback(entry)
76
77 except Exception as exc:
78 _log.error('An unhandled exception was raised while'
79 + ' processing {0}'.format(
80 entry))
81
82 mark_entry_failed(entry.id, exc)
83 json_processing_callback(entry)
84 raise
85
86 def on_failure(self, exc, task_id, args, kwargs, einfo):
87 """
88 If the processing failed we should mark that in the database.
89
90 Assuming that the exception raised is a subclass of
91 BaseProcessingFail, we can use that to get more information
92 about the failure and store that for conveying information to
93 users about the failure, etc.
94 """
95 entry_id = args[0]
96 mark_entry_failed(entry_id, exc)
97
98 entry = mgg.database.MediaEntry.query.filter_by(id=entry_id).first()
99 json_processing_callback(entry)