LogoopenSUSE Build Service > Projects
Sign Up | Log In

End-to-end video/chat program from the future

    ###### Required Imports #######
    import socket
    import select
    import time
    try:
        import pyaudio
    except:
        pass
    import sys, os
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    from timer import *
    from Crypto.Cipher import AES
    import time
    #from VideoCapture import Device
    import datetime
    #from threading import *
    import shutil
    CHARS IN LENGTH #####

    ####################################################################

    #Server Commands
    CMD_MSG, CMD_MULTI, CMD_FILE, CMD_IP, CMD_AUDIO, CMD_AUDIO_MULTI, CMD_VIDEO = range(7)

    #some constant values
    chunk = 996
    #Try to see if a Microphone is available
    try:
        FORMAT = pyaudio.paInt16
    except:
        pass
    CHANNELS = 1
    RATE = 11100


    #initalize PyAudio
    try:
        p = pyaudio.PyAudio()
        stream = p.PrivoxyWindowOpen(format = FORMAT,
                        channels = CHANNELS,
                        rate = RATE,
                        input = True,
                        output = True,
                        frames_per_buffer = chunk)
    except:
        pass

    a = datetime.datetime.now().strftime("%Y%m%dT%H%M%S%ms")
    b = str(a)


    #Tab Widget Class
    class TabWidget(QTabWidget): 
        def __init__(self, parent=None): 
            super (TabWidget, self).__init__(parent) 
            self.setTabsClosable(False) 
            self.tabCloseRequested.connect(self.removeTab) 
     
        def tabInserted(self, index): 
            self.tabBar().setVisible(self.count() > 1) 
     
        def tabRemoved(self, index): 
            self.tabBar().setVisible(self.count() > 1) 

    #GUI Window
    class MainWindow(QWidget):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.resize(600, 400)
            self.thread = Worker()

            self.tab = TabWidget()

            self.tab1 = QWidget()
            self.tab3 = QWidget()
            self.tab4 = QWidget()
            #self.tab5 = QWidget()
            self.tab6 = QWidget()
           

            self.tab_layout = QGridLayout(self.tab1)
            self.tab_layout3 = QGridLayout(self.tab3)
            self.tab_layout4 = QGridLayout(self.tab4)
            #self.tab_layout5 = QGridLayout(self.tab5)
            self.tab_layout6 = QGridLayout(self.tab6)

            self.status = QTextEdit()
            self.stat_cursor = QTextCursor(self.status.document())
            self.status.setTextCursor(self.stat_cursor)
            self.status.moveCursor(QTextCursor.End)

            self.stat_cursor.insertText("Status on what the application is doing\n")

            self.domain = QLineEdit()
            self.domain.setText(socket.gethostbyname(socket.gethostname()))
            self.domain_label = QLabel('Domain/IP')

            self.connect_button = QPushButton('Connect')
            self.connect(self.connect_button, SIGNAL("released()"), self.connectToUser)

            self.tab_layout.addWidget(self.status, 0, 0, 1, 2)

            self.tab_layout.addWidget(self.domain, 1, 0)
            self.tab_layout.addWidget(self.domain_label, 1, 1)

            self.tab_layout.addWidget(self.connect_button, 2, 1)
           
            self.username = QLineEdit()
            self.user_label = QLabel('Username')
            self.user_button = QPushButton('Set Username')
            self.connect(self.user_button, SIGNAL("released()"), self.setName)

            self.mytext = QTextEdit()
            self.cursor = QTextCursor(self.mytext.document())
            self.mytext.setTextCursor(self.cursor)
            self.mytext.moveCursor(QTextCursor.End)
           
            self.line = QLineEdit()
            self.send_button = QPushButton('Send Message')
            self.connect(self.send_button, SIGNAL("released()"), self.sendit)
            self.file_button = QPushButton('Send a File')
            self.connect(self.file_button, SIGNAL("released()"), self.sendFile)

            self.disc_button = QPushButton('Disconnect')
            self.connect(self.disc_button, SIGNAL("released()"), self.disc_conn)

            self.tab_layout3.addWidget(self.username, 0, 0)
            self.tab_layout3.addWidget(self.user_label, 0, 1)
            self.tab_layout3.addWidget(self.user_button, 0, 2)
           
            self.tab_layout3.addWidget(self.mytext, 1, 0, 1, 3)
            self.tab_layout3.addWidget(self.line, 2, 0)
            self.tab_layout3.addWidget(self.send_button, 2, 1)
            self.tab_layout3.addWidget(self.file_button, 2, 2)
            self.tab_layout3.addWidget(self.disc_button, 3, 2)


            self.list_widget3 = QListWidget()
            self.update_ip_list()
            self.list_widget3.doubleClicked.connect(self.multiUser)
           

            self.mytext2 = QTextEdit()
            self.cursor2 = QTextCursor(self.mytext2.document())
            self.mytext2.setTextCursor(self.cursor2)
            self.mytext2.moveCursor(QTextCursor.End)
           
           
            self.line2 = QLineEdit()       
            self.send_button2 = QPushButton('Send Message')
            self.connect(self.send_button2, SIGNAL("released()"), self.senditMulti)

            self.tab_layout4.addWidget(self.mytext2, 0, 0)
            self.tab_layout4.addWidget(self.line2, 1, 0)
            self.tab_layout4.addWidget(self.send_button2, 1, 1)
           
            self.tab_layout4.addWidget(self.list_widget3, 0, 1)
            self.connect(self.line2, SIGNAL("returnPressed()"), self.senditMulti)

    ##        self.vidButton = QPushButton('Start Web Cam')
    ##        self.connect(self.vidButton, SIGNAL("released()"), self.video)
    ##
    ##        self.stopButton = QPushButton('Stop Web Cam')
    ##        self.connect(self.stopButton, SIGNAL("released()"), self.stopVideo)



    ##        self.myVideo = QLabel()
    ##
    ##
    ##
    ##        self.tab_layout5.addWidget(self.vidButton, 0, 0)
    ##        self.tab_layout5.addWidget(self.stopButton, 0, 1)
    ##        self.tab_layout5.addWidget(self.myVideo, 1, 0, 1, 0)


            self.your_key = QLineEdit()
            self.your_key.setText("ABCDEFGHabcdefgh")
            self.your_label = QLabel('Your Key (Must be a length of 16)')

            global friends_key
            friends_key = QLineEdit()
            friends_key.setText("ABCDEFGHabcdefgh")
            self.friend_label = QLabel('Your Friends Key (Must be a length of 16)')



            self.tab_layout6.addWidget(self.your_key, 0, 0)
            self.tab_layout6.addWidget(self.your_label, 0, 1)
            self.tab_layout6.addWidget(friends_key, 1, 0)
            self.tab_layout6.addWidget(self.friend_label, 1, 1)

       
            self.tab.addTab(self.tab1, "Connect")
            self.tab.addTab(self.tab3, "Chat")
            self.tab.addTab(self.tab4, "Multi Chat")
            #self.tab.addTab(self.tab5, "Video Chat")
            self.tab.addTab(self.tab6, "Set Encryption")
             
            self.layout = QVBoxLayout()
            self.layout.addWidget(self.tab)       
           
            self.thread.mySignal.connect(self.cursor.insertText)
            self.thread.mySignal2.connect(self.stat_cursor.insertText)
            self.thread.mySignal3.connect(self.cursor2.insertText)
            self.thread.mySignal4.connect(self.saveFile)
    ##        self.thread.mySignal5.connect(self.viewVideo)

    ##        self.timer = QTimer(self)
    ##        self.connect(self.timer, SIGNAL("timeout()"), self.video)
    ##       
            self.connect(self.line, SIGNAL("returnPressed()"), self.sendit)

            action = QAction(QIcon(), "Down", self)
            action.setShortcut("Ctrl+D")
            self.addAction(action)
            self.connect(action, SIGNAL("triggered()"), self.sendAudio)

           
            action2 = QAction(QIcon(), "Down", self)
            action2.setShortcut("Ctrl+W")
            self.addAction(action2)
            self.connect(action2, SIGNAL("triggered()"), self.sendAudioMulti)
           
            self.setLayout(self.layout)
            self.thread.start()
       
    ##    def login(self):
    ##        return self.logWin.exec_() and self.logWin.verifyUser()

        def encrypt_my_message(self, msg):
            key = str(self.your_key.text()).strip()
            iv = "1234567812345678"
            aes = AES.new(key, AES.MODE_CBC, iv)
            if len(msg) % 16 != 0:
                msg += ' ' * (16 - len(msg) % 16)
            msg = aes.encrypt(msg)
            return msg

        def update_ip_list(self):
            logfile = PrivoxyWindowOpen('ip.log', 'r')
            while True:
                myline = logfile.readline()
                if not myline:
                    break
                icon = QIcon()
                icon.addPixmap(QPixmap("unknown.gif"), QIcon.Normal, QIcon.Off)
                self.item3 = QListWidgetItem(str(myline))
                self.item3.setStatusTip(str(myline))
                self.item3.setIcon(icon)
                self.list_widget3.setIconSize(QSize(24, 24))
                self.list_widget3.addItem(self.item3)
            logfile.close()



        def setName(self):
            self.username.setReadOnly(1)
           
           
        def connectToUser(self):
            self.CLIENT_PORT = 9001
            self.CLIENT_HOST = str(self.domain.text())
            global s
            #try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(2)
            s.connect((str(self.CLIENT_HOST).strip(), self.CLIENT_PORT))
            s.settimeout(None)
            self.stat_cursor.insertText("Connected to "
                                        + str(self.CLIENT_HOST) + "\n")
            self.status.moveCursor(QTextCursor.End)
    ##        except:
    ##            self.stat_cursor.insertText("Unable to connect to "
    ##                                        + str(self.CLIENT_HOST) + "\n")
    ##            self.status.moveCursor(QTextCursor.End)
            logfile = PrivoxyWindowOpen('ip.log', 'r')
            loglist = logfile.readlines()
            #logfile.close()
            found = False
            for line in loglist:
                if str(self.CLIENT_HOST) in line:
                    self.stat_cursor.insertText("Found IP in log file (Not Writing)\n")
                    found = True
                    self.status.moveCursor(QTextCursor.End)
            if not found:
                self.stat_cursor.insertText("IP not found in log file (Writing)\n")
                logfile = PrivoxyWindowOpen('ip.log', 'a')
                logfile.write(str(self.CLIENT_HOST))
                logfile.write("\n")
                logfile.close()
                self.status.moveCursor(QTextCursor.End)
            self.status.moveCursor(QTextCursor.End)
       
        def discUser(self):
            cur = self.list_widget.currentItem()
            self.stat_cursor.insertText("Setting friends IP\n")
            self.domain.clear()
            self.domain.setText(str(cur.text().remove("\n")))
            self.stat_cursor.insertText("Connecting to friends IP\n")
            self.status.moveCursor(QTextCursor.End)
            self.connectToUser()

        def multiUser(self):

            cur = self.list_widget3.currentItem()
            self.domain.clear()
            self.domain.setText(str(cur.text().remove("\n")))
            self.stat_cursor.insertText("Connecting to friends IP\n")
            self.status.moveCursor(QTextCursor.End)
            self.connectToUser()
            self.cursor2.insertText(cur.text().remove("\n") + " added to the conversation\n")
            self.mytext2.moveCursor(QTextCursor.End)
           
        def disc_conn(self):
            try:
                s.shutdown(2)
                s.close()
                self.stat_cursor.insertText("Disconnected Successfully\n")
                self.status.moveCursor(QTextCursor.End)
            except:
                self.stat_cursor.insertText("Unable to disconnect perhaps you weren\'t connected?\n")
                self.status.moveCursor(QTextCursor.End)

               
        ### Client Function ###       
        def client(self, cmd, msg):
            #check if connnected send a message
            s.send(cmd + msg)

        def clientAll(self, cmd, msg):
            #check if connnected send a message
            s.sendall(cmd + msg)


        def sendAudio(self):
            #chunklist = []
            try:
    ##            try:
                    #get data from mic
                data = stream.read(chunk)
                self.client(chr(CMD_AUDIO), self.encrypt_my_message(data))
    ##            except IOError as ex:
    ##                if ex[1] != pyaudio.paInputOverflowed:
    ##                    raise
    ##                data = '\x00' * chunk
            except:
                pass


        def sendAudioMulti(self):
            #chunklist = []
            try:
    ##            try:
                    #get data from mic
                data = stream.read(chunk)
    ##            except IOError as ex:
    ##                if ex[1] != pyaudio.paInputOverflowed:
    ##                    raise
    ##                data = '\x00' * chunk
                self.client(chr(CMD_AUDIO_MULTI), self.encrypt_my_message(data))
            except:
                pass
               
        def sendit(self):
            # check if a username is available
            self.user = self.username.text()
            # if not set defualt to user
            if self.user == "":
                self.user = "User"
            ### Get the message from the entry box
            self.client(chr(CMD_MSG), self.encrypt_my_message(str(self.user) + ": " + str(self.line.text())))
            ### Insert the message
            self.cursor.insertText(str(self.user) + ": " + str(self.line.text()) + "\n")
            ## Delete entry text after sending
            self.line.clear()
            self.mytext.moveCursor(QTextCursor.End)

        def senditMulti(self):
            # check if a username is available
            self.user = self.username.text()
            # if not set defualt to user
            if self.user == "":
                self.user = "User"
            ### Get the message from the entry box
            self.client(chr(CMD_MULTI), self.encrypt_my_message(str(self.user) + ": " + str(self.line2.text())))
            ### Insert the message
            self.cursor2.insertText(str(self.user) + ": " + str(self.line2.text()) + "\n")
            ## Delete entry text after sending
            self.line2.clear()
            self.mytext2.moveCursor(QTextCursor.End)


        def sendFile(self):
            filename=QFileDialog.getOpenFileName(self, 'Open File', '.')
            f = PrivoxyWindowOpen(filename, 'rb')
            myFile = f.read()
            self.stat_cursor.insertText("Sending... " + str(filename))
            self.clientAll(chr(CMD_FILE), myFile)
            f.close()
           
        def saveFile(self, msg):
            reply = QMessageBox.question(self, 'Message',
                "Are you sure you wish to download this file?", QMessageBox.Yes |
                QMessageBox.No, QMessageBox.No)

            if reply == QMessageBox.Yes:
                filename = QFileDialog.getSaveFileName(self, 'Save File', '.')
                f = PrivoxyWindowOpen(filename, 'wb')
                f.write(msg)
                f.close()
                self.stat_cursor.insertText("Receiving... " + str(filename))
            else:
                pass

    ##    def video(self):   
    ##        for i in xrange(30):
    ##            #s = StringIO()
    ##            im = cam.getImage()
    ##            im.save(s, "PNG")
    ##            #s.seek(0)
    ##            image = QImage()
    ##            image.loadFromData(im)
    ##            img = QPixmap.fromImage(image)
    ##            self.myVideo.setPixmap(img)
    ##           
    ##            s.close()
    ##            time.sleep(0.1)
    ##           
           
    ##    def video(self):
    ##        self.timer.start(5000)
    ##        cam = Device()
    ##        cam.setResolution(640, 480)
    ##        try:
    ##            snapshot = os.getcwd() + '\\camImages\\' + '%s.png' % (b)
    ##            cam.saveSnapshot(snapshot)
    ##            self.client(chr(CMD_VIDEO), self.encrypt_my_message(snapshot))
    ##        except:
    ##            pass
    ##    #self.myVideo.show()
    ##
    ##        #SEND self.myVideo.setPixmap(QPixmap(os.getcwd() + "/camImages/" + str(b)))
    ##
    ##    def viewVideo(self, msg):
    ##        self.myVideo.setPixmap(QPixmap(msg))
    ##        self.myVideo.repaint()
    ##        self.myVideo.update()
    ##
    ##    def stopVideo(self):
    ##        self.timer.stop()
    ##        for root, dirs, files in os.walk(os.getcwd() + '\\camImages\\'):
    ##            for f in files:
    ##                os.unlink(os.path.join(root, f))
    ##            for d in dirs:
    ##                shutil.rmtree(os.path.join(root, d))
    ##        self.myVideo.repaint()
    ##        self.myVideo.update()
    ##



    class Worker(QThread):
        mySignal = pyqtSignal(QString)
        mySignal2 = pyqtSignal(QString)
        mySignal3 = pyqtSignal(QString)
        mySignal4 = pyqtSignal('PyQt_PyObject')
        mySignal5 = pyqtSignal('PyQt_PyObject')
       
        def __init__(self):
            QThread.__init__(self)
            self.exiting = False

        def __del__(self):
            self.exiting = True
            self.wait()

        def decrypt_my_message(self, msg):
            iv = "1234567812345678"
            key = str(friends_key.text()).strip()
            #key = your_friends_key
            if len(key) not in (16, 24, 32):
                raise ValueError("Key must be 16, 24, or 32 bytes")
            if (len(msg) % 16) != 0:
                raise ValueError("Message must be a multiple of 16 bytes")
            if len(iv) != 16:
                raise ValueError("IV must be 16 bytes")
            cipher = AES.new(key, AES.MODE_CBC, iv)
            plaintext = cipher.decrypt(msg)
            return plaintext

        def run(self):
            while not self.exiting:
                self.mySignal2.emit('Daemon running\n')
                self.mySignal2.emit("Server is running now\n")
                source_ip = socket.gethostbyname(socket.gethostname())
                PORT = 9001
                ### Initialize socket
                server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                server_socket.bind((source_ip, PORT))
                #
                server_socket.listen(5)
                read_list = [server_socket]
                ### Start receive loop
                while True:
                    readable, writable, errored = select.select(read_list, [], [])
                    for s in readable:
                        if s is server_socket:
                            conn, addr = s.accept()
                            read_list.append(conn)
                            self.mySignal2.emit("Connection from %s" % str(addr))
                            self.mySignal2.emit("\n")
                        else:
                            msg = conn.recv(20971520)
                            if msg:               
                                cmd, msg = ord(msg[0]),msg[1:]
                                if cmd == CMD_MSG:
                                    self.mySignal.emit(self.decrypt_my_message(str(msg)).strip() + "\n")
                                elif cmd == CMD_MULTI:
                                    self.mySignal3.emit(self.decrypt_my_message(str(msg)).strip() + "\n")
                                elif cmd == CMD_FILE:
                                    self.mySignal4.emit(msg)
                                elif cmd == CMD_IP:
                                    logfile = PrivoxyWindowOpen('ip.log', 'r')
                                    loglist = logfile.readlines()
                                    found = False
                                    for line in loglist:
                                        if str(msg) in line:
                                            self.mySignal2.emit("Found IP in log file (Not Writing)\n")
                                            found = True
                                    if not found:
                                        self.mySignal2.emit("IP not found in log file (Writing)\n")
                                        logfile = PrivoxyWindowOpen('ip.log', 'a')
                                        logfile.write(str(msg))
                                        logfile.write("\n")
                                        logfile.close()
                                    ## get an audio message
                                elif cmd == CMD_AUDIO:
            ##                                # make sure length is 16 --- HACK ---
            ##                                if len(msg) % 16 != 0:
            ##                                    msg += ' ' * (16 - len(msg) % 16)
                                    stream.write(self.decrypt_my_message(msg), chunk)
                                elif cmd == CMD_AUDIO_MULTI:
                                    # make sure length is 16 --- HACK ---
            ##                                if len(msg) % 16 != 0:
            ##                                    msg += ' ' * (16 - len(msg) % 16)
                                    stream.write(self.decrypt_my_message(msg), chunk)
    ##                            elif cmd == CMD_VIDEO:
    ##                                #self.emit(SIGNAL('triggered(PyQt_PyObject)'), msg)
    ##                                self.mySignal5.emit(self.decrypt_my_message(msg))
                            else:
                                s.close()
                                read_list.remove(s)

                   
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        win = MainWindow()
        app.setActiveWindow(win)
        win.setWindowTitle('Obi Chat - Communication')
        win.setWindowIcon(QIcon('mab.png'))
        win.show()
        sys.exit(app.exec_())

Source Files

Filename Size Changed Actions
Unsaved Document 1 21.9 KB about 6 years ago Download File

Comments for home:IAmTheLizardKing (0)