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

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

Generate an exception when the result document is empty

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 = config.get(section, 'doctype')
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'] == self.doctype and
71                        (job['format'] == '' or job['format'] in self.formats)
72                )
73                return eligable
74
75        def process(self, job):
76                """
77                Process a job. Backends must override this method.
78                """
79                raise NotImplementedError
80
81        def save_document(self, job):
82                """
83                Save the file in a job to a temporary location and return the full path.
84                Note that the job ID is used to form the name rather than the original filename
85                to help avoid collisions.
86                """
87                if not 'job' in job or not 'filename' in job or not 'doctype' in job or not 'document' in job:
88                        raise BackendException('Could not save job document to temporary file. Invalid job.', True)
89
90                (root, ext) = os.path.splitext(job['filename'])
91                tmp_dir = os.path.normpath(self.config.get('global', 'tmp_files'))
92                if not os.path.exists(tmp_dir):
93                        logging.info('Temporary storage %s does not exist. Attempting to create', tmp_dir)
94                        try:
95                                os.makedirs(tmp_dir)
96                        except OSError:
97                                raise BackendException('Could not create temporary storage location %s' % tmp_dir)
98               
99                filename = os.path.join(tmp_dir, job['job'] + ext)
100                logging.debug('Temporary filename: %s' % filename)
101                try:
102                        file = open(filename, 'wb')
103                        file.write(base64.b64decode(job['document']))
104                        file.close()
105                except (IOError):
106                        raise BackendException('Could not write temporary file %s' % filename)
107                except TypeError:
108                        raise BackendException('Document is not base64 encoded', True)
109
110                return filename
111
112        def load_document(self, path, encode=True):
113                try:
114                        file = open(path, 'rb')
115                        contents = file.read()
116                        file.close()
117                except (IOError):
118                        raise BackendException('Could not read file %s' % path, True)
119
120                if contents == '':
121                        raise BackendException('File %s is empty' % path, True)
122
123                if encode:
124                        contents = base64.b64encode(contents)
125                return contents
126
Note: See TracBrowser for help on using the repository browser.