Spaces:
Sleeping
Sleeping
import streamlit as st | |
import random | |
import json | |
import os | |
from dotenv import load_dotenv | |
import requests | |
# ๅ ่ฝฝ็ฏๅขๅ้ | |
load_dotenv() | |
# ๅฎไนๅ็ฑป่กจๆ ๅ่กจ | |
EMOJI_CATEGORIES = { | |
"่กจๆ ไธๆ ็ปช": [ | |
"๐", "๐", "๐", "๐", "๐ ", "๐", "๐คฃ", "๐", "๐", "๐", "๐", "๐", | |
"๐", "๐ฅฐ", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐คช", "๐คจ", | |
"๐ง", "๐ค", "๐", "๐คฉ", "๐ฅณ", "๐", "๐", "๐", "๐", "๐", "๐", "๐" | |
], | |
"ๅจ็ฉ": [ | |
"๐ถ", "๐ฑ", "๐ญ", "๐น", "๐ฐ", "๐ฆ", "๐ป", "๐ผ", "๐จ", "๐ฏ", "๐ฆ", "๐ฎ", | |
"๐ท", "๐ธ", "๐ต", "๐", "๐ง", "๐ฆ", "๐ฆ", "๐ฆ ", "๐ฆ", "๐ฆ", "๐บ", "๐" | |
], | |
"ๆค็ฉ": [ | |
"๐ธ", "๐ฎ", "๐น", "๐บ", "๐ป", "๐ผ", "๐ท", "๐ฑ", "๐ฒ", "๐ณ", "๐ด", "๐ต", | |
"๐พ", "๐ฟ", "โ๏ธ", "๐", "๐", "๐", "๐", "๐ชด", "๐", "๐" | |
], | |
"้ฃ็ฉ": [ | |
"๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐", "๐ซ", "๐", "๐", "๐", | |
"๐ฅญ", "๐", "๐ฅฅ", "๐ฅ", "๐ ", "๐", "๐ฅ", "๐ฅฆ", "๐ฅฌ", "๐ฅ", "๐ถ๏ธ", "๐ซ", | |
"๐ฅ", "๐ง", "๐ง ", "๐ฅ", "๐ ", "๐ฅ", "๐ฅฏ", "๐", "๐ฅ", "๐ฅจ", "๐ง", "๐ฅ", | |
"๐ณ", "๐ฅ", "๐ฅฉ", "๐", "๐", "๐ฆด", "๐ญ", "๐", "๐", "๐", "๐ซ", "๐ฅช" | |
], | |
"ๆดปๅจไธ่ฟๅจ": [ | |
"โฝ", "๐", "๐", "โพ", "๐ฅ", "๐พ", "๐", "๐", "๐ฅ", "๐ฑ", "๐ช", "๐", | |
"๐ธ", "๐", "๐", "๐ฅ", "๐", "๐ช", "๐ฅ ", "โณ", "๐ช", "๐น", "๐ฃ", "๐คฟ" | |
], | |
"ไบค้ๅทฅๅ ท": [ | |
"๐", "๐", "๐", "๐", "๐", "๐๏ธ", "๐", "๐", "๐", "๐", "๐ป", "๐", | |
"๐", "๐", "๐ต", "๐๏ธ", "๐ฒ", "๐ด", "๐", "๐", "๐", "๐", "โ๏ธ", "๐" | |
], | |
"ๅฐ็นไธๅปบ็ญ": [ | |
"๐ ", "๐ก", "๐ข", "๐ฃ", "๐ค", "๐ฅ", "๐ฆ", "๐จ", "๐ฉ", "๐ช", "๐ซ", "๐ฌ", | |
"๐ญ", "๐ฏ", "๐ฐ", "๐", "๐ผ", "๐ฝ", "โช", "๐", "๐", "โฉ๏ธ", "๐", "โฒ" | |
], | |
"็ฉๅไธ็ฌฆๅท": [ | |
"๐ฑ", "๐ป", "โจ๏ธ", "๐ฅ๏ธ", "๐จ๏ธ", "๐ฑ๏ธ", "๐ฒ๏ธ", "๐ท", "๐ธ", "๐น", "๐ฅ", "๐ฝ๏ธ", | |
"๐บ", "๐ป", "๐๏ธ", "๐๏ธ", "๐๏ธ", "๐งญ", "โฑ๏ธ", "โฒ๏ธ", "โฐ", "๐ฐ๏ธ", "๐ก", "๐", | |
"๐", "๐", "๐", "๐ฎ", "๐ฒ", "๐ญ", "๐จ", "๐ช", "๐๏ธ", "๐ซ", "๐๏ธ", "๐ท๏ธ" | |
] | |
} | |
# ๅฎไนๆฐๆฎๆไปถ่ทฏๅพ | |
DATA_FILE = "stories_data.json" | |
HUGGINGFACE_API_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN") | |
API_URL = "https://api-inference.huggingface.co/models/HuggingFaceH4/zephyr-7b-beta" | |
def query_huggingface(payload): | |
"""่ฐ็จHugging Face API""" | |
headers = { | |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}", | |
"Content-Type": "application/json" | |
} | |
simplified_payload = { | |
"inputs": payload["inputs"], | |
"parameters": { | |
"max_new_tokens": 250, | |
"temperature": 0.7, | |
"top_p": 0.9, | |
"do_sample": True, | |
"return_full_text": False | |
} | |
} | |
try: | |
response = requests.post(API_URL, headers=headers, json=simplified_payload, timeout=60) | |
if response.status_code != 200: | |
st.error(f"API call failed, status code: {response.status_code}") | |
return None | |
result = response.json() | |
return result | |
except Exception as e: | |
st.error(f"API request error: {str(e)}") | |
return None | |
def generate_story_with_ai(emojis): | |
"""Generate story using AI""" | |
emoji_text = ' '.join(emojis) | |
prompt = f"""Create a short story (100-150 words) using these emojis: {emoji_text} | |
Instructions: | |
1. Write a coherent story that naturally incorporates the given emojis | |
2. The story must be suitable for all ages and have a clear structure: | |
- Beginning: Introduce the main character and setting | |
- Middle: Present a small challenge or interesting situation | |
- End: Resolve the situation with a satisfying conclusion | |
3. Important rules: | |
- Write as one continuous narrative without any section markers | |
- Do not use labels like 'Story event:' or 'Story resolution:' | |
- Ensure the story has a proper ending (no cliffhangers) | |
- Keep sentences complete (no trailing thoughts) | |
- Maintain a consistent tone throughout | |
4. Example flow (do not copy this exactly): | |
"Character encounters situation โ faces challenge โ resolves it โ learns or achieves something" | |
Begin the story with: | |
Once upon a sunny day,""" | |
try: | |
with st.spinner('Creating story...'): | |
response = query_huggingface({"inputs": prompt}) | |
if response and isinstance(response, list) and len(response) > 0: | |
story = response[0].get('generated_text', '').strip() | |
story = story.replace(prompt, '').strip() | |
if not story: | |
st.error("Failed to generate story. Please try again.") | |
return None | |
# ๆธ ็ๆๆๅฏ่ฝ็็ซ ่ๆ ่ฎฐๅๆ ไบๆ ็ญพ | |
markers_to_remove = [ | |
'Story event:', 'Story resolution:', 'Story middle:', | |
'Story end:', 'Story summary:', 'Story continuation:', | |
'Story ending:', 'Story begins:', 'Story continues:', | |
'Story concludes:', 'Beginning:', 'Middle:', 'End:', | |
'Continuation:', 'Ending:', 'Event:', 'Resolution:', | |
'Finally:', 'In conclusion:', 'The end:', 'Summary:', | |
'Next:', 'Then:', 'After that:', 'Eventually:' | |
] | |
# ็งป้คๆๆๆ ่ฎฐ | |
for marker in markers_to_remove: | |
story = story.replace(marker, '') | |
# ๆธ ็ๅคไฝ็็ฉบ่กๅ็ฉบๆ ผ | |
story = '\n'.join(line for line in story.split('\n') if line.strip()) | |
story = ' '.join(story.split()) | |
# ๆฃๆฅๅนถไฟฎๅคไธๅฎๆด็็ปๅฐพ | |
incomplete_endings = ('and', 'but', 'or', 'so', 'while', 'as', 'then', 'when', '...') | |
while story.endswith(incomplete_endings) or story.rstrip()[-1] not in '.!?': | |
story = story.rsplit(' ', 1)[0].rstrip() | |
if not story: | |
break | |
# ็กฎไฟๆ ไบๆ้ๅฝ็็ปๅฐพๆ ็น | |
if story and story[-1] not in '.!?': | |
story += '.' | |
final_story = f"Once upon a sunny day, {story}\n\n(Emojis used: {emoji_text})" | |
return final_story | |
st.error("Failed to generate story. Please try again.") | |
return None | |
except Exception as e: | |
st.error(f"Error generating story: {str(e)}") | |
return None | |
def load_stories(): | |
"""ไปๆไปถๅ ่ฝฝๆ ไบๆฐๆฎ""" | |
if os.path.exists(DATA_FILE): | |
try: | |
with open(DATA_FILE, 'r', encoding='utf-8') as f: | |
return json.load(f) | |
except Exception as e: | |
st.error(f"Error loading data: {str(e)}") | |
return [] | |
return [] | |
def save_stories_to_file(stories): | |
"""ไฟๅญๆ ไบๆฐๆฎๅฐๆไปถ""" | |
try: | |
with open(DATA_FILE, 'w', encoding='utf-8') as f: | |
json.dump(stories, f, ensure_ascii=False, indent=2) | |
except Exception as e: | |
st.error(f"Error saving data: {str(e)}") | |
# ๅๅงๅๆๅ ่ฝฝๆ ไบๆฐๆฎ | |
if 'stories' not in st.session_state: | |
st.session_state.stories = load_stories() | |
def save_story(story): | |
"""ไฟๅญๆฐๆ ไบๅนถๆดๆฐๆไปถ""" | |
st.session_state.stories.append({"story": story, "votes": 0}) | |
save_stories_to_file(st.session_state.stories) | |
def update_votes(): | |
"""ๆดๆฐๆไปถไธญ็ๆ็ฅจๆฐๆฎ""" | |
save_stories_to_file(st.session_state.stories) | |
def main(): | |
st.set_page_config(page_title="Emoji Story Generator", page_icon="๐") | |
st.title("Emoji Story Generator") | |
# Initialize session state for selected emojis | |
if 'selected_emojis' not in st.session_state: | |
st.session_state.selected_emojis = [] | |
# Create tab layout | |
ENGLISH_CATEGORIES = { | |
"Faces & Emotions": EMOJI_CATEGORIES["่กจๆ ไธๆ ็ปช"], | |
"Animals": EMOJI_CATEGORIES["ๅจ็ฉ"], | |
"Plants": EMOJI_CATEGORIES["ๆค็ฉ"], | |
"Food": EMOJI_CATEGORIES["้ฃ็ฉ"], | |
"Activities & Sports": EMOJI_CATEGORIES["ๆดปๅจไธ่ฟๅจ"], | |
"Transportation": EMOJI_CATEGORIES["ไบค้ๅทฅๅ ท"], | |
"Places & Buildings": EMOJI_CATEGORIES["ๅฐ็นไธๅปบ็ญ"], | |
"Objects & Symbols": EMOJI_CATEGORIES["็ฉๅไธ็ฌฆๅท"] | |
} | |
tabs = st.tabs(list(ENGLISH_CATEGORIES.keys())) | |
# Display emojis in each tab | |
for tab, (category, emojis) in zip(tabs, ENGLISH_CATEGORIES.items()): | |
with tab: | |
st.write(f"Select {category}:") | |
cols = st.columns(8) | |
for i, emoji in enumerate(emojis): | |
if cols[i % 8].button(emoji, key=f"{category}_{emoji}"): | |
if emoji not in st.session_state.selected_emojis: | |
if len(st.session_state.selected_emojis) < 5: | |
st.session_state.selected_emojis.append(emoji) | |
else: | |
st.warning("Maximum 5 emojis allowed!") | |
# Display selected emojis | |
if st.session_state.selected_emojis: | |
st.write("---") | |
st.write("Selected emojis:", " ".join(st.session_state.selected_emojis)) | |
col1, col2 = st.columns([1, 4]) | |
with col1: | |
if st.button("Clear Selection"): | |
st.session_state.selected_emojis = [] | |
st.rerun() | |
with col2: | |
if st.button("Generate Story"): | |
story = generate_story_with_ai(st.session_state.selected_emojis) | |
if story: | |
save_story(story) | |
st.write("Generated Story:") | |
st.write(story) | |
st.success("Story saved!") | |
else: | |
st.write("Please select at least one emoji.") | |
# Display saved stories | |
if st.session_state.stories: | |
st.markdown("---") | |
st.header("Generated Stories") | |
sorted_stories = sorted(st.session_state.stories, | |
key=lambda x: x['votes'], | |
reverse=True) | |
for idx, story_data in enumerate(sorted_stories): | |
col1, col2 = st.columns([4, 1]) | |
with col1: | |
st.write(f"{idx + 1}. {story_data['story']} (Likes: {story_data['votes']})") | |
with col2: | |
if st.button(f"๐", key=f"vote_{idx}"): | |
story_data['votes'] += 1 | |
update_votes() | |
st.success("Liked!") | |
st.rerun() | |
if __name__ == "__main__": | |
main() | |