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

Last change on this file was 379, checked in by sander, 8 years ago

Make the factory client run like a daemon

File size: 5.0 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.io import IOException
19from com.sun.star.uno import RuntimeException
20from com.sun.star.lang import IllegalArgumentException
21from com.sun.star.beans import PropertyValue
22from com.sun.star.connection import NoConnectException
23from com.sun.star.document.UpdateDocMode import QUIET_UPDATE
24
25FAMILY_MASTER = "Master"
26FAMILY_PRESENTATION = "Presentation"
27FAMILY_SPREADSHEET = "Spreadsheet"
28FAMILY_TEXT = "Text"
29
30FAMILY_BY_DOCTYPE = {
31        "odt": FAMILY_TEXT,
32        "sxw": FAMILY_TEXT,
33        "doc": FAMILY_TEXT,
34        "rtf": FAMILY_TEXT,
35        "txt": FAMILY_TEXT,
36        "wpd": FAMILY_TEXT,
37        "html": FAMILY_TEXT,
38        "ods": FAMILY_SPREADSHEET,
39        "sxc": FAMILY_SPREADSHEET,
40        "xls": FAMILY_SPREADSHEET,
41        "odp": FAMILY_PRESENTATION,
42        "sxi": FAMILY_PRESENTATION,
43        "ppt": FAMILY_PRESENTATION
44}
45
46FILTER_BY_FORMAT = {
47        "pdf": {
48                FAMILY_TEXT: "writer_pdf_Export",
49                FAMILY_SPREADSHEET: "calc_pdf_Export",
50                FAMILY_PRESENTATION: "impress_pdf_Export"
51        },
52        "odf": {
53                FAMILY_TEXT: "writer8",
54                FAMILY_SPREADSHEET: "calc8",
55                FAMILY_PRESENTATION: "impress8"
56        }
57}
58
59def _unoProps(**args):
60        props = []
61        for key in args:
62                prop = PropertyValue()
63                prop.Name = key
64                prop.Value = args[key]
65                props.append(prop)
66        return tuple(props)
67
68
69class OOOServerException(BackendException):
70        def __str__(self):
71                return 'OOOServerException: ' + BackendException.__str__(self)
72       
73
74class OOOServer(Backend):
75        """
76        Backend for the headless OpenOffice.org server
77        """
78        def initialize(self):
79                localContext = uno.getComponentContext()
80                resolver = localContext.ServiceManager.createInstanceWithContext('com.sun.star.bridge.UnoUrlResolver', localContext)
81
82                if self.config.has_option(self.section, 'ooo_host') and self.config.has_option(self.section, 'ooo_port'):
83                        self.ooo_host = self.config.get(self.section, 'ooo_host')
84                        self.ooo_port = self.config.get(self.section, 'ooo_port')
85                        try:
86                                context = resolver.resolve('uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext' % (self.ooo_host, self.ooo_port))
87                        except NoConnectException:
88                                raise OOOServerException('Failed to connect to OpenOffice.org on %s port %s' % (self.ooo_host, self.ooo_port))
89                elif self.config.has_option(self.section, 'ooo_pipe'):
90                        self.ooo_pipe = self.config.get(self.section, 'ooo_pipe')
91                        try:
92                                context = resolver.resolve('uno:pipe,name=%s;urp;StarOffice.ComponentContext' % self.ooo_pipe)
93                        except NoConnectException:
94                                raise OOOServerException('Failed to connect to OpenOffice.org on pipe "%s"' % self.ooo_pipe)
95                else:
96                        raise OOOServerException('Failed to connect to OpenOffice.org. No connection method configured.')
97                               
98                self.desktop = context.ServiceManager.createInstanceWithContext('com.sun.star.frame.Desktop', context)
99       
100        def filter_name(self, doctype, format):
101                try:
102                        family = FAMILY_BY_DOCTYPE[doctype]
103                except KeyError:
104                        raise OOOServerException("Unknown input doctype: '%s'" % doctype, True)
105                try:
106                        filterByFamily = FILTER_BY_FORMAT[format]
107                except KeyError:
108                        raise OOOServerException("Unknown output format: '%s'" % format, True)
109                try:
110                        return filterByFamily[family]
111                except KeyError:
112                        raise OOOServerException("Unsupported conversion: from '%s' to '%s'" % (doctype, format), True)
113
114        def file_url(self, path):
115                return uno.systemPathToFileUrl(os.path.abspath(path))
116
117        def process(self, job):
118                src_file = self.save_document(job)
119                (root, ext) = os.path.splitext(src_file)
120                dst_file = root + '_result' + ext
121
122                if (job['format'] == ''):
123                        job['format'] = 'pdf'
124
125                src_file_url = self.file_url(src_file)
126                filter_name = self.filter_name(job['doctype'], job['format'])
127
128                try:
129                        document = self.desktop.loadComponentFromURL(src_file_url, "_blank", 0, _unoProps(Hidden=True, ReadOnly=True, UpdateDocMode=QUIET_UPDATE))
130
131                        if document is None:
132                                raise OOOServerException("The document '%s' could not be opened." % src_file_url, True)
133
134                        url = self.file_url(dst_file)
135                        props = _unoProps(FilterName=filter_name)
136
137                        try:
138                                document.storeToURL(url, props)
139                        except IOException, e:
140                                raise OOOServerException("IOException: OOOServer could not store document to %s with properties %s. Exception: %s" % (url, props, e), True)
141
142                        document.close(True)
143                except RuntimeException:
144                        raise OOOServerException("UNO RuntimeException in OOOServer. The server probably died. Unloading backend.", False)
145                except IllegalArgumentException:
146                        raise OOOServerException("UNO IllegalArgument in OOOServer. Source file cannot be read.", True)
147
148
149                logging.info('OOOServer converted %s to %s' % (src_file, dst_file))
150                contents = self.load_document(dst_file)
151                os.unlink(src_file)
152                os.unlink(dst_file)
153
154                return (job['format'], contents)
155
Note: See TracBrowser for help on using the repository browser.