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

Last change on this file since 79 was 79, checked in by sander, 12 years ago

Match a factory when the job has no format specified

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