File size: 4,510 Bytes
32eaf3b
 
 
e804c23
 
 
32eaf3b
 
 
 
e804c23
 
 
32eaf3b
 
e804c23
32eaf3b
 
 
 
e804c23
 
 
 
 
 
 
 
 
 
 
 
 
32eaf3b
 
 
 
 
9e95aa8
 
5f07eaa
9e95aa8
 
 
 
e804c23
 
32eaf3b
e804c23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9e95aa8
e804c23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9e95aa8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import os
import csv
import gradio as gr
import itertools
import random
from collections import deque

DATA_FILENAME = "data.csv"
DATA_FILE = os.path.join("/data", DATA_FILENAME)

MAX_LINES = 20

def generate_html(me: str) -> str:
    with open(DATA_FILE) as csvfile:
        reader = csv.reader(csvfile)
        rows = deque(reader, maxlen=MAX_LINES)
        if len(rows) == 0:
            return "no messages yet"
        else:
            html = "<div class='chatbot'>"
            for row, _ in itertools.zip_longest(rows, range(MAX_LINES), fillvalue=("", "")):
                username = row[0]
                if username == me:
                    msg_type = "own"
                elif username == "[chatbot]":
                    msg_type = "admin"
                elif username == "":
                    msg_type = "empty"
                else:
                    msg_type = "other"
                html += "<div class='message'>"
                html += f"<span class='nick'>{row[0]}</span>"
                html += f"<span class='{msg_type}'>{row[1]}</span>"
                html += "</div>"
            html += "</div>"
            return html


def refresh(state):
    def do_refresh():
        print(f"refresh, username: {state.value['username']}")
        return generate_html(state.value["username"])
    return do_refresh


def store_message(writer: str, message: str, me: str):
    if writer and message:
        with open(DATA_FILE, "a") as csvfile:
            csv.writer(csvfile).writerow([writer, message])

    return generate_html(me)

anons = "alligator, anteater, armadillo, auroch, axolotl, badger, bat, bear, beaver, blobfish, buffalo, camel, chameleon, cheetah, chipmunk, chinchilla, chupacabra, cormorant, coyote, crow, dingo, dinosaur, dog, dolphin, dragon, duck, dumbo octopus, elephant, ferret, fox, frog, giraffe, goose, gopher, grizzly, hamster, hedgehog, hippo, hyena, jackal, jackalope, ibex, ifrit, iguana, kangaroo, kiwi, koala, kraken, lemur, leopard, liger, lion, llama, manatee, mink, monkey, moose, narwhal, nyan cat, orangutan, otter, panda, penguin, platypus, python, pumpkin, quagga, quokka, rabbit, raccoon, rhino, sheep, shrew, skunk, slow loris, squirrel, tiger, turtle, unicorn, walrus, wolf, wolverine, wombat"
anons = anons.split(",")

def login(username, state):
    if username == "":
        username = f"Anonymous {random.choice(anons).strip()}"
    print(username)
    state["username"] = username
    store_message("[chatbot]", f"{username} joins the chat", username)
    return (
        state,
        gr.update(visible=False),
        gr.update(visible=True),
        generate_html(username),
    )

def send_message(message, state):
    username = state["username"]
    store_message(username, message, me=username)
    return (generate_html(username), "")

css = """
.message {height: 28px;}
.nick {font-weight:bold;}
.other {background-color:cornflowerblue;color:white; padding:4px;margin:4px;border-radius:4px; }
.own {background-color:lime;color:white; padding:4px;margin:4px;border-radius:4px; }
.admin {background-color:orange;color:black; padding:4px;margin:4px;border-radius:4px; }
"""
with gr.Blocks(css=css) as demo:
    state = gr.Variable({
        'username': None,
    })

    gr.Markdown(
        """
        <h1><center>Persistent Storage Chat</center></h1>
        <p>This is a simple demo that implements a chatroom using persistent storage.
        All the messages are saved in a file, but only the last 20 ones are displayed.</p>
        """
    )

    with gr.Group():
        with (login_box := gr.Row().style(equal_height=True)):
            username = gr.Textbox(
                label="What's your name? (leave empty for anonymous)", show_label=True, max_lines=1
            )
            login_btn = gr.Button("Enter the chat")

    with (chat_box := gr.Box(visible=False)):
        with gr.Row():
            output = gr.HTML(refresh(state), label="Chat", every=5.0)
        with gr.Row():
            message = gr.Textbox(
                label="Your message", show_label=False, max_lines=1
            )

    username.submit(
        login,
        inputs=[username, state],
        outputs=[state, login_box, chat_box, output],
    )
    login_btn.click(
        fn=login,
        inputs=[username, state],
        outputs=[state, login_box, chat_box, output],
    )

    message.submit(
        send_message,
        inputs=[message, state],
        outputs=[output, message],
    )
demo.launch(enable_queue=True)