-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcommand_line.py
executable file
·416 lines (387 loc) · 20.2 KB
/
command_line.py
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#!/usr/bin/python3
# -*-coding:Utf-8 -*
"""A file for command-line arguments"""
import argparse, gettext, locale, os, sys, unicodedata
gettext.install('command_line','./i18n')
arguments = { # essayer d'ajouter les commandes de DATE
"""A dict whith following tree :
DEST : {
'short' : '-r',
'long' : '--research',
'help' : 'description for zsh or fish',
'options' : 'if necessary',
},
"""
# Main options
'TODAY': {
'short':[],
'long': ['--'],
},
'DEPUIS':{
'short':[],
'long' : ['--from'],
},
'JUSQUE':{
'short':[],
'long' : ['--to'],
},
'INVERSE':{
'short':['-r'],
'long' : ['--reverse'],
},
# Print options
'verbose':{
'short':['-v'],
'long' : ['--verbose'],
},
'couleur':{
'short':['-c'],
'long' : ['--color','--colour'],
},
'degre':{
'short':['-d'],
'long' : ['--degree'],
},
'jour_semaine':{
'short':['-w'],
'long' : ['--weekday'],
},
'print_proper':{
'short':['-R'],
'long': ['--print-proper'],
},
'transfert':{
'short':['-t'],
'long' : ['--transfert'],
},
'temporal_ou_sanctoral':{
'short':['-s'],
'long' : ['--temporsanct'],
},
'temps_liturgique':{
'short':['-L'],
'long' : ['--liturgical-time'],
},
'date_affichee':{
'short':['-D'],
'long' : ['--print-date'],
},
'textes':{
'short':[],
'long' : ['--show-texts'],
},
'martyrology':{
'short':['-M'],
'long':['--show-martyrology'],
},
'station':{
'short':['-I'],
'long':['--statio'],
},
'pal':{
'short':['-a'],
'long':['--pal'],
},
'langue':{
'short':['-l'],
'long' : ['--language'],
'options': ['fr','en','la'],
},
'status':{
'short':['-A'],
'long':['--status'],
},
# Selection options
'propre': {
'short':['-p',],
'long':['--proper','--rite',],
'options':['roman',
'american','australian','brazilian','canadian','english','french','newzealander','polish','portuguese','scottish','spanish','strasburger','welsh',
]
},
'ordo': {
'short':['-o'],
'long':['--ordo'],
'options':['1962'],
},
'plus': {
'short':['-m'],
'long':['--more'],
},
# System options
'navigateur': {
'short':['-b'],
'long':['--browser'],
},
'gui':{
'short':['-g'],
'long':['--gui'],
},
'version': {
'short':[],
'long':['--version'],
},
'poems': {
'short':[],
'long':['--poems'],
},
'settings' : {
'short':[],
'long' : ['--set'],
},
# History options
'historique': {
'short' : ['-H'],
'long' : ['--show-history'],
},
'entree_historique': {
'short': ['-S'],
'long' : ['--select-entry'],
},
'suivant': {
'short': ['-N'],
'long' : ['--next'],
},
'precedent':{
'short': ['-P'],
'long': ['--previous'],
},
# Export options
'export':{
'short': ['-e'],
'long': ['--export'],
},
'output': {
'short': ['-O'],
'long': ['--output'],
},
# Help
'help':{
'short':['-h'],
'long':['--help'],
}
}
class AutoCompleter():
def __init__(self):
self.options = arguments
self.options_ = []
def autocomplete(self):
if 'AUTO_COMPLETE' not in os.environ:
return
words = os.environ['COMP_WORDS'].split()[1:]
cword = int(os.environ['COMP_CWORD'])
short_options = set()
for arg in words:
try:
if arg[0] == '-' and arg[1] != '-':
short_options = short_options.union(set(arg[1:]))
except IndexError:
continue
if len(words) > 1:
blast_one = words[-2]
else:
blast_one = False
if len(words) > 0:
last_one = words[-1]
else:
blast_one = False
last_one = False
self.options_ = []
for value in self.options.values():
if 'options' in value:
if (last_one in value['long'] or last_one in value['short']) or ((blast_one in value['long'] or blast_one in value['short']) and [True for val in value['options'] if last_one in val and last_one != val]): #BUG il fait choisir deux langues...
self.options_ = value['options']
break
for long_one in value['long']:
if long_one in words:
value['long'] = []
break
for short_one in value['short']:
if short_one[1] in short_options:
value['long'] = []
self.options_ += value['long']
try:
# curr is the current word, with cword being a 1-based index
curr = words[cword - 1]
except IndexError:
curr = ''
if self.options_ == []:
self.options_.append('--')
complete = ' '.join(sorted(filter(lambda x: x.startswith(curr),self.options_)))
print(complete)
sys.exit(1)
def default_language():
"""A function which defines default language of the system
If a language was set default by user, return it"""
file = os.path.expanduser('~/.theochrone/config/LANG')
try:
with open(file) as f:
return f.read()
except FileNotFoundError:
pass
try:
lang = locale.getdefaultlocale()[0].split('_')[0]
except ValueError: # an unknown locale can be found and raise the ValueError
lang = 'en'
if lang not in arguments['langue']['options']:
lang = 'en'
return lang
def default_proper():
"""Return the proper selected by the user.
If no proper was selected, return the roman proper"""
file = os.path.expanduser('~/.theochrone/config/PROPER')
try:
with open(file) as f:
return f.read()
except FileNotFoundError:
return 'roman'
class CoursDeLangue(argparse.Action):
"""A class to set language name entered by user"""
def __call__(self,parser,namespace,value,option_string=None):
language_available = { 'fr': (_('francais'),'fr'),
'en':('en',_('english')),
'la':('la',_('latina'))}
def sans_accent(mot):
"""Prend des mots avec accents, cédilles, etc. et les renvoie sans, et en minuscules.""" # voir si on ne peut pas le mettre dans officia.
return ''.join(c for c in unicodedata.normalize('NFD',mot.lower()) if unicodedata.category(c) != 'Mn')
value = sans_accent(value.lower())
for key,values in language_available.items():
if value in values or value == key:
value = key
break
if value not in arguments['langue']['options']:
print(_("Language entered is not available. Default language will be used instead."))
value = default_language()
setattr(namespace,self.dest,value)
### Command-line args ###
def args():
"""A function which returns args."""
parser = argparse.ArgumentParser(
prog='Theochrone',
formatter_class=argparse.RawTextHelpFormatter,
description=_("""A universal calendar for the Tridentine Mass (i.e. Extraordinary Form of the Roman Rite)"""),
epilog=_("Please pray God for me."),
)
main = parser.add_argument_group(_('Main options'), description=_("Main options of the program"))
main.add_argument('DATE', nargs='*',help=_("""Theochrone accepts many formats :
- Nothing : current day
- A complete date with year, month and day of month, for example as following :
- DD MM YYYY
- DD-MM-YYYY
- DD/MM/YYYY
- DDMMYYYY (eight characters required)
- Day in figures, month in letters, year in figures :
ex. 30 december 1990 ; 8th july 1990
- weekday before the date as above : ex. Wednesday the 24th of January 2017
WARNING !!! The order of these elements much depends on your language.
- You can imply one of these elements, and so works Theochrone :
- a figure between 1 and 31 : day of the current month in the current year
- a weekday in letters only : the requested day in the current week
(starting with Sunday)
- a month only (ex : july, sept,...) : the complete month of the current year
- the day and the month without year : current year used
- a number between 1600 and 4100 : the complete year.
- a word as listed below in your current language :
- 'week' : the complete current week, starting with Sunday,
ending with Saturday.
You can also ask for 'next' or 'last' 'week', which returns the week
after current, and the past one.
- 'tomorrow' : the day after current one.
You can also ask for the 'day after tomorrow'.
- 'yesterday' : the day before current one.
You can also ask for the 'day before yesterday'.
- 'next month', or 'previous month', which returns the month
after current one, and the month before current one.
- 'next year', or 'previous year', which returns the year
after current one, and the year before current one.
All of these formats are also accepted by the --from and --to options. (See below)
"""))
main.add_argument('--',dest='TODAY',action='store_true',help=_("""Convenient argument for Windows and OS X users.
Returns results for current date."""))
main.add_argument('--from',dest='DEPUIS',nargs='*',default=1,help=_("""With --to option, --from option can be used to point out the beginning of the period you want to print.
Arguments accepted have exactly the same format as DATE (see above).
--from may be implied : if --to point out a date later than the current day,
--from would automatically considered to be the current day ;
else, it would be the first of january of the current year.""" ))
main.add_argument('--to',dest='JUSQUE',nargs='*',default=1,help=_("""With --from option, --to option can be used to point out the end of the period you want to print.
Arguments accepted have exactly the same format as DATE (see above).
--to may be implied : if --from point out a date prior to the current day,
--to would automatically considered to be the current day ;
else, it would be the 31st of december of the current year."""))
main.add_argument('-r','--reverse',dest='INVERSE',nargs='*',default=1,help=_("""Alpha. Does not work properly.
Reverse is to be a way to find and print feast by entering their names as arguments,
ex : -r Easter, -r 21 Sunday after Pentecost,...
Every other options are available with this one.
With -M option, search is done inside the Roman Martyrology"""))
affichage = parser.add_argument_group(_('Print options'),description=_("Convenient options for printing results"))
affichage.add_argument('-v','--verbose', help=_("make theochrone more verbose. Equals to -cdstwLD, and more."),action='store_true')
affichage.add_argument('-c','--color','--colour', dest='couleur', help=_("print liturgical colour"), action='store_true')
affichage.add_argument('-d','--degree', dest='degre', help=_('print degree of the liturgical feast'), action='store_true')
affichage.add_argument('-w','--weekday', dest='jour_semaine',help=_('print weekday'),action='store_true')
affichage.add_argument('-t','--transfert', dest='transfert', help=_('print wether the feast was transfered'), action='store_true')
affichage.add_argument('-s','--temporsanct',dest='temporal_ou_sanctoral', help=_('print whether the feast belongs to the sanctorum or de tempore'), action='store_true')
affichage.add_argument('-L','--liturgical-time', dest='temps_liturgique',help=_('print to which liturgical time the feast belongs to'),action='store_true')
affichage.add_argument('-D','--print-date',dest='date_affichee',help=_('print date'),action='store_true')
affichage.add_argument(*arguments['print_proper']['short'],*arguments['print_proper']['long'],dest='print_proper',help=_("""Prints the name of the proper of the feasts on screen"""),action="store_true")
affichage.add_argument(*arguments['status']['short'],*arguments['status']['long'],dest='status',action="store_true",help=_("""Prints the status of the feasts"""))
affichage.add_argument(*arguments['pal']['short'],*arguments['pal']['long'],dest="pal",help=_("""Include Pro Aliquibus Locis masses in results."""),action="store_true")
affichage.add_argument('--show-texts',dest='textes',help=_("""Show mass texts of the day selected.
Opens the introibo.fr page in a webbrowser.
Works only with -r/--reverse (three results max) or an only date."""),action='store_true')
affichage.add_argument(*arguments['martyrology']['short'],*arguments['martyrology']['long'],dest="martyrology",help=_("""Print the Roman Martyrology for period requested.
With -r/--reverse, search keywords inside Roman Martyrology."""),action='store_true')
affichage.add_argument(*arguments['station']['short'],*arguments['station']['long'],dest='station',help=_("""if there is a statio, print it"""),action='store_true')
affichage.add_argument('-l','--language', dest='langue', action=CoursDeLangue, help=_("""choose your language /!\ ONLY FRENCH AVAILABLE /!\
Available languages :
- French
- English
- Latin"""), default=default_language())
selection = parser.add_argument_group(_('Selection options'),description=_("Options to focus researches"))
selection.add_argument('-p','--proper','--rite', dest='propre', help=_('select which proper or rite you want to use'),action='store',default=default_proper(),choices=arguments['propre']['options'])
selection.add_argument('-o','--ordo', dest='ordo', help=_('select which ordo you want to use'), type=int, action='store',default=1962,choices=[1962])
selection.add_argument('-m','--more',dest='plus', help=_('used with -r/--reverse, print a more complete list of feasts matching with arguments entered'), action='store_true')
history = parser.add_argument_group(_('History options'),description=_('All about history'))
history.add_argument(*arguments['historique']['short'],*arguments['historique']['long'],dest='historique', help=_("Print history and exit. With -r/--reverse, print reverse history"),action='store_true')
history.add_argument(*arguments['entree_historique']['short'],*arguments['entree_historique']['long'],dest='entree_historique',help=_("""Select which entry of the history you want to use again.
Can be used with --next and --previous."""),default=0,const=1,action='store',type=int,nargs='?')
NnPenemies = history.add_mutually_exclusive_group()
NnPenemies.add_argument(*arguments['suivant']['short'],*arguments['suivant']['long'],dest='suivant',help=_("""Research for the next item. Example :
the last item researched was a the 1st of January ; --next will research for the 2nd of January.
It works with a week, a month, a year, and an arbitrary period defined with --from/--to.
You can also specify a number : to take the same example, after the 1st of January,
--next 2 will research for the 3rd of January.
If you specify an entry of the history with --select-entry,
the research will start from this entry, and not from the last one.
If used with DATE or --from/--to, these options will have no effect.
Doesn't work with -r/--reverse."""),action='store',default=0,const=1,type=int,nargs='?')
NnPenemies.add_argument(*arguments['precedent']['short'],*arguments['precedent']['long'],dest='precedent',help=_("""Research for the previous item.
Works the same way as --next, on the other side. See above.
Doesn't work with -r/--reverse"""),action='store',default=0,const=1,type=int,nargs='?') # mettre toutes ces options dans un groupe exclusif avec -r/DATE, etc.
export = parser.add_argument_group(_("Export options"),description=_("""Export results to file in a specific format.
Following options can be used with export:
any date, --pal, --ordo, --proper"""))
export.add_argument(*arguments['export']['long'],*arguments['export']['short'],dest='export',choices=['csv','ics'],action='store',help=_("""Select which file format you want to use. Available: ics, csv"""))
output_required = '--export' in sys.argv or '-e' in sys.argv # WARNING if changes in args # https://stackoverflow.com/questions/19414060/argparse-required-argument-y-if-x-is-present
export.add_argument(*arguments['output']['long'],*arguments['output']['short'],dest='output',action='store',required=output_required,type=argparse.FileType('w'),help=_("Path to the destination. If you want a suffix, please add it."))
system = parser.add_argument_group(_('System options'), description=_("Other options"))
system.add_argument("-b","--browser",dest="navigateur",help=_("""Open Theochrone in your default webbrowser. You can pass args but following options are disabled :
- --from/--to options
- a complete week
- a complete year
- years before 1960, after 2100
- every print option.
If one of the previous args was entered, it will not result an error,
but the program will use default value."""),action="store_true")
system.add_argument(*arguments['gui']['short'],*arguments['gui']['long'],dest='gui',help=_("""Open Theochrone in a Graphical User Interface (GUI).
This is the standard behaviour if Theochrone is opened in a file manager.
You can pass all research types args."""),action='store_true')
system.add_argument('--version', action='version',version='%(prog)s 0.6.1')
system.add_argument('--poems',help=_('open O Crux ave Spes Unica'), action='store_true')
system.add_argument(*arguments['settings']['long'],dest='settings',nargs='?',const='nothing',help=_("""Modify some settings of the program and exits. Following options are available :
- ON/OFF : set settings and history ON (default) or OFF.
OFF also deletes all your personal settings and history, if previously set.
- An integer : set the maximum lines of your history.
- --language : save the default language you want to use.
- --proper : save the default proper you want to use.
Settings and history can be found in '.theochrone', which is in your personal directory."""))
return parser.parse_args()