skilleter-thingy 0.0.38__py3-none-any.whl → 0.0.39__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of skilleter-thingy might be problematic. Click here for more details.

Files changed (69) hide show
  1. {skilleter_thingy-0.0.38.dist-info → skilleter_thingy-0.0.39.dist-info}/METADATA +1 -1
  2. skilleter_thingy-0.0.39.dist-info/RECORD +6 -0
  3. skilleter_thingy-0.0.39.dist-info/entry_points.txt +43 -0
  4. skilleter_thingy-0.0.39.dist-info/top_level.txt +1 -0
  5. __init__.py +0 -6
  6. addpath.py +0 -107
  7. borger.py +0 -269
  8. console_colours.py +0 -63
  9. diskspacecheck.py +0 -67
  10. docker_purge.py +0 -113
  11. ffind.py +0 -536
  12. ggit.py +0 -90
  13. ggrep.py +0 -154
  14. git_br.py +0 -180
  15. git_ca.py +0 -142
  16. git_cleanup.py +0 -287
  17. git_co.py +0 -220
  18. git_common.py +0 -61
  19. git_hold.py +0 -154
  20. git_mr.py +0 -92
  21. git_parent.py +0 -77
  22. git_review.py +0 -1428
  23. git_update.py +0 -385
  24. git_wt.py +0 -96
  25. gitcmp_helper.py +0 -322
  26. gitprompt.py +0 -274
  27. gl.py +0 -174
  28. gphotosync.py +0 -610
  29. linecount.py +0 -155
  30. moviemover.py +0 -133
  31. photodupe.py +0 -136
  32. phototidier.py +0 -248
  33. py_audit.py +0 -131
  34. readable.py +0 -270
  35. remdir.py +0 -126
  36. rmdupe.py +0 -550
  37. rpylint.py +0 -91
  38. skilleter_thingy-0.0.38.dist-info/RECORD +0 -66
  39. skilleter_thingy-0.0.38.dist-info/entry_points.txt +0 -43
  40. skilleter_thingy-0.0.38.dist-info/top_level.txt +0 -43
  41. splitpics.py +0 -99
  42. strreplace.py +0 -82
  43. sysmon.py +0 -435
  44. tfm.py +0 -920
  45. tfparse.py +0 -101
  46. thingy/__init__.py +0 -0
  47. thingy/colour.py +0 -213
  48. thingy/dc_curses.py +0 -278
  49. thingy/dc_defaults.py +0 -221
  50. thingy/dc_util.py +0 -50
  51. thingy/dircolors.py +0 -308
  52. thingy/docker.py +0 -95
  53. thingy/files.py +0 -142
  54. thingy/git.py +0 -1371
  55. thingy/git2.py +0 -1307
  56. thingy/gitlab.py +0 -193
  57. thingy/logger.py +0 -112
  58. thingy/path.py +0 -156
  59. thingy/popup.py +0 -87
  60. thingy/process.py +0 -112
  61. thingy/run.py +0 -334
  62. thingy/tfm_pane.py +0 -595
  63. thingy/tidy.py +0 -160
  64. trimpath.py +0 -84
  65. window_rename.py +0 -92
  66. xchmod.py +0 -125
  67. yamlcheck.py +0 -89
  68. {skilleter_thingy-0.0.38.dist-info → skilleter_thingy-0.0.39.dist-info}/LICENSE +0 -0
  69. {skilleter_thingy-0.0.38.dist-info → skilleter_thingy-0.0.39.dist-info}/WHEEL +0 -0
@@ -1,43 +0,0 @@
1
- [console_scripts]
2
- addpath = src:addpath.addpath
3
- borger = src:borger.borger
4
- console_colours = src:console_colours.console_colours
5
- diskspacecheck = src:diskspacecheck.diskspacecheck
6
- docker-purge = src:docker_purge.docker_purge
7
- ffind = src:ffind.ffind
8
- ggit = src:ggit.ggit
9
- ggrep = src:ggrep.ggrep
10
- git-br = src:git_br.git_br
11
- git-ca = src:git_ca.git_ca
12
- git-cleanup = src:git_cleanup.git_cleanup
13
- git-co = src:git_co.git_co
14
- git-common = src:git_common.git_common
15
- git-hold = src:git_hold.git_hold
16
- git-mr = src:git_mr.git_mr
17
- git-parent = src:git_parent.git_parent
18
- git-review = src:git_review.git_review
19
- git-update = src:git_update.git_update
20
- git-wt = src:git_wt.git_wt
21
- gitcmp-helper = src:gitcmp_helper.gitcmp_helper
22
- gitprompt = src:gitprompt.gitprompt
23
- gl = src:gl.gl
24
- gphotosync = src:gphotosync.gphotosync
25
- linecount = src:linecount.linecount
26
- moviemover = src:moviemover.moviemover
27
- photodupe = src:photodupe.photodupe
28
- phototidier = src:phototidier.phototidier
29
- py-audit = src:py_audit.py_audit
30
- readable = src:readable.readable
31
- remdir = src:remdir.remdir
32
- rmdupe = src:rmdupe.rmdupe
33
- rpylint = src:rpylint.rpylint
34
- s3-sync = src:s3_sync.s3_sync
35
- splitpics = src:splitpics.splitpics
36
- strreplace = src:strreplace.strreplace
37
- sysmon = src:sysmon.sysmon
38
- tfm = src:tfm.tfm
39
- tfparse = src:tfparse.tfparse
40
- trimpath = src:trimpath.trimpath
41
- window-rename = src:window_rename.window_rename
42
- xchmod = src:xchmod.xchmod
43
- yamlcheck = src:yamlcheck.yamlcheck
@@ -1,43 +0,0 @@
1
- __init__
2
- addpath
3
- borger
4
- console_colours
5
- diskspacecheck
6
- docker_purge
7
- ffind
8
- ggit
9
- ggrep
10
- git_br
11
- git_ca
12
- git_cleanup
13
- git_co
14
- git_common
15
- git_hold
16
- git_mr
17
- git_parent
18
- git_review
19
- git_update
20
- git_wt
21
- gitcmp_helper
22
- gitprompt
23
- gl
24
- gphotosync
25
- linecount
26
- moviemover
27
- photodupe
28
- phototidier
29
- py_audit
30
- readable
31
- remdir
32
- rmdupe
33
- rpylint
34
- splitpics
35
- strreplace
36
- sysmon
37
- tfm
38
- tfparse
39
- thingy
40
- trimpath
41
- window_rename
42
- xchmod
43
- yamlcheck
splitpics.py DELETED
@@ -1,99 +0,0 @@
1
- #! /usr/bin/env python3
2
-
3
- ################################################################################
4
- """ Copy a directory full of pictures to a destination, creating subdiretories
5
- with N pictures in each in the destination directory
6
- """
7
- ################################################################################
8
-
9
- import os
10
- import glob
11
- import argparse
12
-
13
- from PIL import Image
14
-
15
- ################################################################################
16
- # Constants
17
-
18
- DEFAULT_SOURCE_DIR = '/storage/Starred Photos/'
19
- DEFAULT_DEST_DIR = '/media/jms/48A7-BE16'
20
- DEFAULT_MAX_SIZE = 3840
21
-
22
- ################################################################################
23
-
24
- def parse_command_line():
25
- """ Parse the command line """
26
-
27
- parser = argparse.ArgumentParser(description='Copy a collection of pictures to a set of numbered directories')
28
-
29
- parser.add_argument('--pics', type=int, help='Number of pictures per directory (default is not to use numbered subdirectories)', default=None)
30
- parser.add_argument('--max-size', type=int, help='Maximum size for each image in pixels (default=%d, images will be resized if larger)' %
31
- DEFAULT_MAX_SIZE, default=DEFAULT_MAX_SIZE)
32
- parser.add_argument('source', nargs=1, help='Source directory', default=DEFAULT_SOURCE_DIR)
33
- parser.add_argument('destination', nargs=1, help='Destination directory', default=DEFAULT_DEST_DIR)
34
-
35
- args = parser.parse_args()
36
-
37
- return args
38
-
39
- ################################################################################
40
-
41
- def copy_images(args):
42
- """ Copy the images """
43
-
44
- dir_num = -1
45
-
46
- pictures = glob.glob(os.path.join(args.source[0], '*'))
47
- dest_dir = args.destination[0]
48
-
49
- if not os.path.isdir(dest_dir):
50
- os.makedirs(dest_dir)
51
-
52
- for index, picture in enumerate(pictures):
53
- picture_name = os.path.basename(picture)
54
-
55
- # Create the new directory in the destination every N pcitures
56
-
57
- if args.pics and index % args.pics == 0:
58
- dir_num += 1
59
- dest_dir = os.path.join(args.destination[0], '%05d' % dir_num)
60
- if not os.path.isdir(dest_dir):
61
- os.makedirs(dest_dir)
62
-
63
- print('%d/%d: Copying %s to %s' % (index + 1, len(pictures), picture, dest_dir))
64
-
65
- # Resize the image if neccessary
66
-
67
- image = Image.open(picture)
68
-
69
- if args.max_size and (image.width > args.max_size or image.height > args.max_size):
70
- if image.width > image.height:
71
- scale = image.width / args.max_size
72
- else:
73
- scale = image.height / args.max_size
74
-
75
- new_size = (round(image.width / scale), round(image.height / scale))
76
-
77
- print(' Resizing from %d x %d to %d x %d' % (image.width, image.height, new_size[0], new_size[1]))
78
-
79
- image.resize(new_size)
80
-
81
- # Write the image
82
-
83
- destination = os.path.join(dest_dir, picture_name)
84
-
85
- image.save(destination)
86
-
87
- ################################################################################
88
-
89
- def splitpics():
90
- """Entry point"""
91
-
92
- args = parse_command_line()
93
-
94
- copy_images(args)
95
-
96
- ################################################################################
97
-
98
- if __name__ == '__main__':
99
- splitpics()
strreplace.py DELETED
@@ -1,82 +0,0 @@
1
- #! /usr/bin/env python3
2
-
3
- ################################################################################
4
- """ Textual search and replace
5
-
6
- For those occasions when you want to search and replace strings with
7
- regexppy characters that upset sed.
8
-
9
- Copyright (C) 2018 John Skilleter """
10
- ################################################################################
11
-
12
- import os
13
- import sys
14
- import argparse
15
- import tempfile
16
-
17
- ################################################################################
18
-
19
- def main():
20
- """ Main function """
21
-
22
- parser = argparse.ArgumentParser(description='Textual search and replace')
23
- parser.add_argument('-i', '--inplace', action='store_true', help='Do an in-place search and replace on the input file')
24
- parser.add_argument('search', nargs=1, action='store', help='Search text')
25
- parser.add_argument('replace', nargs=1, action='store', help='Replacment text')
26
- parser.add_argument('infile', nargs='?', action='store', help='Input file')
27
- parser.add_argument('outfile', nargs='?', action='store', help='Output file')
28
-
29
- args = parser.parse_args()
30
-
31
- # Sanity check
32
-
33
- if args.inplace and not args.infile or args.outfile:
34
- print('For in-place operations you must specify and input file and no output file')
35
-
36
- # Open the input file
37
-
38
- if args.infile:
39
- infile = open(args.infile, 'r')
40
- else:
41
- infile = sys.stdin
42
-
43
- # Open the output file, using a temporary file in the same directory as the input file
44
- # if we are doing in-place operations
45
-
46
- if args.outfile:
47
- outfile = open(args.outfile, 'w')
48
- elif args.inplace:
49
- outfile = tempfile.NamedTemporaryFile(mode='w', delete=False, dir=os.path.dirname(args.infile))
50
- else:
51
- outfile = sys.stdout
52
-
53
- # Perform the searchy-replacey-ness
54
-
55
- for data in infile:
56
- outfile.write(data.replace(args.search[0], args.replace[0]))
57
-
58
- # If we doing in-place then juggle the temporary and input files
59
-
60
- if args.inplace:
61
- mode = os.stat(args.infile).st_mode
62
- outfile.close()
63
- infile.close()
64
- os.rename(outfile.name, args.infile)
65
- os.chmod(args.infile, mode)
66
-
67
- ################################################################################
68
-
69
- def strreplace():
70
- """Entry point"""
71
-
72
- try:
73
- main()
74
- except KeyboardInterrupt:
75
- sys.exit(1)
76
- except BrokenPipeError:
77
- sys.exit(2)
78
-
79
- ################################################################################
80
-
81
- if __name__ == '__main__':
82
- strreplace()
sysmon.py DELETED
@@ -1,435 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- ################################################################################
4
- """Very simple system monitoring dashboard"""
5
- ################################################################################
6
-
7
- import sys
8
- import datetime
9
- import time
10
- import curses
11
-
12
- import psutil
13
-
14
- ################################################################################
15
-
16
- NUM_BOXES_V = 5
17
- NUM_BOXES_H = 2
18
-
19
- UPDATE_PERIOD = 1
20
-
21
- ################################################################################
22
-
23
- def show_system_load(scr, first, w, h, x, y):
24
- """Load averaged"""
25
-
26
- load = psutil.getloadavg()
27
-
28
- x += 2
29
-
30
- if first:
31
- scr.addstr(y+1, x, '1 minute:')
32
- scr.addstr(y+2, x, '5 minute:')
33
- scr.addstr(y+3, x, '15 minute:')
34
- else:
35
- scr.addstr(y+1, x+10, f'{load[0]:6.2f}')
36
- scr.addstr(y+2, x+10, f'{load[1]:6.2f}')
37
- scr.addstr(y+3, x+10, f'{load[2]:6.2f}')
38
-
39
- ################################################################################
40
-
41
- def show_cpu_times(scr, first, w, h, x, y):
42
- """CPU times"""
43
-
44
- info = psutil.cpu_times()
45
-
46
- x += 2
47
-
48
- if first:
49
- scr.addstr(y+1, x, 'Idle:')
50
- scr.addstr(y+2, x, 'System:')
51
- scr.addstr(y+3, x, 'User:')
52
- scr.addstr(y+4, x, 'Nice:')
53
-
54
- x += w//3
55
-
56
- scr.addstr(y+1, x, 'I/O Wait:')
57
- scr.addstr(y+2, x, 'IRQ:')
58
- scr.addstr(y+3, x, 'Soft IRQ:')
59
-
60
- x+= w//3
61
-
62
- scr.addstr(y+1, x, 'Guest:')
63
- scr.addstr(y+2, x, 'Guest Nice:')
64
- else:
65
- total = (info.user + info.system + info.idle + info.nice + info.iowait + info.irq + info.softirq + info.guest + info.guest_nice)/100
66
-
67
- user = info.user / total
68
- system = info.system / total
69
- idle = info.idle / total
70
- nice = info.nice / total
71
- iowait = info.iowait / total
72
- irq = info.irq / total
73
- softirq = info.softirq / total
74
- guest = info.guest / total
75
- guest_nice = info.guest_nice / total
76
-
77
- scr.addstr(y+1, x+9, f'{idle:6.2f}')
78
- scr.addstr(y+2, x+9, f'{system:6.2f}')
79
- scr.addstr(y+3, x+9, f'{user:6.2f}')
80
- scr.addstr(y+4, x+9, f'{nice:6.2f}')
81
-
82
- x += w//3
83
-
84
- scr.addstr(y+1, x+10, f'{iowait:6.2f}')
85
- scr.addstr(y+2, x+10, f'{irq:6.2f}')
86
- scr.addstr(y+3, x+10, f'{softirq:6.2f}')
87
-
88
- x += w//3
89
-
90
- scr.addstr(y+1, x+12, f'{guest:6.2f}')
91
- scr.addstr(y+2, x+12, f'{guest_nice:6.2f}')
92
-
93
- ################################################################################
94
-
95
- def show_disk_access(scr, first, w, h, x, y):
96
- """Disk I/O statistics"""
97
-
98
- info = psutil.disk_io_counters()
99
-
100
- x += 2
101
-
102
- if first:
103
- scr.addstr(y+1, x, 'Read count:')
104
- scr.addstr(y+2, x, 'Write count:')
105
-
106
- scr.addstr(y+4, x, 'Read bytes:')
107
- scr.addstr(y+5, x, 'Write bytes:')
108
-
109
- x += w//3
110
-
111
- scr.addstr(y+1, x, 'Read time:')
112
- scr.addstr(y+2, x, 'Write time:')
113
-
114
- scr.addstr(y+4, x, 'I/O time:')
115
-
116
- x += w//3
117
-
118
- scr.addstr(y+1, x, 'Read merged:')
119
- scr.addstr(y+2, x, 'Write merged:')
120
- else:
121
- scr.addstr(y+1, x+14, f'{info.read_count:12}')
122
- scr.addstr(y+2, x+14, f'{info.write_count:12}')
123
-
124
- scr.addstr(y+4, x+14, f'{info.read_bytes:12}')
125
- scr.addstr(y+5, x+14, f'{info.write_bytes:12}')
126
-
127
- x += w//3
128
-
129
- scr.addstr(y+1, x+14, f'{info.read_time:12}')
130
- scr.addstr(y+2, x+14, f'{info.write_time:12}')
131
-
132
- scr.addstr(y+4, x+14, f'{info.busy_time:12}')
133
-
134
- x += w//3
135
-
136
- scr.addstr(y+1, x+14, f'{info.read_merged_count:12}')
137
- scr.addstr(y+2, x+14, f'{info.write_merged_count:12}')
138
-
139
- ################################################################################
140
-
141
- def show_processes(scr, first, w, h, x, y):
142
- """TBD: Process information"""
143
-
144
- pass
145
-
146
- ################################################################################
147
-
148
- def show_memory(scr, first, w, h, x, y):
149
- """Memory usage"""
150
-
151
- x += 2
152
-
153
- if first:
154
- scr.addstr(y+1, x, 'Total:')
155
- scr.addstr(y+2, x, 'Used:')
156
- scr.addstr(y+3, x, 'Buffers:')
157
- scr.addstr(y+4, x, 'Free:')
158
-
159
- x += w//3
160
-
161
- scr.addstr(y+1, x, 'Active:')
162
- scr.addstr(y+2, x, 'Inactive:')
163
-
164
- scr.addstr(y+4, x, 'Usage:')
165
-
166
- x += w//3
167
-
168
- scr.addstr(y+1, x, 'Shared:')
169
- scr.addstr(y+2, x, 'Slab:')
170
- else:
171
- meminfo = psutil.virtual_memory()
172
- x += 11
173
-
174
- scr.addstr(y+1, x, f'{meminfo.total:12}')
175
- scr.addstr(y+2, x, f'{meminfo.used:12}')
176
- scr.addstr(y+3, x, f'{meminfo.buffers:12}')
177
- scr.addstr(y+4, x, f'{meminfo.free:12}')
178
-
179
- x += w//3
180
-
181
- scr.addstr(y+1, x, f'{meminfo.active:12}')
182
- scr.addstr(y+2, x, f'{meminfo.inactive:12}')
183
-
184
- scr.addstr(y+4, x, f'{meminfo.percent:6.1f}%')
185
-
186
- x += w//3
187
-
188
- scr.addstr(y+1, x, f'{meminfo.shared:12}')
189
- scr.addstr(y+2, x, f'{meminfo.slab:12}')
190
-
191
- ################################################################################
192
-
193
- def show_voltages(scr, first, w, h, x, y):
194
- """TBD: Voltages"""
195
-
196
- pass
197
-
198
- ################################################################################
199
-
200
- def show_cpu_load(scr, first, w, h, x, y):
201
- """CPU load and frequencies"""
202
-
203
- info = psutil.cpu_percent(percpu=True)
204
- freq = psutil.cpu_freq(percpu=True)
205
-
206
- stats = psutil.cpu_stats()
207
-
208
- xo = yo = 0
209
- for n, cpu in enumerate(info):
210
- if first:
211
- scr.addstr(y+yo+1, x+xo+5, 'CPU # : % at MHz')
212
- else:
213
- scr.addstr(y+yo+1, x+xo+10, f'{n:<2}')
214
- scr.addstr(y+yo+1, x+xo+14, f'{cpu:5.1f}%')
215
- scr.addstr(y+yo+1, x+xo+23, f'{freq[n].current:8.2f}')
216
-
217
- yo += 1
218
-
219
- if yo > h-2:
220
- xo += w//3
221
- yo = 0
222
-
223
- x += w//2
224
-
225
- if first:
226
- scr.addstr(y+1, x, 'Context switches:')
227
- scr.addstr(y+2, x, 'Interrupts:')
228
- scr.addstr(y+3, x, 'Soft interrupts:')
229
- else:
230
- x += 18
231
- scr.addstr(y+1, x, f'{stats.ctx_switches:12}')
232
- scr.addstr(y+2, x, f'{stats.interrupts:12}')
233
- scr.addstr(y+3, x, f'{stats.soft_interrupts:12}')
234
-
235
- ################################################################################
236
-
237
- def show_swappery(scr, first, w, h, x, y):
238
- """Swap info"""
239
-
240
- x += 2
241
-
242
- if first:
243
- scr.addstr(y+1, x, 'Swap total:')
244
- scr.addstr(y+2, x, 'Swap used:')
245
- scr.addstr(y+3, x, 'Swap free:')
246
-
247
- x += w//3
248
-
249
- scr.addstr(y+1, x, 'Swap used:')
250
-
251
- x += w//3
252
-
253
- scr.addstr(y+1, x, 'Swapped in:')
254
- scr.addstr(y+2, x, 'Swapped out:')
255
- else:
256
- info = psutil.swap_memory()
257
-
258
- x += 14
259
-
260
- scr.addstr(y+1, x, f'{info.total:12}')
261
- scr.addstr(y+2, x, f'{info.used:12}')
262
- scr.addstr(y+3, x, f'{info.free:12}')
263
-
264
- x += w//3
265
-
266
- scr.addstr(y+1, x, f'{info.percent:6.2f}%')
267
-
268
- x += w//3
269
-
270
- scr.addstr(y+1, x, f'{info.sin:12}')
271
- scr.addstr(y+2, x, f'{info.sout:12}')
272
-
273
- ################################################################################
274
-
275
- def show_network(scr, first, w, h, x, y):
276
- """Network statistics"""
277
-
278
- x += 2
279
-
280
- if first:
281
- scr.addstr(y+1, x, 'Bytes sent:')
282
- scr.addstr(y+2, x, 'Bytes received:')
283
-
284
- scr.addstr(y+4, x, 'Packets sent:')
285
- scr.addstr(y+5, x, 'Packets received:')
286
-
287
- x += w//2
288
-
289
- scr.addstr(y+1, x, 'Send errors:')
290
- scr.addstr(y+2, x, 'Receive errors:')
291
-
292
- scr.addstr(y+4, x, 'Outgoing dropped:')
293
- scr.addstr(y+5, x, 'Incoming dropped:')
294
- else:
295
- info = psutil.net_io_counters()
296
- x += 19
297
-
298
- scr.addstr(y+1, x, f'{info.bytes_sent:12}')
299
- scr.addstr(y+2, x, f'{info.bytes_recv:12}')
300
-
301
- scr.addstr(y+4, x, f'{info.packets_sent:12}')
302
- scr.addstr(y+5, x, f'{info.packets_recv:12}')
303
-
304
- x += w//2
305
-
306
- scr.addstr(y+1, x, f'{info.errout:12}')
307
- scr.addstr(y+2, x, f'{info.errin:12}')
308
-
309
- scr.addstr(y+4, x, f'{info.dropout:12}')
310
- scr.addstr(y+5, x, f'{info.dropin:12}')
311
-
312
- ################################################################################
313
-
314
- def show_temperatures(scr, first, w, h, x, y):
315
- """TBD: Temperatures"""
316
-
317
- pass
318
-
319
- ################################################################################
320
-
321
- # Panel title and the functions used to update them
322
-
323
- BOXES= {
324
- 'System Load': show_system_load,
325
- 'Disk Access': show_disk_access,
326
- 'Processes': show_processes,
327
- 'Memory': show_memory,
328
- 'Voltages': show_voltages,
329
-
330
- 'CPU Load': show_cpu_load,
331
- 'Swap and Paging': show_swappery,
332
- 'Temperatures': show_temperatures,
333
- 'Network': show_network,
334
- 'Total CPU Times': show_cpu_times,
335
- }
336
-
337
- ################################################################################
338
-
339
- def main(stdscr):
340
- """Main function"""
341
-
342
- # Configure curses
343
-
344
- curses.curs_set(0)
345
- curses.start_color()
346
- curses.noecho()
347
- curses.cbreak()
348
- curses.use_default_colors()
349
-
350
- curses.init_pair(1, curses.COLOR_GREEN, 15)
351
- curses.init_pair(2, curses.COLOR_BLUE, 15)
352
-
353
- # Set up the display
354
-
355
- stdscr.keypad(1)
356
- stdscr.nodelay(True)
357
- stdscr.bkgdset(' ', curses.color_pair(0))
358
-
359
- # Outer loop iterates whenever the console window changes size
360
-
361
- terminate = False
362
-
363
- while not terminate:
364
- stdscr.clear()
365
-
366
- height, width = stdscr.getmaxyx()
367
-
368
- box_h = height // NUM_BOXES_V
369
- box_w = width // NUM_BOXES_H
370
-
371
- # Draw the titles and text on the first iteration
372
- # Just draw the statistics on the subsequent ones
373
-
374
- first_time = True
375
- window_resize = False
376
-
377
- # Inner loop just updates display until
378
-
379
- while not window_resize and not terminate:
380
- now = datetime.datetime.now()
381
-
382
- stdscr.addstr(0, 1, now.strftime('%02H:%02M:%02S'), curses.COLOR_BLACK)
383
- stdscr.addstr(0, width-11, now.strftime('%02Y-%02m-%02d'), curses.COLOR_BLACK)
384
-
385
- for i, box in enumerate(BOXES):
386
- x, y = divmod(i, NUM_BOXES_V)
387
-
388
- x *= box_w
389
- y *= box_h
390
-
391
- title_x = x+(box_w - len(box))//2
392
- stdscr.addstr(y, title_x, box, curses.A_BOLD)
393
-
394
- stdscr.attron(curses.color_pair(1 if first_time else 2))
395
-
396
- BOXES[box](stdscr, first_time, box_w, box_h, x, y+1)
397
-
398
- # Update the display, clear the first-time draw-static-content flag
399
-
400
- stdscr.refresh()
401
- first_time = False
402
-
403
- # Wait for the next update
404
-
405
- elapsed = (datetime.datetime.now() - now).total_seconds()
406
-
407
- if elapsed < UPDATE_PERIOD:
408
- time.sleep(UPDATE_PERIOD - elapsed)
409
-
410
- # Check for keypress or window resize
411
-
412
- keyboard = stdscr.getch()
413
-
414
- if keyboard in (ord('Q'), ord('q')):
415
- terminate = True
416
-
417
- elif keyboard == curses.KEY_RESIZE:
418
- window_resize = True
419
-
420
- ################################################################################
421
-
422
- def sysmon():
423
- """Entry point"""
424
-
425
- try:
426
- curses.wrapper(main)
427
- except KeyboardInterrupt:
428
- sys.exit(1)
429
- except BrokenPipeError:
430
- sys.exit(2)
431
-
432
- ################################################################################
433
-
434
- if __name__ == "__main__":
435
- sysmon()