Ethscriptions commited on
Commit
67ed9d6
·
verified ·
1 Parent(s): 707779e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -39
app.py CHANGED
@@ -119,7 +119,6 @@ def fetch_and_process_server_movies(priority_movie_titles=None):
119
  }
120
 
121
  # 4. Prepare data for the two display views
122
- # For View by Hall
123
  by_hall = defaultdict(list)
124
  for content_name, details in movie_details.items():
125
  for hall_name in details['halls']:
@@ -131,7 +130,6 @@ def fetch_and_process_server_movies(priority_movie_titles=None):
131
  item['details']['assert_name'] or item['content_name']
132
  ))
133
 
134
- # For View by Movie
135
  view2_list = []
136
  for content_name, details in movie_details.items():
137
  if details.get('assert_name'):
@@ -161,24 +159,46 @@ def get_circled_number(hall_name):
161
 
162
 
163
  def format_play_time(time_str):
164
- """Converts HH:MM:SS to total minutes (integer)."""
165
- if not time_str or not isinstance(time_str, str):
166
- return None
167
  try:
168
- parts = time_str.split(':')
169
- hours = int(parts[0])
170
  minutes = int(parts[1])
171
  return hours * 60 + minutes
172
  except (ValueError, IndexError):
173
  return None
174
 
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  # --- Streamlit Main UI ---
177
  st.title('影城排片效率与内容分析工具')
178
  st.write("上传 `影片映出日累计报表.xlsx` 进行效率分析,或点击下方按钮查询 TMS 服务器影片内容。")
179
 
180
  uploaded_file = st.file_uploader("请在此处上传 Excel 文件", type=['xlsx', 'xls', 'csv'])
181
- full_day_analysis = pd.DataFrame()
182
 
183
  if uploaded_file is not None:
184
  try:
@@ -197,23 +217,40 @@ if uploaded_file is not None:
197
  '座次比': '{:.2%}', '场次比': '{:.2%}', '票房比': '{:.2%}', '座次效率': '{:.2f}',
198
  '场次效率': '{:.2f}'}
199
 
200
- st.markdown("### 全天排片效率分析")
201
  full_day_analysis = process_and_analyze_data(df.copy())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  if not full_day_analysis.empty:
203
- table_height = (len(full_day_analysis) + 1) * 35 + 3
204
  st.dataframe(
205
- full_day_analysis.style.format(format_config).apply(style_efficiency, axis=1).hide(axis="index"),
206
- height=table_height, use_container_width=True, hide_index = True)
207
 
208
  st.markdown("#### 黄金时段排片效率分析 (14:00-21:00)")
209
- start_time, end_time = pd.to_datetime('14:00:00').time(), pd.to_datetime('21:00:00').time()
210
- prime_time_df = df[df['放映时间'].between(start_time, end_time)]
211
- prime_time_analysis = process_and_analyze_data(prime_time_df.copy())
212
  if not prime_time_analysis.empty:
213
- table_height_prime = (len(prime_time_analysis) + 1) * 35 + 3
214
  st.dataframe(
215
- prime_time_analysis.style.format(format_config).apply(style_efficiency, axis=1).hide(axis="index"),
216
- height=table_height_prime, use_container_width=True, hide_index = True)
217
 
218
  if not full_day_analysis.empty:
219
  st.markdown("##### 复制当日排片列表")
@@ -224,42 +261,33 @@ if uploaded_file is not None:
224
  except Exception as e:
225
  st.error(f"处理文件时出错: {e}")
226
 
227
-
228
  st.markdown("### TMS 服务器影片内容查询")
229
  if st.button('点击查询 TMS 服务器'):
230
  with st.spinner("正在从 TMS 服务器获取数据中..."):
231
  try:
232
- priority_titles = full_day_analysis['影片'].tolist() if not full_day_analysis.empty else []
233
- halls_data, movie_list_sorted = fetch_and_process_server_movies(priority_titles)
234
  st.toast("TMS 服务器数据获取成功!", icon="🎉")
235
 
236
- # --- View by Movie (Table Format) ---
237
  st.markdown("#### 按影片查看所在影厅")
238
-
239
- view2_data = [{
240
- '影片名称': item['assert_name'],
241
- '所在影厅': " ".join(sorted([get_circled_number(h) for h in item['halls']])),
242
- '文件名': item['content_name'],
243
- '时长': format_play_time(item['play_time'])
244
- } for item in movie_list_sorted]
245
  df_view2 = pd.DataFrame(view2_data)
246
  st.dataframe(df_view2, hide_index=True, use_container_width=True)
247
 
248
- # --- View by Hall (Table Format) ---
249
  st.markdown("#### 按影厅查看影片内容")
250
  hall_tabs = st.tabs(halls_data.keys())
251
  for tab, hall_name in zip(hall_tabs, halls_data.keys()):
252
  with tab:
253
- view1_data_for_tab = [{
254
- '影片名称': item['details']['assert_name'],
255
- '所在影厅': " ".join(sorted([get_circled_number(h) for h in item['details']['halls']])),
256
- '文件名': item['content_name'],
257
- '时长': format_play_time(item['details']['play_time'])
258
- } for item in halls_data[hall_name]]
259
  df_view1_tab = pd.DataFrame(view1_data_for_tab)
260
  st.dataframe(df_view1_tab, hide_index=True, use_container_width=True)
261
 
262
  except Exception as e:
263
- st.error(f"查询服务器时出错: {e}")
264
-
265
-
 
119
  }
120
 
121
  # 4. Prepare data for the two display views
 
122
  by_hall = defaultdict(list)
123
  for content_name, details in movie_details.items():
124
  for hall_name in details['halls']:
 
130
  item['details']['assert_name'] or item['content_name']
131
  ))
132
 
 
133
  view2_list = []
134
  for content_name, details in movie_details.items():
135
  if details.get('assert_name'):
 
159
 
160
 
161
  def format_play_time(time_str):
162
+ if not time_str or not isinstance(time_str, str): return None
 
 
163
  try:
164
+ parts = time_str.split(':');
165
+ hours = int(parts[0]);
166
  minutes = int(parts[1])
167
  return hours * 60 + minutes
168
  except (ValueError, IndexError):
169
  return None
170
 
171
 
172
+ # --- UPDATED Helper function to add TMS location column ---
173
+ def add_tms_locations_to_analysis(analysis_df, tms_movie_list):
174
+ locations = []
175
+ for index, row in analysis_df.iterrows():
176
+ movie_title = row['影片']
177
+ found_versions = []
178
+ for tms_movie in tms_movie_list:
179
+ # FIX 3: Change matching from 'in' to 'startswith'
180
+ if tms_movie['assert_name'].startswith(movie_title):
181
+ version_name = tms_movie['assert_name'].replace(movie_title, '').strip()
182
+ circled_halls = " ".join(sorted([get_circled_number(h) for h in tms_movie['halls']]))
183
+
184
+ # FIX 2: Handle empty version name to remove colon
185
+ if version_name:
186
+ found_versions.append(f"{version_name}:{circled_halls}")
187
+ else:
188
+ found_versions.append(circled_halls)
189
+
190
+ locations.append('|'.join(found_versions))
191
+
192
+ analysis_df['影片所在影厅位置'] = locations
193
+ return analysis_df
194
+
195
+
196
  # --- Streamlit Main UI ---
197
  st.title('影城排片效率与内容分析工具')
198
  st.write("上传 `影片映出日累计报表.xlsx` 进行效率分析,或点击下方按钮查询 TMS 服务器影片内容。")
199
 
200
  uploaded_file = st.file_uploader("请在此处上传 Excel 文件", type=['xlsx', 'xls', 'csv'])
201
+ query_tms_for_location = st.checkbox("查询 TMS 找影片所在影厅")
202
 
203
  if uploaded_file is not None:
204
  try:
 
217
  '座次比': '{:.2%}', '场次比': '{:.2%}', '票房比': '{:.2%}', '座次效率': '{:.2f}',
218
  '场次效率': '{:.2f}'}
219
 
 
220
  full_day_analysis = process_and_analyze_data(df.copy())
221
+ prime_time_analysis = process_and_analyze_data(
222
+ df[df['放映时间'].between(pd.to_datetime('14:00:00').time(), pd.to_datetime('21:00:00').time())].copy())
223
+
224
+ if query_tms_for_location:
225
+ with st.spinner("正在关联查询 TMS 服务器..."):
226
+ _, tms_movie_list = fetch_and_process_server_movies()
227
+ full_day_analysis = add_tms_locations_to_analysis(full_day_analysis, tms_movie_list)
228
+ prime_time_analysis = add_tms_locations_to_analysis(prime_time_analysis, tms_movie_list)
229
+
230
+ # FIX 1: Reorder columns
231
+ if '影片所在影厅位置' in full_day_analysis.columns:
232
+ cols_full = full_day_analysis.columns.tolist()
233
+ cols_full.insert(1, cols_full.pop(cols_full.index('影片所在影厅位置')))
234
+ full_day_analysis = full_day_analysis[cols_full]
235
+
236
+ if '影片所在影厅位置' in prime_time_analysis.columns:
237
+ cols_prime = prime_time_analysis.columns.tolist()
238
+ cols_prime.insert(1, cols_prime.pop(cols_prime.index('影片所在影厅位置')))
239
+ prime_time_analysis = prime_time_analysis[cols_prime]
240
+
241
+ st.toast("TMS 影片位置关联成功!", icon="🔗")
242
+
243
+ st.markdown("### 全天排片效率分析")
244
  if not full_day_analysis.empty:
 
245
  st.dataframe(
246
+ full_day_analysis.style.format(format_config),
247
+ use_container_width=True, hide_index=True)
248
 
249
  st.markdown("#### 黄金时段排片效率分析 (14:00-21:00)")
 
 
 
250
  if not prime_time_analysis.empty:
 
251
  st.dataframe(
252
+ prime_time_analysis.style.format(format_config),
253
+ use_container_width=True, hide_index=True)
254
 
255
  if not full_day_analysis.empty:
256
  st.markdown("##### 复制当日排片列表")
 
261
  except Exception as e:
262
  st.error(f"处理文件时出错: {e}")
263
 
264
+ st.divider()
265
  st.markdown("### TMS 服务器影片内容查询")
266
  if st.button('点击查询 TMS 服务器'):
267
  with st.spinner("正在从 TMS 服务器获取数据中..."):
268
  try:
269
+ halls_data, movie_list_sorted = fetch_and_process_server_movies()
 
270
  st.toast("TMS 服务器数据获取成功!", icon="🎉")
271
 
 
272
  st.markdown("#### 按影片查看所在影厅")
273
+ view2_data = [{'影片名称': item['assert_name'],
274
+ '所在影厅': " ".join(sorted([get_circled_number(h) for h in item['halls']])),
275
+ '文件名': item['content_name'], '时长': format_play_time(item['play_time'])} for item in
276
+ movie_list_sorted]
 
 
 
277
  df_view2 = pd.DataFrame(view2_data)
278
  st.dataframe(df_view2, hide_index=True, use_container_width=True)
279
 
 
280
  st.markdown("#### 按影厅查看影片内容")
281
  hall_tabs = st.tabs(halls_data.keys())
282
  for tab, hall_name in zip(hall_tabs, halls_data.keys()):
283
  with tab:
284
+ view1_data_for_tab = [{'影片名称': item['details']['assert_name'], '所在影厅': " ".join(
285
+ sorted([get_circled_number(h) for h in item['details']['halls']])),
286
+ '文件名': item['content_name'],
287
+ '时长': format_play_time(item['details']['play_time'])} for item in
288
+ halls_data[hall_name]]
 
289
  df_view1_tab = pd.DataFrame(view1_data_for_tab)
290
  st.dataframe(df_view1_tab, hide_index=True, use_container_width=True)
291
 
292
  except Exception as e:
293
+ st.error(f"查询服务器时出错: {e}")