Spaces:
Sleeping
Sleeping
File size: 6,945 Bytes
c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c 98dd4d1 78c326c c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 c8c0b31 98dd4d1 6c08b31 98dd4d1 c92bdd2 c556d1c 98dd4d1 | 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 | import streamlit as st
import googleapiclient.discovery
import google.generativeai as genai
from datetime import datetime, timedelta
# Configure page
st.set_page_config(
page_title="YouTube Content Strategist",
page_icon="π",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS
st.markdown("""
<style>
.header { font-size: 2.5em !important; color: #FF4B4B !important; margin-bottom: 30px !important; }
.sidebar .sidebar-content { background-color: #F0F2F6; }
.stProgress > div > div > div > div { background-color: #FF4B4B; }
.day-card { padding: 20px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); margin-bottom: 20px; background-color: white; }
body { background-size: cover; background-position: center; background-repeat: no-repeat; background-attachment: fixed; }
.main > div { background-color: rgba(255, 255, 255, 0.9); padding: 20px; border-radius: 10px; }
</style>
""", unsafe_allow_html=True)
# Session state for content plan
if 'content_plan' not in st.session_state:
st.session_state.content_plan = None
# Sidebar configuration
with st.sidebar:
st.header("Configuration βοΈ")
YOUTUBE_API_KEY = st.text_input("YouTube API Key", type="password")
GEMINI_API_KEY = st.text_input("Gemini API Key", type="password")
MAX_VIDEOS = st.slider("Max Videos to Analyze", 1, 20, 10)
COMMENTS_PER_VIDEO = st.slider("Comments per Video", 10, 100, 50)
# Main content
st.markdown('<div class="header">π₯ YouTube Content Strategist</div>', unsafe_allow_html=True)
st.write("Generate data-driven content plans using YouTube audience insights.")
# Helper functions
def get_actual_channel_id(youtube, channel_url):
"""Extract real channel ID from a handle (@username) or custom URL."""
if "@" in channel_url:
username = channel_url.split("@")[-1]
request = youtube.channels().list(part="id", forHandle=username)
elif "channel/" in channel_url:
return channel_url.split("channel/")[-1]
else:
return None
response = request.execute()
if "items" in response and response["items"]:
return response["items"][0]["id"]
return None
def get_channel_videos(youtube, channel_id):
"""Fetch recent video IDs from the channel."""
request = youtube.search().list(
part="id",
channelId=channel_id,
maxResults=min(MAX_VIDEOS, 50), # Ensure within API limit
order="date",
type="video"
)
response = request.execute()
return [item['id']['videoId'] for item in response.get("items", [])]
def get_video_comments(youtube, video_id):
"""Fetch comments from a video."""
request = youtube.commentThreads().list(
part="snippet",
videoId=video_id,
maxResults=min(COMMENTS_PER_VIDEO, 100), # Ensure within API limit
textFormat="plainText"
)
response = request.execute()
return [item['snippet']['topLevelComment']['snippet']['textDisplay'] for item in response.get("items", [])]
def analyze_comments(comments):
"""Analyze comments using Gemini API and generate a content plan."""
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel('gemini-1.5-pro')
prompt = f"""
Analyze the following YouTube comments and generate a 10-day content plan.
Each day should include:
1. Content Topic
2. Objective
3. Format
4. Engagement Strategy
5. Success Metrics
Comments:
{comments}
"""
response = model.generate_content(prompt)
return response.text
# Get channel URL
channel_url = st.text_input("Enter YouTube Channel URL:", placeholder="https://www.youtube.com/@ChannelName")
if st.button("Generate Content Plan π"):
if not all([YOUTUBE_API_KEY, GEMINI_API_KEY, channel_url]):
st.error("Please fill all required fields!")
else:
try:
youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
genai.configure(api_key=GEMINI_API_KEY)
with st.spinner("π Analyzing channel..."):
channel_id = get_actual_channel_id(youtube, channel_url)
if not channel_id:
st.error("Invalid channel URL!")
st.stop()
video_ids = get_channel_videos(youtube, channel_id)
all_comments = []
progress_bar = st.progress(0)
for idx, video_id in enumerate(video_ids):
progress = (idx + 1) / len(video_ids)
progress_bar.progress(progress, text=f"π₯ Collecting comments from video {idx+1}/{len(video_ids)}...")
all_comments.extend(get_video_comments(youtube, video_id))
with st.spinner("π§ Analyzing comments and generating plan..."):
content_plan = analyze_comments(all_comments)
st.session_state.content_plan = content_plan
progress_bar.empty()
except Exception as e:
st.error(f"Error: {str(e)}")
# Display results
if st.session_state.content_plan:
st.markdown("## π
10-Day Content Plan")
st.success("Here's your personalized content strategy based on audience insights!")
start_date = datetime.now()
for day in range(10):
current_date = start_date + timedelta(days=day)
with st.expander(f"Day {day+1} - {current_date.strftime('%b %d')}", expanded=True if day == 0 else False):
plan_lines = st.session_state.content_plan.split("\n")
start_index = day * 5
if start_index + 4 < len(plan_lines):
st.markdown(f"""
<div class="day-card">
<h3>{plan_lines[start_index] if start_index < len(plan_lines) else 'No Topic'}</h3>
<p>π― Objective: {plan_lines[start_index+1] if start_index+1 < len(plan_lines) else 'N/A'}</p>
<p>πΉ Format: {plan_lines[start_index+2] if start_index+2 < len(plan_lines) else 'N/A'}</p>
<p>π‘ Engagement Strategy: {plan_lines[start_index+3] if start_index+3 < len(plan_lines) else 'N/A'}</p>
<p>π Success Metrics: {plan_lines[start_index+4] if start_index+4 < len(plan_lines) else 'N/A'}</p>
</div>
""", unsafe_allow_html=True)
st.download_button(
label="π₯ Download Full Plan",
data=st.session_state.content_plan,
file_name=f"content_plan_{datetime.now().strftime('%Y%m%d')}.txt",
mime="text/plain"
)
with st.expander("βΉοΈ How to use this tool"):
st.markdown("""
1. **Get API Keys**:
- YouTube Data API: [Get it here](https://console.cloud.google.com/)
- Gemini API: [Get it here](https://makersuite.google.com/)
2. **Enter Channel URL**:
3. **Adjust Settings**:
4. **Generate Plan**:
5. **Download & Track Results**.
""")
|