""" paperless_formats.py - Dateiformate und ihre Bearbeitbarkeit in LibreOffice. Zentral gehalten, weil drei Stellen dieselbe Information brauchen: die Versionsauswahl beim Öffnen, die Wahl des Speicherfilters beim Zurueck- schreiben und der Hinweis, wenn eine Fassung nicht sinnvoll bearbeitbar ist. """ # Endung -> (Anzeigename, LibreOffice-Filter oder None, bearbeitbar) # # "bearbeitbar" meint: LibreOffice kann die Datei öffnen UND im selben # Format wieder speichern, sodass ein sinnvoller Rückweg ins Archiv # entsteht. PDF lässt sich zwar in Draw öffnen, ein Zurückschreiben # ergaebe aber ein anderes Dokument - deshalb hier "nur Ansicht". FORMATS = { ".odt": ("ODF Text", "writer8", True), ".ods": ("ODF Tabelle", "calc8", True), ".odp": ("ODF Präsentation", "impress8", True), ".odg": ("ODF Zeichnung", "draw8", True), ".doc": ("Word 97", "MS Word 97", True), ".docx": ("Word", "MS Word 2007 XML", True), ".dot": ("Word-Vorlage", "MS Word 97 Vorlage", True), ".rtf": ("Rich Text", "Rich Text Format", True), ".xls": ("Excel 97", "MS Excel 97", True), ".xlsx": ("Excel", "Calc MS Excel 2007 XML", True), ".ppt": ("PowerPoint 97", "MS PowerPoint 97", True), ".pptx": ("PowerPoint", "Impress MS PowerPoint 2007 XML", True), ".txt": ("Text", "Text", True), ".csv": ("CSV", "Text - txt - csv (StarCalc)", True), ".pdf": ("PDF", None, False), ".eml": ("E-Mail", None, False), ".msg": ("E-Mail", None, False), ".xml": ("XML", None, False), ".html": ("HTML", None, False), ".zip": ("Archiv", None, False), ".png": ("Bild", None, False), ".jpg": ("Bild", None, False), ".jpeg": ("Bild", None, False), ".tif": ("Bild", None, False), ".tiff": ("Bild", None, False), } MIME_TO_EXT = { "application/vnd.oasis.opendocument.text": ".odt", "application/vnd.oasis.opendocument.spreadsheet": ".ods", "application/vnd.oasis.opendocument.presentation": ".odp", "application/vnd.oasis.opendocument.graphics": ".odg", "application/msword": ".doc", "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx", "application/vnd.ms-excel": ".xls", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx", "application/vnd.ms-powerpoint": ".ppt", "application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx", "application/rtf": ".rtf", "text/rtf": ".rtf", "text/plain": ".txt", "text/csv": ".csv", "application/pdf": ".pdf", "message/rfc822": ".eml", "text/html": ".html", "application/xml": ".xml", "text/xml": ".xml", "application/zip": ".zip", } def extension(filename=None, mime_type=None): """Endung aus Dateiname oder MIME-Typ, immer kleingeschrieben.""" if filename and "." in filename: return "." + filename.rsplit(".", 1)[-1].lower() if mime_type: return MIME_TO_EXT.get(mime_type.split(";")[0].strip().lower(), "") return "" def describe(filename=None, mime_type=None): """(Anzeigename, Filter, bearbeitbar) für eine Datei.""" ext = extension(filename, mime_type) if ext in FORMATS: return FORMATS[ext] return (ext.lstrip(".").upper() or "unbekannt", None, False) def is_editable(filename=None, mime_type=None): return describe(filename, mime_type)[2] def is_known(filename=None, mime_type=None): """ Ist das Format in der Tabelle verzeichnet? Wichtig für die Unterscheidung zweier Fälle: Ein PDF ist BEKANNT und nicht bearbeitbar — da hilft kein Zureden. Ein unbekanntes Format dagegen ist womöglich sehr wohl bearbeitbar, es steht nur nicht in der Tabelle. Dann soll der Anwender entscheiden dürfen, statt vom Programm ausgebremst zu werden. """ return extension(filename, mime_type) in FORMATS def detail(filename=None, mime_type=None): """ Ausführliche Angabe für Hinweistexte: Anzeigename plus die Rohdaten, aus denen er abgeleitet wurde. Damit lässt sich erkennen, welche Formate in FORMATS ergänzt werden sollten. """ name = describe(filename, mime_type)[0] teile = [t for t in (filename, mime_type) if t] return "%s — %s" % (name, ", ".join(teile)) if teile else name # Dokumentart -> Vorgabeformat für Dateien, die noch nie gespeichert wurden. # Ermittelt über supportsService() am geöffneten Dokument. SERVICE_DEFAULTS = ( ("com.sun.star.text.TextDocument", ".odt", "writer8"), ("com.sun.star.sheet.SpreadsheetDocument", ".ods", "calc8"), ("com.sun.star.presentation.PresentationDocument", ".odp", "impress8"), ("com.sun.star.drawing.DrawingDocument", ".odg", "draw8"), ("com.sun.star.formula.FormulaProperties", ".odf", "math8"), ) def default_for_document(doc): """ (Endung, Filter) für ein Dokument ohne Speicherort. Ein neu angelegtes, noch nie gespeichertes Dokument hat keinen URL. Damit es trotzdem abgelegt werden kann, wird es in ein temporäres Verzeichnis geschrieben - im zur Anwendung passenden ODF-Format. """ for service, ext, filt in SERVICE_DEFAULTS: try: if doc.supportsService(service): return ext, filt except Exception: continue return ".odt", "writer8" def store_filter(filename=None, mime_type=None): """LibreOffice-Filtername zum Speichern im Originalformat.""" return describe(filename, mime_type)[1] def label(filename=None, mime_type=None): """Kurzbeschreibung für die Anzeige, z. B. 'ODF Text'.""" return describe(filename, mime_type)[0]