tomtat / pages_notebook.py
tiendung's picture
first commit
675b3d2
raw
history blame
8.03 kB
import re
import html
import uuid
import urllib
import streamlit as st
from pages.sticky_header import sticky_container
import sys; sys.path.append('../')
from pages_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 = st.tabs(["Danh sách các liên kết", "Chỉnh sửa danh sách các liên kết"])
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 = st.session_state["urls_input"].strip().split()
##############
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()