Spaces:
Build error
Build error
исправление ошибки
Browse files- app.py +6 -6
- data_loader.py +3 -3
- ui_components.py +29 -29
- utils.py +15 -15
app.py
CHANGED
|
@@ -28,7 +28,7 @@ locale = load_locale(st.session_state.lang)
|
|
| 28 |
st.markdown(f"<style>{load_css()}</style>", unsafe_allow_html=True)
|
| 29 |
|
| 30 |
# Получение уникальных значений для фильтров
|
| 31 |
-
moods = [locale[
|
| 32 |
all_tags = get_unique_tags(df)
|
| 33 |
|
| 34 |
# Рендеринг сайдбара с фильтрами
|
|
@@ -38,11 +38,11 @@ selected_filters = render_sidebar(cookie, locale, all_langs, moods, all_tags)
|
|
| 38 |
filtered_df = apply_filters(
|
| 39 |
locale,
|
| 40 |
df=df,
|
| 41 |
-
search_query=selected_filters[
|
| 42 |
-
absurdity_range=selected_filters[
|
| 43 |
-
selected_mood=selected_filters[
|
| 44 |
-
selected_tags=selected_filters[
|
| 45 |
-
sort_option=selected_filters[
|
| 46 |
)
|
| 47 |
|
| 48 |
# Основной контент
|
|
|
|
| 28 |
st.markdown(f"<style>{load_css()}</style>", unsafe_allow_html=True)
|
| 29 |
|
| 30 |
# Получение уникальных значений для фильтров
|
| 31 |
+
moods = [locale['filter_all']] + get_unique_mood(df)
|
| 32 |
all_tags = get_unique_tags(df)
|
| 33 |
|
| 34 |
# Рендеринг сайдбара с фильтрами
|
|
|
|
| 38 |
filtered_df = apply_filters(
|
| 39 |
locale,
|
| 40 |
df=df,
|
| 41 |
+
search_query=selected_filters['search_query'],
|
| 42 |
+
absurdity_range=selected_filters['absurdity_range'],
|
| 43 |
+
selected_mood=selected_filters['selected_mood'],
|
| 44 |
+
selected_tags=selected_filters['selected_tags'],
|
| 45 |
+
sort_option=selected_filters['sort_option']
|
| 46 |
)
|
| 47 |
|
| 48 |
# Основной контент
|
data_loader.py
CHANGED
|
@@ -6,14 +6,14 @@ import streamlit as st
|
|
| 6 |
def load_data():
|
| 7 |
"""Загрузка и кэширование набора данных"""
|
| 8 |
dataset = load_dataset("loim/ru_fantasy_characters")
|
| 9 |
-
return pd.DataFrame(dataset[
|
| 10 |
|
| 11 |
@st.cache_data
|
| 12 |
def get_unique_mood(_df):
|
| 13 |
"""Получение уникальных значений настроения"""
|
| 14 |
-
return sorted(_df[
|
| 15 |
|
| 16 |
@st.cache_data
|
| 17 |
def get_unique_tags(_df):
|
| 18 |
"""Получение уникальных тегов"""
|
| 19 |
-
return sorted({tag for tags in _df[
|
|
|
|
| 6 |
def load_data():
|
| 7 |
"""Загрузка и кэширование набора данных"""
|
| 8 |
dataset = load_dataset("loim/ru_fantasy_characters")
|
| 9 |
+
return pd.DataFrame(dataset['train'])
|
| 10 |
|
| 11 |
@st.cache_data
|
| 12 |
def get_unique_mood(_df):
|
| 13 |
"""Получение уникальных значений настроения"""
|
| 14 |
+
return sorted(_df['mood'].unique().tolist())
|
| 15 |
|
| 16 |
@st.cache_data
|
| 17 |
def get_unique_tags(_df):
|
| 18 |
"""Получение уникальных тегов"""
|
| 19 |
+
return sorted({tag for tags in _df['tags'] for tag in tags.split()})
|
ui_components.py
CHANGED
|
@@ -21,7 +21,7 @@ def render_sidebar(cookie, locale, all_langs, moods, all_tags):
|
|
| 21 |
cookie.set("lang", st.session_state.lang_select)
|
| 22 |
|
| 23 |
st.selectbox(
|
| 24 |
-
locale[
|
| 25 |
all_langs,
|
| 26 |
index=all_langs.index(st.session_state.lang),
|
| 27 |
on_change=on_language_change,
|
|
@@ -30,15 +30,15 @@ def render_sidebar(cookie, locale, all_langs, moods, all_tags):
|
|
| 30 |
|
| 31 |
st.markdown("---")
|
| 32 |
|
| 33 |
-
st.title(locale[
|
| 34 |
-
search_query = st.text_input(locale[
|
| 35 |
sort_option = st.selectbox(
|
| 36 |
-
locale[
|
| 37 |
-
locale[
|
| 38 |
)
|
| 39 |
-
absurdity_range = st.slider(locale[
|
| 40 |
-
selected_mood = st.selectbox(locale[
|
| 41 |
-
selected_tags = st.multiselect(locale[
|
| 42 |
|
| 43 |
return {
|
| 44 |
"search_query": search_query,
|
|
@@ -52,14 +52,14 @@ def render_sidebar(cookie, locale, all_langs, moods, all_tags):
|
|
| 52 |
def generate_rpg_card(locale, row):
|
| 53 |
"""Генерация RPG-карточки персонажа"""
|
| 54 |
return f"""
|
| 55 |
-
**{locale[
|
| 56 |
|
| 57 |
-
**{locale[
|
| 58 |
-
**{locale[
|
| 59 |
-
**{locale[
|
| 60 |
-
**{locale[
|
| 61 |
|
| 62 |
-
**{locale[
|
| 63 |
> {row['first_message']}
|
| 64 |
"""
|
| 65 |
|
|
@@ -72,16 +72,16 @@ def render_character_card(locale, row):
|
|
| 72 |
|
| 73 |
col1, col2 = st.columns([1, 3])
|
| 74 |
with col1:
|
| 75 |
-
st.markdown(f"**{locale[
|
| 76 |
-
st.markdown(f"**{locale[
|
| 77 |
-
st.markdown(f"**{locale[
|
| 78 |
-
st.markdown(f"**{locale[
|
| 79 |
|
| 80 |
with col2:
|
| 81 |
-
st.markdown(f"**{locale[
|
| 82 |
-
st.markdown(f"**{locale[
|
| 83 |
|
| 84 |
-
with st.expander(locale[
|
| 85 |
rpg_card = generate_rpg_card(locale, row)
|
| 86 |
st.code(rpg_card, language="markdown")
|
| 87 |
|
|
@@ -92,7 +92,7 @@ def render_main_content(locale, filtered_df):
|
|
| 92 |
st.title("🧙 Fantasy Characters Explorer")
|
| 93 |
|
| 94 |
if len(filtered_df) == 0:
|
| 95 |
-
st.warning(locale[
|
| 96 |
else:
|
| 97 |
# Инициализация состояния пагинации
|
| 98 |
if 'page' not in st.session_state:
|
|
@@ -106,7 +106,7 @@ def render_main_content(locale, filtered_df):
|
|
| 106 |
col1, col2, _ = st.columns([2, 3, 5])
|
| 107 |
with col1:
|
| 108 |
st.selectbox(
|
| 109 |
-
locale[
|
| 110 |
options=[5, 10, 20],
|
| 111 |
index=1,
|
| 112 |
key='per_page',
|
|
@@ -114,7 +114,7 @@ def render_main_content(locale, filtered_df):
|
|
| 114 |
)
|
| 115 |
with col2:
|
| 116 |
st.number_input(
|
| 117 |
-
locale[
|
| 118 |
min_value=0,
|
| 119 |
max_value=total_pages-1,
|
| 120 |
value=st.session_state.page,
|
|
@@ -128,7 +128,7 @@ def render_main_content(locale, filtered_df):
|
|
| 128 |
end_idx = min((st.session_state.page + 1) * st.session_state.per_page, len(filtered_df))
|
| 129 |
|
| 130 |
# Отображение статистики
|
| 131 |
-
st.markdown(locale[
|
| 132 |
|
| 133 |
# Рендеринг только видимых карточек
|
| 134 |
for idx in range(start_idx, end_idx):
|
|
@@ -139,18 +139,18 @@ def render_main_content(locale, filtered_df):
|
|
| 139 |
if total_pages > 1:
|
| 140 |
cols = st.columns(4)
|
| 141 |
with cols[0]:
|
| 142 |
-
if st.button(locale[
|
| 143 |
st.session_state.page = 0
|
| 144 |
st.rerun()
|
| 145 |
with cols[1]:
|
| 146 |
-
if st.button(locale[
|
| 147 |
st.session_state.page -= 1
|
| 148 |
st.rerun()
|
| 149 |
with cols[2]:
|
| 150 |
-
if st.button(locale[
|
| 151 |
st.session_state.page += 1
|
| 152 |
st.rerun()
|
| 153 |
with cols[3]:
|
| 154 |
-
if st.button(locale[
|
| 155 |
st.session_state.page = total_pages-1
|
| 156 |
st.rerun()
|
|
|
|
| 21 |
cookie.set("lang", st.session_state.lang_select)
|
| 22 |
|
| 23 |
st.selectbox(
|
| 24 |
+
locale['filter_lang'],
|
| 25 |
all_langs,
|
| 26 |
index=all_langs.index(st.session_state.lang),
|
| 27 |
on_change=on_language_change,
|
|
|
|
| 30 |
|
| 31 |
st.markdown("---")
|
| 32 |
|
| 33 |
+
st.title(locale['filter_title'])
|
| 34 |
+
search_query = st.text_input(locale['filter_search'], "")
|
| 35 |
sort_option = st.selectbox(
|
| 36 |
+
locale['filter_sort_title'],
|
| 37 |
+
locale['filter_sort']
|
| 38 |
)
|
| 39 |
+
absurdity_range = st.slider(locale['filter_absurd'], 0, 10, (0, 10))
|
| 40 |
+
selected_mood = st.selectbox(locale['filter_mood'], moods)
|
| 41 |
+
selected_tags = st.multiselect(locale['filter_tags'], all_tags)
|
| 42 |
|
| 43 |
return {
|
| 44 |
"search_query": search_query,
|
|
|
|
| 52 |
def generate_rpg_card(locale, row):
|
| 53 |
"""Генерация RPG-карточки персонажа"""
|
| 54 |
return f"""
|
| 55 |
+
**{locale['rpt_card_world']}** {row['world']}
|
| 56 |
|
| 57 |
+
**{locale['rpt_card_name']}** {row['name']}
|
| 58 |
+
**{locale['rpt_card_desc']}** {row['description']}
|
| 59 |
+
**{locale['rpt_card_story']}** {row['short_story']}
|
| 60 |
+
**{locale['rpt_card_style']}** {row['style']}
|
| 61 |
|
| 62 |
+
**{locale['rpt_card_msg']}**
|
| 63 |
> {row['first_message']}
|
| 64 |
"""
|
| 65 |
|
|
|
|
| 72 |
|
| 73 |
col1, col2 = st.columns([1, 3])
|
| 74 |
with col1:
|
| 75 |
+
st.markdown(f"**{locale['char_world']}** {row['world']}")
|
| 76 |
+
st.markdown(f"**{locale['char_mood']}** `{row['mood']}`")
|
| 77 |
+
st.markdown(f"**{locale['char_absurd']}** `{row['absurdity']}/10`")
|
| 78 |
+
st.markdown(f"**{locale['char_tags']}** `{' '.join(row['tags'].split())}`")
|
| 79 |
|
| 80 |
with col2:
|
| 81 |
+
st.markdown(f"**{locale['char_desc']}** {row['description']}")
|
| 82 |
+
st.markdown(f"**{locale['char_style']}** *{row['style']}*")
|
| 83 |
|
| 84 |
+
with st.expander(locale['char_rpg_card'], expanded=False):
|
| 85 |
rpg_card = generate_rpg_card(locale, row)
|
| 86 |
st.code(rpg_card, language="markdown")
|
| 87 |
|
|
|
|
| 92 |
st.title("🧙 Fantasy Characters Explorer")
|
| 93 |
|
| 94 |
if len(filtered_df) == 0:
|
| 95 |
+
st.warning(locale['main_not_found'])
|
| 96 |
else:
|
| 97 |
# Инициализация состояния пагинации
|
| 98 |
if 'page' not in st.session_state:
|
|
|
|
| 106 |
col1, col2, _ = st.columns([2, 3, 5])
|
| 107 |
with col1:
|
| 108 |
st.selectbox(
|
| 109 |
+
locale['main_counter'],
|
| 110 |
options=[5, 10, 20],
|
| 111 |
index=1,
|
| 112 |
key='per_page',
|
|
|
|
| 114 |
)
|
| 115 |
with col2:
|
| 116 |
st.number_input(
|
| 117 |
+
locale['main_page'],
|
| 118 |
min_value=0,
|
| 119 |
max_value=total_pages-1,
|
| 120 |
value=st.session_state.page,
|
|
|
|
| 128 |
end_idx = min((st.session_state.page + 1) * st.session_state.per_page, len(filtered_df))
|
| 129 |
|
| 130 |
# Отображение статистики
|
| 131 |
+
st.markdown(locale['main_found'].format(len(filtered_df), st.session_state.page, total_pages-1))
|
| 132 |
|
| 133 |
# Рендеринг только видимых карточек
|
| 134 |
for idx in range(start_idx, end_idx):
|
|
|
|
| 139 |
if total_pages > 1:
|
| 140 |
cols = st.columns(4)
|
| 141 |
with cols[0]:
|
| 142 |
+
if st.button(locale['pages_first'], disabled=(st.session_state.page == 0)):
|
| 143 |
st.session_state.page = 0
|
| 144 |
st.rerun()
|
| 145 |
with cols[1]:
|
| 146 |
+
if st.button(locale['pages_before'], disabled=(st.session_state.page == 0)):
|
| 147 |
st.session_state.page -= 1
|
| 148 |
st.rerun()
|
| 149 |
with cols[2]:
|
| 150 |
+
if st.button(locale['pages_next'], disabled=(st.session_state.page >= total_pages-1)):
|
| 151 |
st.session_state.page += 1
|
| 152 |
st.rerun()
|
| 153 |
with cols[3]:
|
| 154 |
+
if st.button(locale['pages_last'], disabled=(st.session_state.page == total_pages-1)):
|
| 155 |
st.session_state.page = total_pages-1
|
| 156 |
st.rerun()
|
utils.py
CHANGED
|
@@ -3,27 +3,27 @@ import streamlit as st
|
|
| 3 |
@st.cache_data
|
| 4 |
def get_search_mask(df, search_query):
|
| 5 |
return (
|
| 6 |
-
df[
|
| 7 |
-
df[
|
| 8 |
-
df[
|
| 9 |
-
df[
|
| 10 |
-
df[
|
| 11 |
-
df[
|
| 12 |
)
|
| 13 |
|
| 14 |
@st.cache_data
|
| 15 |
def apply_filters(locale, df, search_query, absurdity_range, selected_mood, selected_tags, sort_option):
|
| 16 |
"""Применение фильтров и сортировки"""
|
| 17 |
filtered_df = df[
|
| 18 |
-
(df[
|
| 19 |
-
(df[
|
| 20 |
]
|
| 21 |
|
| 22 |
-
if selected_mood != locale[
|
| 23 |
-
filtered_df = filtered_df[filtered_df[
|
| 24 |
|
| 25 |
if selected_tags:
|
| 26 |
-
filtered_df = filtered_df[filtered_df[
|
| 27 |
|
| 28 |
if search_query:
|
| 29 |
mask = get_search_mask(df, search_query)
|
|
@@ -31,10 +31,10 @@ def apply_filters(locale, df, search_query, absurdity_range, selected_mood, sele
|
|
| 31 |
|
| 32 |
# Сортировка
|
| 33 |
sort_columns = {
|
| 34 |
-
locale[
|
| 35 |
-
locale[
|
| 36 |
-
locale[
|
| 37 |
-
locale[
|
| 38 |
}
|
| 39 |
col, asc = sort_columns[sort_option]
|
| 40 |
return filtered_df.sort_values(col, ascending=asc)
|
|
|
|
| 3 |
@st.cache_data
|
| 4 |
def get_search_mask(df, search_query):
|
| 5 |
return (
|
| 6 |
+
df['world'].str.contains(search_query, case=False, na=False) |
|
| 7 |
+
df['name'].str.contains(search_query, case=False, na=False) |
|
| 8 |
+
df['short_story'].str.contains(search_query, case=False, na=False) |
|
| 9 |
+
df['description'].str.contains(search_query, case=False, na=False) |
|
| 10 |
+
df['style'].str.contains(search_query, case=False, na=False) |
|
| 11 |
+
df['first_message'].str.contains(search_query, case=False, na=False)
|
| 12 |
)
|
| 13 |
|
| 14 |
@st.cache_data
|
| 15 |
def apply_filters(locale, df, search_query, absurdity_range, selected_mood, selected_tags, sort_option):
|
| 16 |
"""Применение фильтров и сортировки"""
|
| 17 |
filtered_df = df[
|
| 18 |
+
(df['absurdity'] >= absurdity_range[0]) &
|
| 19 |
+
(df['absurdity'] <= absurdity_range[1])
|
| 20 |
]
|
| 21 |
|
| 22 |
+
if selected_mood != locale['filter_all']:
|
| 23 |
+
filtered_df = filtered_df[filtered_df['mood'] == selected_mood]
|
| 24 |
|
| 25 |
if selected_tags:
|
| 26 |
+
filtered_df = filtered_df[filtered_df['tags'].str.contains("|".join(selected_tags))]
|
| 27 |
|
| 28 |
if search_query:
|
| 29 |
mask = get_search_mask(df, search_query)
|
|
|
|
| 31 |
|
| 32 |
# Сортировка
|
| 33 |
sort_columns = {
|
| 34 |
+
locale['filter_sort'][0]: ("name", True),
|
| 35 |
+
locale['filter_sort'][1]: ("name", False),
|
| 36 |
+
locale['filter_sort'][2]: ("absurdity", True),
|
| 37 |
+
locale['filter_sort'][3]: ("absurdity", False)
|
| 38 |
}
|
| 39 |
col, asc = sort_columns[sort_option]
|
| 40 |
return filtered_df.sort_values(col, ascending=asc)
|