TextExporter.write_files()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 11
nop 3
dl 0
loc 13
rs 9.85
c 0
b 0
f 0
1
#!/usr/bin/env python
2
# encoding: utf-8
3
4
import os
5
import re
6
import unicodedata
7
8
from jrnl.color import ERROR_COLOR
9
from jrnl.color import RESET_COLOR
10
11
12
class TextExporter:
13
    """This Exporter can convert entries and journals into text files."""
14
15
    names = ["text", "txt"]
16
    extension = "txt"
17
18
    @classmethod
19
    def export_entry(cls, entry):
20
        """Returns a string representation of a single entry."""
21
        return str(entry)
22
23
    @classmethod
24
    def export_journal(cls, journal):
25
        """Returns a string representation of an entire journal."""
26
        return "\n".join(cls.export_entry(entry) for entry in journal)
27
28
    @classmethod
29
    def write_file(cls, journal, path):
30
        """Exports a journal into a single file."""
31
        try:
32
            with open(path, "w", encoding="utf-8") as f:
33
                f.write(cls.export_journal(journal))
34
                return f"[Journal exported to {path}]"
35
        except IOError as e:
36
            return f"[{ERROR_COLOR}ERROR{RESET_COLOR}: {e.filename} {e.strerror}]"
37
38
    @classmethod
39
    def make_filename(cls, entry):
40
        return entry.date.strftime("%Y-%m-%d") + "_{}.{}".format(
41
            cls._slugify(str(entry.title)), cls.extension
42
        )
43
44
    @classmethod
45
    def write_files(cls, journal, path):
46
        """Exports a journal into individual files for each entry."""
47
        for entry in journal.entries:
48
            try:
49
                full_path = os.path.join(path, cls.make_filename(entry))
50
                with open(full_path, "w", encoding="utf-8") as f:
51
                    f.write(cls.export_entry(entry))
52
            except IOError as e:
53
                return "[{2}ERROR{3}: {0} {1}]".format(
54
                    e.filename, e.strerror, ERROR_COLOR, RESET_COLOR
55
                )
56
        return "[Journal exported to {}]".format(path)
57
58
    def _slugify(string):
59
        """Slugifies a string.
60
        Based on public domain code from https://github.com/zacharyvoase/slugify
61
        """
62
        normalized_string = str(unicodedata.normalize("NFKD", string))
63
        no_punctuation = re.sub(r"[^\w\s-]", "", normalized_string).strip().lower()
64
        slug = re.sub(r"[-\s]+", "-", no_punctuation)
65
        return slug
66
67
    @classmethod
68
    def export(cls, journal, output=None):
69
        """Exports to individual files if output is an existing path, or into
70
        a single file if output is a file name, or returns the exporter's
71
        representation as string if output is None."""
72
        if output and os.path.isdir(output):  # multiple files
73
            return cls.write_files(journal, output)
74
        elif output:  # single file
75
            return cls.write_file(journal, output)
76
        else:
77
            return cls.export_journal(journal)
78