hackerbyhobby commited on
Commit
60ee370
·
unverified ·
1 Parent(s): 05a7e7d

patched lang detect bug

Browse files
Files changed (2) hide show
  1. app.py +13 -13
  2. app.py.working_ocr_selection_prepatch +210 -0
app.py CHANGED
@@ -90,13 +90,11 @@ def boost_probabilities(probabilities: dict, text: str):
90
 
91
  def smishing_detector(input_type, text, image):
92
  """
93
- Only use the textbox if input_type == "Text",
94
- otherwise perform OCR on the image if input_type == "Screenshot".
95
  """
96
  if input_type == "Text":
97
  combined_text = text.strip() if text else ""
98
  else:
99
- # input_type == "Screenshot"
100
  combined_text = ""
101
  if image is not None:
102
  combined_text = pytesseract.image_to_string(image, lang="spa+eng").strip()
@@ -110,7 +108,6 @@ def smishing_detector(input_type, text, image):
110
  "urls_found": []
111
  }
112
 
113
- # Zero-shot classification
114
  result = classifier(
115
  sequences=combined_text,
116
  candidate_labels=CANDIDATE_LABELS,
@@ -118,11 +115,18 @@ def smishing_detector(input_type, text, image):
118
  )
119
  original_probs = {k: float(v) for k, v in zip(result["labels"], result["scores"])}
120
 
121
- # Boost logic
122
  boosted = boost_probabilities(original_probs, combined_text)
123
- boosted = {k: float(v) for k, v in boosted.items() if isinstance(v, (int, float))}
124
 
125
- detected_lang = boosted.pop("detected_lang", "en")
 
 
 
 
 
 
 
 
 
126
  final_label = max(boosted, key=boosted.get)
127
  final_confidence = round(boosted[final_label], 3)
128
 
@@ -136,12 +140,8 @@ def smishing_detector(input_type, text, image):
136
  return {
137
  "detected_language": detected_lang,
138
  "text_used_for_classification": combined_text,
139
- "original_probabilities": {
140
- k: round(v, 3) for k, v in original_probs.items()
141
- },
142
- "boosted_probabilities": {
143
- k: round(v, 3) for k, v in boosted.items()
144
- },
145
  "label": final_label,
146
  "confidence": final_confidence,
147
  "smishing_keywords_found": found_smishing,
 
90
 
91
  def smishing_detector(input_type, text, image):
92
  """
93
+ Main detection function combining text (if 'Text') and OCR (if 'Screenshot').
 
94
  """
95
  if input_type == "Text":
96
  combined_text = text.strip() if text else ""
97
  else:
 
98
  combined_text = ""
99
  if image is not None:
100
  combined_text = pytesseract.image_to_string(image, lang="spa+eng").strip()
 
108
  "urls_found": []
109
  }
110
 
 
111
  result = classifier(
112
  sequences=combined_text,
113
  candidate_labels=CANDIDATE_LABELS,
 
115
  )
116
  original_probs = {k: float(v) for k, v in zip(result["labels"], result["scores"])}
117
 
 
118
  boosted = boost_probabilities(original_probs, combined_text)
 
119
 
120
+ # Patched snippet begins
121
+ # 1. Extract language first, preserving it
122
+ detected_lang = boosted.get("detected_lang", "en")
123
+ # 2. Remove it so only numeric keys remain
124
+ boosted.pop("detected_lang", None)
125
+ # 3. Convert numeric values to float
126
+ for k, v in boosted.items():
127
+ boosted[k] = float(v)
128
+ # Patched snippet ends
129
+
130
  final_label = max(boosted, key=boosted.get)
131
  final_confidence = round(boosted[final_label], 3)
132
 
 
140
  return {
141
  "detected_language": detected_lang,
142
  "text_used_for_classification": combined_text,
143
+ "original_probabilities": {k: round(v, 3) for k, v in original_probs.items()},
144
+ "boosted_probabilities": {k: round(v, 3) for k, v in boosted.items()},
 
 
 
 
145
  "label": final_label,
146
  "confidence": final_confidence,
147
  "smishing_keywords_found": found_smishing,
app.py.working_ocr_selection_prepatch ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pytesseract
3
+ from PIL import Image
4
+ from transformers import pipeline
5
+ import re
6
+ from langdetect import detect
7
+ from deep_translator import GoogleTranslator
8
+
9
+ # Translator instance
10
+ translator = GoogleTranslator(source="auto", target="es")
11
+
12
+ # 1. Load separate keywords for SMiShing and Other Scam (assumed in English)
13
+ with open("smishing_keywords.txt", "r", encoding="utf-8") as f:
14
+ SMISHING_KEYWORDS = [line.strip().lower() for line in f if line.strip()]
15
+
16
+ with open("other_scam_keywords.txt", "r", encoding="utf-8") as f:
17
+ OTHER_SCAM_KEYWORDS = [line.strip().lower() for line in f if line.strip()]
18
+
19
+ # 2. Zero-Shot Classification Pipeline
20
+ model_name = "joeddav/xlm-roberta-large-xnli"
21
+ classifier = pipeline("zero-shot-classification", model=model_name)
22
+ CANDIDATE_LABELS = ["SMiShing", "Other Scam", "Legitimate"]
23
+
24
+ def get_keywords_by_language(text: str):
25
+ """
26
+ Detect language using `langdetect` and translate keywords if needed.
27
+ """
28
+ snippet = text[:200]
29
+ try:
30
+ detected_lang = detect(snippet)
31
+ except Exception:
32
+ detected_lang = "en"
33
+
34
+ if detected_lang == "es":
35
+ smishing_in_spanish = [
36
+ translator.translate(kw).lower() for kw in SMISHING_KEYWORDS
37
+ ]
38
+ other_scam_in_spanish = [
39
+ translator.translate(kw).lower() for kw in OTHER_SCAM_KEYWORDS
40
+ ]
41
+ return smishing_in_spanish, other_scam_in_spanish, "es"
42
+ else:
43
+ return SMISHING_KEYWORDS, OTHER_SCAM_KEYWORDS, "en"
44
+
45
+ def boost_probabilities(probabilities: dict, text: str):
46
+ """
47
+ Boost probabilities based on keyword matches and presence of URLs.
48
+ """
49
+ lower_text = text.lower()
50
+ smishing_keywords, other_scam_keywords, detected_lang = get_keywords_by_language(text)
51
+
52
+ smishing_count = sum(1 for kw in smishing_keywords if kw in lower_text)
53
+ other_scam_count = sum(1 for kw in other_scam_keywords if kw in lower_text)
54
+
55
+ smishing_boost = 0.30 * smishing_count
56
+ other_scam_boost = 0.30 * other_scam_count
57
+
58
+ found_urls = re.findall(r"(https?://[^\s]+)", lower_text)
59
+ if found_urls:
60
+ smishing_boost += 0.35
61
+
62
+ p_smishing = probabilities.get("SMiShing", 0.0)
63
+ p_other_scam = probabilities.get("Other Scam", 0.0)
64
+ p_legit = probabilities.get("Legitimate", 1.0)
65
+
66
+ p_smishing += smishing_boost
67
+ p_other_scam += other_scam_boost
68
+ p_legit -= (smishing_boost + other_scam_boost)
69
+
70
+ # Clamp
71
+ p_smishing = max(p_smishing, 0.0)
72
+ p_other_scam = max(p_other_scam, 0.0)
73
+ p_legit = max(p_legit, 0.0)
74
+
75
+ # Re-normalize
76
+ total = p_smishing + p_other_scam + p_legit
77
+ if total > 0:
78
+ p_smishing /= total
79
+ p_other_scam /= total
80
+ p_legit /= total
81
+ else:
82
+ p_smishing, p_other_scam, p_legit = 0.0, 0.0, 1.0
83
+
84
+ return {
85
+ "SMiShing": p_smishing,
86
+ "Other Scam": p_other_scam,
87
+ "Legitimate": p_legit,
88
+ "detected_lang": detected_lang
89
+ }
90
+
91
+ def smishing_detector(input_type, text, image):
92
+ """
93
+ Only use the textbox if input_type == "Text",
94
+ otherwise perform OCR on the image if input_type == "Screenshot".
95
+ """
96
+ if input_type == "Text":
97
+ combined_text = text.strip() if text else ""
98
+ else:
99
+ # input_type == "Screenshot"
100
+ combined_text = ""
101
+ if image is not None:
102
+ combined_text = pytesseract.image_to_string(image, lang="spa+eng").strip()
103
+
104
+ if not combined_text:
105
+ return {
106
+ "text_used_for_classification": "(none)",
107
+ "label": "No text provided",
108
+ "confidence": 0.0,
109
+ "keywords_found": [],
110
+ "urls_found": []
111
+ }
112
+
113
+ # Zero-shot classification
114
+ result = classifier(
115
+ sequences=combined_text,
116
+ candidate_labels=CANDIDATE_LABELS,
117
+ hypothesis_template="This message is {}."
118
+ )
119
+ original_probs = {k: float(v) for k, v in zip(result["labels"], result["scores"])}
120
+
121
+ # Boost logic
122
+ boosted = boost_probabilities(original_probs, combined_text)
123
+ boosted = {k: float(v) for k, v in boosted.items() if isinstance(v, (int, float))}
124
+
125
+ detected_lang = boosted.pop("detected_lang", "en")
126
+ final_label = max(boosted, key=boosted.get)
127
+ final_confidence = round(boosted[final_label], 3)
128
+
129
+ lower_text = combined_text.lower()
130
+ smishing_keys, scam_keys, _ = get_keywords_by_language(combined_text)
131
+
132
+ found_urls = re.findall(r"(https?://[^\s]+)", lower_text)
133
+ found_smishing = [kw for kw in smishing_keys if kw in lower_text]
134
+ found_other_scam = [kw for kw in scam_keys if kw in lower_text]
135
+
136
+ return {
137
+ "detected_language": detected_lang,
138
+ "text_used_for_classification": combined_text,
139
+ "original_probabilities": {
140
+ k: round(v, 3) for k, v in original_probs.items()
141
+ },
142
+ "boosted_probabilities": {
143
+ k: round(v, 3) for k, v in boosted.items()
144
+ },
145
+ "label": final_label,
146
+ "confidence": final_confidence,
147
+ "smishing_keywords_found": found_smishing,
148
+ "other_scam_keywords_found": found_other_scam,
149
+ "urls_found": found_urls,
150
+ }
151
+
152
+ #
153
+ # Gradio interface with dynamic visibility
154
+ #
155
+ def toggle_inputs(choice):
156
+ """
157
+ Return updates for (text_input, image_input) based on the radio selection.
158
+ """
159
+ if choice == "Text":
160
+ # Show text input, hide image
161
+ return gr.update(visible=True), gr.update(visible=False)
162
+ else:
163
+ # choice == "Screenshot"
164
+ # Hide text input, show image
165
+ return gr.update(visible=False), gr.update(visible=True)
166
+
167
+ with gr.Blocks() as demo:
168
+ gr.Markdown("## SMiShing & Scam Detector (Choose Text or Screenshot)")
169
+
170
+ with gr.Row():
171
+ input_type = gr.Radio(
172
+ choices=["Text", "Screenshot"],
173
+ value="Text",
174
+ label="Choose Input Type"
175
+ )
176
+
177
+ text_input = gr.Textbox(
178
+ lines=3,
179
+ label="Paste Suspicious SMS Text",
180
+ placeholder="Type or paste the message here...",
181
+ visible=True # default
182
+ )
183
+
184
+ image_input = gr.Image(
185
+ type="pil",
186
+ label="Upload Screenshot",
187
+ visible=False # hidden by default
188
+ )
189
+
190
+ # Whenever input_type changes, toggle which input is visible
191
+ input_type.change(
192
+ fn=toggle_inputs,
193
+ inputs=input_type,
194
+ outputs=[text_input, image_input],
195
+ queue=False
196
+ )
197
+
198
+ # Button to run classification
199
+ analyze_btn = gr.Button("Classify")
200
+ output_json = gr.JSON(label="Result")
201
+
202
+ # On button click, call the smishing_detector
203
+ analyze_btn.click(
204
+ fn=smishing_detector,
205
+ inputs=[input_type, text_input, image_input],
206
+ outputs=output_json
207
+ )
208
+
209
+ if __name__ == "__main__":
210
+ demo.launch()