Spaces:
Running
Running
Update utils/functions.py
Browse files- utils/functions.py +85 -147
utils/functions.py
CHANGED
@@ -7,10 +7,9 @@ import requests
|
|
7 |
import os
|
8 |
from datetime import datetime
|
9 |
import logging
|
|
|
10 |
|
11 |
-
|
12 |
-
from sqlalchemy.ext.declarative import declarative_base
|
13 |
-
from sqlalchemy.orm import sessionmaker
|
14 |
|
15 |
# Konfiguracja logowania
|
16 |
logging.basicConfig(
|
@@ -19,169 +18,103 @@ logging.basicConfig(
|
|
19 |
format='%(asctime)s %(levelname)s:%(message)s'
|
20 |
)
|
21 |
|
22 |
-
#
|
23 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
Base = declarative_base()
|
29 |
-
|
30 |
-
# Definicje modeli
|
31 |
-
class FakeNumber(Base):
|
32 |
-
__tablename__ = "fake_numbers"
|
33 |
-
id = Column(Integer, primary_key=True, index=True)
|
34 |
-
phone_number = Column(String, unique=True, index=True, nullable=False)
|
35 |
-
reported_at = Column(DateTime, default=datetime.utcnow)
|
36 |
-
|
37 |
-
class AnalysisHistory(Base):
|
38 |
-
__tablename__ = "analysis_history"
|
39 |
-
id = Column(Integer, primary_key=True, index=True)
|
40 |
-
timestamp = Column(DateTime, default=datetime.utcnow)
|
41 |
-
message = Column(String, nullable=False)
|
42 |
-
phone_number = Column(String, nullable=False)
|
43 |
-
analysis = Column(String, nullable=False)
|
44 |
-
risk_assessment = Column(String, nullable=False)
|
45 |
-
recommendations = Column(String, nullable=False)
|
46 |
-
|
47 |
-
class Stats(Base):
|
48 |
-
__tablename__ = "stats"
|
49 |
-
id = Column(Integer, primary_key=True, index=True)
|
50 |
-
total_analyses = Column(Integer, default=0)
|
51 |
-
total_frauds_detected = Column(Integer, default=0)
|
52 |
-
|
53 |
-
# Tworzenie tabel w bazie danych (je艣li jeszcze nie istniej膮)
|
54 |
-
Base.metadata.create_all(bind=engine)
|
55 |
|
56 |
# Funkcje pomocnicze
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
def add_fake_number(phone_number):
|
59 |
"""
|
60 |
-
Dodaje numer telefonu do
|
61 |
"""
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
logging.info(f"Numer {phone_number} zosta艂 pomy艣lnie dodany do bazy danych.")
|
71 |
-
return True
|
72 |
-
else:
|
73 |
-
logging.info(f"Numer {phone_number} ju偶 istnieje w bazie danych.")
|
74 |
-
return False
|
75 |
-
except Exception as e:
|
76 |
-
db.rollback()
|
77 |
-
logging.error(f"Nie uda艂o si臋 zapisa膰 numeru {phone_number}: {e}")
|
78 |
return False
|
79 |
-
finally:
|
80 |
-
db.close()
|
81 |
|
82 |
def is_fake_number(phone_number):
|
83 |
"""
|
84 |
-
Sprawdza, czy dany numer telefonu jest oznaczony jako fa艂szywy w
|
85 |
"""
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
return exists
|
91 |
-
except Exception as e:
|
92 |
-
logging.error(f"Nie uda艂o si臋 sprawdzi膰 numeru {phone_number}: {e}")
|
93 |
-
return False
|
94 |
-
finally:
|
95 |
-
db.close()
|
96 |
|
97 |
def add_to_history(message, phone_number, analysis, risk, recommendations):
|
98 |
"""
|
99 |
-
Dodaje wpis do historii analiz.
|
100 |
"""
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
logging.info(f"Dodano wpis do historii analiz dla numeru {phone_number}.")
|
113 |
-
except Exception as e:
|
114 |
-
db.rollback()
|
115 |
-
logging.error(f"Nie uda艂o si臋 zapisa膰 historii analiz dla numeru {phone_number}: {e}")
|
116 |
-
finally:
|
117 |
-
db.close()
|
118 |
|
119 |
-
def
|
120 |
"""
|
121 |
-
|
122 |
"""
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
if not stats:
|
127 |
-
stats = Stats()
|
128 |
-
db.add(stats)
|
129 |
-
|
130 |
-
stats.total_analyses += 1
|
131 |
-
if fraud_detected:
|
132 |
-
stats.total_frauds_detected += 1
|
133 |
-
|
134 |
-
db.commit()
|
135 |
-
logging.info(f"Statystyki zosta艂y zaktualizowane: Analiz {stats.total_analyses}, Oszustw {stats.total_frauds_detected}.")
|
136 |
-
except Exception as e:
|
137 |
-
db.rollback()
|
138 |
-
logging.error(f"Nie uda艂o si臋 zaktualizowa膰 statystyk: {e}")
|
139 |
-
finally:
|
140 |
-
db.close()
|
141 |
|
142 |
-
def
|
143 |
"""
|
144 |
-
|
145 |
"""
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
else:
|
153 |
-
logging.info("Brak statystyk w bazie danych.")
|
154 |
-
return {"total_analyses": 0, "total_frauds_detected": 0}
|
155 |
-
except Exception as e:
|
156 |
-
logging.error(f"Nie uda艂o si臋 pobra膰 statystyk: {e}")
|
157 |
-
return {"total_analyses": 0, "total_frauds_detected": 0}
|
158 |
-
finally:
|
159 |
-
db.close()
|
160 |
|
161 |
-
def
|
162 |
"""
|
163 |
-
Pobiera
|
164 |
"""
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
history = []
|
169 |
-
for entry in history_entries:
|
170 |
-
history.append({
|
171 |
-
'timestamp': entry.timestamp,
|
172 |
-
'message': entry.message,
|
173 |
-
'phone_number': entry.phone_number,
|
174 |
-
'analysis': entry.analysis,
|
175 |
-
'risk_assessment': entry.risk_assessment,
|
176 |
-
'recommendations': entry.recommendations
|
177 |
-
})
|
178 |
-
logging.info("Historia analiz zosta艂a pobrana pomy艣lnie.")
|
179 |
-
return history
|
180 |
-
except Exception as e:
|
181 |
-
logging.error(f"Nie uda艂o si臋 pobra膰 historii analiz: {e}")
|
182 |
-
return []
|
183 |
-
finally:
|
184 |
-
db.close()
|
185 |
|
186 |
def get_phone_info(phone_number):
|
187 |
"""
|
@@ -189,8 +122,12 @@ def get_phone_info(phone_number):
|
|
189 |
"""
|
190 |
try:
|
191 |
parsed_number = phonenumbers.parse(phone_number, None)
|
192 |
-
country = geocoder.description_for_number(parsed_number, '
|
193 |
-
operator = carrier.name_for_number(parsed_number, '
|
|
|
|
|
|
|
|
|
194 |
logging.info(f"Numer {phone_number} - Kraj: {country}, Operator: {operator}.")
|
195 |
return country, operator
|
196 |
except phonenumbers.NumberParseException as e:
|
@@ -211,11 +148,13 @@ def simple_checks(message, language):
|
|
211 |
|
212 |
selected_keywords = scam_keywords.get(language, scam_keywords['English'])
|
213 |
|
214 |
-
|
|
|
|
|
215 |
warnings.append("Wiadomo艣膰 zawiera s艂owa kluczowe zwi膮zane z potencjalnym oszustwem.")
|
216 |
if re.search(r'http[s]?://', message):
|
217 |
warnings.append("Wiadomo艣膰 zawiera link.")
|
218 |
-
if re.search(r'\b(podaj|prze艣lij|udost臋pnij)\b.*\b(has艂o|kod|dane osobowe|numer konta)\b',
|
219 |
warnings.append("Wiadomo艣膰 zawiera pro艣b臋 o poufne informacje.")
|
220 |
return warnings
|
221 |
|
@@ -227,13 +166,12 @@ def analyze_message(message, phone_number, additional_info, api_key, language):
|
|
227 |
logging.error("Brak klucza API.")
|
228 |
return "Brak klucza API.", "Brak klucza API.", "Brak klucza API."
|
229 |
|
230 |
-
url = "https://api.sambanova.ai/v1/chat/completions"
|
231 |
headers = {
|
232 |
"Authorization": f"Bearer {api_key}",
|
233 |
"Content-Type": "application/json"
|
234 |
}
|
235 |
|
236 |
-
# System prompts w trzech j臋zykach
|
237 |
system_prompts = {
|
238 |
'Polish': """
|
239 |
Jeste艣 zaawansowanym asystentem AI specjalizuj膮cym si臋 w identyfikacji fa艂szywych wiadomo艣ci SMS. Twoim zadaniem jest przeprowadzenie szczeg贸艂owej analizy wiadomo艣ci, wykorzystuj膮c g艂臋boki proces my艣lenia i dostarczaj膮c kompleksow膮 ocen臋. Twoja odpowied藕 powinna by膰 podzielona na trzy sekcje:
|
|
|
7 |
import os
|
8 |
from datetime import datetime
|
9 |
import logging
|
10 |
+
import json
|
11 |
|
12 |
+
import pycountry # Upewnij si臋, 偶e zainstalowa艂e艣 t臋 bibliotek臋: pip install pycountry
|
|
|
|
|
13 |
|
14 |
# Konfiguracja logowania
|
15 |
logging.basicConfig(
|
|
|
18 |
format='%(asctime)s %(levelname)s:%(message)s'
|
19 |
)
|
20 |
|
21 |
+
# Definiowanie 艣cie偶ek do plik贸w JSON
|
22 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
23 |
+
DATA_DIR = os.path.join(BASE_DIR, '..', 'data')
|
24 |
+
FAKE_NUMBERS_FILE = os.path.join(DATA_DIR, 'fake_numbers.json')
|
25 |
+
HISTORY_FILE = os.path.join(DATA_DIR, 'history.json')
|
26 |
+
STATS_FILE = os.path.join(DATA_DIR, 'stats.json')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
# Funkcje pomocnicze
|
29 |
|
30 |
+
def load_json(file_path):
|
31 |
+
"""艁aduje dane z pliku JSON. Je艣li plik nie istnieje, zwraca pust膮 list臋 lub domy艣lny obiekt."""
|
32 |
+
if not os.path.exists(file_path):
|
33 |
+
if file_path.endswith('stats.json'):
|
34 |
+
return {"total_analyses": 0, "total_frauds_detected": 0}
|
35 |
+
else:
|
36 |
+
return []
|
37 |
+
with open(file_path, 'r', encoding='utf-8') as file:
|
38 |
+
try:
|
39 |
+
data = json.load(file)
|
40 |
+
return data
|
41 |
+
except json.JSONDecodeError:
|
42 |
+
logging.error(f"Nie mo偶na za艂adowa膰 danych z {file_path}. Plik jest uszkodzony.")
|
43 |
+
if file_path.endswith('stats.json'):
|
44 |
+
return {"total_analyses": 0, "total_frauds_detected": 0}
|
45 |
+
return []
|
46 |
+
|
47 |
+
def save_json(file_path, data):
|
48 |
+
"""Zapisuje dane do pliku JSON."""
|
49 |
+
with open(file_path, 'w', encoding='utf-8') as file:
|
50 |
+
json.dump(data, file, ensure_ascii=False, indent=4)
|
51 |
+
logging.info(f"Dane zosta艂y zapisane do {file_path}.")
|
52 |
+
|
53 |
def add_fake_number(phone_number):
|
54 |
"""
|
55 |
+
Dodaje numer telefonu do pliku fake_numbers.json jako fa艂szywy, je艣li jeszcze go tam nie ma.
|
56 |
"""
|
57 |
+
fake_numbers = load_json(FAKE_NUMBERS_FILE)
|
58 |
+
if phone_number not in fake_numbers:
|
59 |
+
fake_numbers.append(phone_number)
|
60 |
+
save_json(FAKE_NUMBERS_FILE, fake_numbers)
|
61 |
+
logging.info(f"Numer {phone_number} zosta艂 pomy艣lnie dodany do fake_numbers.json.")
|
62 |
+
return True
|
63 |
+
else:
|
64 |
+
logging.info(f"Numer {phone_number} ju偶 istnieje w fake_numbers.json.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
return False
|
|
|
|
|
66 |
|
67 |
def is_fake_number(phone_number):
|
68 |
"""
|
69 |
+
Sprawdza, czy dany numer telefonu jest oznaczony jako fa艂szywy w pliku fake_numbers.json.
|
70 |
"""
|
71 |
+
fake_numbers = load_json(FAKE_NUMBERS_FILE)
|
72 |
+
exists = phone_number in fake_numbers
|
73 |
+
logging.info(f"Sprawdzanie numeru {phone_number}: {'znaleziony' if exists else 'nie znaleziony'}.")
|
74 |
+
return exists
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
def add_to_history(message, phone_number, analysis, risk, recommendations):
|
77 |
"""
|
78 |
+
Dodaje wpis do historii analiz w pliku history.json.
|
79 |
"""
|
80 |
+
history = load_json(HISTORY_FILE)
|
81 |
+
history.append({
|
82 |
+
"timestamp": datetime.now().isoformat(),
|
83 |
+
"message": message,
|
84 |
+
"phone_number": phone_number,
|
85 |
+
"analysis": analysis,
|
86 |
+
"risk_assessment": risk,
|
87 |
+
"recommendations": recommendations
|
88 |
+
})
|
89 |
+
save_json(HISTORY_FILE, history)
|
90 |
+
logging.info(f"Dodano wpis do history.json dla numeru {phone_number}.")
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
|
92 |
+
def get_history():
|
93 |
"""
|
94 |
+
Pobiera histori臋 analiz z pliku history.json jako list臋 s艂ownik贸w.
|
95 |
"""
|
96 |
+
history = load_json(HISTORY_FILE)
|
97 |
+
logging.info("Historia analiz zosta艂a pobrana pomy艣lnie.")
|
98 |
+
return history
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
def update_stats(fraud_detected=False):
|
101 |
"""
|
102 |
+
Aktualizuje statystyki analiz w pliku stats.json.
|
103 |
"""
|
104 |
+
stats = load_json(STATS_FILE)
|
105 |
+
stats["total_analyses"] += 1
|
106 |
+
if fraud_detected:
|
107 |
+
stats["total_frauds_detected"] += 1
|
108 |
+
save_json(STATS_FILE, stats)
|
109 |
+
logging.info(f"Statystyki zosta艂y zaktualizowane: Analiz {stats['total_analyses']}, Oszustw {stats['total_frauds_detected']}.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
+
def get_stats():
|
112 |
"""
|
113 |
+
Pobiera statystyki analiz z pliku stats.json.
|
114 |
"""
|
115 |
+
stats = load_json(STATS_FILE)
|
116 |
+
logging.info("Statystyki zosta艂y pobrane pomy艣lnie.")
|
117 |
+
return stats
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
def get_phone_info(phone_number):
|
120 |
"""
|
|
|
122 |
"""
|
123 |
try:
|
124 |
parsed_number = phonenumbers.parse(phone_number, None)
|
125 |
+
country = geocoder.description_for_number(parsed_number, 'pl') # Zmiana na 'pl' dla polskiego
|
126 |
+
operator = carrier.name_for_number(parsed_number, 'pl') # Zmiana na 'pl' dla polskiego
|
127 |
+
if not country:
|
128 |
+
country = "Nieznany"
|
129 |
+
if not operator:
|
130 |
+
operator = "Nieznany"
|
131 |
logging.info(f"Numer {phone_number} - Kraj: {country}, Operator: {operator}.")
|
132 |
return country, operator
|
133 |
except phonenumbers.NumberParseException as e:
|
|
|
148 |
|
149 |
selected_keywords = scam_keywords.get(language, scam_keywords['English'])
|
150 |
|
151 |
+
message_lower = message.lower()
|
152 |
+
|
153 |
+
if any(keyword in message_lower for keyword in selected_keywords):
|
154 |
warnings.append("Wiadomo艣膰 zawiera s艂owa kluczowe zwi膮zane z potencjalnym oszustwem.")
|
155 |
if re.search(r'http[s]?://', message):
|
156 |
warnings.append("Wiadomo艣膰 zawiera link.")
|
157 |
+
if re.search(r'\b(podaj|prze艣lij|udost臋pnij|sende|眉bermittle|teile)\b.*\b(has艂o|kod|dane osobowe|numer konta|Passwort|Code|pers枚nliche Daten|Kontonummer)\b', message_lower):
|
158 |
warnings.append("Wiadomo艣膰 zawiera pro艣b臋 o poufne informacje.")
|
159 |
return warnings
|
160 |
|
|
|
166 |
logging.error("Brak klucza API.")
|
167 |
return "Brak klucza API.", "Brak klucza API.", "Brak klucza API."
|
168 |
|
169 |
+
url = "https://api.sambanova.ai/v1/chat/completions" # Upewnij si臋, 偶e to poprawny URL
|
170 |
headers = {
|
171 |
"Authorization": f"Bearer {api_key}",
|
172 |
"Content-Type": "application/json"
|
173 |
}
|
174 |
|
|
|
175 |
system_prompts = {
|
176 |
'Polish': """
|
177 |
Jeste艣 zaawansowanym asystentem AI specjalizuj膮cym si臋 w identyfikacji fa艂szywych wiadomo艣ci SMS. Twoim zadaniem jest przeprowadzenie szczeg贸艂owej analizy wiadomo艣ci, wykorzystuj膮c g艂臋boki proces my艣lenia i dostarczaj膮c kompleksow膮 ocen臋. Twoja odpowied藕 powinna by膰 podzielona na trzy sekcje:
|