-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathred_alert.dart
184 lines (154 loc) · 6.1 KB
/
red_alert.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import 'dart:async';
import 'dart:convert';
import 'dart:io' if (dart.library.html) 'dart:html' as html;
import 'dart:math';
// import for non-web platform
import 'package:http/http.dart' as http;
//import for web platform
import 'package:http/browser_client.dart' as httpForWeb;
import 'package:flutter/foundation.dart' show kIsWeb;
import '../common/constants.dart';
import '../common/red_alert_logger.dart';
import '../models/area.dart';
typedef AlarmCallback = Function();
class RedAlert {
late List<Area> selectedAreas;
late String cookies;
late Map<String, String> headers;
late AlarmCallback onAlarmActivated;
late bool isAlarmActive;
late Timer alertCheckTimer;
//todo fix issues with this field
late var _client; //= http.BrowserClient();
RedAlert(this.selectedAreas, {required this.onAlarmActivated}) {
//todo change this according to platform running
if (kIsWeb) {
_client = httpForWeb.BrowserClient();
} else {
_client = http.Client();
}
cookies = "";
isAlarmActive = false;
headers = {
"Host": "www.oref.org.il",
"Connection": "keep-alive",
"Content-Type": "application/json;charset=UTF-8",
"charset": "utf-8",
"X-Requested-With": "XMLHttpRequest",
"sec-ch-ua-mobile": "?0",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"sec-ch-ua-platform": "Windows",
"Accept": "*/*",
"sec-ch-ua":
'"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://www.oref.org.il/12481-he/Pakar.aspx",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
// "Access-Control-Allow-Origin": "*", // Add this line for CORS
// "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
// "Access-Control-Allow-Methods": "GET, HEAD",
// "Cookie": "MUID=192650EE77FE691A3DC8430C766E6814",
};
// Initialize the timer for periodic alert checks
alertCheckTimer = Timer.periodic(const Duration(seconds: 1), (timer) async {
await getCookies();
// Check for new alerts
final alertsData = await getRedAlerts();
if (alertsData != null) {
final alertCount = getAlertCount(alertsData);
if (alertCount > 0) {
activateAlarm();
}
}
});
}
void cancelTimer() {
alertCheckTimer.cancel();
//todo change this according to platform running
if (kIsWeb) {
(_client as httpForWeb.BrowserClient).close();
} else {
(_client as http.Client).close();
}
}
/// Fetches cookies from the host.
Future<void> getCookies() async {
const host = RedAlertConstants.host;
var uri = Uri.parse(host);
final response = await _client.get(uri, headers: headers);
cookies = response.headers["set-cookie"] ?? cookies;
// headers = response.headers;
RedAlertLogger.logInfo('[-] Showing response.headers ...${response.headers}');
RedAlertLogger.logInfo('[-] Showing cookies 1...$cookies');
}
int getAlertCount(Map<String, dynamic> alertsData) {
return (alertsData["data"] as List).length;
}
Future<Map<String, dynamic>?> getRedAlerts() async {
const host = RedAlertConstants.alertsEndpoint;
try {
final Uri uri = Uri.parse(host);
// Attach cookies to the headers
Map<String, String> headersWithCookies = {...headers};
if (cookies.isNotEmpty) {
headersWithCookies.addAll( {"cookie": cookies});// = cookies;
}
RedAlertLogger.logInfo('[-] Showing cookies 2...$cookies');
RedAlertLogger.logInfo('[-] Showing headersWithCookies ...$headersWithCookies');
// return null;
//todo think about diffrentiation between mobile and chrome\web
final response = await _client.get(uri, headers: headersWithCookies);
if (response.statusCode == 200) {
final String responseBody = response.body;
final alerts = responseBody.replaceAll("\n", "").replaceAll("\r", "");
// Remove BOM and other non-RedAlertLogger.logInfoable characters
final cleanAlerts = alerts.replaceAll(RegExp('[^ -~]+'), '');
if (cleanAlerts.isEmpty) {
return null;
}
// Decode the response using UTF-8 encoding
const utf8Decoder = Utf8Decoder(allowMalformed: true);
final cleanedResponse = utf8Decoder.convert(responseBody.codeUnits);
RedAlertLogger.logInfo('[-] Showing cleanedResponse ...$cleanedResponse');
final Map<String, dynamic> json = jsonDecode(cleanedResponse);
if ((json["data"] as List).isEmpty) {
return null;
}
json["timestamp"] = DateTime.now().millisecondsSinceEpoch;
return json;
} else {
// Handle non-200 status code
RedAlertLogger.logError('Non-200 status code: ${response.statusCode}');
RedAlertLogger.logInfo('Non-200 response body:\n${response.body}');
return null; // or throw an exception if necessary
}
} catch (e, stackTrace) {
// Handle the error, log it, or return a specific value
RedAlertLogger.logError('Error in getRedAlerts: ${e.hashCode} ${e.runtimeType} $e\n$stackTrace');
return null; // or throw the error again if necessary
}
}
void activateAlarm() {
if (!isAlarmActive) {
// Set the alarm active flag to true
isAlarmActive = true;
// Trigger the callback function provided by HomeScreen
onAlarmActivated();
// Set a timer for 10 minutes (600 seconds)
Timer(const Duration(minutes: 10), () {
// When the timer expires, reset the alarm flag
if (isAlarmActive) {
// Check if the alarm is still active before resetting
isAlarmActive = false;
//todo remove duplicate call here?
// Trigger the callback function provided by HomeScreen to reset UI
onAlarmActivated();
//todo add response from RedAlert code into home screen callabck
}
});
}
}
}