Display IRC Chat in TextView with galde, gtk3 and python 2.7 - python-2.7

This is my first try in building a gui and im trying to set up an irc client on ubuntu 14.04. Actually i got stuck when i tried to output the chat data in a textview on the gui but i think im missing something important here.
I was already able to send the chat data into the textview, when i put a while-loop into the button_clicked event. But then the whole gui of course hang up. So either the Chat read function reads only once or always. At least i tried to rearrange the structure around the Gtk.main() and it lead me to a "maximum recursion depth exceeded in cmp" error. it might have something to do with the setup of def init().
Maybe you could have a look at my code.
best regards,
yoshiwob
uimain.py
#!/usr/bin/python
from gi.repository import Gtk
import botmain
from botmain import connect, message, disconnect, read_chat, userlist
import os
class Gui:
def __init__(self):
Gtk.Builder().add_from_file("gladeui/uimain.glade")
Gtk.Builder().connect_signals(Gui())
window = Gtk.Builder().get_object("window1")
window.show_all()
def onDeleteWindow(self, *args):
Gtk.main_quit(*args)
def on_BTexit_clicked(self, button):
os._exit(0)
def on_BTconnect_clicked(self, button):
if button.get_label() == 'Connect':
button.set_label('Disonnect')
connected = True
connect()
# twitch_userlist()
else:
button.set_label('Connect')
disconnect()
connected = False
def on_BTsend_clicked(self, entry):
message(entry.get_text())
def main():
read_chat(builder)
Gtk.main_iteration_do(True)
if __name__ == "__main__":
Gui()
main();
botmain.py
import socket #imports module allowing connection to IRC
import threading #imports module allowing timing functions
from gi.repository import Gtk
from gnome_sudoku import gtk_goodies
import time
#sets variables for connection to twitch chat
bot_owner = 'deryoshiii'
nick = '-nick-'
channel = '#-nick-'
server = 'irc.twitch.tv'
password = '-oauth-'
irc = socket.socket()
queue = 13 #sets variable for anti-spam queue functionality
connected = False
def connect():
print("Connecting...")
irc.settimeout(300)
irc.connect((server, 6667)) #connects to the server
#sends variables for connection to twitch chat
irc.send('PASS ' + password + '\r\n')
irc.send('USER ' + nick + ' 0 * :' + bot_owner + '\r\n')
irc.send('NICK ' + nick + '\r\n')
irc.send('JOIN ' + channel + '\r\n')
print("Connected")
def userlist():
print('getting userlist...')
irc.send('WHO %s' % channel)
#http://www.qtcentre.org/threads/18292-Python-PyQt-IRC-Client
def disconnect():
irc.send('QUIT :')
# irc.shutdown(socket.SHUT_RDWR)
# irc.close()
def message(msg): #function for sending messages to the IRC chat
global queue
queue = 5
#print queue
if queue < 20: #ensures does not send >20 msgs per 30 seconds.
irc.send('PRIVMSG ' + channel + ' :' + msg + '\r\n')
else:
print('Message deleted')
def queuetimer(): #function for resetting the queue every 30 seconds
global queue
#print 'queue reset'
queue = 0
threading.Timer(30,queuetimer).start()
queuetimer()

Related

Tornado on pika consumer can't run

I want to build monitoring system using RabbitMQ and Tornado. I can run the producer and my consumer can consume the data on queue but the data cant be show on website.
This just my experiment before I using the sensor
import pika
import tornado.ioloop
import tornado.web
import tornado.websocket
import logging
from threading import Thread
logging.basicConfig(lvl=logging.INFO)
clients=[]
credentials = pika.credentials.PlainCredentials('ayub','ayub')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.43.101',
5672,
'/',
credentials))
channel = connection.channel()
def threaded_rmq():
channel.basic_consume('Queue',
on_message_callback= consumer_callback,
auto_ack=True,
exclusive=False,
consumer_tag=None,
arguments=None)
channel.start_consuming()
def disconect_rmq():
channel.stop_consuming()
Connection.close()
logging.info('Disconnected from broker')
def consumer_callback(ch,method,properties,body):
for itm in clients:
itm.write_message(body)
class SocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
logging.info('websocket open')
clients.remove(self)
def close(self):
logging.info('websocket closed')
clients.remove(self)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("websocket.html")
application = tornado.web.Application([
(r'/ws',SocketHandler),
(r"/", MainHandler),
])
def startTornado():
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
def stopTornado():
tornado.ioloop.IOLoop.instance().stop()
if __name__ == "__main__":
logging.info('starting thread RMQ')
threadRMQ = Thread(target=threaded_rmq)
threadRMQ.start()
logging.info('starting thread tornado')
threadTornado = Thread(target=startTornado)
threadTornado.start()
try:
raw_input("server ready")
except SyntaxError:
pass
try:
logging.info('disconnected')
disconnect_rmq()
except Exception, e:
pass
stopTornado()
but I got this error
WARNING:tornado.access:404 GET /favicon.ico (192.168.43.10) 0.98ms
please help me
In your SocketHandler.open function you need to add the client not remove it.
Also consider using a set for clients instead of a list because the remove operation will be faster:
clients = set()
...
class SocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
logging.info('websocket open')
clients.add(self)
def close(self):
logging.info('websocket closed')
clients.remove(self)
The message you get regarding favicon.ico is actually a warning and it's harmless (the browser is requesting an icon to show for web application but won't complain if none is available).
You might also run into threading issues because Tornado and Pika are running in different threads so you will have to synchronize them; you can use Tornado's IOLoop.add_callback method for that.

Python Flask App with MQTT

I'm trying to use my Flask app as a subscriber, but it does not call the on_message callback when receiving a message. Instead, I get about like the following:
Connected with result code 0
Closing data file...
Connected with result code 0
Closing data file...
This is how I am running the Flask app:
main.py:
from flask import Flask, render_template, redirect, url_for
from flask_bootstrap import Bootstrap
from flask_nav import Nav
from flask_nav.elements import *
import paho.mqtt.client as mqtt
import time
broker_address = <broker_ip>
port = 1883
timeout = 60
username = "first"
password = "last"
uuid = "1234"
topic = "mytopic"
qos = 0
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe(topic)
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload) + '\n')
def on_disconnect(client, userdata, rc):
print("Closing data file...")
client = mqtt.Client(client_id=uuid)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
client.username_pw_set(username, password)
client.connect(broker_address, port, 60)
client.loop_start()
<other Flask code>
if __name__ == "__main__":
app.run(debug=True)
I've tried using a another Python script to generate some fake data to publish to the topic, but only when that script is running to I get the output above. If that script is not running, then the main.py seems to wait for messages. This is the other script:
fake_data.py:
import paho.mqtt.client as mqtt
import time
broker_address = <broker_ip>
port = 1883
timeout = 60
username = "first"
password = "last"
uuid = "1234"
topic = "mytopic"
qos = 0
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client = mqtt.Client(client_id=uuid, clean_session=True)
client.on_connect = on_connect
client.username_pw_set(username, password)
client.connect(broker_address, port, 60)
client.loop_start()
while True:
count = 0
while count != 30:
print("Publishing {0}".format(count))
client.publish(topic, count, qos=0)
count += 1
time.sleep(1)
My question is why the Flask app keeps connecting and disconnecting endlessly without actually processing a message.
The client id needs to be different for all clients connected to a broker. In the code you've posted both the subscriber and the publisher are using the same client id (uuid=1234).
When 2 clients with the same client id connect to the broker, the broker will kick the oldest off. If this is then set to reconnect it will then kick the second one off.
Set uuid to different values.
I know this is from a long time ago...but I believe I know the answer! In case anyone else is having the same problem (disconnecting and reconnecting): your app has to be set to keep looping the client. "client.loop_start()" is actually behaving as designed in your case. If you want the connection to stay open for a program that runs indefinitely, replace that with "client.loop_forever()".
My First Answer!
Cheers!

python,SocketServer : How to use the main thread timeout method in a multi-threaded scenario

my request is close main thread after more than 2 min.i called serve_forever() ,but don't know how to close the main thread.my codes:
import SocketServer,socket
import threading,time,re
last_request_time = 0
class ThreadSocketServer(SocketServer.ThreadingMixIn,SocketServer.TCPServer):pass
class RequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
global last_request_time
last_request_time = time.time()
# print last_request_time
intact_data = []
while True:
data = str(self.request.recv(1024))
intact_data.append(data)
# if response[-16:-1].find('clientcomplete'):
if re.search('clientcomplete', data):
print 'server recv complete'
self.request.send('Finished')
break
self.request.close()
if __name__ == '__main__':
server = ThreadSocketServer(('192.168.3.33',12345),RequestHandler)
# server.handle_request()
server.serve_forever()
i tried server.handle_request(),but it can't seem to support multi threading.

Why won't my wxFrame close properly?

I am trying to build a basic messaging system, but I have hit a major roadblock in the process. I can't get the window to close without it not responding and me having to close it in the Task Manager. From what I've read online, it sounds like I need to close when a sys.exit(0) to exit all the threads and connections. I have been stuck on this problem for days so I would really appreciate an answer and explanation to why it doesn't work! The meat of the problem is in the close_window() function. It is run able provided you have a basic server that accepts a connection. Thanks!
import wx
import socket
import threading
import sys
class oranges(wx.Frame):
def __init__(self,parent,id):
##Unimportant stuff
wx.Frame.__init__(self,parent,id," Retro Message",size=(500,500))
self.frame=wx.Panel(self)
self.input_box=wx.TextCtrl(self.frame, -1,pos=(15,350),size=(455,120),style=wx.NO_BORDER| wx.TE_MULTILINE)
self.messaging_box=wx.TextCtrl(self.frame, -1,pos=(15,15),size=(455,285),style=wx.NO_BORDER | wx.TE_MULTILINE|wx.TE_READONLY)
send_button=wx.Button(self.frame,label="Send",pos=(350,315),size=(75,40))
self.Bind(wx.EVT_BUTTON, self.sender,send_button)
self.Bind(wx.EVT_CLOSE, self.close_window)
self.counter = 1
self.socket_connect = socket.socket()
self.setup()
def sender(self,event):
self.socket_connect.send(self.input_box.GetValue())
self.input_box.Clear()
self.Refresh()
##Important stuff
def close_window(self,event): #This is the function in question#
self.counter = 0
self.socket_connect.shutdown(socket.SHUT_RDWR)
sys.exit(0)
def setup(self):
self.ip_enter = wx.TextEntryDialog(None, "Enter in the IP:", "Setup", "192.168.1.1")
if self.ip_enter.ShowModal() ==wx.ID_OK:
self.offical_ip = self.ip_enter.GetValue()
try:
self.socket_connect.connect((self.offical_ip,5003))
self.username = "false" #Tells the server just to give the user a IP username
self.Thread1 = threading.Thread(target = self.listening_connect)
self.Thread1.start()
except socket.error:
self.error_connect()
else:
sys.exit(0)
def listening_connect(self):
self.socket_connect.send(self.username)
while self.counter != 0:
data = self.socket_connect.recv(1024)
self.messaging_box.AppendText(data)
self.Refresh()
if not data:
break
self.socket_connect.close()
def error_connect(self):
pop_ups = wx.MessageDialog(None, "Failed to Connect to Server!", 'Error', wx.OK)
pop_ups.ShowModal()
self.setup()
if __name__=="__main__":
app=wx.App(False)
window=oranges(parent=None,id=-1)
window.Show()
app.MainLoop()
Here is a basic server program that should work with it(I am unable to test it but it is very similar to the real one)
import socket
HOST = '192.168.1.1'
PORT=5003
s = socket.socket()
s.bind((HOST, PORT))
s.listen(1)
c,addr = s.accept()
while True:
data = c.recv(1024)
if not data:
break
c.close()
You need to wait for the thread to end. Otherwise it's probably going to make the script hang. Why? Well the thread is separate from the GUI thread, so it doesn't get killed just because you closed down your wxPython application. Here is what I would recommend:
def close_window(self, event):
self.Thread1.join()
self.Destroy()
This makes the script wait for the thread to finish before closing the application. If you want the frame to disappear, then you should call self.Hide() before the join. Another method would be to put some logic in your thread where you can send it a message that tells it the application is shutting down, so the thread needs to abort.
You should probably check out the following Stack answer:
Is there any way to kill a Thread in Python?

python code for serial data to print on window.

I am quite new to python and pyserial. My pc was installed with python 2.7.4 with pyserial and I want to print the serially received data on a seperate window on my pc. First the window has to be opened, then after the serial data should print on that window. Here the window has to be opened once and the serial data has to be continously print on the window until the device stops tramsmitting the data.
I tried with this code, but its worthless.
please someone help me with the code.
import serial
import Tkinter
from Tkinter import *
s = serial.Serial('COM10',9600) # open serial port
master = Tk()
master.geometry("1360x750") # a window pop up with width (1360) and height(750) which exatly fits my monitor screen..
while 1:
if s.inWaiting():
text = s.readline(s.inWaiting())
frameLabel = Frame( master, padx=40, pady =40)
frameLabel.pack()
w = Text( frameLabel, wrap='word', font="TimesNewRoman 37")
w.insert(12.0,text )
w.pack()
w.configure( bg=master.cget('bg'), relief='flat', state='Normal' )
mainloop()
The problem here is that you have two loops that should be constantly running: The mainloop for the GUI and the loop for transmitting the serial data. What you can do to solve this is to start a new thread to receive the content of the serial port, put it in a Queue, and check periodically in the GUI thread the content of this queue:
import serial
import threading
import time
import Queue
import Tkinter as tk
class SerialThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
s = serial.Serial('/dev/ttyS0',9600)
s.write(str.encode('*00T%'))
time.sleep(0.2)
while True:
if s.inWaiting():
text = s.readline(s.inWaiting())
self.queue.put(text)
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.geometry("1360x750")
frameLabel = tk.Frame(self, padx=40, pady =40)
self.text = tk.Text(frameLabel, wrap='word', font='TimesNewRoman 37',
bg=self.cget('bg'), relief='flat')
frameLabel.pack()
self.text.pack()
self.queue = Queue.Queue()
thread = SerialThread(self.queue)
thread.start()
self.process_serial()
def process_serial(self):
value=True
while self.queue.qsize():
try:
new=self.queue.get()
if value:
self.text.delete(1.0, 'end')
value=False
self.text.insert('end',new)
except Queue.Empty:
pass
self.after(100, self.process_serial)
app = App()
app.mainloop()
This code is tested with my Pi3 ttyS0 serial port and serially connected PC and slave device:
its 100% working with single device connected serially