-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcal.py
130 lines (103 loc) · 3.41 KB
/
cal.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
#!/usr/bin/env python
#
# cal.py
# ------
# Copyright (c) 2017 Chandranath Gunjal. Available under the MIT License
#
# A friendlier cal - converts month names.
#
# o With no arguments, print calendar for current month & year
# o With two arguments, assumes month & year are given
# o With one argument
# - the argument is assumed to be a month (if valid) for this year.
# - a "month+/-" format uses the next/prev year.
# - a lone "+/-" prints the next/prev month's calendar.
# - a leading zero forces the argument to be a "year".
#
import calendar
import datetime
import getopt
import sys
def month2num(given):
"""Convert a given month name to numeric"""
months = ['january', 'february', 'march', 'april',
'may', 'june', 'july', 'august',
'september', 'october', 'november', 'december'
]
given = given.lower()
for i, mth in enumerate(months, 1):
if mth.startswith(given):
return i
return 0
def build_cal_args(args):
"""Determine the year/month. Return list [year] or [year, month]"""
t = datetime.date.today()
m, y = t.month, t.year
x = None
if len(args) == 0:
# no args - print default calendar
x = [y, m]
elif len(args) == 1:
# cal + ==> next month
if args[0] == '+':
x = [y + 1, 1] if (m == 12) else [y, m + 1]
# cal - ==> prev month
elif args[0] == '-':
x = [y - 1, 12] if (m == 1) else [y, m - 1]
# cal jun+ or cal 12+ ==> given month for next year
elif args[0].endswith('+'):
m = month2num(args[0][:-1])
x = [y + 1, int(args[0][:-1])] if (m == 0) else [y + 1, m]
# cal jun- or cal 12- ==> given month for prev year
elif args[0].endswith('-'):
m = month2num(args[0][:-1])
x = [y - 1, int(args[0][:-1])] if (m == 0) else [y - 1, m]
# cal 0nn ==> assume as year
elif args[0].startswith('0'):
x = [int(args[0])]
# cal numeric ==> assume as month if in 1..12
elif args[0].isnumeric():
m = int(args[0])
x = [y, m] if (1 <= m <= 12) else [m]
# cal any ==> convert month if possible or let cal handle it
else:
m = month2num(args[0])
x = [int(args[0])] if (m == 0) else [y, m]
elif len(args) == 2:
# cal month year
m = month2num(args[0])
x = [int(args[1]), int(args[0])] if (m == 0) \
else [int(args[1]), m]
return x
def print_cal(ym):
"""Print calendar for [year, month]."""
tc = calendar.TextCalendar(firstweekday=6)
tc.pryear(ym[0]) if len(ym) == 1 else tc.prmonth(ym[0], ym[1])
# Main
# ====
if __name__ == '__main__':
synopsis = """usage: cal.py -h [mth][+|-] | mth year | [0]year
Month names (shortened or otherwise) can be used.
"""
def usage():
"""Print usage and exit"""
print(synopsis)
sys.exit(2)
def parse_args(argv):
"""Parse command line arguments"""
try:
opts, args = getopt.getopt(argv, 'h', ['help'])
except getopt.GetoptError:
usage()
for opt, arg in opts:
if opt in ['-h', '--help']:
usage()
if len(args) > 2:
usage()
return args
# main
alist = parse_args(sys.argv[1:])
try:
print_cal(build_cal_args(alist))
except:
usage()