File size: 8,218 Bytes
0f97b90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
675f40a
0f97b90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
675f40a
0f97b90
 
 
 
 
 
72d1759
 
 
 
 
675f40a
 
 
 
 
 
72d1759
 
0f97b90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a64d7a
0f03dc6
8a64d7a
 
 
 
0f97b90
 
8a64d7a
 
 
 
 
 
 
0f97b90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
import json
import os

import requests


def get_transcript_for_url(url: str) -> dict:
    """
    This function fetches the transcript data for a signed URL.
    If the URL results in a direct download, it processes the downloaded content.

    :param url: Signed URL for the JSON file
    :return: Parsed JSON data as a dictionary
    """
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()

        if "application/json" in response.headers.get("Content-Type", ""):
            return response.json()  # Parse and return JSON directly

        # If not JSON, assume it's a file download (e.g., content-disposition header)
        content_disposition = response.headers.get("Content-Disposition", "")
        if "attachment" in content_disposition:
            # Process the content as JSON
            return json.loads(response.content)

        return json.loads(response.content)

    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred: {http_err}")
    except requests.exceptions.RequestException as req_err:
        print(f"Request error occurred: {req_err}")
    except json.JSONDecodeError as json_err:
        print(f"JSON decoding error: {json_err}")

    return {}


def setup_openai_key() -> None:
    """Set up OpenAI API key from file."""
    try:
        with open("api.key", "r") as f:
            os.environ["OPENAI_API_KEY"] = f.read().strip()
    except FileNotFoundError:
        print("Using ENV variable")


openai_tools = [
    {
        "type": "function",
        "function": {
            "name": "correct_speaker_name_with_url",
            "description": "If a User provides a link to Agenda file, call the correct_speaker_name_with_url function to correct the speaker names based on the url, i.e if a user says 'Here is the Luma link for the event' and provides a link to the event, the function will correct the speaker names based on the event.",
            "parameters": {
                "type": "object",
                "properties": {
                    "url": {"type": "string", "description": "The url to the agenda."}
                },
                "required": ["url"],
                "additionalProperties": False,
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "correct_call_type",
            "description": "If the user tells you the correct call type, you have to apologize and call this function with correct call type.",
            "parameters": {
                "type": "object",
                "properties": {
                    "call_type": {
                        "type": "string",
                        "description": "The correct call type. If street interview, call type is 'si'.",
                    }
                },
                "required": ["call_type"],
                "additionalProperties": False,
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_image",
            "description": "If the user asks you to show crops, you need to call this function",
            "parameters": {
                "type": "object",
                "properties": {},
                "required": [],
                "additionalProperties": False,
            },
        },
    },
]


css = """
.gradio-container {

    padding-top: 0px !important;
    padding-left: 0px !important;
    padding-right: 0px !important;
    padding: 0px !important;
    margin: 0px !important;
}
#component-0 {
    gap: 0px !important;
}

.icon-button-wrapper button[title="Clear"] {
    display: none !important;
}

.image-preview .icon-button-wrapper {
    display: block !important;
}

.image-preview .icon-button-wrapper button[title="Clear"] {
    display: block !important;
}

.download-link {
    display: none !important;
}

footer {
    display: none !important;
}
#chatbot_box{
    flex-grow: 1 !important;
    border-width: 0px !important;
}

#link-frame {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    right: -100px !important;
    bottom: -100px !important;
    display: none !important;
}
.html-container {
    display: none !important;
}
a {
    text-decoration: none !important;
}
#topic {
    color: #999 !important;
}
.bubble-wrap {
    padding-top: 0px !important;
}
.message-content {
    border: 0px !important;
    margin: 5px !important;
}
.message-row {
    border-style: none !important;
    margin: 0px !important;
    width: 100% !important;
    max-width: 100% !important;
}
.flex-wrap {
    border-style: none !important;
}

.panel-full-width {
    border-style: none !important;
    border-width: 0px !important;
}
ol {
    list-style-position: outside; 
    margin-left: 20px;
}

body.waiting * {
cursor: progress;
}
"""
head = f"""
    <script defer src="https://www.gstatic.com/firebasejs/11.1.0/firebase-firestore.js"></script>
    <script type="module">
        // Import the functions you need from the SDKs you need
        import {{ initializeApp }} from "https://www.gstatic.com/firebasejs/11.1.0/firebase-app.js";
        import {{ getDatabase, ref, set }} from "https://www.gstatic.com/firebasejs/11.1.0/firebase-database.js";
        // TODO: Add SDKs for Firebase products that you want to use
        // https://firebase.google.com/docs/web/setup#available-libraries
        console.log("Initializing Firebase");
        // Your web app's Firebase configuration
        // For Firebase JS SDK v7.20.0 and later, measurementId is optional
        const firebaseConfig = {{
            apiKey: "{os.getenv('FIREBASE_API_KEY')}",
            authDomain: "{os.getenv('FIREBASE_AUTH_DOMAIN')}",
            databaseURL: "{os.getenv('FIREBASE_DATABASE_URL')}",
            projectId: "{os.getenv('FIREBASE_PROJECT_ID')}",
            storageBucket: "{os.getenv('FIREBASE_STORAGE_BUCKET')}",
            messagingSenderId: "{os.getenv('FIREBASE_MESSAGING_SENDER_ID')}",
            appId: "{os.getenv('FIREBASE_APP_ID')}",
            measurementId: "{os.getenv('FIREBASE_MEASUREMENT_ID')}"
        }};

        // Initialize Firebase
        const app = initializeApp(firebaseConfig);
        const realtimeDB = getDatabase(app);
        const rollAccount = "{os.getenv('ROLL_ACCOUNT')}";
        const COLLECTIONS = {{
            COLLAB_EDIT_LINK: "collab_link_handler",
        }};

        // Event listener for click
        document.addEventListener('click', function (event) {{
            var link = event.target.closest('a');
            event.preventDefault();
            if (link && link.href) {{

                // Parse the URL to extract 'st' and 'et'
                const url = new URL(link.href);
                const startTime = url.searchParams.get('st');
                const endTime = url.searchParams.get('et');
                const userId = url.searchParams.get('uid') || "";

                if (startTime || endTime) {{
                    let components = url.pathname.split("/");
                    let callId = components[2];
                    let recordingSessionId = components[3];

                    let data = {{
                        startTime: parseInt(startTime, 10),
                        endTime: parseInt(endTime, 10),
                    }};

                    console.log("Data to save:", data);

                    // Firebase reference
                    let reference = ref(
                        realtimeDB,
                        `${{rollAccount}}/${{COLLECTIONS.COLLAB_EDIT_LINK}}/${{userId}}/${{callId}}/${{recordingSessionId}}`
                    );

                    set(reference, data)
                        .then(() => {{
                            console.log("Data saved successfully:", data);
                        }})
                        .catch((error) => {{
                            console.error("Error saving data:", error);
                        }});
                }}
            }}
        }});
    </script>
"""