Coverage for /media/ldata/code/tendril/tendril/utils/libreoffice.py: 0%

# Coverage for /media/ldata/code/tendril/tendril/utils/libreoffice.py : 0%

## 51 statements 0 run 51 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | # Copyright (C) 2015 Chintalagiri Shashank # # This file is part of Tendril. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ The LibreOffice Utils Module (:mod:`tendril.utils.libreoffice`) =============================================================== This module provides utilities to deal with LibreOffice files. Functionality is implemented lazily, so this doesn't really do much. Presently, whatever it does do, it does by relying on external python code, executed in a shell by :mod:`subprocess`. This is required since the default LibreOffice install I have only supports a python 3 API. For details about how it actually works, look at the documentation of the :mod:`sofficehelpers` package. The scripts used from that package are : - :mod:`sofficehelpers.ssconverter` for converting spreadsheets to CSV files. .. todo:: Publish the :mod:`sofficehelpers` package somewhere, or find a pre-existing alternative. If there is a functionally sufficient alternative, it will probably be better. """ from tendril.utils.fsutils import TEMPDIR import shutil import os import subprocess import atexit #: A list of all files currently open which the module is responsible for. open_files = [] class XLFile(object): """ This class allows reading data from LibreOffice supported Spreadsheet files, by converting each sheet into a CSV file, which can then be read by application code. Note that this is a one way conversion only. The original spreadsheet file is not written to. When the object is instantiated, a copy of the file is made in the temporary folder by :func:`_make_copy`, which is then converted into one CSV file per sheet in the original spreadsheet file by :func:`_make_csv_files`. It then adds itself to the modules :data:`open_files` list. :param filepath: The path of the spreadsheet to be opened. :ivar fpath: The path to the original spreadsheet file. :ivar fname: The file name of the original spreadsheet file. :ivar _csv_list: The list of CSV files generated from the spreadsheet, one per sheet. """ def __init__(self, filepath): self.fpath = filepath self.fname = os.path.split(filepath)[1] self._csv_list = [] self._tfpath = self._make_copy() self._make_csv_files() open_files.append(self) def get_csv_path(self, sheetname): """ Gets the path to the CSV file that was created at object initialization corresponding to the sheetname provided. :param sheetname: Name of the Spreadsheet Sheet. """ for (sname, spath) in self._csv_list: if sname == sheetname: return spath return None def _make_copy(self): """ Makes a copy of the original file in the temporary directory """ tfpath = os.path.join(TEMPDIR, self.fname) shutil.copyfile(self.fpath, tfpath) return tfpath def _make_csv_files(self): """ Converts a SpreadSheet file supported by LibreOffice into a set of CSV files, one per sheet, using the :mod:`sofficehelpers.ssconverter` script. The output is parsed by :func:`_parse_sscout`. """ fname = os.path.splitext(self.fname)[0] csvpath = os.path.join(TEMPDIR, fname + '-%s.csv') cstrl = ["ssconverter", self._tfpath, csvpath] self._csv_list = self._parse_sscout(subprocess.check_output(cstrl)) def _parse_sscout(self, string): """ Parses the output of the :mod:`sofficehelpers.ssconverter` script, extracting the Sheet names and corresponding CSV file names from the output. """ fname = os.path.splitext(self.fname)[0] rlist = [x.strip() for x in string.split('\n')[1:-1]] rlist = [(os.path.split(x)[1][len(fname) + 1:-4], x) for x in rlist] return rlist def close(self): """ Closes the object and removes it from the :data:`open_files` list. Also runs :func:`_clean` to remove all the files it created. """ self._clean() open_files.remove(self) def _clean(self): """ Removes all temporary files created during the object instantiation. """ os.remove(self._tfpath) for (s, csvpath) in self._csv_list: os.remove(csvpath) def get_xlf(fpath): """ Gets the :class:`XLFile` object for the spreadsheet at ``fpath``, `opening` the file and creating the object if it does not already exist. :param fpath: Path of the spreadsheet file to open. :return: The opened :class:`XLFile` instance. """ """ :param fpath: :return: """ for f in open_files: if f.fpath == fpath: return f f = XLFile(fpath) return f def ooutils_cleanup(): """ Called when the python interpreter is shutting down. Cleans up all `tendril.utils.libreoffice` related objects and other artifacts created by the module. Performs the following tasks: - Closes all :data:`open_files` """ for f in open_files: f.close() atexit.register(ooutils_cleanup)