9 #tell pyGTK, if possible, that we want GTKv2
12 #Some distributions come with GTK2, but not pyGTK
19 print "You need to install pyGTK or GTKv2 ",
20 print "or set your PYTHONPATH correctly."
21 print "try: export PYTHONPATH=",
22 print "/usr/local/lib/python2.2/site-packages/"
25 #now we have both gtk and gtk.glade imported
26 #Also, we know we are running GTK v2
31 In this init we are going to display the main
34 gladefile="vvend.glade"
36 self.wTree=gtk.glade.XML (gladefile,windowname)
37 # we only have two callbacks to register, but
38 # you could register any number, or use a
39 # special class that automatically
40 # registers all callbacks. If you wanted to pass
41 # an argument, you would use a tuple like this:
42 # dic = { "on button1_clicked" :
43 # (self.button1_clicked, arg1,arg2) , ...
46 "on_button1_clicked" : self.keypad_clicked,
47 "on_button2_clicked" : self.keypad_clicked,
48 "on_button3_clicked" : self.keypad_clicked,
49 "on_button4_clicked" : self.keypad_clicked,
50 "on_button5_clicked" : self.keypad_clicked,
51 "on_button6_clicked" : self.keypad_clicked,
52 "on_button7_clicked" : self.keypad_clicked,
53 "on_button8_clicked" : self.keypad_clicked,
54 "on_button9_clicked" : self.keypad_clicked,
55 "on_button10_clicked" : self.keypad_clicked,
56 "on_button11_clicked" : self.keypad_clicked,
57 "on_vvend_destroy_event" : self.quit,
58 "on_vvend_delete_event" : self.quit }
59 self.wTree.signal_autoconnect (dic)
60 display = self.wTree.get_widget("label1")
61 display.set_text("*5N4CK0RZ*")
63 # vending machine password set here
64 self.vendpw = "AAAAAAAAAAAAAAAA"
68 #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
69 #s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
73 # s.bind((listenhost, listenport))
74 # # only one connection
77 # #GDK->gtk.gdk in GTK V 2.0
78 # id=gtk.input_add(s, gtk.gdk.INPUT_READ, self.handleNewConnection)
93 def keypad_clicked(self,widget):
94 key = widget.get_label()
99 self.do_send('2'+key+' keypress\n')
101 def handleNewConnection(self,source,condition):
102 #source is a socket in GTK v 1 and a fd in version 2
103 conn, addr = source.accept()
104 sys.stdout.write(conn.recv(1))
108 # from http://www.pythonbrasil.com.br/moin.cgi/MonitorandoSocketsComPygtk
111 def send(self, data=None, widget=None):
112 text = self.entry.get_text()
114 self.entry.set_text('')
118 def do_send(self, data):
120 # envia ''data'' para todos os clientes conectados
122 for addr, (conn, tag) in self.clients.iteritems():
127 # inicializa o servidor
130 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
131 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
132 self.sock.bind(('localhost', port))
134 print "listening on ", port
139 self.server_tag = gtk.input_add(self.sock, gtk.gdk.INPUT_READ, self.accept)
141 # mantemos uma lista dos clientes conectados
145 def accept(self, source, condition):
148 # esperando para ser aceito
150 conn, addr = source.accept()
151 self.insert("%s:%s conectado\n" % addr)
153 # insere o cliente na lista e registra o método self.write como
154 # callback para quando existirem dados esperando para serem lidos
157 self.clients[addr] = (conn, gtk.input_add(conn, gtk.gdk.INPUT_READ, self.write))
159 def write(self, source, condition):
161 # método chamado quando um cliente envia dados
163 data = source.recv(1024)
164 if data.strip() == 'bye' or not len(data):
166 # se o cliente enviar um ''bye'', desconecte-o :)
169 for addr, (conn, tag) in self.clients.iteritems():
171 gtk.input_remove(tag)
172 self.insert('%s:%s desconectado\n' % addr)
173 del self.clients[addr]
175 self.server_tag = gtk.input_add(self.sock, gtk.gdk.INPUT_READ, self.accept)
177 elif data.strip() == 'quit':
180 for (addr, port), (conn, tag) in self.clients.iteritems():
182 self.insert('%s:%s >>> %s\n'%(addr, port, data.strip()))
183 self.handle_command(data.strip())
188 def insert(self, data):
189 statusbar = self.wTree.get_widget("statusbar1")
191 statusbar.remove(1, self.messageid)
192 self.messageid=statusbar.push(1,data)
194 def quit(self, *args):
195 sys.stdout.write("quiting...\n")
196 gtk.input_remove(self.server_tag)
197 for addr, (conn, tag) in self.clients.iteritems():
198 gtk.input_remove(tag)
203 sys.stdout.write("quit!\n")
212 ABOUT ROM information
213 B[S][nn] beep [synchronously] for a duration nn (optional)
214 C[S][nn] silence [synchronously] for a duration nn (optional)
215 Dxxxxxxxxxx show a message on the display
216 ECHO {ON|OFF} turn echo on or off
217 GETROM download the ROM source code using xmodem
218 H[...] this help screen
219 *JUMPxxxx jumps to a subroutine at location xxxx
220 *PEEKxxxx returns the value of the byte at location xxxx
221 *POKExxxxyy sets the value of location xxxx to yy
223 S[...] query all internal switch states
226 *Wxxxxxxxxxxxx set a new password for authenticated vends. xxx=16 chars
227 password will be converted to uppercase
229 Very few functions are available when the machine is in standalone
230 mode (DIP SW 1 is set)
231 + denotes that this item requires authentication if DIP SW 2 is set
232 * denotes that DIP SW 3 must be set to use these
233 Commands starting with # are ignored (comments)
240 The Virtual Vending Machine Company
242 Mark Tearle, June 2004
246 def do_vend_all(self):
247 for i in range(11,99):
248 self.do_send("101 Vending "+i+"\n")
249 self.do_send("153 Home sensors failing\n")
250 self.do_send("102 Vend all motors complete\n")
252 def do_vend(self,command):
255 self.do_send("153 Home sensors failing\n")
257 self.insert("Vending ",command)
258 self.do_send("100 Vend successful\n")
260 def do_display(self,string):
261 display = self.wTree.get_widget("label1")
262 display.set_text("%10.10s" % (string))
263 self.do_send('300 Written\n')
265 def do_beep(self,command):
266 sys.stdout.write("\a")
268 def do_silence(self,command):
271 def do_switches(self):
272 self.do_send("600 3F 3F\n")
275 self.do_send("000 PONG!\n")
277 def handle_command(self, command):
278 command = string.upper(command)
280 if string.find(command, "HELP",0) == 0:
282 elif string.find(command, "ABOUT",0) == 0:
284 elif string.find(command, "PING",0) == 0:
286 elif string.find(command, "VALL",0) == 0:
288 elif string.find(command, "V",0) == 0:
289 self.do_vend(command)
290 elif string.find(command, "B",0) == 0:
291 self.do_beep(command)
292 elif string.find(command, "C",0) == 0:
293 self.do_silence(command)
294 elif string.find(command, "S",0) == 0:
296 elif string.find(command, "D",0) == 0:
297 self.do_display(command[1:])
301 # we start the app like this...
307 # http://www.async.com.br/faq/pygtk/index.py?req=show&file=faq20.011.htp