Rahul-Sainy commited on
Commit
7ddc816
Β·
verified Β·
1 Parent(s): f7e3885

Upload 2 files

Browse files
pages/πŸŽ₯_Video_Data.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+
3
+ import numpy
4
+ import streamlit as st
5
+ import plotly.express as px
6
+ import plotly.graph_objects as go
7
+ from streamlit_extras.chart_container import chart_container
8
+ from textblob import TextBlob
9
+
10
+ from streamlit_extras.metric_cards import style_metric_cards
11
+ from streamlit_extras.switch_page_button import switch_page
12
+
13
+ from analyze_comments import analyze_comments
14
+ from channelVideoDataExtraction import *
15
+
16
+
17
+ ########################################################################################################################
18
+ # FUNCTIONS
19
+ ########################################################################################################################
20
+ def get_comments():
21
+ comment_data = getVideoComments(api_key, video_id)
22
+ return comment_data
23
+
24
+
25
+ def tag_list(tags):
26
+ tag_list_html = ""
27
+ for tag in tags:
28
+ tag_list_html += f'<span class="tag">{tag}</span>'
29
+ return tag_list_html
30
+
31
+
32
+ def render_insight_card(title, names, emoji="πŸ’‘"):
33
+ card_content = f"""
34
+ ### {emoji} {title}
35
+ {'<br>'.join([f"**{name}**" for name in names])}
36
+ """
37
+ return card_content
38
+
39
+
40
+ ########################################################################################################################
41
+ # PAGE CONFIGURATION
42
+ ########################################################################################################################
43
+ st.set_page_config(page_title="Video Statistics",
44
+ page_icon="πŸ“Š",
45
+ layout="wide")
46
+
47
+ ########################################################################################################################
48
+ # VIDEO STATISTICAL DATA CONFIGURATION
49
+ ########################################################################################################################
50
+ if st.session_state['video_id'] is None:
51
+ st.error("No Video Has been selected to view statistics. Please select a video from the home page.")
52
+ if st.button("Go Home"):
53
+ switch_page("Home")
54
+ else:
55
+ api_key = st.session_state.api_key
56
+ all_video_data = st.session_state.all_video_df
57
+ video_id = st.session_state['video_id']
58
+
59
+ video_row = all_video_data[all_video_data['id'] == video_id]
60
+
61
+ title = video_row['title'].values[0]
62
+ image_url = video_row['thumbnail'].values[0]
63
+ view_count = video_row['view_count'].values[0]
64
+ like_count = video_row['like_count'].values[0]
65
+ favourite_count = video_row['favorite_count'].values[0]
66
+ comment_count = video_row['comment_count'].values[0]
67
+ duration = round(video_row['duration_minutes'].values[0], 2)
68
+ publish_date = video_row['published_date'].values[0]
69
+ tags = video_row['tags'].values[0]
70
+
71
+ # Format view count and subscriber count with commas
72
+ view_count_formatted = "{:,}".format(view_count)
73
+ like_count_formatted = "{:,}".format(like_count)
74
+ comment_count_formatted = "{:,}".format(comment_count)
75
+
76
+ st.subheader(title, divider="green")
77
+
78
+ col1, col2, col3 = st.columns(3)
79
+
80
+ with col1:
81
+ st.image(image_url)
82
+ st.markdown(f"**Published on:** {publish_date}")
83
+
84
+ with col2:
85
+ col2.metric("Total Views", view_count_formatted, "")
86
+ col2.metric("Total Likes", like_count_formatted, "")
87
+ col2.metric("Total Comments", comment_count_formatted, "")
88
+ style_metric_cards(background_color="#000000",
89
+ border_left_color="#049204",
90
+ border_color="#0E0E0E"
91
+ )
92
+
93
+ with col3:
94
+ # Define the CSS style for the tags
95
+ css = """
96
+ <style>
97
+ .tag {
98
+ background-color: #4CAF50; /* Change the background color to green */
99
+ color: white;
100
+ padding: 4px 8px;
101
+ margin-right: 8px;
102
+ border-radius: 4px;
103
+ font-weight: bold;
104
+ display: inline-block; /* Prevent overlapping */
105
+ margin-bottom: 8px; /* Add some vertical spacing */
106
+ }
107
+ </style>
108
+ """
109
+
110
+ st.subheader("Video Tags")
111
+ # Display the tags
112
+ st.markdown(css, unsafe_allow_html=True)
113
+ st.markdown(tag_list(tags), unsafe_allow_html=True)
114
+
115
+ st.subheader("Duration")
116
+ st.markdown(f''':green[{duration}] Minutes''')
117
+
118
+ ########################################################################################################################
119
+ # COMMENT DATA CONFIGURATIONS
120
+ ########################################################################################################################
121
+
122
+ st.subheader("Top 10 Comments", divider="green")
123
+
124
+ with st.spinner("Getting Comment Data...."):
125
+ comment_data = get_comments()
126
+ top_10_comments_df = comment_data.head(10)
127
+ st.table(top_10_comments_df)
128
+
129
+ st.subheader("All Commenters List", divider="green")
130
+ unique_commenters = comment_data['author'].unique()
131
+ st.markdown(f'''Total Number of Commenters: :green[{len(unique_commenters)}]''')
132
+ with st.expander("Click to see all commenters"):
133
+ commenters_text = "\n".join(unique_commenters)
134
+ st.text_area("List of Commenters", commenters_text, height=200)
135
+
136
+ ########################################################################################################################
137
+ # COMMENT TRENDS AND SENTIMENT ANALYSIS
138
+ ########################################################################################################################
139
+
140
+ st.subheader("Comment Trends Over Time & Sentiment Analysis", divider="green")
141
+ col1, col2 = st.columns(2)
142
+
143
+ with col1:
144
+ comment_data['comment_date'] = pd.to_datetime(comment_data['comment_date'])
145
+ comment_data_grouped = comment_data.groupby(comment_data['comment_date'].dt.date).agg(
146
+ {"comment_id": "count", "like_count": "sum"}).reset_index()
147
+
148
+ fig = go.Figure()
149
+
150
+ # Add traces for comments and likes
151
+ fig.add_trace(go.Scatter(x=comment_data_grouped['comment_date'],
152
+ y=comment_data_grouped['comment_id'],
153
+ mode='lines+markers',
154
+ name='Number of Comments',
155
+ line=dict(color='blue')))
156
+ fig.add_trace(go.Scatter(x=comment_data_grouped['comment_date'],
157
+ y=comment_data_grouped['like_count'],
158
+ mode='lines+markers',
159
+ name='Like Count',
160
+ line=dict(color='orange')))
161
+
162
+ # Update layout for better appearance
163
+ fig.update_layout(title='Comment and Like Trends Over Time',
164
+ xaxis_title='Date',
165
+ yaxis_title='Count',
166
+ template="plotly_dark")
167
+
168
+ st.plotly_chart(fig, use_container_width=True)
169
+
170
+ with col2:
171
+ def get_sentiment(text):
172
+ analysis = TextBlob(text)
173
+ # Classify the polarity of the text
174
+ if analysis.sentiment.polarity > 0:
175
+ return 'Positive'
176
+ elif analysis.sentiment.polarity == 0:
177
+ return 'Neutral'
178
+ else:
179
+ return 'Negative'
180
+
181
+
182
+ comment_data['Sentiment'] = comment_data['comment_text'].apply(get_sentiment)
183
+ sentiment_counts = comment_data['Sentiment'].value_counts()
184
+
185
+ with chart_container(comment_data):
186
+ fig = go.Figure(go.Pie(
187
+ labels=sentiment_counts.index,
188
+ values=sentiment_counts.values,
189
+ hole=0.3
190
+ ))
191
+
192
+ fig.update_layout(title_text="Sentiment Analysis of Comments")
193
+ st.plotly_chart(fig, use_container_width=True)
194
+
195
+ ########################################################################################################################
196
+ # COMMENT NETWORK ANALYSIS
197
+ ########################################################################################################################
198
+ with st.spinner("Applying Network Analysis to Comments"):
199
+ # Analyze the comments and display the results
200
+ st.title("Comments Network Analysis & Community Detection")
201
+
202
+ centrality_df, fig_subgraph, fig_communities, no_of_communities = analyze_comments(comment_data)
203
+
204
+ # Display the centrality measures within an expander
205
+ with st.expander("Top 10 Comment Author Centrality Measures"):
206
+ st.table(centrality_df.head(10))
207
+
208
+ st.subheader("πŸ“Š Network Insights")
209
+
210
+ # Arrange cards in columns
211
+ col1, col2 = st.columns(2)
212
+
213
+ with col1:
214
+ st.markdown(render_insight_card("Top Influencers",
215
+ centrality_df.nlargest(5, 'Degree Centrality')['Author'].tolist(), "🌟"),
216
+ unsafe_allow_html=True)
217
+ st.markdown(render_insight_card("Most Active Responders",
218
+ centrality_df.nlargest(5, 'Out-Degree Centrality')['Author'].tolist(), "πŸ’¬"),
219
+ unsafe_allow_html=True)
220
+
221
+ with col2:
222
+ st.markdown(render_insight_card("Key Information Spreaders",
223
+ centrality_df.nlargest(5, 'Betweenness Centrality')['Author'].tolist(),
224
+ "🌐"), unsafe_allow_html=True)
225
+ st.markdown(render_insight_card("Most Responded-To Authors",
226
+ centrality_df.nlargest(5, 'In-Degree Centrality')['Author'].tolist(), "🎯"),
227
+ unsafe_allow_html=True)
228
+
229
+ st.markdown("---") # Divider
230
+
231
+ # Graphical Insights
232
+ col1, col2 = st.columns(2)
233
+
234
+ with col1:
235
+ # Display the subgraph visualization with a brief title/description
236
+ st.subheader("πŸ”— Sub Network Visualization")
237
+ st.caption("Top 50 Authors based on Degree Centrality")
238
+ st.pyplot(fig_subgraph)
239
+
240
+ with col2:
241
+ # Display the communities visualization with a brief title/description
242
+ st.subheader("πŸ‘₯ Community Visualization")
243
+ st.caption(f"Communities in Sample of 500 Nodes: {no_of_communities} detected")
244
+ st.pyplot(fig_communities)
pages/πŸ“…_Post_Scheduler.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from datetime import datetime, timedelta
4
+
5
+
6
+ ########################################################################################################################
7
+ # FUNCTIONS
8
+ ########################################################################################################################
9
+ # Function to suggest the next publishing date
10
+ def suggest_next_publish_date(video_data):
11
+ video_data['published_date'] = pd.to_datetime(video_data['published_date'])
12
+ df_sorted = video_data.sort_values(by='published_date', ascending=False)
13
+ average_diff = (df_sorted['published_date'] - df_sorted['published_date'].shift(-1)).mean()
14
+ return df_sorted['published_date'].iloc[0] + average_diff
15
+
16
+
17
+ ########################################################################################################################
18
+ # SCHEDULED POST DB CONFIG
19
+ ########################################################################################################################
20
+ # Excel filepath
21
+ EXCEL_DB = 'scheduled_posts.xlsx'
22
+
23
+ # Try to read the Excel file, if it doesn't exist, create a new DataFrame
24
+ try:
25
+ df = pd.read_excel(EXCEL_DB)
26
+ except FileNotFoundError:
27
+ columns = ["title", "description", "date", "time"]
28
+ df = pd.DataFrame(columns=columns)
29
+ df.to_excel(EXCEL_DB, index=False) # Create the Excel file with the columns
30
+
31
+ ########################################################################################################################
32
+ # PAGE CONFIGURATION
33
+ ########################################################################################################################
34
+ st.set_page_config(page_title="Content Publishing Calender",
35
+ page_icon="πŸ“Š",
36
+ layout="wide")
37
+
38
+ # Load video data
39
+ video_data = pd.read_excel('all_video_Data.xlsx') # Replace with your video data file path
40
+
41
+ # Get the suggested date
42
+ suggested_date = suggest_next_publish_date(video_data)
43
+
44
+ ########################################################################################################################
45
+ # PAGE CONTENT CONFIGURATION
46
+ ########################################################################################################################
47
+ # Display the suggested date with enhanced styling
48
+ st.markdown(f"""
49
+ <style>
50
+ .suggested-date {{
51
+ background-color: #4CAF50;
52
+ color: white;
53
+ padding: 10px 20px;
54
+ border-radius: 10px;
55
+ font-size: 20px;
56
+ text-align: center;
57
+ }}
58
+ </style>
59
+ <div class="suggested-date">Suggested next publishing date: {suggested_date.strftime('%Y-%m-%d %H:%M:%S')}</div>
60
+ """, unsafe_allow_html=True)
61
+
62
+ # Input fields
63
+ video_title = st.text_input("Video Title")
64
+ video_description = st.text_area("Video Description")
65
+ schedule_date = st.date_input("Schedule Date", suggested_date.date()) # Default to the suggested date
66
+ schedule_time = st.time_input("Schedule Time")
67
+
68
+ if st.button("Schedule Video"):
69
+ # Append to DataFrame and save back to Excel
70
+ df = df.append({
71
+ "title": video_title,
72
+ "description": video_description,
73
+ "date": schedule_date,
74
+ "time": schedule_time
75
+ }, ignore_index=True)
76
+ df.to_excel(EXCEL_DB, index=False)
77
+ st.success("Video scheduled!")
78
+
79
+ # Display scheduled posts
80
+ st.subheader("Scheduled Videos")
81
+ st.table(df)