jrnl.args   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 295
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 203
dl 0
loc 295
rs 10
c 0
b 0
f 0
wmc 5

1 Function

Rating   Name   Duplication   Size   Complexity  
B parse_args() 0 267 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A WrappingFormatter._split_lines() 0 6 3
1
import argparse
2
import re
3
import textwrap
4
5
from .commands import postconfig_decrypt
6
from .commands import postconfig_encrypt
7
from .commands import postconfig_import
8
from .commands import postconfig_list
9
from .commands import preconfig_diagnostic
10
from .commands import preconfig_version
11
from .output import deprecated_cmd
12
from .plugins import EXPORT_FORMATS
13
from .plugins import IMPORT_FORMATS
14
from .plugins import util
15
16
17
class WrappingFormatter(argparse.RawTextHelpFormatter):
18
    """Used in help screen"""
19
20
    def _split_lines(self, text, width):
21
        text = text.split("\n\n")
22
        text = map(lambda t: self._whitespace_matcher.sub(" ", t).strip(), text)
23
        text = map(lambda t: textwrap.wrap(t, width=56), text)
24
        text = [item for sublist in text for item in sublist]
25
        return text
26
27
28
def parse_args(args=[]):
29
    """
30
    Argument parsing that is doable before the config is available.
31
    Everything else goes into "text" for later parsing.
32
    """
33
    parser = argparse.ArgumentParser(
34
        formatter_class=WrappingFormatter,
35
        add_help=False,
36
        description="Collect your thoughts and notes without leaving the command line",
37
        epilog=textwrap.dedent(
38
            """
39
        Thank you to all of our contributors! Come see the whole list of code and
40
        financial contributors at https://github.com/jrnl-org/jrnl. And special
41
        thanks to Bad Lip Reading for the Yoda joke in the Writing section above."""
42
        ),
43
    )
44
45
    optional = parser.add_argument_group("Optional Arguments")
46
    optional.add_argument(
47
        "--debug",
48
        dest="debug",
49
        action="store_true",
50
        help="Print information useful for troubleshooting",
51
    )
52
53
    standalone = parser.add_argument_group(
54
        "Standalone Commands",
55
        "These commands will exit after they complete. You may only run one at a time.",
56
    )
57
    standalone.add_argument("--help", action="help", help="Show this help message")
58
    standalone.add_argument("-h", action="help", help=argparse.SUPPRESS)
59
    standalone.add_argument(
60
        "--version",
61
        action="store_const",
62
        const=preconfig_version,
63
        dest="preconfig_cmd",
64
        help="Print version information",
65
    )
66
    standalone.add_argument(
67
        "-v",
68
        action="store_const",
69
        const=preconfig_version,
70
        dest="preconfig_cmd",
71
        help=argparse.SUPPRESS,
72
    )
73
    standalone.add_argument(
74
        "--diagnostic",
75
        action="store_const",
76
        const=preconfig_diagnostic,
77
        dest="preconfig_cmd",
78
        help=argparse.SUPPRESS,
79
    )
80
    standalone.add_argument(
81
        "--list",
82
        action="store_const",
83
        const=postconfig_list,
84
        dest="postconfig_cmd",
85
        help="List all configured journals",
86
    )
87
    standalone.add_argument(
88
        "--ls",
89
        action="store_const",
90
        const=postconfig_list,
91
        dest="postconfig_cmd",
92
        help=argparse.SUPPRESS,
93
    )
94
    standalone.add_argument(
95
        "-ls",
96
        action="store_const",
97
        const=lambda **kwargs: deprecated_cmd(
98
            "-ls", "--list or --ls", callback=postconfig_list, **kwargs
99
        ),
100
        dest="postconfig_cmd",
101
        help=argparse.SUPPRESS,
102
    )
103
    standalone.add_argument(
104
        "--encrypt",
105
        help="Encrypt selected journal with a password",
106
        action="store_const",
107
        metavar="TYPE",
108
        const=postconfig_encrypt,
109
        dest="postconfig_cmd",
110
    )
111
    standalone.add_argument(
112
        "--decrypt",
113
        help="Decrypt selected journal and store it in plain text",
114
        action="store_const",
115
        metavar="TYPE",
116
        const=postconfig_decrypt,
117
        dest="postconfig_cmd",
118
    )
119
    standalone.add_argument(
120
        "--import",
121
        action="store_const",
122
        metavar="TYPE",
123
        const=postconfig_import,
124
        dest="postconfig_cmd",
125
        help=f"""
126
        Import entries from another journal.
127
128
        Optional parameters:
129
130
        --file FILENAME (default: uses stdin)
131
132
        --format [{util.oxford_list(IMPORT_FORMATS)}] (default: jrnl)
133
        """,
134
    )
135
    standalone.add_argument(
136
        "--file",
137
        metavar="FILENAME",
138
        dest="filename",
139
        help=argparse.SUPPRESS,
140
        default=None,
141
    )
142
    standalone.add_argument("-i", dest="filename", help=argparse.SUPPRESS)
143
144
    compose_msg = """
145
    To add a new entry into your journal, simply write it on the command line:
146
147
        jrnl yesterday: I was walking and I found this big log.
148
149
    The date and the following colon ("yesterday:") are optional. If you leave
150
    them out, "now" will be used:
151
152
        jrnl Then I rolled the log over.
153
154
    Also, you can mark extra special entries ("star" them) with an asterisk:
155
156
        jrnl *And underneath was a tiny little stick.
157
158
    Please note that asterisks might be a special character in your shell, so you
159
    might have to escape them. When in doubt about escaping, put quotes around
160
    your entire entry:
161
162
        jrnl "saturday at 2am: *Then I was like 'That log had a child!'" """
163
164
    composing = parser.add_argument_group(
165
        "Writing", textwrap.dedent(compose_msg).strip()
166
    )
167
    composing.add_argument("text", metavar="", nargs="*")
168
169
    read_msg = (
170
        "To find entries from your journal, use any combination of the below filters."
171
    )
172
    reading = parser.add_argument_group("Searching", textwrap.dedent(read_msg))
173
    reading.add_argument(
174
        "-on", dest="on_date", metavar="DATE", help="Show entries on this date"
175
    )
176
    reading.add_argument(
177
        "-from",
178
        dest="start_date",
179
        metavar="DATE",
180
        help="Show entries after, or on, this date",
181
    )
182
    reading.add_argument(
183
        "-to",
184
        dest="end_date",
185
        metavar="DATE",
186
        help="Show entries before, or on, this date (alias: -until)",
187
    )
188
    reading.add_argument("-until", dest="end_date", help=argparse.SUPPRESS)
189
    reading.add_argument(
190
        "-contains",
191
        dest="contains",
192
        metavar="TEXT",
193
        help="Show entries containing specific text (put quotes around text with spaces)",
194
    )
195
    reading.add_argument(
196
        "-and",
197
        dest="strict",
198
        action="store_true",
199
        help='Show only entries that match all conditions, like saying "x AND y" (default: OR)',
200
    )
201
    reading.add_argument(
202
        "-starred",
203
        dest="starred",
204
        action="store_true",
205
        help="Show only starred entries (marked with *)",
206
    )
207
    reading.add_argument(
208
        "-n",
209
        dest="limit",
210
        default=None,
211
        metavar="NUMBER",
212
        help="Show a maximum of NUMBER entries (note: '-n 3' and '-3' have the same effect)",
213
        nargs="?",
214
        type=int,
215
    )
216
    reading.add_argument(
217
        "-not",
218
        dest="excluded",
219
        nargs="?",
220
        default=[],
221
        metavar="TAG",
222
        action="append",
223
        help="Exclude entries with this tag",
224
    )
225
226
    search_options_msg = """    These help you do various tasks with the selected entries from your search.
227
    If used on their own (with no search), they will act on your entire journal"""
228
    exporting = parser.add_argument_group(
229
        "Searching Options", textwrap.dedent(search_options_msg)
230
    )
231
    exporting.add_argument(
232
        "--edit",
233
        dest="edit",
234
        help="Opens the selected entries in your configured editor",
235
        action="store_true",
236
    )
237
    exporting.add_argument(
238
        "--delete",
239
        dest="delete",
240
        action="store_true",
241
        help="Interactively deletes selected entries",
242
    )
243
    exporting.add_argument(
244
        "--format",
245
        metavar="TYPE",
246
        dest="export",
247
        choices=EXPORT_FORMATS,
248
        help=f"""
249
        Display selected entries in an alternate format.
250
251
        TYPE can be: {util.oxford_list(EXPORT_FORMATS)}.
252
253
        Optional parameters:
254
255
        --file FILENAME Write output to file instead of stdout
256
        """,
257
        default=False,
258
    )
259
    exporting.add_argument(
260
        "--export",
261
        metavar="TYPE",
262
        dest="export",
263
        choices=EXPORT_FORMATS,
264
        help=argparse.SUPPRESS,
265
    )
266
    exporting.add_argument(
267
        "--tags",
268
        dest="tags",
269
        action="store_true",
270
        help="Alias for '--format tags'. Returns a list of all tags and number of occurences",
271
    )
272
    exporting.add_argument(
273
        "--short",
274
        dest="short",
275
        action="store_true",
276
        help="Show only titles or line containing the search tags",
277
    )
278
    exporting.add_argument(
279
        "-s",
280
        dest="short",
281
        action="store_true",
282
        help=argparse.SUPPRESS,
283
    )
284
    exporting.add_argument(
285
        "-o",
286
        dest="filename",
287
        help=argparse.SUPPRESS,
288
    )
289
290
    # Handle '-123' as a shortcut for '-n 123'
291
    num = re.compile(r"^-(\d+)$")
292
    args = [num.sub(r"-n \1", arg) for arg in args]
293
294
    return parser.parse_intermixed_args(args)
295