def hold_resume(self, button):
        nick = self.calling_user
        tcp_port = int(self.usersDic[nick]['port'])
        ip = self.usersDic[nick]['ip']
        tcp_socket = socket(AF_INET, SOCK_STREAM)
        tcp_socket.settimeout(5)

        if str(button) == self.HOLD:
            # Intercambiamos
            self.app.hideWidgetType(gui.BUTTON, self.HOLD)
            self.app.showWidgetType(gui.BUTTON, self.RESUME)
            # Congelamos
            self.on_hold.set()
            # Notificamos al otro usuario
            try:
                tcp_socket.connect((ip, tcp_port))
                Protocolo.call_hold(Usuario.APP_USER.nick, tcp_socket)
                tcp_socket.close()
            except:
                pass
        if str(button) == self.RESUME:
            # Intercambiamos
            self.app.hideWidgetType(gui.BUTTON, self.RESUME)
            self.app.showWidgetType(gui.BUTTON, self.HOLD)
            # Descongelamos
            self.on_hold.clear()
            # Notificamos al otro usuario
            try:
                tcp_socket.connect((ip, tcp_port))
                Protocolo.call_resume(Usuario.APP_USER.nick, tcp_socket)
                tcp_socket.close()
            except:
                pass
        return
    def __hang(self, button):
        nick = self.calling_user
        self.state_lock.acquire()

        # Enviamos fin de conexion
        try:
            tcp_socket = socket(AF_INET, SOCK_STREAM)
            # Timeout para conexion con el otro usuario
            tcp_socket.settimeout(5)
            tcp_socket.connect(
                (self.usersDic[nick]['ip'], int(self.usersDic[nick]['port'])))
            Protocolo.call_end(Usuario.APP_USER.nick, tcp_socket)
            tcp_socket.close()
        except Exception as e:
            pass

        self.__change_call_buttons(self.FROM_CALL)
        # Finalizamos la llamada
        self.end_call.set()
        self.STATE = STATE_LOGGED
        self.state_lock.release()
        return
    def control_port_listen(self):
        user_tcp_port = Usuario.APP_USER.tcpPort

        # Preparamos el socket
        server_socket = socket(AF_INET, SOCK_STREAM)
        server_socket.bind(('', int(user_tcp_port)))
        server_socket.listen(5)
        server_socket.settimeout(self.TIMEOUT)

        # Bucle de lectura de puerto
        while True:

            # Abrimos el mensaje/listen con timeout para probar los flags periodicamente
            try:
                conection_socket, addr = server_socket.accept()
                msg = conection_socket.recv(self.MAX_LISTEN)
                msg = msg.decode('utf-8')
                # Actualizamos la lista de usuarios cada vez que nos llaman
                self.usersDic = Protocolo.list_users()
                if 'CALLING' in msg:
                    self.called_manager(msg)
                elif 'CALL_HOLD' in msg:
                    self.call_hold_manager(msg)
                elif 'CALL_RESUME' in msg:
                    self.call_resume_manager(msg)
                elif 'CALL_END' in msg:
                    self.call_end_manager(msg)
                elif 'CALL_ACCEPTED' in msg:
                    self.call_accepted_manager(msg)
                elif 'CALL_DENIED' in msg:
                    self.call_denied_manager(msg)
                elif 'CALL_BUSY' in msg:
                    self.call_busy_manager(msg)
                # Cualquier otro caso es descartado por malformacion

            except Exception as e:
                # Salimos en caso de que el  hilo maestro lo indique
                if self.end_gui.is_set():
                    return
    def __left_frame(self):
        self.app.startLabelFrame('Registered users', row=0, column=0)
        self.app.setSticky('we')
        self.app.startScrollPane(self.USERS_PANE, column=0, row=0, rowspan=2)

        self.usersDic = Protocolo.list_users()
        for user, i in zip(self.usersDic, range(len(self.usersDic))):
            #Aniadimos i-esimo frame
            self.app.startFrame(self.USER_FRAME + user,
                                row=i,
                                column=0,
                                colspan=2)
            self.app.setSticky("nws")
            self.app.setExpand("both")
            #Metemos dentro button y label
            self.app.addIconButton('call.' + user, self.__call,
                                   'md-camera-video', i, 0, 1)
            self.app.addLabel(user, user, i, 1, 1)
            self.app.stopFrame()

        self.app.stopScrollPane()
        self.app.stopLabelFrame()
Пример #5
0
    def __user_register(self, usuario, clave, port, ip, udp_port):
        # Llamamos al protocolo para que registre/renueve el usuario
        result = Protocolo.register(usuario, clave, port, ip)

        if result:
            # Caso efectivo
            # Guardamos el nuevo diccionario con el usuario registrado
            self.users[usuario] = {
                'port': port,
                'ip': ip,
                'udp_port': udp_port
            }
            with open(self.USERS, 'w') as f:
                json.dump(self.users, f)

            # Indicamos el usuario que se ha creado y cerramos el interfaz
            Usuario.APP_USER = Usuario(usuario, port, udp_port)
            self.app.stop()
        else:
            # Caso de fallo
            # indicamos error
            ind = self.app.getLabelWidget('Indicador')
            ind.config(text='Usuario o clave invalido.')
    def __pressBusqueda(self, busquedaButton):
        search = self.app.getEntry(self.BUSQUEDA_ENTRY)
        # Borramos info antigua: frame, label y button, y el scrollPane
        self.app.openFrame(self.RESULTS_FRAME)
        try:
            for nick in self.searchDic:
                self.app.removeWidgetType(gui.BUTTON, 'callResult.' + nick)
                self.app.removeWidgetType(gui.FRAME, self.RESULT_FRAME + nick)
                self.app.removeWidgetType(gui.LABEL, 'result_' + nick)
            self.app.removeWidgetType('scrollPane', self.RESULTS_PANE)

        except Exception as e:
            print(e)
        # No usamos los users de usersDic in case hay nuevos registrados
        # Aprovechamos para actualizar el diccionario de todos los users
        self.searchDic = {}
        self.usersDic = Protocolo.list_users()
        for nick in self.usersDic:
            # Si la string buscada coincide con el nick, lo aniadimos al diccionario
            if search in nick:
                self.searchDic[nick] = self.usersDic[nick]

        # Y actualizamos el scroll pane de los resultados con los nuevos resultados
        self.__update_results_pane()
    def called_manager(self, msg):
        campos = msg.split(' ')
        # Caso de paquete mal formado
        if len(campos) != 3: return

        nick = campos[1]
        dst_udp_port = campos[2]
        # Intentamos abrir un socket de control, sino lo logramos no hacemos nada
        try:
            tcp_socket = socket(AF_INET, SOCK_STREAM)
            # Timeout para conexion con el otro usuario
            tcp_socket.settimeout(10)
            tcp_socket.connect(
                (self.usersDic[nick]['ip'], int(self.usersDic[nick]['port'])))
        except Exception as e:
            print(e)
            return

        # Comprobamos que estamos en login, sino mandamos un paquete de ocupado
        self.state_lock.acquire()
        if self.STATE != STATE_LOGGED:
            # Nos protegemos contra casos de error al enviar un BUSY
            try:
                # Abrimos conexion con el puerto de control del usuario
                Protocolo.call_busy(Usuario.APP_USER.nick, tcp_socket)
                tcp_socket.close()
            except Exception as e:
                print(e)
            # Caso de algun fallo de ip, puerto o conexion no peta el programa
            self.state_lock.release()
            return

        # Creamos esta variable para comunicarnos con el subventana cuando nos llamen
        # Con value sabemos la decision del usuario
        self.value = False
        # Establecemos el usuario y llamamos a la ventana emergente
        self.calling_user_lock.acquire()
        self.calling_user = nick
        self.called_subwindow()
        # Esperamos a que responda el usuario
        self.esperar_resultado.acquire()
        # Caso de aceptar de llamada
        if self.value == True:
            # Abrimos un socket UDP en el que recibir el video (pedimos puerto al OS)
            # Lo guardamos en una variable de clase para que pueda acceder el hilo
            self.sock_udp = socket(AF_INET, SOCK_DGRAM)
            udp_port = int(Usuario.APP_USER.udp_port)
            self.sock_udp.bind(('', udp_port))
            # Enviamos paquete de llamada aceptada
            Protocolo.call_accept(Usuario.APP_USER.nick, udp_port, tcp_socket)
            # Inciamos el thread con el inicio de la llamada
            t = Thread(target=self.video_managing_thread,
                       args=(dst_udp_port, ))
            t.start()
            self.STATE = STATE_CALL
            self.__change_call_buttons(self.TO_CALL)
        else:
            # Caso de rechazar eliminamos el calling user
            self.calling_user = None
            Protocolo.call_deny(Usuario.APP_USER.nick, tcp_socket)
        tcp_socket.close()
        self.calling_user_lock.release()
        self.state_lock.release()
        return
    def __call(self, button):
        # Solo podemos llamar cuando estamos en estado de logged
        self.state_lock.acquire()
        if self.STATE != STATE_LOGGED:
            self.state_lock.release()
            return
        self.state_lock.release()

        nick = button[button.find('.') + 1:]
        # Variable utiles del usuario a llamar
        tcp_port = int(self.usersDic[nick]['port'])
        ip = self.usersDic[nick]['ip']

        self.state_lock.acquire()
        # Abrimos un socket UDP
        self.sock_udp = socket(AF_INET, SOCK_DGRAM)
        udp_port = int(Usuario.APP_USER.udp_port)
        self.sock_udp.bind(('', udp_port))
        # Intentamos abrir el puerto y enviar paquete de llamada
        # si fallamos solo cerramos la comunicacion (posibles ips o puertos malformados)
        try:
            tcp_socket = socket(AF_INET, SOCK_STREAM)
            # Timeout para conectar con el otro usuario
            tcp_socket.settimeout(5)
            tcp_socket.connect((ip, tcp_port))
            Protocolo.call(Usuario.APP_USER.nick, udp_port, tcp_socket)
            tcp_socket.close()
        except Exception as e:
            print(e)
            # Borramos info anterior
            try:
                self.app.destroySubWindow(self.INFO)
            except:
                pass
            # Indicamos que el servidor no logra conectarse
            self.app.startSubWindow(self.INFO, modal=True)
            self.app.addLabel('Indicacion2', 'El usuario esta offline')
            self.app.stopSubWindow()
            self.app.showSubWindow(self.INFO)
            # Cerramos
            self.sock_udp.close()
            self.state_lock.release()
            return

        # Indicamos que estamos a la espera de respuesta por parte del usuario con nick
        self.STATE = STATE_WAIT_ANSWER
        self.state_lock.release()
        self.calling_user_lock.acquire()
        self.calling_user = nick
        self.calling_user_lock.release()

        # Creamos una nueva ventana  (recordar que hay que destruir la anterior)
        try:
            self.app.destroySubWindow(self.WAITING_WINDOW)
        except:
            pass

        self.app.startSubWindow(self.WAITING_WINDOW, modal=True)
        self.app.addLabel('Indicacion', 'Esperando respuesta de la llamada')
        self.app.addButton('Cancelar', self.cancel_call)
        self.app.stopSubWindow()
        # Lanzamos la subwindow
        self.app.showSubWindow(self.WAITING_WINDOW)
        return