1 """Passes command-line args from duplicate processes to the primary one.
2
3 Copyright 2007-2011 Research Foundation State University of New York
4 This file is part of QUB Express.
5
6 QUB Express is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 QUB Express is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License,
17 named LICENSE.txt, in the QUB Express program directory. If not, see
18 <http://www.gnu.org/licenses/>.
19
20 """
21
22 import gobject
23 import sys
24 from qubx.sock import *
25 from qubx.util_types import *
26
27
29 """
30 SingleInstance(port)
31
32 Construct this when your app starts, to initiate communication with any duplicates.
33 If it is the only instance, this will start a background server, and pass any args
34 to mySingleInstance.OnArg(arg).
35 If there is an existing instance, this will pass sys.argv[1:] to it.
36
37 It is your responsibility to check if mySingleInstance.duplicate, and quit.
38
39 example:
40
41 >>> import sys, qubx.singleInstance
42 >>> mySingleInstance = qubx.singleInstance.SingleInstance(MY_APPS_HIGH_PORT_NUMBER)
43 >>> if mySingleInstance.duplicate:
44 ... sys.exit(0)
45 >>> print sys.argv[1:]
46 """
48 self.port = port
49 self.backlog = []
50 self._OnArg = None
51 self.duplicate = False
52 try:
53 if self.send_args(*sys.argv[1:]):
54 self.duplicate = True
55 except:
56 self.start_serving()
57 for arg in sys.argv[1:]:
58 self.do_OnArg(arg)
60 self._OnArg = OnArg
61 for arg in self.backlog:
62 gobject.idle_add(self.OnArg, arg)
63 OnArg = property(lambda s: s._OnArg, set_OnArg)
65 if self.OnArg:
66 gobject.idle_add(self.OnArg, arg)
67 else:
68 self.backlog.append(arg)
70 self.thread = Thread(target=self.serve)
71 self.thread.setDaemon(True)
72 self.thread.start()
74 try:
75 serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
76 serv.bind(('localhost', self.port))
77 serv.listen(5)
78 while True:
79 client, addr = serv.accept()
80 worker = Thread(target=lambda: self.read(client))
81 worker.setDaemon(True)
82 worker.start()
83 except:
84 pass
85 - def read(self, client):
86 try:
87 chars = []
88 while True:
89 c = client.recv(1)
90 if not c:
91 break
92 if c == '\n':
93 print ''.join(chars)
94 self.do_OnArg(''.join(chars))
95 chars = []
96 else:
97 chars.append(c)
98 except:
99 pass
101 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
102 sock.connect(('localhost', self.port))
103 sock.settimeout(1.0)
104 for arg in args:
105 sock.send("%s\n" % arg)
106 return len(args)
107