diff --git a/ekgplotter/ekgplotter/main.py b/ekgplotter/ekgplotter/main.py
index 3cee49d..a6e949b 100644
--- a/ekgplotter/ekgplotter/main.py
+++ b/ekgplotter/ekgplotter/main.py
@@ -22,19 +22,23 @@
#
# Copyright (C) 2014 Stefan Kögl
-from __future__ import absolute_import
+
#import objgraph
+#import gc
+#gc.set_debug(gc.DEBUG_LEAK)
+
from datetime import datetime
import threading
-import Queue
+import queue
import numpy as np
import string,cgi,time, random, socket
from os import curdir, sep
-from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
-from SocketServer import ThreadingMixIn, ForkingMixIn
+import os.path
+from http.server import BaseHTTPRequestHandler, HTTPServer
+from socketserver import ThreadingMixIn, ForkingMixIn
import select
import re
@@ -42,7 +46,7 @@ from collections import deque
from PyQt4.QtCore import QBuffer, QByteArray, QIODevice
-from PyQt4 import QtGui
+from PyQt4 import QtGui, QtCore
import pyqtgraph as pg
@@ -56,9 +60,6 @@ from chaosc.lib import resolve_host
#except ImportError:
from chaosc.osc_lib import *
-QtGui.QApplication.setGraphicsSystem('opengl')
-
-print "systemInfo", pg.systemInfo()
try:
from chaosc.c_osc_lib import decode_osc
@@ -66,18 +67,6 @@ except ImportError as e:
print(e)
from chaosc.osc_lib import decode_osc
-QAPP = QtGui.QApplication([])
-
-
-class PlotWindow(PlotWidget):
- def __init__(self, title=None, **kargs):
- self.win = QtGui.QMainWindow()
- PlotWidget.__init__(self, **kargs)
- self.win.setCentralWidget(self)
- for m in ['resize']:
- setattr(self, m, getattr(self.win, m))
- if title is not None:
- self.win.setWindowTitle(title)
class OSCThread(threading.Thread):
@@ -93,8 +82,8 @@ class OSCThread(threading.Thread):
self.osc_sock.bind(self.own_address)
self.osc_sock.setblocking(0)
- print "%s: starting up osc receiver on '%s:%d'" % (
- datetime.now().strftime("%x %X"), self.own_address[0], self.own_address[1])
+ print("%s: starting up osc receiver on '%s:%d'" % (
+ datetime.now().strftime("%x %X"), self.own_address[0], self.own_address[1]))
self.subscribe_me()
@@ -110,13 +99,13 @@ class OSCThread(threading.Thread):
:param token: token to get authorized for subscription
:type token: str
"""
- print "%s: subscribing to '%s:%d' with label %r" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1], self.args.subscriber_label)
- msg = OSCMessage("/subscribe")
- msg.appendTypedArg(self.own_address[0], "s")
- msg.appendTypedArg(self.own_address[1], "i")
- msg.appendTypedArg(self.args.authenticate, "s")
+ print("%s: subscribing to '%s:%d' with label %r" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1], self.args.subscriber_label))
+ msg = OSCMessage(b"/subscribe")
+ msg.appendTypedArg(bytes(self.own_address[0], "ascii"), b"s")
+ msg.appendTypedArg(self.own_address[1], b"i")
+ msg.appendTypedArg(bytes(self.args.authenticate, "ascii"), b"s")
if self.args.subscriber_label is not None:
- msg.appendTypedArg(self.args.subscriber_label, "s")
+ msg.appendTypedArg(bytes(self.args.subscriber_label, "ascii"), b"s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
@@ -124,11 +113,11 @@ class OSCThread(threading.Thread):
if self.args.keep_subscribed:
return
- print "%s: unsubscribing from '%s:%d'" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1])
- msg = OSCMessage("/unsubscribe")
- msg.appendTypedArg(self.own_address[0], "s")
- msg.appendTypedArg(self.own_address[1], "i")
- msg.appendTypedArg(self.args.authenticate, "s")
+ print("%s: unsubscribing from '%s:%d'" % (datetime.now().strftime("%x %X"), self.chaosc_address[0], self.chaosc_address[1]))
+ msg = OSCMessage(b"/unsubscribe")
+ msg.appendTypedArg(bytes(self.own_address[0], "ascii"), b"s")
+ msg.appendTypedArg(self.own_address[1], b"i")
+ msg.appendTypedArg(bytes(self.args.authenticate, "ascii"), b"s")
self.osc_sock.sendto(msg.encode_osc(), self.chaosc_address)
def run(self):
@@ -138,18 +127,18 @@ class OSCThread(threading.Thread):
if reads:
osc_input = reads[0].recv(4096)
osc_address, typetags, messages = decode_osc(osc_input, 0, len(osc_input))
- #print "thread osc_address", osc_address
- if osc_address.find("ekg") > -1 or osc_address.find("plot") != -1:
- queue.put_nowait((osc_address, messages))
+ #print("thread osc_address", osc_address)
+ if osc_address.find(b"ekg") > -1 or osc_address.find(b"plot") != -1:
+ msg_queue.put_nowait((osc_address, messages))
else:
- queue.put_nowait(("/bjoern/ekg", [0]))
- queue.put_nowait(("/merle/ekg", [0]))
- queue.put_nowait(("/uwe/ekg", [0]))
+ msg_queue.put_nowait((b"/bjoern/ekg", [0]))
+ msg_queue.put_nowait((b"/merle/ekg", [0]))
+ msg_queue.put_nowait((b"/uwe/ekg", [0]))
self.unsubscribe_me()
- print "OSCThread is going down"
+ print("OSCThread is going down")
-queue = Queue.Queue()
+msg_queue = queue.Queue()
class Actor(object):
shadowPen = pg.mkPen(255, 255, 255)
@@ -231,8 +220,9 @@ class Actor(object):
class EkgPlot(object):
def __init__(self, actor_names, num_data, colors):
-
+ self.qtapp = QtGui.QApplication([])
self.plot = pg.PlotWidget(title="
EKG
")
+ self.plot.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.plot.hide()
self.plot.setLabel('left', "Amplitude
")
self.plot.setLabel('bottom', "Time
")
@@ -256,8 +246,8 @@ class EkgPlot(object):
self.set_positions()
- self.ekg_regex = re.compile("^/(.*?)/ekg$")
- self.ctl_regex = re.compile("^/plot/(.*?)$")
+ self.ekg_regex = re.compile(b"^/(.*?)/ekg$")
+ self.ctl_regex = re.compile(b"^/plot/(.*?)$")
self.updated_actors = set()
@@ -298,12 +288,12 @@ class EkgPlot(object):
actor_name = res.group(1)
actor_obj = self.actors[actor_name]
if value == 1 and not actor_obj.active:
- print "actor on", actor_name
+ print("actor on", actor_name)
self.plot.addItem(actor_obj)
actor_obj.active = True
self.active_actors.append(actor_obj)
elif value == 0 and not actor_obj.active:
- print "actor off", actor_name
+ print("actor off", actor_name)
self.plot.removeItem(actor_obj)
actor_obj.active = True
self.active_actors.remove(actor_obj)
@@ -313,45 +303,43 @@ class EkgPlot(object):
class MyHandler(BaseHTTPRequestHandler):
- def __del__(self):
- self.thread.running = False
- self.thread.join()
def do_GET(self):
try:
self.path=re.sub('[^.a-zA-Z0-9]', "",str(self.path))
if self.path=="" or self.path==None or self.path[:1]==".":
- self.send_error(403,'Forbidden')
+ self.send_error(403)
if self.path.endswith(".html"):
- f = open(curdir + sep + self.path)
+ directory = os.path.dirname(os.path.abspath(__file__))
+ data = open(os.path.join(directory, self.path), "rb").read()
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
- self.wfile.write(f.read())
- f.close()
+ self.wfile.write(data)
elif self.path.endswith(".mjpeg"):
self.thread = thread = OSCThread(self.server.args)
thread.daemon = True
thread.start()
self.send_response(200)
- actor_names = ["bjoern", "merle", "uwe"]
+ actor_names = [b"bjoern", b"merle", b"uwe"]
num_data = 100
colors = ["r", "g", "b"]
- plotter = EkgPlot(actor_names, num_data, colors)
+ self.plotter = plotter = EkgPlot(actor_names, num_data, colors)
- self.wfile.write("Content-Type: multipart/x-mixed-replace; boundary=--aaboundary\r\n\r\n")
+ self.send_header("Content-Type", "multipart/x-mixed-replace; boundary=--aaboundary\r\n\r\n")
+ self.end_headers()
#lastTime = time.time()
#fps = None
while 1:
while 1:
try:
- osc_address, args = queue.get_nowait()
- except Queue.Empty:
+ osc_address, args = msg_queue.get_nowait()
+ except queue.Empty:
break
plotter.update(osc_address, args[0])
@@ -361,8 +349,28 @@ class MyHandler(BaseHTTPRequestHandler):
buffer = QBuffer()
buffer.open(QIODevice.WriteOnly)
img.save(buffer, "JPG", 100)
- JpegData = buffer.data()
- self.wfile.write("--aaboundary\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\n%s\r\n\r\n\r\n" % (len(JpegData), JpegData))
+ JpegData = buffer.data().data()
+ try:
+ self.send_header("--aaboundary", None)
+ self.send_header("Content-Type", "image/jpeg")
+ self.send_header("Content-length", len(JpegData))
+ self.end_headers()
+ self.wfile.write(JpegData + b"\r\n\r\n\r\n")
+ except (BrokenPipeError, ConnectionResetError) as e:
+ print("Error:", e)
+ if hasattr(self, "plotter"):
+ print("children", plotter.plot.children())
+ plotter.plot.deleteLater()
+ plotter.plot.close()
+ self.plotter.qtapp.processEvents()
+ del self.plotter.plot
+ del self.plotter.qtapp
+ del self.plotter
+ del plotter
+ thread.running = False
+ thread.join()
+ return
+
del JpegData
del buffer
del img
@@ -378,17 +386,19 @@ class MyHandler(BaseHTTPRequestHandler):
#print '%0.2f fps' % fps
elif self.path.endswith(".jpeg"):
- f = open(curdir + sep + self.path)
+ directory = os.path.dirname(os.path.abspath(__file__))
+ data = open(os.path.join(directory, self.path), "rb").read()
self.send_response(200)
self.send_header('Content-type','image/jpeg')
self.end_headers()
- self.wfile.write(f.read())
- f.close()
+ self.wfile.write(data)
return
except (KeyboardInterrupt, SystemError):
- print "queue size", queue.qsize()
+ print("queue size", queue.qsize())
thread.running = False
thread.join()
+ if hasattr(self, "plotter"):
+ plotter.plot.deleteLater()
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
@@ -411,19 +421,22 @@ def main():
http_host, http_port = resolve_host(args.http_host, args.http_port)
- print http_host, http_port
+ print(http_host, http_port)
server = JustAHTTPServer((http_host, http_port), MyHandler)
server.args = args
- print "%s: starting up http server on '%s:%d'" % (
- datetime.now().strftime("%x %X"), http_host, http_port)
+ print("%s: starting up http server on '%s:%d'" % (
+ datetime.now().strftime("%x %X"), http_host, http_port))
- print "before start:"
+ print("before start:")
#objgraph.show_growth()
try:
server.serve_forever()
except KeyboardInterrupt:
- print '^C received, shutting down server'
+ print('^C received, shutting down server')
+ print()
+ #print(gc.garbage)
+ #print()
#print "queue size", queue.qsize()
#print "show growth", objgraph.show_growth()
#import random
diff --git a/ekgplotter/setup.py b/ekgplotter/setup.py
index 3cb5b9a..30bc081 100644
--- a/ekgplotter/setup.py
+++ b/ekgplotter/setup.py
@@ -7,6 +7,7 @@ use_setuptools()
import sys
from setuptools import find_packages, setup
+extras = dict()
if sys.version_info >= (3,):
extras['use_2to3'] = True