boompack commited on
Commit
1d5717d
·
verified ·
1 Parent(s): ed0485e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -26
app.py CHANGED
@@ -1,15 +1,30 @@
1
  import gradio as gr
2
  import re
 
3
  import logging
4
  from typing import Tuple, Optional
 
 
5
 
6
  logging.basicConfig(level=logging.INFO)
7
  logger = logging.getLogger(__name__)
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  def extract_comment_data(comment_text: str) -> Tuple[Optional[str], Optional[str], int, int]:
10
  """Извлекает данные из комментария"""
11
  try:
12
- # Пропускаем информацию о посте
13
  if 'отметок "Нравится"' in comment_text:
14
  return None, None, 0, 0
15
 
@@ -26,7 +41,6 @@ def extract_comment_data(comment_text: str) -> Tuple[Optional[str], Optional[str
26
  for i, line in enumerate(lines):
27
  if username in line and i + 1 < len(lines):
28
  comment = lines[i + 1].strip()
29
- # Очищаем комментарий
30
  comment = re.sub(r'\d+\s*(?:ч\.|нед\.)\s*$', '', comment)
31
  comment = re.sub(r'"Нравится":\s*\d+\s*Ответить\s*$', '', comment)
32
  break
@@ -45,69 +59,162 @@ def extract_comment_data(comment_text: str) -> Tuple[Optional[str], Optional[str
45
  logger.error(f"Error extracting data: {e}")
46
  return None, None, 0, 0
47
 
 
48
  def analyze_post(content_type: str, link: str, post_likes: int,
49
  post_date: str, description: str, comment_count: int,
50
  all_comments: str) -> Tuple[str, str, str, str, str]:
51
  """Анализирует пост и комментарии"""
52
  try:
53
- # Разделяем на блоки комментариев
 
 
54
  blocks = re.split(r'(?=Фото профиля)', all_comments)
55
  blocks = [b.strip() for b in blocks if b.strip()]
56
 
57
  comments_data = []
 
 
 
58
 
59
- # Обрабатываем каждый блок
60
  for block in blocks:
61
  username, comment, likes, time = extract_comment_data(block)
62
  if username and comment:
 
 
 
 
63
  comments_data.append({
64
  'username': username,
65
  'comment': comment,
66
  'likes': likes,
67
- 'time': time
 
 
 
68
  })
 
 
 
 
 
69
 
70
- # Формируем выходные данные
71
- usernames = "\n".join(item['username'] for item in comments_data)
72
- comments = "\n".join(item['comment'] for item in comments_data)
73
- likes = "\n".join(str(item['likes']) for item in comments_data)
74
  total_likes = sum(item['likes'] for item in comments_data)
 
 
 
 
 
75
 
76
  analytics = f"""
77
- 📊 Анализ комментариев:
78
- Всего комментариев: {len(comments_data)}
79
- Уникальных пользователей: {len(set(item['username'] for item in comments_data))}
80
- Общее количество лайков: {total_likes}
 
 
 
 
 
 
 
 
 
 
 
81
  """
82
 
83
- return analytics, usernames, comments, likes, str(total_likes)
 
 
 
 
 
 
84
 
85
  except Exception as e:
86
  logger.error(f"Analysis error: {e}")
87
  return str(e), "", "", "", "0"
88
 
89
- # Интерфейс Gradio
90
  iface = gr.Interface(
91
  fn=analyze_post,
92
  inputs=[
93
- gr.Radio(choices=["Photo", "Video"], label="Content Type", value="Photo"),
94
- gr.Textbox(label="Link to Post"),
95
- gr.Number(label="Likes", value=0),
96
- gr.Textbox(label="Post Date"),
97
- gr.Textbox(label="Description", lines=3),
98
- gr.Number(label="Comment Count", value=0),
99
- gr.Textbox(label="Comments", lines=10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  ],
101
  outputs=[
102
- gr.Textbox(label="Analytics Summary", lines=10),
103
  gr.Textbox(label="Usernames"),
104
  gr.Textbox(label="Comments"),
105
  gr.Textbox(label="Likes Chronology"),
106
  gr.Textbox(label="Total Likes on Comments")
107
  ],
108
- title="Instagram Comment Analyzer",
109
- description="Анализатор комментариев Instagram"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  )
111
 
112
  if __name__ == "__main__":
113
- iface.launch()
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import re
3
+ import emoji
4
  import logging
5
  from typing import Tuple, Optional
6
+ from functools import lru_cache
7
+ from collections import Counter
8
 
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
+ def count_emojis(text: str) -> int:
13
+ """Подсчет количества эмодзи в тексте"""
14
+ return len([c for c in text if c in emoji.EMOJI_DATA])
15
+
16
+ def extract_mentions(text: str) -> list:
17
+ """Извлечение упоминаний пользователей"""
18
+ return re.findall(r'@(\w+)', text)
19
+
20
+ def is_spam(text: str) -> bool:
21
+ """Определение спам-комментариев"""
22
+ spam_indicators = ['🔥' * 3, '❤️' * 3, 'follow me', 'check my']
23
+ return any(indicator in text.lower() for indicator in spam_indicators)
24
+
25
  def extract_comment_data(comment_text: str) -> Tuple[Optional[str], Optional[str], int, int]:
26
  """Извлекает данные из комментария"""
27
  try:
 
28
  if 'отметок "Нравится"' in comment_text:
29
  return None, None, 0, 0
30
 
 
41
  for i, line in enumerate(lines):
42
  if username in line and i + 1 < len(lines):
43
  comment = lines[i + 1].strip()
 
44
  comment = re.sub(r'\d+\s*(?:ч\.|нед\.)\s*$', '', comment)
45
  comment = re.sub(r'"Нравится":\s*\d+\s*Ответить\s*$', '', comment)
46
  break
 
59
  logger.error(f"Error extracting data: {e}")
60
  return None, None, 0, 0
61
 
62
+ @lru_cache(maxsize=100)
63
  def analyze_post(content_type: str, link: str, post_likes: int,
64
  post_date: str, description: str, comment_count: int,
65
  all_comments: str) -> Tuple[str, str, str, str, str]:
66
  """Анализирует пост и комментарии"""
67
  try:
68
+ if not all_comments or 'Фото профиля' not in all_comments:
69
+ return "Ошибка: неверный формат данных", "", "", "", "0"
70
+
71
  blocks = re.split(r'(?=Фото профиля)', all_comments)
72
  blocks = [b.strip() for b in blocks if b.strip()]
73
 
74
  comments_data = []
75
+ total_emojis = 0
76
+ mentions = []
77
+ spam_count = 0
78
 
 
79
  for block in blocks:
80
  username, comment, likes, time = extract_comment_data(block)
81
  if username and comment:
82
+ emoji_count = count_emojis(comment)
83
+ comment_mentions = extract_mentions(comment)
84
+ is_spam_comment = is_spam(comment)
85
+
86
  comments_data.append({
87
  'username': username,
88
  'comment': comment,
89
  'likes': likes,
90
+ 'time': time,
91
+ 'emoji_count': emoji_count,
92
+ 'mentions': comment_mentions,
93
+ 'is_spam': is_spam_comment
94
  })
95
+
96
+ total_emojis += emoji_count
97
+ mentions.extend(comment_mentions)
98
+ if is_spam_comment:
99
+ spam_count += 1
100
 
101
+ # Подсчет статистики
102
+ total_comments = len(comments_data)
103
+ unique_users = len(set(item['username'] for item in comments_data))
 
104
  total_likes = sum(item['likes'] for item in comments_data)
105
+ avg_likes = total_likes / total_comments if total_comments > 0 else 0
106
+
107
+ # Топ комментаторы
108
+ commenter_counts = Counter(item['username'] for item in comments_data)
109
+ top_commenters = commenter_counts.most_common(5)
110
 
111
  analytics = f"""
112
+ 📊 Подробный анализ комментариев:
113
+
114
+ Основные метрики:
115
+ Всего комментариев: {total_comments}
116
+ • Уникальных пользователей: {unique_users}
117
+ • Общее количество лайков: {total_likes}
118
+ • Среднее количество лайков: {avg_likes:.1f}
119
+
120
+ Дополнительная информация:
121
+ • Использовано эмодзи: {total_emojis}
122
+ • Количество упоминаний: {len(mentions)}
123
+ • Выявлено спам-комментариев: {spam_count}
124
+
125
+ Топ комментаторы:
126
+ {chr(10).join(f'• {user}: {count} комментария' for user, count in top_commenters if count > 1)}
127
  """
128
 
129
+ return (
130
+ analytics,
131
+ "\n".join(item['username'] for item in comments_data),
132
+ "\n".join(item['comment'] for item in comments_data),
133
+ "\n".join(str(item['likes']) for item in comments_data),
134
+ str(total_likes)
135
+ )
136
 
137
  except Exception as e:
138
  logger.error(f"Analysis error: {e}")
139
  return str(e), "", "", "", "0"
140
 
141
+ # Создаем интерфейс Gradio
142
  iface = gr.Interface(
143
  fn=analyze_post,
144
  inputs=[
145
+ gr.Radio(
146
+ choices=["Photo", "Video"],
147
+ label="Content Type",
148
+ value="Photo"
149
+ ),
150
+ gr.Textbox(
151
+ label="Link to Post",
152
+ placeholder="Вставьте ссылку на пост"
153
+ ),
154
+ gr.Number(
155
+ label="Likes",
156
+ value=0,
157
+ minimum=0
158
+ ),
159
+ gr.Textbox(
160
+ label="Post Date",
161
+ placeholder="YYYY-MM-DD"
162
+ ),
163
+ gr.Textbox(
164
+ label="Description",
165
+ lines=3,
166
+ placeholder="Описание поста"
167
+ ),
168
+ gr.Number(
169
+ label="Comment Count",
170
+ value=0,
171
+ minimum=0
172
+ ),
173
+ gr.Textbox(
174
+ label="Comments",
175
+ lines=10,
176
+ placeholder="Вставьте комментарии"
177
+ )
178
  ],
179
  outputs=[
180
+ gr.Textbox(label="Analytics Summary", lines=15),
181
  gr.Textbox(label="Usernames"),
182
  gr.Textbox(label="Comments"),
183
  gr.Textbox(label="Likes Chronology"),
184
  gr.Textbox(label="Total Likes on Comments")
185
  ],
186
+ title="Enhanced Instagram Comment Analyzer",
187
+ description="""
188
+ Анализатор комментариев Instagram с расширенной аналитикой.
189
+ Возможности:
190
+ • Анализ комментариев и лайков
191
+ • Подсчет эмодзи и упоминаний
192
+ • Определение спам-комментариев
193
+ • Статистика по пользователям
194
+ """,
195
+ theme="default",
196
+ css="""
197
+ .gradio-container {
198
+ font-family: 'Arial', sans-serif;
199
+ }
200
+ .output-text {
201
+ white-space: pre-wrap;
202
+ }
203
+ .analytics-summary {
204
+ background-color: #f5f5f5;
205
+ padding: 15px;
206
+ border-radius: 8px;
207
+ }
208
+ """
209
  )
210
 
211
  if __name__ == "__main__":
212
+ try:
213
+ iface.launch(
214
+ share=True, # Создает публичную ссылку
215
+ debug=True, # Включает режим отладки
216
+ enable_queue=True, # Включает очередь запросов
217
+ show_error=True # Показывает подробности ошибок
218
+ )
219
+ except Exception as e:
220
+ logger.error(f"Error launching interface: {e}", exc_info=True)