source: trunk/factory/src/backends/oooserver.py @ 172

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

Check that the document loaded correctly and raise a recoverable exception if it could not

File size: 4.4 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# Heavily based on PyODConvert, which is
6# Copyright (C) 2007 Mirko Nasato <mirko@artofsolving.com>
7# Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl.html
8
9"""
10This module is a back-end for the headless OpenOffice.org server
11"""
12
13import os
14import uno
15import logging
16
17from backends import Backend, BackendException
18from com.sun.star.beans import PropertyValue
19from com.sun.star.connection import NoConnectException
20from com.sun.star.document.UpdateDocMode import QUIET_UPDATE
21
22FAMILY_MASTER = "Master"
23FAMILY_PRESENTATION = "Presentation"
24FAMILY_SPREADSHEET = "Spreadsheet"
25FAMILY_TEXT = "Text"
26
27FAMILY_BY_DOCTYPE = {
28        "odt": FAMILY_TEXT,
29        "sxw": FAMILY_TEXT,
30        "doc": FAMILY_TEXT,
31        "rtf": FAMILY_TEXT,
32        "txt": FAMILY_TEXT,
33        "wpd": FAMILY_TEXT,
34        "html": FAMILY_TEXT,
35        "ods": FAMILY_SPREADSHEET,
36        "sxc": FAMILY_SPREADSHEET,
37        "xls": FAMILY_SPREADSHEET,
38        "odp": FAMILY_PRESENTATION,
39        "sxi": FAMILY_PRESENTATION,
40        "ppt": FAMILY_PRESENTATION
41}
42
43FILTER_BY_FORMAT = {
44        "pdf": {
45                FAMILY_TEXT: "writer_pdf_Export",
46                FAMILY_SPREADSHEET: "calc_pdf_Export",
47                FAMILY_PRESENTATION: "impress_pdf_Export"
48        },
49        "odf": {
50                FAMILY_TEXT: "writer8",
51                FAMILY_SPREADSHEET: "calc8",
52                FAMILY_PRESENTATION: "impress8"
53        }
54}
55
56def _unoProps(**args):
57        props = []
58        for key in args:
59                prop = PropertyValue()
60                prop.Name = key
61                prop.Value = args[key]
62                props.append(prop)
63        return tuple(props)
64
65
66class OOOServerException(BackendException):
67        def __str__(self):
68                return 'OOOServerException: ' + BackendException.__str__(self)
69       
70
71class OOOServer(Backend):
72        """
73        Backend for the headless OpenOffice.org server
74        """
75        def initialize(self):
76                localContext = uno.getComponentContext()
77                resolver = localContext.ServiceManager.createInstanceWithContext('com.sun.star.bridge.UnoUrlResolver', localContext)
78
79                if self.config.has_option(self.section, 'ooo_host') and self.config.has_option(self.section, 'ooo_port'):
80                        self.ooo_host = self.config.get(self.section, 'ooo_host')
81                        self.ooo_port = self.config.get(self.section, 'ooo_port')
82                        try:
83                                context = resolver.resolve('uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext' % (self.ooo_host, self.ooo_port))
84                        except NoConnectException:
85                                raise OOOServerException('Failed to connect to OpenOffice.org on %s port %s' % (self.ooo_host, self.ooo_port))
86                elif self.config.has_option(self.section, 'ooo_pipe'):
87                        self.ooo_pipe = self.config.get(self.section, 'ooo_pipe')
88                        try:
89                                context = resolver.resolve('uno:pipe,name=%s;urp;StarOffice.ComponentContext' % self.ooo_pipe)
90                        except NoConnectException:
91                                raise OOOServerException('Failed to connect to OpenOffice.org on pipe "%s"' % self.ooo_pipe)
92                else:
93                        raise OOOServerException('Failed to connect to OpenOffice.org. No connection method configured.')
94                               
95                self.desktop = context.ServiceManager.createInstanceWithContext('com.sun.star.frame.Desktop', context)
96       
97        def filter_name(self, doctype, format):
98                try:
99                        family = FAMILY_BY_DOCTYPE[doctype]
100                except KeyError:
101                        raise OOOServerException("Unknown input doctype: '%s'" % doctype, True)
102                try:
103                        filterByFamily = FILTER_BY_FORMAT[format]
104                except KeyError:
105                        raise OOOServerException("Unknown output format: '%s'" % format, True)
106                try:
107                        return filterByFamily[family]
108                except KeyError:
109                        raise OOOServerException("Unsupported conversion: from '%s' to '%s'" % (doctype, format), True)
110
111        def file_url(self, path):
112                return uno.systemPathToFileUrl(os.path.abspath(path))
113
114        def process(self, job):
115                src_file = self.save_document(job)
116                (root, ext) = os.path.splitext(src_file)
117                dst_file = root + '_result' + ext
118
119                if (job['format'] == ''):
120                        job['format'] = 'pdf'
121
122                src_file_url = self.file_url(src_file)
123                filter_name = self.filter_name(job['doctype'], job['format'])
124                document = self.desktop.loadComponentFromURL(src_file_url, "_blank", 0, _unoProps(Hidden=True, ReadOnly=True, UpdateDocMode=QUIET_UPDATE))
125
126                if document is None:
127                        raise OOOServerException("The document '%s' could not be opened." % src_file_url, True)
128
129                document.storeToURL(self.file_url(dst_file), _unoProps(FilterName=filter_name))
130                document.close(True)
131
132                logging.info('OOOServer converted %s to %s' % (src_file, dst_file))
133                contents = self.load_document(dst_file)
134                os.unlink(src_file)
135                os.unlink(dst_file)
136
137                return (job['format'], contents)
138
Note: See TracBrowser for help on using the repository browser.