Spaces:
Build error
Build error
File size: 8,463 Bytes
6e00079 cc146e8 6e00079 cc146e8 6e00079 c441560 a8a7773 cc146e8 a8a7773 7aaf509 a8a7773 7aaf509 6e00079 7aaf509 bdbd74f 6e00079 7aaf509 6e00079 a8a7773 6e00079 cc146e8 6e00079 cc146e8 6e00079 cc146e8 6e00079 a8a7773 cc146e8 a8a7773 7aaf509 a8a7773 7aaf509 a8a7773 7aaf509 a8a7773 cc146e8 751ca76 cc146e8 a8a7773 cc146e8 df6bdf5 a8a7773 cc146e8 df6bdf5 6e00079 c7d803a 6e00079 7aaf509 6e00079 cc146e8 6e00079 1dd15f5 6e00079 7aaf509 6e00079 cc146e8 6e00079 7aaf509 6e00079 7aaf509 6e00079 a8a7773 cc146e8 6e00079 7aaf509 6e00079 7aaf509 6e00079 7aaf509 6e00079 7aaf509 6e00079 a8a7773 |
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 |
import streamlit as st
from database import get_hash, upsert_data
@st.cache_resource
def load_css():
"""Загрузка CSS стилей"""
with open("assets/styles.css") as f:
return f.read()
def render_sidebar(localS, locale, all_langs, moods, all_tags):
"""Рендеринг боковой панели с фильтрами"""
with st.sidebar:
st.markdown(
"""
[](
https://huggingface.co/datasets/loim/ru_fantasy_characters)
"""
)
def on_language_change():
if st.session_state.lang_select != st.session_state.lang:
localS.setItem("lang", st.session_state.lang_select)
st.selectbox(
locale['filter_lang'],
all_langs,
index=all_langs.index(st.session_state.lang),
on_change=on_language_change,
key="lang_select"
)
st.markdown("---")
st.title(locale['filter_title'])
search_query = st.text_input(locale['filter_search'], "")
sort_option = st.selectbox(
locale['filter_sort_title'],
locale['filter_sort']
)
absurdity_range = st.slider(locale['filter_absurd'], 0, 10, (0, 10))
selected_mood = st.selectbox(locale['filter_mood'], moods)
selected_tags = st.multiselect(locale['filter_tags'], all_tags)
return {
"search_query": search_query,
"sort_option": sort_option,
"absurdity_range": absurdity_range,
"selected_mood": selected_mood,
"selected_tags": selected_tags
}
@st.cache_data
def generate_rpg_card(locale, row):
"""Генерация RPG-карточки персонажа"""
return f"""
{locale['rpt_card_world']} {row['world']}
{locale['rpt_card_name']} {row['name']}
{locale['rpt_card_desc']} {row['description']}
{locale['rpt_card_story']} {row['short_story']}
{locale['rpt_card_style']} {row['style']}
{locale['rpt_card_msg']} {row['first_message']}
"""
# Кэшированный рендеринг карточек
@st.cache_data
def render_character_card(locale, row):
with st.container():
st.markdown("---")
st.markdown(f"### {row['name']}")
st.caption(f"*{row['short_story']}*")
col1, col2 = st.columns([1, 3])
with col1:
st.markdown(f"**{locale['char_world']}** {row['world']}")
st.markdown(f"**{locale['char_mood']}** `{row['mood']}`")
st.markdown(f"**{locale['char_absurd']}** `{row['absurdity']}/10`")
st.markdown(f"**{locale['char_tags']}** `{' '.join(row['tags'].split())}`")
with col2:
st.markdown(f"**{locale['char_desc']}** {row['description']}")
st.markdown(f"**{locale['char_style']}** *{row['style']}*")
with st.expander(locale['char_rpg_card'], expanded=False):
rpg_card = generate_rpg_card(locale, row)
st.code(rpg_card, language="markdown")
def render_character_rating(locale, database, localS, row):
current_hash = row['hash']
rating_data, _ = get_hash(database, "rating", current_hash)
rating_data = rating_data[1][0] if rating_data[1] else {"hash": current_hash, "likes": 0, "dislikes": 0}
# Проверяем, оценивали ли уже этот хэш
if current_hash in st.session_state.rated and (rating_data['likes'] != 0 or rating_data['dislikes'] != 0):
# Показываем текущий рейтинг
st.write(locale["rating_text"].format(rating_data['likes'], rating_data['dislikes']))
else:
# Показываем кнопки для оценки
if st.button(locale["rating_like"], key=f"like_{current_hash}"):
rating_data["likes"] += 1
upsert_data(database, "rating", rating_data)
st.session_state.rated.append(current_hash)
localS.setItem("rated", st.session_state.rated)
st.rerun()
if st.button(locale["rating_dislike"], key=f"dislike_{current_hash}"):
rating_data["dislikes"] += 1
upsert_data(database, "rating", rating_data)
st.session_state.rated.append(current_hash)
localS.setItem("rated", st.session_state.rated)
st.rerun()
def feedback_system(locale, database, localS):
if 'feedback_enabled' not in st.session_state:
st.session_state.feedback_enabled = False
if st.session_state.feedback_enabled:
st.header(locale["feedback_header"])
rating = st.slider(locale["feedback_rating"], 1, 5, 3)
comment = st.text_area(locale["feedback_comment_label"], help=locale["feedback_comment_help"])
if st.button(locale["feedback_send_btn"]):
if comment.strip() == "" and rating == 3:
st.warning(locale["feedback_warn"])
else:
upsert_data(database, "feedback", {"text": comment.strip(), "rating": rating})
st.success(locale["feedback_suc"])
else:
if st.button(locale["feedback_quest"]):
st.session_state.feedback_enabled = True
st.rerun()
def render_main_content(locale, database, localS, filtered_df):
feedback_system(locale, database, localS)
"""Рендеринг основного контента с пагинацией"""
st.title("🧙 Characters Explorer")
if len(filtered_df) == 0:
st.warning(locale['main_not_found'])
else:
# Инициализация состояния пагинации
if 'page' not in st.session_state:
st.session_state.page = 0
# Настройки пагинации
per_page = 5 # Персонажей на странице
total_pages = max(1, (len(filtered_df) // per_page) + (1 if len(filtered_df) % per_page else 0))
if st.session_state.page >= total_pages:
st.session_state.page = 0
# Управление пагинацией в колонках
col1, col2, _ = st.columns([2, 3, 5])
with col1:
st.selectbox(
locale['main_counter'],
options=[5, 10, 20],
index=0,
key='per_page',
on_change=lambda: st.session_state.update(page=0)
)
with col2:
st.number_input(
locale['main_page'],
min_value=0,
max_value=total_pages-1,
value=st.session_state.page,
key='page_input',
format="%d",
on_change=lambda: setattr(st.session_state, 'page', st.session_state.page_input)
)
# Рассчет диапазона записей
start_idx = st.session_state.page * st.session_state.per_page
end_idx = min((st.session_state.page + 1) * st.session_state.per_page, len(filtered_df))
# Отображение статистики
st.markdown(locale['main_found'].format(len(filtered_df), st.session_state.page, total_pages-1))
# Рендеринг только видимых карточек
for idx in range(start_idx, end_idx):
row = filtered_df.iloc[idx]
render_character_card(locale, row)
render_character_rating(locale, database, localS, row)
st.markdown("---")
# Кнопки навигации
if total_pages > 1:
cols = st.columns(4)
with cols[0]:
if st.button(locale['pages_first'], disabled=(st.session_state.page == 0)):
st.session_state.page = 0
st.rerun()
with cols[1]:
if st.button(locale['pages_before'], disabled=(st.session_state.page == 0)):
st.session_state.page -= 1
st.rerun()
with cols[2]:
if st.button(locale['pages_next'], disabled=(st.session_state.page >= total_pages-1)):
st.session_state.page += 1
st.rerun()
with cols[3]:
if st.button(locale['pages_last'], disabled=(st.session_state.page == total_pages-1)):
st.session_state.page = total_pages-1
st.rerun() |