summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2018-03-31 21:20:21 +0200
committerjvoisin2018-03-31 21:20:21 +0200
commit12b3b39d4d5520af04233578ec93138eb192621e (patch)
tree80a4f97ba2cece14f40eee889a4330a828148062
parent0bbafc4cc52d02f763db93b67703113b88db9107 (diff)
Add support for .odt
-rw-r--r--src/libreoffice.py54
-rw-r--r--tests/data/dirty.odtbin0 -> 14114 bytes
-rw-r--r--tests/test_libmat2.py26
3 files changed, 79 insertions, 1 deletions
diff --git a/src/libreoffice.py b/src/libreoffice.py
new file mode 100644
index 0000000..b7e0dfb
--- /dev/null
+++ b/src/libreoffice.py
@@ -0,0 +1,54 @@
1import re
2import subprocess
3import json
4import zipfile
5import tempfile
6import shutil
7import os
8
9from . import abstract, parser_factory
10
11class LibreOfficeParser(abstract.AbstractParser):
12 mimetypes = {
13 'application/vnd.oasis.opendocument.text',
14 }
15
16 def get_meta(self):
17 """
18 Yes, I know that parsing xml with regexp ain't pretty,
19 be my guest and fix it if you want.
20 """
21 metadata = {}
22 zipin = zipfile.ZipFile(self.filename)
23 for item in zipin.namelist():
24 if item == 'meta.xml':
25 content = zipin.read(item).decode('utf-8')
26 for (key, value) in re.findall(r"<((?:meta|dc).+?)>(.+)</\1>", content, re.I):
27 metadata[key] = value
28 if not metadata: # better safe than sorry
29 metadata[item] = 'harmful content'
30 zipin.close()
31 return metadata
32
33 def remove_all(self):
34 zin = zipfile.ZipFile(self.filename, 'r')
35 zout = zipfile.ZipFile(self.output_filename, 'w')
36 temp_folder = tempfile.mkdtemp()
37
38 for item in zin.infolist():
39 if item.filename[-1] == '/':
40 continue # `is_dir` is added in Python3.6
41 elif item.filename == 'meta.xml':
42 continue # don't keep metadata files
43
44 zin.extract(member=item, path=temp_folder)
45 tmp_parser = parser_factory.get_parser(os.path.join(temp_folder, item.filename))
46 if tmp_parser is None:
47 print("%s isn't supported" % item.filename)
48 continue
49 tmp_parser.remove_all()
50 zout.write(tmp_parser.output_filename, item.filename)
51 shutil.rmtree(temp_folder)
52 zout.close()
53 zin.close()
54 return True
diff --git a/tests/data/dirty.odt b/tests/data/dirty.odt
new file mode 100644
index 0000000..926ebff
--- /dev/null
+++ b/tests/data/dirty.odt
Binary files differ
diff --git a/tests/test_libmat2.py b/tests/test_libmat2.py
index 717de3f..743a845 100644
--- a/tests/test_libmat2.py
+++ b/tests/test_libmat2.py
@@ -4,7 +4,7 @@ import unittest
4import shutil 4import shutil
5import os 5import os
6 6
7from src import pdf, png, jpg, audio, office 7from src import pdf, png, jpg, audio, office, libreoffice
8 8
9class TestGetMeta(unittest.TestCase): 9class TestGetMeta(unittest.TestCase):
10 def test_pdf(self): 10 def test_pdf(self):
@@ -46,6 +46,14 @@ class TestGetMeta(unittest.TestCase):
46 self.assertEqual(meta['dc:creator'], 'julien voisin') 46 self.assertEqual(meta['dc:creator'], 'julien voisin')
47 self.assertEqual(meta['Application'], 'LibreOffice/5.4.5.1$Linux_X86_64 LibreOffice_project/40m0$Build-1') 47 self.assertEqual(meta['Application'], 'LibreOffice/5.4.5.1$Linux_X86_64 LibreOffice_project/40m0$Build-1')
48 48
49 def test_libreoffice(self):
50 p = libreoffice.LibreOfficeParser('./tests/data/dirty.odt')
51 meta = p.get_meta()
52 self.assertEqual(meta['meta:initial-creator'], 'jvoisin ')
53 self.assertEqual(meta['meta:creation-date'], '2011-07-26T03:27:48')
54 self.assertEqual(meta['meta:generator'], 'LibreOffice/3.3$Unix LibreOffice_project/330m19$Build-202')
55
56
49 57
50class TestCleaning(unittest.TestCase): 58class TestCleaning(unittest.TestCase):
51 def test_pdf(self): 59 def test_pdf(self):
@@ -153,3 +161,19 @@ class TestCleaning(unittest.TestCase):
153 self.assertEqual(p.get_meta(), {}) 161 self.assertEqual(p.get_meta(), {})
154 162
155 os.remove('./tests/data/clean.docx') 163 os.remove('./tests/data/clean.docx')
164
165
166 def test_libreoffice(self):
167 shutil.copy('./tests/data/dirty.odt', './tests/data/clean.odt')
168 p = libreoffice.LibreOfficeParser('./tests/data/clean.odt')
169
170 meta = p.get_meta()
171 self.assertIsNotNone(meta)
172
173 ret = p.remove_all()
174 self.assertTrue(ret)
175
176 p = libreoffice.LibreOfficeParser('./tests/data/clean.odt.cleaned')
177 self.assertEqual(p.get_meta(), {})
178
179 os.remove('./tests/data/clean.odt')