Skip to content
Snippets Groups Projects
Commit f3833b23 authored by Martin Vassor's avatar Martin Vassor
Browse files

Ajout TP TCP

parent cf071c8c
No related branches found
No related tags found
No related merge requests found
from textual import on, work
from textual.screen import ModalScreen
from textual.reactive import reactive
from textual.message import Message
from textual.app import App, ComposeResult
from textual.widgets import Input, RichLog, Button
from textual.widgets import Header, Footer
from time import sleep
import asyncio
import json
class MessageWidget(RichLog):
class NewMessage(Message):
def __init__(self, msg: str) -> None:
self.msg = msg
super().__init__()
async def get_new_message(log: MessageWidget, reader):
while True:
## À remplacer
log.post_message(MessageWidget.NewMessage("Message par défault: 1/seconde"))
await asyncio.sleep(1)
async def send_message(text, writer, log: MessageWidget):
# À remplacer
log.post_message(MessageWidget.NewMessage(text))
async def connection(login: str, password: str, log: MessageWidget):
return (None, None)
class ConnectScreen(ModalScreen):
def compose(self) -> ComposeResult:
yield Input(placeholder="Identifiant", id="login")
yield Input(placeholder="Mot de passe", id="pw", password=True)
@on(Input.Submitted)
async def login_submitted(self, event: Input.Submitted) -> None:
login = self.query_one("#login").value
pw = self.query_one("#pw").value
self.app.pop_screen()
(reader, writer) = await connection(login, pw, self.app.query_one(MessageWidget))
self.app.socket_snd = writer
self.app.socket_rcv = reader
async def on_button_pressed(self, event: Button.Pressed) -> None:
login = self.query_one("#login").value
pw = self.query_one("#pw").value
self.app.pop_screen()
(reader, writer) = await connection(login, pw, self.app.query_one(MessageWidget))
self.app.socket_snd = writer
self.app.socket_rcv = reader
class ChatApp(App[str]):
"""A small TCP chat App"""
connected = reactive(False)
socket_snd = None
socket_rcv = None
def compose(self) -> ComposeResult:
yield Header()
yield MessageWidget()
yield Input(placeholder="Message", id="send_msg")
yield Footer()
@on(Input.Submitted)
async def handle_message_request(self, event: Input.Submitted) -> None:
if event.input.id == "send_msg":
text_log = self.query_one(MessageWidget)
await send_message(event.value, self.socket_snd, text_log)
input_field = self.query_one(Input)
input_field.clear()
else:
# L'évènement vient des champs de connexion.
self.get_messages()
@on(MessageWidget.NewMessage)
def handle_new_message(self, event: MessageWidget.NewMessage) -> None:
text_log = self.query_one(MessageWidget)
text_log.write(content=event.msg)
@on(Button.Pressed)
def start_connection(self, event: Button.Pressed) -> None:
self.get_messages()
@work(exclusive=True)
async def get_messages(self) -> None:
log = self.query_one(MessageWidget)
asyncio.create_task(get_new_message(log, self.socket_rcv))
def watch_connected(self, value) -> None:
if not value:
self.push_screen(ConnectScreen())
self.connected = True
else:
pass
if __name__ == "__main__":
app = ChatApp()
msg = app.run()
if msg:
print(msg)
File added
This diff is collapsed.
%%
%% This is file `messagepassing.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% messagepassing.dtx (with options: `package')
%% This is a generated file.
%% Copyright (C) 2022 by Martin Vassor
%%
%% This file may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either
%% version 1.3 of this license or (at your option) any later
%% version. The latest version of this license is in:
%%
%% http://www.latex-project.org/lppl.txt
%%
%% and version 1.3 or later is part of all distributions of
%% LaTeX version 2005/12/01 or later.
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{messagepassing}[2023/12/13 v1.2 A package to draw message passing diagrams]
\RequirePackage{tikz}
\usetikzlibrary{quotes, calc, arrows.meta}
\RequirePackage{xparse}
\RequirePackage{float}
\newcounter{processnb}
\setcounter{processnb}{0}
\newcounter{maxtime}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}
\newfloat{float_messagepassing}{t b h p}{.mp}
\floatname{float_messagepassing}{Execution}
\newif\ifmp@vertical\mp@verticalfalse
\DeclareOption{vertical}{
\mp@verticaltrue
}
\newif\ifmp@annotatevertical\mp@annotateverticalfalse
\DeclareOption{annotatevertical}{
\mp@annotateverticaltrue
}
\ProcessOptions\relax
\ifmp@vertical
\newcommand{\mp@processnameanchor}{south}
\newcommand{\mp@timeticksanchor}{east}
\newcommand{\mp@messagelabelanchor}{south}
\newcommand{\mp@stateintervalanchor}{north west}
\newcommand{\mp@checkpointanchor}{east}
\newcommand{\mp@verticalrotation}{270}
\ifmp@annotatevertical
\newcommand{\mp@annotaterotation}{270}
\else
\newcommand{\mp@annotaterotation}{0}
\fi
\else
\newcommand{\mp@processnameanchor}{east}
\newcommand{\mp@timeticksanchor}{north}
\newcommand{\mp@messagelabelanchor}{west}
\newcommand{\mp@stateintervalanchor}{south west}
\newcommand{\mp@checkpointanchor}{north}
\newcommand{\mp@verticalrotation}{0}
\newcommand{\mp@annotaterotation}{0}
\fi
\newcommand{\mp@oobcolour}{red}
\newcommand{\oobcolour}[1]{
\renewcommand\mp@oobcolour{#1}
}
\newcommand{\mp@colouredboxcolour}{red}
\newcommand{\colouredboxcolour}[1]{
\renewcommand\mp@colouredboxcolour{#1}
}
\newif\iftimeline
\ExplSyntaxOn
%% 1st argument: tikz arguments
%% 2nd argument: Float caption (turns in floating)
%% 3rd argument: Float placement (`p` by default)
%% 4th argument: Float label
\NewDocumentEnvironment{messagepassing} {o o o o}
{
\timelinefalse
\setcounter{processnb}{0}
\IfNoValueTF{#2} {
}{
\IfNoValueTF{#3}{
\begin{float_messagepassing}[p]
} {
\begin{float_messagepassing}[#3]
}
\begin{center}
}
\IfNoValueTF{#1}{
\begin{tikzpicture}[rotate=\mp@verticalrotation]
} {
\begin{tikzpicture}[rotate=\mp@verticalrotation, #1]
}
}{
%% Draw timeline if boolean is true
\iftimeline
\begin{pgfonlayer}{background}
\setcounter{maxtime}{\@maxtime}
\addtocounter{maxtime}{-1}
\coordinate (maxtime) at (\@maxtime, 0);
\addtocounter{processnb}{1}
\coordinate (timeline) at (0, -\value{processnb});
\draw (timeline) node [anchor=\mp@processnameanchor] {{\it time}};
\draw[->] (timeline) -- ($(timeline) + (maxtime)$);
\foreach \i in {0,...,\value{maxtime}} {
\draw ($(timeline) + (\i, 0) + (0, 0.1)$) -- ($(timeline) + (\i, 0) + (0, -0.1)$) node [anchor=\mp@timeticksanchor] {$\i$};
}
\end{pgfonlayer}
\else
\fi
\end{tikzpicture}
\IfNoValueTF{#2} {
\linebreak
} {
\end{center}
\caption{#2}
\IfNoValueTF{#4} {
}{
\label{#4}
}
\end{float_messagepassing}
}
}
\ExplSyntaxOff
%% #1: name
%% #2: display name
\NewDocumentCommand{\newprocess}{m o}{
\addtocounter{processnb}{1}
\coordinate (#1) at (0, -\value{processnb});
\draw (#1) node[anchor=\mp@processnameanchor] {\IfValueTF{#2}{#2}{$#1$}};
}
%% #1: name
%% #2: display name
%% #3: width
\NewDocumentCommand{\newprocesswithlength}{m o m}{
\newprocess{#1}[#2]
\processlength{#1}{#3}
}
%% #1: name
%% #2: display name
%% #3: state interval name
\NewDocumentCommand{\newprocesswithstateinterval}{m o m}{
\newprocess{#1}[#2]
\stateinterval{#1}{0}{#3}
}
%% #1: name
%% #2: display name
%% #3: width
%% #4: crash name
\NewDocumentCommand{\newprocesswithcrash}{m o m m}{
\newprocesswithlength{#1}[#2]{#3}
\crash{#1}{#3}{#4}
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
\newcommand{\send}[4]{
\draw[->] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $);
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: message name
%% #6: message name display options
\NewDocumentCommand{\sendwithname}{m m m m m o}{
\IfValueTF{#6}{
\draw[->] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $) node[anchor=\mp@messagelabelanchor, pos=0.3, #6] {#5};
}{
\draw[->] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $) node[anchor=\mp@messagelabelanchor, pos=0.3] {#5};
}
}
%% #1: process name
%% #2: process width
\newcommand{\processlength}[2]{
\draw (#1) -- +(#2, 0);
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: state interval name
\newcommand{\sendwithstateinterval}[5] {
\send{#1}{#2}{#3}{#4}
\stateinterval{#3}{#4}{#5}
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: state interval name
%% #6: message name
%% #7: message name display options
\NewDocumentCommand{\sendwithstateintervalandname}{m m m m m m o} {
\sendwithname{#1}{#2}{#3}{#4}{#6}[#7]
\stateinterval{#3}{#4}{#5}
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: OoB message name
%% #6: OoB message name display options
\NewDocumentCommand{\sendoutofband}{m m m m m o}{
\IfValueTF{#6}{
\draw[->, color=\mp@oobcolour] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $) node[anchor=\mp@messagelabelanchor, pos=0.3, #6] {#5};
}{
\draw[->, color=\mp@oobcolour] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $) node[anchor=\mp@messagelabelanchor, pos=0.3] {#5};
}
}
%% #1: process's name
%% #2: state interval date
%% #3: state interval name
\newcommand{\stateinterval}[3] {
\stateintervalspecial{#1}{#2}{#3}{#3}
}
%% #1: process's name
%% #2: state interval date
%% #3: coordinate name
%% #4: state interval label
\newcommand{\stateintervalspecial}[4] {
\coordinate (#3) at ($ (#1) +(#2, 0) $);
\draw (#3) + (0, 0.1) -- +(0, -0.1) node[anchor=\mp@stateintervalanchor] {$#4$};
}
%% #1: process's name
%% #2: checkpoint date
%% #3: checkpoint name
\newcommand{\checkpoint}[3]{
\coordinate (#3) at ($ (#1) + (#2, 0) $);
\fill (#3) + (-0.05, 0.1) rectangle +(0.05, -0.1);
\draw (#3) + (0, -0.1) node[anchor=\mp@checkpointanchor] {$#3$};
}
%% #1: process's name
%% #2: checkpoint date
%% #3: checkpoint coordinate name
%% #4: checkpoint label
\newcommand{\checkpointspecial}[4]{
\coordinate (#3) at ($ (#1) + (#2, 0) $);
\fill (#3) + (-0.05, 0.1) rectangle +(0.05, -0.1);
\draw (#3) + (0, -0.1) node[anchor=\mp@checkpointanchor] {#4};
}
%% #1: process's name
%% #2: crash date
%% #3: crash name
\newcommand{\crash}[3]{
\coordinate (#3) at ($ (#1) + (#2, 0) $);
\draw (#3) + (-0.1, -0.1) -- +(0.1, 0.1);
\draw (#3) + (0.1, -0.1) -- +(-0.1, 0.1);
}
%% #1: process's name
%% #2: restart date
%% #3: restart length
\newcommand{\restart}[3]{
\draw (#1) + (#2, 0) -- ($ (#1) + (#2, 0) + (#3, 0) $);
}
%% #1: first process's name
%% #2: second process's name
%% #3: begining of the grey box
%% #4: end of the grey box
%% #5: caption
\newcommand{\colouredbox}[5]{
\begin{pgfonlayer}{background}
\fill[color=\mp@colouredboxcolour!20] ($(#1) + (#3, 0)$) rectangle ($(#2) + (#4, 0)$) node[midway, color = \mp@colouredboxcolour, rotate=\mp@annotaterotation]{#5};
\end{pgfonlayer}
}
%% #1: Timeline length
\newcommand{\drawtimeline}[1]{
\timelinetrue
\def\@maxtime{#1}
}
%% #1: process's name
%% #2: annotation date
%% #3: annotation
\newcommand{\annotate}[3]{
\annotatexplicit{#1}{#2}{#3}{#3}
}
%% Same than annotate, but with the coordinate name provided explicitly
%% #1: process's name
%% #2: annotation date
%% #3: annotation
%% #4: coordinate name
\newcommand{\annotatexplicit}[4]{
\coordinate (#4) at ($ (#1) +(#2, 0.1) $);
\draw (#4) node[rotate=\mp@annotaterotation, anchor=south] {#3};
}
\endinput
%%
%% End of file `messagepassing.sty'.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment