Download notebook.py from Symato/tomtat: direct link, hf CLI and curl.
- Browser
- Download file 9.04 kB
-
https://huggingface.co/spaces/Symato/tomtat/resolve/main/notebook.py
- Command line
-
hf download hf://spaces/Symato/tomtat/notebook.py
-
curl -L -o notebook.py https://huggingface.co/spaces/Symato/tomtat/resolve/main/notebook.py
9.04 kB
| import re | |
| import html | |
| import uuid | |
| import urllib | |
| import streamlit as st | |
| from notebook_helpers import * | |
| from text_utils import * | |
| import config | |
| # Kích hoạt chế độ toàn màn hình (full width) | |
| st.set_page_config(layout="wide") | |
| ################################################################### | |
| # Define HTML and CSS for the tooltip | |
| html_content = """ | |
| <style> | |
| .tooltip { | |
| position: relative; | |
| display: inline-block; | |
| cursor: pointer; | |
| } | |
| .tooltip .tooltiptext { | |
| font-weight: normal; | |
| visibility: hidden; | |
| width: 320px; | |
| background-color: #eadef9; | |
| color: black; | |
| text-align: left; | |
| border-radius: 6px; | |
| padding: 0.6em; | |
| position: absolute; | |
| z-index: 1; | |
| top: 100%; | |
| left: 50%; | |
| margin-left: -60px; | |
| opacity: 20%; | |
| transition: opacity 0.3s; | |
| } | |
| .tooltip:hover .tooltiptext { | |
| visibility: visible; | |
| opacity: 1; | |
| } | |
| </style> | |
| """ | |
| st.markdown(html_content, unsafe_allow_html=True) | |
| def javascript(source: str) -> None: | |
| div_id = uuid.uuid4() | |
| st.markdown(f""" | |
| <div style="display:none" id="{div_id}"> | |
| <iframe src="javascript: \ | |
| var script = document.createElement('script'); \ | |
| script.type = 'text/javascript'; \ | |
| script.text = {html.escape(repr(source))}; \ | |
| var div = window.parent.document.getElementById('{div_id}'); \ | |
| div.appendChild(script); \ | |
| div.parentElement.parentElement.parentElement.style.display = 'none'; \ | |
| "/> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| ################################################################### | |
| if "urls_input" not in st.session_state: | |
| st.session_state["urls_input"] = normalize_text(default_urls_input) | |
| tab1, tab2, tab3 = st.tabs([ | |
| "Danh sách các liên kết", | |
| "Chỉnh sửa danh sách các liên kết", | |
| "Tổng hợp, tương tác với tất cả nội dung" | |
| ]) | |
| with tab3: | |
| if "prompt" not in st.session_state: | |
| st.session_state["prompt"] = "Tóm tắt ngắn gọn 10 chính ý từ các văn bản được cung cấp, mỗi ý chính một gạch đầu dòng." | |
| if not got_all_urls(st.session_state["urls_input"]): | |
| st.write("Bạn phải duyệt từng liên kết để lấy và kiểm tra nội dung trước khi xem bản tổng hợp này.") | |
| else: | |
| prompt = st.text_area( | |
| f"Yêu cầu của bạn", | |
| value = st.session_state["prompt"], | |
| height = 6, | |
| key = f"DocChat" | |
| ) | |
| if st.button("Tạo nội dung tổng hợp"): | |
| st.session_state["prompt"] = prompt | |
| print(">>> prompt", st.session_state["prompt"]) | |
| st.session_state["response"] = docchat(st.session_state["urls_input"], st.session_state["prompt"]) | |
| st.rerun() | |
| if "response" in st.session_state: | |
| st.write(st.session_state["response"]) | |
| with tab2: | |
| edited_urls_input = st.text_area( | |
| "Thêm hoặc bớt các liên kết", | |
| value=st.session_state["urls_input"], | |
| height=500, | |
| key=f"edit_urls_input" | |
| ) | |
| if st.button("Cập nhật thay đổi"): | |
| st.session_state["urls_input"] = normalize_text(edited_urls_input) | |
| st.session_state['selected_url'] = None | |
| st.success("Đã lưu thay đổi!") | |
| st.rerun() | |
| with tab1: | |
| # Giao diện Streamlit với 2 cột bằng nhau, chiếm trọn màn hình | |
| col1, col2 = st.columns([3, 6]) | |
| urls = get_urls(st.session_state["urls_input"]) | |
| ############## | |
| with col1: | |
| ############## | |
| # Hiển thị danh sách các URL và cho phép chọn | |
| for idx, url in enumerate(urls): | |
| url_preview = url[:50] + "..." # rút gọn | |
| if st.button(url_preview, key = idx): | |
| st.session_state['selected_url'] = url | |
| ############## | |
| with col2: | |
| ############## | |
| if 'selected_url' not in st.session_state or st.session_state["selected_url"] is None: | |
| "Nhấn vào url để hiển thị nội dung" | |
| else: | |
| selected_url = st.session_state['selected_url'] | |
| fresh_text = url_content(selected_url) | |
| _, chunks = add_chunk_markers(fresh_text, para = True) | |
| # Hiển thị url | |
| st.markdown(selected_url)#, help="tooltip") | |
| # Hiển thị summary và nhận xét | |
| text = url_content(selected_url) # tuy ko dùng nhưng phải lấy text trước thì mới có cái để summ | |
| llm_generated = get_llm_gen_contents(selected_url) | |
| if "summary" in llm_generated: | |
| summ = llm_generated["summary"] | |
| # Hiển thị phần tóm tắt văn bản | |
| summ = re.sub(r'<cite>((?:\[\d+\])+)</cite>', r' \1', summ) | |
| summ_sub = rf'<strong><a href="#" sourceid="chunk_\1" target="" class="cite tooltip">[\1]\ | |
| <span class="tooltiptext">__chunk_\1_text__</span></a></strong>' | |
| summ = re.sub(r'\[(\d+)\]', summ_sub, summ) | |
| for idx, chunk in enumerate(chunks): | |
| chunk = re.sub(r'https?://', '', chunk, flags = re.IGNORECASE | re.MULTILINE) | |
| summ = summ.replace(f"__chunk_{idx}_text__", f"{chunk}") | |
| st.write(summ, unsafe_allow_html = True) | |
| tab1, tab2, tab3, tab4, tab5 = st.tabs([ | |
| "Xem nội dung", | |
| "Bản tinh gọn", | |
| "Chỉnh sửa nội dung", | |
| "Cào lại nội dung", | |
| "Xóa nội dung", | |
| ]) | |
| ###################### | |
| with tab1: | |
| ###################### | |
| marked_chunks = [ f'<span id="chunk_{i}" class="source">{c}</span>' for i, c in enumerate(chunks) ] | |
| content = "\n\n".join(marked_chunks) | |
| st.write(content, unsafe_allow_html = True) | |
| # Nhúng javascript sau cùng để hilite citing | |
| # https://discuss.streamlit.io/t/injecting-js/22651/6 | |
| javascript(""" | |
| function removeHilite() { | |
| document.querySelectorAll('.hilite').forEach(element => { | |
| element.classList.remove('hilite'); | |
| element.setAttribute("style", "background: #FFFFFF;") | |
| }); | |
| } | |
| setTimeout(() => { | |
| console.log("BẮT ĐẦU NHÚNG JS"); | |
| removeHilite(); | |
| document.querySelectorAll('.cite').forEach(element => { | |
| console.log('Element:', element); | |
| element.addEventListener('click', () => { | |
| let chunkId = element.getAttribute("sourceid"); | |
| removeHilite(); | |
| let hiliteElem = document.getElementById(chunkId); | |
| console.log('Element to hilite:', chunkId, hiliteElem); | |
| hiliteElem.classList.add('hilite'); | |
| hiliteElem.setAttribute("style", "background: #eadef9;") | |
| // Scroll into view | |
| hiliteElem.scrollIntoView({ behavior: "smooth", block: "center" }); | |
| }); | |
| }); | |
| }, 200); | |
| """.strip()) | |
| ###################### | |
| with tab2: | |
| ###################### | |
| clean_view = get_clean_view(selected_url) | |
| if clean_view is None: | |
| st.write("Hệ thống đang tạo nội dung, vui lòng chờ ...") | |
| if st.button("Reload"): | |
| st.rerun() | |
| else: | |
| st.write(clean_view) | |
| if st.button("Dùng bản tinh gọn làm nội dung"): | |
| url_content(selected_url, update_text = clean_view) | |
| st.success("Đã lưu thay đổi!") | |
| st.rerun() | |
| ###################### | |
| with tab3: | |
| ###################### | |
| fresh_text = url_content(selected_url) | |
| edited_text = st.text_area( | |
| f"*Lưu ý: Văn bản không được dài quá {config.text_max_words} từ, nếu quá sẽ tự động cắt bỏ*", | |
| value =fresh_text, | |
| height = 500, | |
| key = f"edit_{selected_url}" | |
| ) | |
| if st.button("Lưu thay đổi"): | |
| url_content(selected_url, update_text = edited_text) | |
| st.success("Đã lưu thay đổi!") | |
| st.rerun() | |
| ###################### | |
| with tab4: | |
| ###################### | |
| if st.button("Bạn chắc chắn muốn cào lại nội dung?"): | |
| reset_content(selected_url) | |
| st.rerun() | |
| ###################### | |
| with tab5: | |
| ###################### | |
| if st.button("Bạn chắc chắn muốn xóa nội dung?"): | |
| urls_input = st.session_state["urls_input"] | |
| urls_input = urls_input.replace(selected_url, "") | |
| st.session_state["urls_input"] = normalize_text(urls_input) | |
| st.session_state['selected_url'] = None | |
| st.success("Đã xóa nội dung!") | |
| st.rerun() | |