rafaldembski commited on
Commit
fa7dec9
verified
1 Parent(s): 58f1198

Update utils/functions.py

Browse files
Files changed (1) hide show
  1. 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
- from sqlalchemy import create_engine, Column, String, Integer, DateTime
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
- # Konfiguracja bazy danych SQLite
23
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
24
- DATABASE_URL = f"sqlite:///{os.path.join(BASE_DIR, '..', 'scam_detector.db')}"
25
-
26
- engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
27
- SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
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 bazy danych jako fa艂szywy, je艣li jeszcze go tam nie ma.
61
  """
62
- db = SessionLocal()
63
- try:
64
- existing_number = db.query(FakeNumber).filter(FakeNumber.phone_number == phone_number).first()
65
- if not existing_number:
66
- new_number = FakeNumber(phone_number=phone_number)
67
- db.add(new_number)
68
- db.commit()
69
- db.refresh(new_number)
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 bazie danych.
85
  """
86
- db = SessionLocal()
87
- try:
88
- exists = db.query(FakeNumber).filter(FakeNumber.phone_number == phone_number).first() is not None
89
- logging.info(f"Sprawdzanie numeru {phone_number}: {'znaleziony' if exists else 'nie znaleziony'}.")
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
- db = SessionLocal()
102
- try:
103
- new_entry = AnalysisHistory(
104
- message=message,
105
- phone_number=phone_number,
106
- analysis=analysis,
107
- risk_assessment=risk,
108
- recommendations=recommendations
109
- )
110
- db.add(new_entry)
111
- db.commit()
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 update_stats(fraud_detected=False):
120
  """
121
- Aktualizuje statystyki analiz w bazie danych.
122
  """
123
- db = SessionLocal()
124
- try:
125
- stats = db.query(Stats).first()
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 get_stats():
143
  """
144
- Pobiera statystyki analiz z bazy danych.
145
  """
146
- db = SessionLocal()
147
- try:
148
- stats = db.query(Stats).first()
149
- if stats:
150
- logging.info("Statystyki zosta艂y pobrane pomy艣lnie.")
151
- return {"total_analyses": stats.total_analyses, "total_frauds_detected": stats.total_frauds_detected}
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 get_history():
162
  """
163
- Pobiera histori臋 analiz z bazy danych jako list臋 s艂ownik贸w.
164
  """
165
- db = SessionLocal()
166
- try:
167
- history_entries = db.query(AnalysisHistory).order_by(AnalysisHistory.timestamp.desc()).all()
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, 'en') # Mo偶esz zmieni膰 j臋zyk na 'pl' lub 'de'
193
- operator = carrier.name_for_number(parsed_number, 'en') # Mo偶esz zmieni膰 j臋zyk na 'pl' lub 'de'
 
 
 
 
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
- if any(keyword in message.lower() for keyword in selected_keywords):
 
 
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', message.lower()):
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: