diff --git a/ltchat-qt4.py b/ltchat-qt4.py
new file mode 100644
index 0000000..c258e0a
--- /dev/null
+++ b/ltchat-qt4.py
@@ -0,0 +1,336 @@
+#!/usr/bin/python2
+"""
+ Qt4 GUI front-end to the Lightron chat.
+ Copyright (C) 2016-2017 Glen Harpring
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+try:
+ from PyQt4 import QtCore, QtGui
+except ImportError: #Fallback to PySide is basically PyQt4 and is still included in the latest Ubuntu releases.
+ from PySide import QtCore, QtGui
+from HTMLParser import HTMLParser
+import sys,os,httplib,urllib,urllib2,math,time,json
+global getChat
+getChat = httplib.HTTPSConnection('lightron.org')
+class ChatBrowser(QtGui.QTextBrowser):
+ def loadResource(self,type,name):
+ if type == 1:
+ return urllib2.urlopen(str(name.toString())).read()
+ if type == 2 or type == 3:
+ if not str(name.toString()) in self.cache:
+ print "Downloading "+name.toString()+" of type "+str(type)+" into memory..."
+ try:
+ self.cache[str(name.toString())] = urllib2.urlopen(str(name.toString())).read()
+ print "[DONE]"
+ except:
+ print "[FAIL]"
+ return False
+ if type == 2:
+ return QtGui.QImage.fromData(self.cache[str(name.toString())],os.path.splitext(name.toString())[1].upper())
+ elif type == 3:
+ return self.cache[str(name.toString())]
+
+class main(object):
+ def setup(self, MainWindow):
+ global USERNAME,WHOSONLINE,PING,CHATS,wait,COOKIE,mself,FIRST
+ mself=self
+ COOKIE="";USERNAME = "Guest";WHOSONLINE = "";CHATS = "Loading...";PING = '?';wait=3;self.prevCHATS="";FIRST=True;
+ self.thread = QtCore.QThread() #Create a generic thread for now
+ self.chatstyle = """
+.chat
+{
+ width: 293px;
+
+ font-size: 11px;
+ font-family: verdana, sans-serif;
+ line-height: 18px;
+}
+
+.chat .input .message
+{
+ width: 205px;
+ float: left;
+}
+
+.chat .input .send
+{
+ width: 60px;
+ padding: 0px;
+ margin-top: 2px;
+}
+
+.chat .output
+{
+ clear: both;
+ margin-top: 5px;
+
+ width: 100%;
+ height: 350px;
+
+ overflow-x: hidden;
+ overflow-y: scroll;
+}
+
+.chat .output img
+{
+ max-width: 100%;
+ max-height: 200px;
+}
+
+.chat .message
+{
+ width: 98%;
+ border-bottom: 1px solid #CCC;
+}
+
+.chat .user
+{
+ font-size: 12px;
+ font-weight: bold;
+ font-family: Arial;
+ padding-right:3px;
+}
+
+.chat .timestamp
+{
+ color: #555;
+ font-size: 10px;
+ margin-left: 30px;
+}
+
+.chat .delete
+{
+ float: right;
+ margin-right: 10px;
+}"""
+ MainWindow.setObjectName("MainWindow")
+ MainWindow.resize(335,400)
+ MainWindow.setWindowTitle("Lightron Chat GUI")
+
+ self.centralwidget = QtGui.QWidget(MainWindow)
+ self.centralwidget.setObjectName("centralwidget")
+ self.gridLayout = QtGui.QGridLayout(self.centralwidget)
+ self.gridLayout.setObjectName("gridLayout")
+
+ self.label = QtGui.QLabel(self.centralwidget)
+ self.label.setObjectName("label")
+ self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
+
+ self.label_3 = QtGui.QLabel(self.centralwidget)
+ self.label_3.setObjectName("label_3")
+ self.gridLayout.addWidget(self.label_3, 1, 1, 1, 2)
+
+ self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
+ self.pushButton_2.setObjectName("pushButton_2")
+ self.pushButton_2.setText("Options")
+ QtCore.QObject.connect(self.pushButton_2,QtCore.SIGNAL("clicked()"),self.showOptions)
+ self.gridLayout.addWidget(self.pushButton_2, 1, 3, 1, 1)
+
+ self.textBrowser = ChatBrowser(self.centralwidget)
+ self.textBrowser.setObjectName("textBrowser")
+ self.textBrowser.cache = {}
+ self.textBrowser.setOpenExternalLinks(True)
+ self.gridLayout.addWidget(self.textBrowser, 2, 0, 1, 4)
+
+ self.pushButton = QtGui.QPushButton(self.centralwidget)
+ self.pushButton.setObjectName("pushButton")
+ self.pushButton.setText("Send")
+ QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"),self.send)
+ self.gridLayout.addWidget(self.pushButton, 3, 3, 1, 1)
+
+ self.lineEdit = QtGui.QLineEdit(self.centralwidget)
+ self.lineEdit.setObjectName("lineEdit")
+ self.gridLayout.addWidget(self.lineEdit, 3, 0, 1, 3)
+
+ self.label_2 = QtGui.QLabel(self.centralwidget)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout.addWidget(self.label_2, 5, 0, 1, 4)
+ MainWindow.setCentralWidget(self.centralwidget)
+
+ self.updateTimer = QtCore.QTimer(MainWindow)
+ self.updateTimer.timeout.connect(self.update)
+ self.updateTimer.start(4000)
+ self.updated();self.update()
+
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
+ def update(self):
+ if not self.thread.isRunning():
+ self.prevCHATS = CHATS
+ self.thread = UpdatingChat()
+ self.thread.finished.connect(self.updated)
+ self.thread.start()
+ def send(self):
+ global COOKIE
+ postdata = urllib.urlencode({'input':str(self.lineEdit.text())})
+ con = httplib.HTTPSConnection("lightron.org")
+ con.request("POST","/Chat",postdata,{"User-Agent":"Mozilla/5.0 QTextBrowser/Qt4 LTChatGUI/beta","Cookie":COOKIE,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"})
+ ChatsResponse = con.getresponse()
+ self.lineEdit.setText("")
+ self.updated();self.update()
+ def showOptions(self):
+ self.options = QtGui.QMenu()
+ if USERNAME == "Guest":
+ self.optionsLogin = self.options.addAction("Login")
+ QtCore.QObject.connect(self.optionsLogin,QtCore.SIGNAL("triggered()"),self.login)
+ else:
+ self.optionsProfile = self.options.addAction("Profile")
+ QtCore.QObject.connect(self.optionsProfile,QtCore.SIGNAL("triggered()"),self.profile)
+ self.optionsLogout = self.options.addAction("Logout")
+ QtCore.QObject.connect(self.optionsLogout,QtCore.SIGNAL("triggered()"),self.logout)
+ self.options.addSeparator()
+ #self.optionsToC = self.options.addAction("License Agreement")
+ #QtCore.QObject.connect(self.optionsToC,QtCore.SIGNAL("triggered()"),self.gpl)
+
+ self.options.exec_(QtGui.QCursor().pos())
+ def gpl(self):
+ webbrowser.open('https://www.gnu.org/licenses/gpl-3.0-standalone.html')
+ def updated(self):
+ global USERNAME, COOKIE
+ if USERNAME == "Guest":
+ self.label.setText("Please sign in to chat.")
+ out=True
+ else:
+ self.label.setText("Hello, "+USERNAME+"!")
+ out=False
+ self.pushButton.setHidden(out)
+ self.lineEdit.setHidden(out)
+ #self.label_3.setText("")
+ self.label_2.setText(""+WHOSONLINE+"; "+str(PING)+"ms")
+ if CHATS == "":
+ print "Returned chat appears to be blank."
+
+ elif not self.prevCHATS == CHATS:
+ self.textBrowser.setHtml('\n
")
+ def login(self):
+ login()
+ def completeLogin(self):
+ global USERNAME, COOKIE
+ postdata = urllib.urlencode({'loginType':'login','username':loginDia.lineEdit.text(),'password':loginDia.lineEdit_2.text()})
+ con = httplib.HTTPSConnection("lightron.org")
+ con.request("POST","/Authentication",postdata,{"User-Agent":"Mozilla/5.0 QTextBrowser/Qt4 LTChatGUI/beta","Cookie":COOKIE,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"})
+ data = con.getresponse()
+ datar = str(data.read())
+ if not datar == "1":
+ QtGui.QMessageBox.warning(MainWindow,'LTChat','Username and/or password invalid.',QtGui.QMessageBox.Ok)
+ loginDia.lineEdit_2.selectAll()
+ else:
+ #self.lineEdit.setText(str(data))
+ #COOKIE = data.getheader('Cookie')
+ USERNAME = loginDia.lineEdit.text()
+ loginDia.hide()
+ self.update()
+ def logout(self):
+ global USERNAME, COOKIE
+ USERNAME = "Guest";COOKIE="";
+ self.updated()
+ def profile(self):
+ profile()
+ def changepass(self):
+ return;
+class LoginDialog(QtGui.QDialog):
+ def __init__(self):
+ super(LoginDialog,self).__init__()
+ self.setup()
+ def setup(self):
+ self.setWindowTitle("Login to LTChat")
+ self.resize(335,80)
+
+ self.gridLayout = QtGui.QGridLayout(self)
+ self.gridLayout.setObjectName("gridLayout")
+ spacerItem = QtGui.QSpacerItem(260, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+ self.gridLayout.addItem(spacerItem, 2, 0, 1, 1)
+ self.pushButton = QtGui.QPushButton(self)
+ self.pushButton.setObjectName("pushButton")
+ self.pushButton.setText("Login!")
+ self.pushButton.setShortcut("Enter, Return")
+ QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"),mself.completeLogin)
+ self.gridLayout.addWidget(self.pushButton, 2, 1, 1, 1)
+ self.lineEdit = QtGui.QLineEdit(self)
+ self.lineEdit.setObjectName("lineEdit")
+ self.lineEdit.setPlaceholderText("Username")
+ self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 2)
+ self.lineEdit_2 = QtGui.QLineEdit(self)
+ self.lineEdit_2.setEchoMode(QtGui.QLineEdit.Password)
+ self.lineEdit_2.setObjectName("lineEdit_2")
+ self.lineEdit_2.setPlaceholderText("Password")
+ self.gridLayout.addWidget(self.lineEdit_2, 1, 0, 1, 2)
+
+ QtCore.QMetaObject.connectSlotsByName(self)
+
+class profileDialog(QtGui.QDialog):
+ def __init__(self):
+ super(profileDialog,self).__init__()
+ self.setup()
+ def setup(self):
+ self.setWindowTitle("My Profile - LTChat")
+ self.resize(335,80)
+
+ self.gridLayout = QtGui.QGridLayout(self)
+ self.gridLayout.setObjectName("gridLayout")
+ spacerItem = QtGui.QSpacerItem(260, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+ self.gridLayout.addItem(spacerItem, 2, 0, 1, 1)
+ self.pushButton = QtGui.QPushButton(self)
+ self.pushButton.setObjectName("pushButton")
+ self.pushButton.setText("Close")
+ self.pushButton.setShortcut("Enter, Return")
+ QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"),self.close)
+ self.gridLayout.addWidget(self.pushButton, 2, 1, 1, 1)
+ self.profileImage = QtGui.QLabel()
+ image = "https://lightron.org/inc/images/avatar/101.png"
+ self.proImage = QtGui.QPixmap.fromImage(mself.textBrowser.loadResource(2,QtCore.QUrl(image)))
+ self.profileImage.setPixmap(self.proImage)
+ self.gridLayout.addWidget(self.profileImage, 0, 0, 1, 2)
+ QtCore.QMetaObject.connectSlotsByName(self)
+
+
+class UpdatingChat(QtCore.QThread):
+ def run(self):
+ global USERNAME,WHOSONLINE,PING,CHATS,wait,getChat,FIRST,COOKIE
+ if FIRST:
+ FIRST = False;
+ con = httplib.HTTPSConnection("lightron.org")
+ con.request("GET","/","",{"User-Agent":"Mozilla/5.0 QTextBrowser/Qt4 LTChatGUI/beta"})
+ data = con.getresponse()
+ COOKIE = data.getheader('Set-Cookie').split(" ")[0]
+ wait=wait+1
+ defheader = {"User-Agent":"Mozilla/5.0 QTextBrowser/Qt4 LTChatGUI/beta","Cookie":COOKIE}
+ getChat = httplib.HTTPSConnection('lightron.org')
+ timebefore=time.time(); getChat.request("GET","/Chat","",defheader); timeafter=time.time()
+ ChatsResponse = json.loads(getChat.getresponse().read())
+ thechatshtm = ChatsResponse["output"]
+ WHOSONLINE = ChatsResponse["chatters"]
+ CHATS = str(thechatshtm.replace("