source: trunk/factory/src/backends/__init__.py @ 335

Last change on this file since 335 was 335, checked in by sander, 11 years ago

Do not crash factory when the oooserver dies mid-conversion

File size: 3.9 KB
Line 
1# Officeshots.org - Test your office documents in different applications
2# Copyright (C) 2009 Stichting Lone Wolves
3# Written by Sander Marechal <s.marechal@jejik.com>
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Affero General Public License as
7# published by the Free Software Foundation, either version 3 of the
8# License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18"""
19The core backend class
20"""
21
22import os
23import base64
24import logging
25
26class BackendException:
27        """
28        A base Backend exception class. Backends should derive their own
29        exceptions from this.
30
31        When the Factory catches this exception and recoverable is False, then
32        the backend will be unloaded.
33        """
34        def __init__(self, message, recoverable = False):
35                self.message = message
36                self.recoverable = recoverable
37       
38        def __str__(self):
39                if self.recoverable:
40                        return self.message + ' (Recoverable)'
41                return self.message + ' (Not recoverable)'
42
43class Backend:
44        """
45        The base backend class. Backends shoudl derive from this
46        """
47        def __init__(self, options, config, section):
48                self.options = options
49                self.config = config
50                self.section = section
51
52                self.application = config.get(section, 'application').lower()
53                self.version = config.get(section, 'version').lower()
54                self.doctype = [s.strip() for s in config.get(section, 'doctype').split(',')]
55                self.formats = [s.strip() for s in config.get(section, 'formats').split(',')]
56       
57        def initialize(self):
58                """
59                This is called right after instanciating the backend.
60                """
61                pass   
62
63        def can_process(self, job):
64                """
65                Return True if this backend is eligable to process this Job, False otherwise
66                """
67                eligable = (
68                        job['application'].lower() == self.application and
69                        job['version'].lower() == self.version and
70                        job['doctype'] in self.doctype and
71                        (job['format'] == '' or job['format'] in self.formats)
72                )
73
74                return eligable
75
76        def process(self, job):
77                """
78                Process a job. Backends must override this method.
79                """
80                raise NotImplementedError
81
82        def save_document(self, job):
83                """
84                Save the file in a job to a temporary location and return the full path.
85                Note that the job ID is used to form the name rather than the original filename
86                to help avoid collisions.
87                """
88                if not 'job' in job or not 'filename' in job or not 'doctype' in job or not 'document' in job:
89                        raise BackendException('Could not save job document to temporary file. Invalid job.', True)
90
91                (root, ext) = os.path.splitext(job['filename'])
92                tmp_dir = os.path.normpath(self.config.get('global', 'tmp_files'))
93                if not os.path.exists(tmp_dir):
94                        logging.info('Temporary storage %s does not exist. Attempting to create', tmp_dir)
95                        try:
96                                os.makedirs(tmp_dir)
97                        except OSError:
98                                raise BackendException('Could not create temporary storage location %s' % tmp_dir)
99               
100                filename = os.path.join(tmp_dir, job['job'] + ext)
101                logging.debug('Temporary filename: %s' % filename)
102                try:
103                        file = open(filename, 'wb')
104                        file.write(base64.b64decode(job['document']))
105                        file.close()
106                except IOError, e:
107                        raise BackendException('Could not write temporary file %s (%s)' % (filename, e))
108                except TypeError, e:
109                        raise BackendException('Document is not base64 encoded (%s)' % e, True)
110
111                return filename
112
113        def load_document(self, path, encode=True):
114                try:
115                        file = open(path, 'rb')
116                        contents = file.read()
117                        file.close()
118                except (IOError):
119                        raise BackendException('Could not read file %s' % path, True)
120
121                if contents == '':
122                        raise BackendException('File %s is empty' % path, True)
123
124                if encode:
125                        contents = base64.b64encode(contents)
126                return contents
127
Note: See TracBrowser for help on using the repository browser.