File size: 5,919 Bytes
312898d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
127
import json
import base64
from typing import Callable

def load_web_cookie_cache__fn_builder(customize_btns, cookies, predefined_btns)->Callable:
    def load_web_cookie_cache(persistent_cookie_, cookies_):
        import gradio as gr
        from themes.theme import load_dynamic_theme, to_cookie_str, from_cookie_str, assign_user_uuid

        ret = {}
        for k in customize_btns:
            ret.update({customize_btns[k]: gr.update(visible=False, value="")})

        try: persistent_cookie_ = from_cookie_str(persistent_cookie_)    # persistent cookie to dict
        except: return ret

        customize_fn_overwrite_ = persistent_cookie_.get("custom_bnt", {})
        cookies_['customize_fn_overwrite'] = customize_fn_overwrite_
        ret.update({cookies: cookies_})

        for k,v in persistent_cookie_["custom_bnt"].items():
            if v['Title'] == "": continue
            if k in customize_btns: ret.update({customize_btns[k]: gr.update(visible=True, value=v['Title'])})
            else: ret.update({predefined_btns[k]: gr.update(visible=True, value=v['Title'])})
        return ret
    return load_web_cookie_cache

def assign_btn__fn_builder(customize_btns, predefined_btns, cookies, web_cookie_cache)->Callable:
    def assign_btn(persistent_cookie_, cookies_, basic_btn_dropdown_, basic_fn_title, basic_fn_prefix, basic_fn_suffix, clean_up=False):
        import gradio as gr
        from themes.theme import load_dynamic_theme, to_cookie_str, from_cookie_str, assign_user_uuid
        ret = {}
        # 读取之前的自定义按钮
        customize_fn_overwrite_ = cookies_['customize_fn_overwrite']
        # 更新新的自定义按钮
        customize_fn_overwrite_.update({
            basic_btn_dropdown_:
                {
                    "Title":basic_fn_title,
                    "Prefix":basic_fn_prefix,
                    "Suffix":basic_fn_suffix,
                }
            }
        )
        if clean_up:
            customize_fn_overwrite_ = {}
        cookies_.update(customize_fn_overwrite_)    # 更新cookie
        visible = (not clean_up) and (basic_fn_title != "")
        if basic_btn_dropdown_ in customize_btns:
            # 是自定义按钮,不是预定义按钮
            ret.update({customize_btns[basic_btn_dropdown_]: gr.update(visible=visible, value=basic_fn_title)})
        else:
            # 是预定义按钮
            ret.update({predefined_btns[basic_btn_dropdown_]: gr.update(visible=visible, value=basic_fn_title)})
        ret.update({cookies: cookies_})
        try: persistent_cookie_ = from_cookie_str(persistent_cookie_)   # persistent cookie to dict
        except: persistent_cookie_ = {}
        persistent_cookie_["custom_bnt"] = customize_fn_overwrite_      # dict update new value
        persistent_cookie_ = to_cookie_str(persistent_cookie_)          # persistent cookie to dict
        ret.update({web_cookie_cache: persistent_cookie_})             # write persistent cookie
        return ret
    return assign_btn

# cookies, web_cookie_cache = make_cookie_cache()
def make_cookie_cache():
    # 定义 后端state(cookies)、前端(web_cookie_cache)两兄弟
    import gradio as gr
    from toolbox import load_chat_cookies
    # 定义cookies的后端state
    cookies = gr.State(load_chat_cookies())
    # 定义cookies的一个孪生的前端存储区(隐藏)
    web_cookie_cache = gr.Textbox(visible=False, elem_id="web_cookie_cache")
    return cookies, web_cookie_cache

# history, history_cache, history_cache_update = make_history_cache()
def make_history_cache():
    # 定义 后端state(history)、前端(history_cache)、后端setter(history_cache_update)三兄弟
    import gradio as gr
    # 定义history的后端state
    history = gr.State([])
    # 定义history的一个孪生的前端存储区(隐藏)
    history_cache = gr.Textbox(visible=False, elem_id="history_cache")
    # 定义history_cache->history的更新方法(隐藏)。在触发这个按钮时,会先执行js代码更新history_cache,然后再执行python代码更新history
    def process_history_cache(history_cache):
        return json.loads(history_cache)
    # 另一种更简单的setter方法
    history_cache_update = gr.Button("", elem_id="elem_update_history", visible=False).click(
        process_history_cache, inputs=[history_cache], outputs=[history])
    return history, history_cache, history_cache_update



def create_button_with_javascript_callback(btn_value, elem_id, variant, js_callback, input_list, output_list, function, input_name_list, output_name_list):
    import gradio as gr
    middle_ware_component = gr.Textbox(visible=False, elem_id=elem_id+'_buffer')
    def get_fn_wrap():
        def fn_wrap(*args):
            summary_dict = {}
            for name, value in zip(input_name_list, args):
                summary_dict.update({name: value})

            res = function(*args)

            for name, value in zip(output_name_list, res):
                summary_dict.update({name: value})

            summary = base64.b64encode(json.dumps(summary_dict).encode('utf8')).decode("utf-8")
            return (*res, summary)
        return fn_wrap

    btn = gr.Button(btn_value, elem_id=elem_id, variant=variant)
    call_args = ""
    for name in output_name_list:
        call_args += f"""Data["{name}"],"""
    call_args = call_args.rstrip(",")
    _js_callback = """
        (base64MiddleString)=>{
            console.log('hello')
            const stringData = atob(base64MiddleString);
            let Data = JSON.parse(stringData);
            call = JS_CALLBACK_GEN;
            call(CALL_ARGS);
        }
    """.replace("JS_CALLBACK_GEN", js_callback).replace("CALL_ARGS", call_args)

    btn.click(get_fn_wrap(), input_list, output_list+[middle_ware_component]).then(None, [middle_ware_component], None, _js=_js_callback)
    return btn