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
|
#! /usr/bin/env python3
"""Main thread."""
import signal
import sys
import threading
import log
from cmd_ui import CmdUI
from tcp_server import TCPServer
from users_text_manager import UsersTextManager
class _ArgsError(Exception):
"""Exception raised by _Args."""
pass
class _Args(object):
"""Arguments of this program.
Attributes:
port: Port number.
user_list_filename: Default user list.
save_filename: Name of the file to save the text.
"""
DOCUMENT = '[usage] <port_number> <user_list_filename> <save_filename>\n'
def __init__(self):
if len(sys.argv) != 4:
raise _ArgsError('Wrong length of arguments.')
try:
self.port = int(sys.argv[1])
except ValueError as e:
raise _ArgsError(e)
self.user_list_filename = sys.argv[2]
self.saved_filename = sys.argv[3]
class _ShrVimServerError(Exception):
"""Error raised by ShrVimServer."""
pass
class ShrVimServer(threading.Thread):
"""Main class.
Attributes:
_users_text_manager: Instance of UsersTextManager.
_tcp_server: Instance of TCPServer.
_cmd_ui: Instance of CmdUI.
"""
def __init__(self):
"""Constructor."""
super(ShrVimServer, self).__init__()
try:
self._args = _Args()
except _ArgsError as e:
raise _ShrVimServerError(str(e) + '\n' + _Args.DOCUMENT)
self._users_text_manager = UsersTextManager(self._args.saved_filename)
self._tcp_server = TCPServer(self._args.port, self._users_text_manager)
self._cmd_ui = CmdUI(['load %s' % self._args.user_list_filename],
self._users_text_manager, self._tcp_server, self)
log.info.interface = self._cmd_ui
log.error.interface = self._cmd_ui
def run(self):
"""Starts the program."""
self._tcp_server.start()
self._cmd_ui.start()
self._cmd_ui.join()
self._tcp_server.join()
def stop(self):
"""Exits the program."""
self._cmd_ui.stop()
self._tcp_server.stop()
class _SignalHandler(object):
"""Single handler.
It will handle below the signals:
SIGTERM, SIGINT - Exit the program.
Attributes:
_shrvim_server: Instance of ShrVimServer.
"""
def __init__(self, shrvim_server):
"""Constructor.
Args:
shrvim_server: Instance of ShrVimServer.
"""
self._shrvim_server = shrvim_server
signal.signal(signal.SIGTERM, self._handler)
signal.signal(signal.SIGINT, self._handler)
def _handler(self, number, unused_frame):
"""Signal handler function.
Args:
number: The signal number to be handle.
"""
if number in (signal.SIGTERM, signal.SIGINT):
self._shrvim_server.stop()
def main():
"""Program entry point."""
try:
shrvim_server = ShrVimServer()
_SignalHandler(shrvim_server)
shrvim_server.start()
shrvim_server.join()
except _ShrVimServerError as e:
print(e)
sys.exit(1)
if __name__ == '__main__':
main()
|