borgend.py

Wed, 07 Feb 2018 20:39:01 +0000

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 07 Feb 2018 20:39:01 +0000
changeset 113
6993964140bd
parent 92
a1d3721ef5fa
permissions
-rwxr-xr-x

Time snapshot fixes.
Python's default arguments are purely idiotic (aka. pythonic): generated
only once. This makes sense in a purely functional language, which Python
lightyears away from, but severely limits their usefulness in an imperative
language. Decorators also seem clumsy for this, as one would have to tell
the number of positional arguments for things to work nice, being able to
pass the snapshot both positionally and as keyword. No luck.
So have to do things the old-fashioned hard way.

0
f5aecaad0bcf Some rough drafting
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 #!/usr/local/bin/python3
89
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
2 #
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
3 # Borgend by Tuomo Valkonen, 2018
51cc2e25af38 Added author information headers and content information to source files
Tuomo Valkonen <tuomov@iki.fi>
parents: 87
diff changeset
4 #
0
f5aecaad0bcf Some rough drafting
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
6 # Common modules
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
7 import os
45
aa2a95dc6093 Further improvements to state reporting; indicate busyness if repository lock cannot be acquired
Tuomo Valkonen <tuomov@iki.fi>
parents: 43
diff changeset
8 import sys
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
9 import argparse
43
8f3ac19f11b6 Use platform package to detect whether to:
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
10 import platform
80
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
11 import logging
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
12 # Own modules needed at this stage
80
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
13 import borgend.branding as branding
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
14 import borgend.locations as locations
49
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
15
db33dfa64ad6 Improved scheduler
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
16 #
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
17 # Argument processing
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
18 #
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
19
92
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
20 epilog_format="""
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
21 Configuration file location:
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
22
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
23 %s
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
24
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
25 Log directory:
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
26
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
27 %s/
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
28 """
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
29
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
30 parser=argparse.ArgumentParser(
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
31 description=branding.appname_stylised + ": BorgBackup scheduler, queue, and tray icon.",
92
a1d3721ef5fa Show log directory in --help
Tuomo Valkonen <tuomov@iki.fi>
parents: 89
diff changeset
32 epilog=epilog_format % (locations.cfgfile, locations.logs_dir),
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
33 formatter_class=argparse.RawDescriptionHelpFormatter)
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
34
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
35 parser.add_argument(
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
36 '--no-tray',
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
37 dest='notray',
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
38 action='store_true',
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
39 help='Do not show the tray icon')
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
40
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
41 parser.add_argument(
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
42 '--debug',
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
43 dest='debug',
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
44 action='store_true',
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
45 help='Set logging level to debug')
73
4f0e9cf8f230 Added --debug switch to enable debug logging level
Tuomo Valkonen <tuomov@iki.fi>
parents: 52
diff changeset
46
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
47 args=parser.parse_args()
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
48
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
49 #
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
50 # Done parsing args, import our own modules, and launch everything
41
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
51 #
e2641cb9ca6d --no-tray command line option for running on non-MacOS systems
Tuomo Valkonen <tuomov@iki.fi>
parents: 40
diff changeset
52
80
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
53 import borgend.config as config
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
54 import borgend.dreamtime as dreamtime
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
55 import borgend.loggers as loggers
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
56 from borgend.scheduler import Scheduler
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
57 from borgend.repository import Repository
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
58 from borgend.backup import Backup
31
b4b4bb7a2ec5 More logging detail
Tuomo Valkonen <tuomov@iki.fi>
parents: 10
diff changeset
59
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
60 logger=loggers.mainlogger
34
9fce700d42de Log window and other logging improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 33
diff changeset
61
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
62 if args.debug:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
63 logger.setLevel(logging.DEBUG)
34
9fce700d42de Log window and other logging improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 33
diff changeset
64
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
65 tray = None
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
66 repos=[]
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
67 backups=[]
1
4cdc9c1f6b28 basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 0
diff changeset
68
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
69 try:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
70 dreamtime.start_monitoring()
76
4b08fca3ce34 Dreamtime scheduling: discount system sleep periods
Tuomo Valkonen <tuomov@iki.fi>
parents: 74
diff changeset
71
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
72 scheduler = Scheduler()
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
73 scheduler.start()
40
cfbeeec8cb82 Improved exception reporting etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
74
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
75 repoconfigs=config.settings['repositories']
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 73
diff changeset
76
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 85
diff changeset
77 logger.info('Initialising repositories')
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
78 for i in range(len(repoconfigs)):
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
79 r=Repository(i, repoconfigs[i])
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
80 repos.append(r)
74
4f56142e7497 Separated repository configuration form backup configuration;
Tuomo Valkonen <tuomov@iki.fi>
parents: 73
diff changeset
81
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
82 backupconfigs=config.settings['backups']
1
4cdc9c1f6b28 basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 0
diff changeset
83
87
a214d475aa28 Better recovery from errors; fixes to potential race conditions in scheduler and repository queue
Tuomo Valkonen <tuomov@iki.fi>
parents: 85
diff changeset
84 logger.info('Initialising backups')
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
85 for i in range(len(backupconfigs)):
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
86 b=Backup(i, backupconfigs[i], scheduler)
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
87 backups.append(b)
3
4cad934aa9ce Can launch borg now; output not yet processed
Tuomo Valkonen <tuomov@iki.fi>
parents: 2
diff changeset
88
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
89 if args.notray or platform.system()!='Darwin':
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
90 # Wait for scheduler to finish
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
91 run=scheduler.join
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
92 else:
82
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
93 # This is needed for Ctrl+C to work.
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
94 # TODO: proper exit handler, which seems to require
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
95 # ditching/forking/extending rumps to extend the NSApp class
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
96 from PyObjCTools.AppHelper import installMachInterrupt
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
97 installMachInterrupt()
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
98 # Start UI, and let it handle exit control
80
a409242121d5 Better package-like organisation
Tuomo Valkonen <tuomov@iki.fi>
parents: 79
diff changeset
99 from borgend.ui import BorgendTray
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
100 tray=BorgendTray(backups);
85
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
101 run=tray.run
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
102
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
103 for r in repos:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
104 r.start()
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
105
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
106 for b in backups:
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
107 b.start()
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
108
56a000d15965 On startup, for better scheduling, obtain previous backup time with 'borg list'
Tuomo Valkonen <tuomov@iki.fi>
parents: 82
diff changeset
109 run()
9
aa121291eb0e Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
110
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
111 except Exception as err:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
112 # TODO: Should write errors here to stderr;
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
113 # perhaps add an extra stderr logger for error level messages
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
114 logger.exception("Exception fell through: exiting")
9
aa121291eb0e Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
115
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
116 finally:
82
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
117 logger.debug("Exiting")
4e7678dd7b42 Enable Ctrl+C in MacOS UI mode.
Tuomo Valkonen <tuomov@iki.fi>
parents: 80
diff changeset
118
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
119 for b in backups:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
120 b.terminate()
9
aa121291eb0e Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
121
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
122 for r in repos:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
123 r.terminate()
9
aa121291eb0e Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
124
79
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
125 if tray:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
126 tray.quit()
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
127 else:
b075b3db3044 Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.
Tuomo Valkonen <tuomov@iki.fi>
parents: 78
diff changeset
128 logging.shutdown()
9
aa121291eb0e Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents: 8
diff changeset
129

mercurial