himanshudasmldl commited on
Commit
22edc61
·
verified ·
1 Parent(s): c73d48d

Upload 7 files

Browse files
Files changed (5) hide show
  1. Dockerfile +25 -23
  2. app.py +89 -18
  3. login.py +100 -0
  4. main.py +6 -0
  5. src/story_gen.py +11 -5
Dockerfile CHANGED
@@ -1,23 +1,25 @@
1
- FROM python:3.13-slim
2
-
3
- WORKDIR /app
4
-
5
-
6
- # Install PortAudio + tools
7
- RUN apt-get update && apt-get install -y \
8
- portaudio19-dev \
9
- libportaudio2 \
10
- libportaudiocpp0 \
11
- && apt-get clean && rm -rf /var/lib/apt/lists/*
12
-
13
- COPY requirements.txt ./
14
- COPY src/ ./src/
15
- COPY app.py ./
16
-
17
- RUN pip3 install -r requirements.txt
18
-
19
- EXPOSE 8501
20
-
21
- #HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
22
-
23
- ENTRYPOINT ["streamlit", "run", "app.py"]
 
 
 
1
+ FROM python:3.13-slim
2
+
3
+ WORKDIR /app
4
+
5
+
6
+ # Install PortAudio + tools
7
+ RUN apt-get update && apt-get install -y \
8
+ portaudio19-dev \
9
+ libportaudio2 \
10
+ libportaudiocpp0 \
11
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
12
+
13
+ COPY requirements.txt ./
14
+ COPY src/ ./src/
15
+ COPY app.py ./
16
+ COPY main.py ./
17
+ COPY login.py ./
18
+
19
+ RUN pip3 install -r requirements.txt
20
+
21
+ EXPOSE 8501
22
+
23
+ #HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
24
+
25
+ ENTRYPOINT ["streamlit", "run", "login.py"]
app.py CHANGED
@@ -1,27 +1,98 @@
1
  import streamlit as st
2
  from src.story_gen import generate_story
3
  from pathlib import Path
 
 
 
4
 
5
- st.set_page_config(page_title="AI Story Generator", page_icon="📚", layout="centered")
 
 
6
 
7
- st.title("📚 AI Story Generator")
8
- st.write("Enter a story plot and let AI turn it into a full story!")
9
 
10
- plot = st.text_area("Enter your story plot:", height=150)
 
 
 
11
 
12
- generate = st.button("Generate Story")
13
 
14
- if generate:
15
- if not plot.strip():
16
- st.warning("Please enter a story plot.")
17
- else:
18
- with st.spinner("Generating story... please wait ⏳"):
19
- response = generate_story(story_plot=plot)
20
- story = response.get('story')
21
- fileName=response.get('fileName')
22
 
23
- st.subheader("✨ Generated Story")
24
- #st.write(story)
25
- f=Path(fileName)
26
- audio_bytes = f.read_bytes()
27
- st.audio(audio_bytes, format="audio/wav")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  from src.story_gen import generate_story
3
  from pathlib import Path
4
+ import threading
5
+ import time
6
+ import os
7
 
8
+ # ------------------- WAV CLEANUP CONFIG -------------------
9
+ WAV_FOLDER = "." # Change to your folder name
10
+ DELETE_AFTER_SECONDS = 300
11
 
 
 
12
 
13
+ def delete_wav_files():
14
+ """Delete .wav files older than 1 hour."""
15
+ if not os.path.exists(WAV_FOLDER):
16
+ return
17
 
18
+ current_time = time.time()
19
 
20
+ for filename in os.listdir(WAV_FOLDER):
21
+ if filename.endswith(".wav"):
22
+ file_path = os.path.join(WAV_FOLDER, filename)
 
 
 
 
 
23
 
24
+ try:
25
+ file_age = current_time - os.path.getmtime(file_path)
26
+
27
+ if file_age > DELETE_AFTER_SECONDS:
28
+ os.remove(file_path)
29
+ print(f"[CLEANER] Deleted (older than 1 hr): {file_path}")
30
+
31
+ except Exception as e:
32
+ print(f"[CLEANER] Error deleting {file_path}: {e}")
33
+
34
+ def background_cleaner():
35
+ """Runs every 1 minute."""
36
+ while True:
37
+ delete_wav_files()
38
+ time.sleep(60)
39
+
40
+
41
+ def load_app():
42
+ # Start background cleaner only once
43
+ if "bg_started" not in st.session_state:
44
+ thread = threading.Thread(target=background_cleaner, daemon=True)
45
+ thread.start()
46
+ st.session_state.bg_started = True
47
+ print("[CLEANER] Background WAV cleaner started.")
48
+
49
+
50
+ # ------------------- STREAMLIT APP -------------------
51
+
52
+ st.set_page_config(page_title="AI Story Generator", page_icon="📚", layout="centered")
53
+
54
+ st.title("📚 AI Story Generator")
55
+ st.write("Enter a story plot and let AI turn it into a full story!")
56
+
57
+ # 🔽 Language dropdown
58
+ language = st.selectbox(
59
+ "Select language for audio:",
60
+ [
61
+ ("English", "en"),
62
+ ("Hindi", "hi"),
63
+ ("Tamil", "ta"),
64
+ ("Telugu", "te"),
65
+ ("Bengali", "bn"),
66
+ ("Gujarati", "gu"),
67
+ ("Kannada", "kn"),
68
+ ("Malayalam", "ml")
69
+ ],
70
+ format_func=lambda x: x[0]
71
+ )
72
+
73
+ plot = st.text_area("Enter your story plot:", height=150)
74
+
75
+ display_story=st.checkbox(label="Display Story")
76
+
77
+ generate = st.button("Generate Story")
78
+
79
+ if generate:
80
+ if not plot.strip():
81
+ st.warning("Please enter a story plot.")
82
+ else:
83
+ with st.spinner("Generating story... please wait ⏳"):
84
+
85
+ # Pass language to your story generator
86
+ response = generate_story(story_plot=plot, language=language)
87
+
88
+ story = response.get('story')
89
+ fileName = response.get('fileName')
90
+
91
+ st.subheader("✨ Generated Story")
92
+
93
+ f = Path(fileName)
94
+ audio_bytes = f.read_bytes()
95
+ st.audio(audio_bytes, format="audio/wav")
96
+
97
+ if display_story:
98
+ st.write(story)
login.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from hashlib import sha256
3
+ from app import load_app
4
+ import os
5
+ import json
6
+ from dotenv import load_dotenv
7
+
8
+ load_dotenv()
9
+
10
+ # -----------------------
11
+ # Mock user database (replace with DB in production)
12
+ # -----------------------
13
+
14
+ USER_CONFIG = json.loads(os.getenv('USER_CONFIG'))
15
+
16
+ print("********************************************")
17
+ print(type(USER_CONFIG))
18
+ print(USER_CONFIG)
19
+ # -----------------------
20
+ # Authentication Utilities
21
+ # -----------------------
22
+ def hash_password(password: str) -> str:
23
+ return sha256(password.encode()).hexdigest()
24
+
25
+ def is_authenticated(username: str, password: str) -> bool:
26
+ if username in USER_CONFIG:
27
+ return USER_CONFIG[username] == password
28
+ return False
29
+
30
+ def login_page():
31
+ st.markdown(
32
+ """
33
+ <h2 style="text-align:center;margin-bottom:30px;">🔐 Secure Login</h2>
34
+ """,
35
+ unsafe_allow_html=True,
36
+ )
37
+
38
+ with st.form("login_form"):
39
+ username = st.text_input("Username", placeholder="Enter username")
40
+ password = st.text_input("Password", type="password", placeholder="Enter password")
41
+ submit = st.form_submit_button("Login")
42
+
43
+ if submit:
44
+ if is_authenticated(username, password):
45
+ st.session_state["auth"] = True
46
+ st.session_state["user"] = username
47
+ st.success("Login successful! Redirecting...")
48
+ st.rerun()
49
+ else:
50
+ st.error("Invalid username or password")
51
+
52
+
53
+ def logout_button():
54
+ # --- TOP CENTER WARNING ---
55
+ st.markdown(
56
+ """
57
+ <div style="text-align:center; margin-top:-20px;">
58
+ <p style="color:#5cb85c; font-size:20px; font-weight:bold;">
59
+ Logged in as: <span style="color:black;">{}</span>
60
+ </p>
61
+ </div>
62
+ """.format(st.session_state['user']),
63
+ unsafe_allow_html=True
64
+ )
65
+
66
+ # --- TOP RIGHT LOGOUT BUTTON ---
67
+ logout_col = st.columns([8, 2]) # Push button to the right
68
+ with logout_col[1]:
69
+ if st.button("Logout", key="logout_btn"):
70
+ st.session_state["auth"] = False
71
+ st.session_state["user"] = None
72
+ st.rerun()
73
+
74
+
75
+ # -----------------------
76
+ # Main App (Protected)
77
+ # -----------------------
78
+ def main_app():
79
+ logout_button()
80
+ load_app()
81
+
82
+
83
+ # -----------------------
84
+ # Streamlit Entry Point
85
+ # -----------------------
86
+ def main():
87
+ # Initialize session state
88
+ if "auth" not in st.session_state:
89
+ st.session_state["auth"] = False
90
+ st.session_state["user"] = None
91
+
92
+ # Render login or app
93
+ if not st.session_state["auth"]:
94
+ login_page()
95
+ else:
96
+ main_app()
97
+
98
+
99
+ if __name__ == "__main__":
100
+ main()
main.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ def main():
2
+ print("Hello from story-app!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
src/story_gen.py CHANGED
@@ -20,7 +20,8 @@ chat = ChatGroq(
20
 
21
 
22
  sys_prompt="""
23
- You are a professional story writer who creates engaging, vivid, emotionally rich stories based on a user's plot or idea.
 
24
 
25
  Your goal:
26
  - Expand the user's plot into a complete story.
@@ -52,6 +53,9 @@ Your output:
52
 
53
  When ready, ask the user:
54
  “Please share your plot or idea for the story.”
 
 
 
55
  """
56
 
57
  simple_prompt="""
@@ -63,15 +67,17 @@ Write the story in STYLE style with:
63
  """
64
 
65
 
66
- def generate_story(story_plot):
67
  messages=[
68
- SystemMessage(content=sys_prompt),
69
  HumanMessage(content=story_plot)
70
  ]
71
  response = chat.invoke(messages)
72
  fileName=f"file_gtt_{uuid.uuid4().hex}.wav"
73
 
74
- tts = gTTS(text=response.content, lang='en')
 
 
75
  tts.save(fileName)
76
 
77
  return {
@@ -80,5 +86,5 @@ def generate_story(story_plot):
80
  }
81
 
82
 
83
- # res=generate_story("write a story on taling lion and river")
84
  # print(res.get('story'))
 
20
 
21
 
22
  sys_prompt="""
23
+ You are a professional story writer who creates engaging, vivid, emotionally rich stories
24
+ based on a user's plot or idea.
25
 
26
  Your goal:
27
  - Expand the user's plot into a complete story.
 
53
 
54
  When ready, ask the user:
55
  “Please share your plot or idea for the story.”
56
+
57
+ Note: Write the story on LANGUAGE only and this story will be given to gtts using LANG for audio
58
+ generation so consider this while creating story
59
  """
60
 
61
  simple_prompt="""
 
67
  """
68
 
69
 
70
+ def generate_story(story_plot,language):
71
  messages=[
72
+ SystemMessage(content=sys_prompt.replace("LANGUAGE",language[0]).replace('LANG',language[1])),
73
  HumanMessage(content=story_plot)
74
  ]
75
  response = chat.invoke(messages)
76
  fileName=f"file_gtt_{uuid.uuid4().hex}.wav"
77
 
78
+
79
+
80
+ tts = gTTS(text=response.content, lang=language[1])
81
  tts.save(fileName)
82
 
83
  return {
 
86
  }
87
 
88
 
89
+ # res=generate_story(story_plot="write a story on lion and river",language="assamese")
90
  # print(res.get('story'))