Update: 2026-06-29 23:45:06
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -15,7 +15,15 @@ object AppLauncher {
|
|||||||
"zaken" to "com.zakinn.app",
|
"zaken" to "com.zakinn.app",
|
||||||
"com.zakinn.app" to "com.zakinn.app",
|
"com.zakinn.app" to "com.zakinn.app",
|
||||||
"tufaddal" to "com.bis.taxi",
|
"tufaddal" to "com.bis.taxi",
|
||||||
"com.bis.taxi" to "com.bis.taxi"
|
"com.bis.taxi" to "com.bis.taxi",
|
||||||
|
"careem" to "com.careem.acma",
|
||||||
|
"com.careem.acma" to "com.careem.acma",
|
||||||
|
"uber" to "com.ubercab",
|
||||||
|
"com.ubercab" to "com.ubercab",
|
||||||
|
"taxif" to "com.taxif.passenger",
|
||||||
|
"com.taxif.passenger" to "com.taxif.passenger",
|
||||||
|
"jeeny" to "me.com.easytaxi",
|
||||||
|
"me.com.easytaxi" to "me.com.easytaxi"
|
||||||
)
|
)
|
||||||
|
|
||||||
fun launchApp(context: Context, appName: String): Boolean {
|
fun launchApp(context: Context, appName: String): Boolean {
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ class ScraperAccessibilityService : AccessibilityService() {
|
|||||||
"ae.com.yalla.go.dubai.client" -> handleYallaGoAutomation(rootNode)
|
"ae.com.yalla.go.dubai.client" -> handleYallaGoAutomation(rootNode)
|
||||||
"com.zakinn.app" -> handleZakinnAutomation(rootNode)
|
"com.zakinn.app" -> handleZakinnAutomation(rootNode)
|
||||||
"com.bis.taxi" -> handleTfadalAutomation(rootNode)
|
"com.bis.taxi" -> handleTfadalAutomation(rootNode)
|
||||||
|
"com.careem.acma" -> handleCareemAutomation(rootNode)
|
||||||
|
"com.ubercab" -> handleUberAutomation(rootNode)
|
||||||
|
"com.taxif.passenger" -> handleTaxiFAutomation(rootNode)
|
||||||
|
"me.com.easytaxi" -> handleJeenyAutomation(rootNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +326,7 @@ class ScraperAccessibilityService : AccessibilityService() {
|
|||||||
private fun searchPriceByCurrency(node: android.view.accessibility.AccessibilityNodeInfo?) {
|
private fun searchPriceByCurrency(node: android.view.accessibility.AccessibilityNodeInfo?) {
|
||||||
if (node == null) return
|
if (node == null) return
|
||||||
val text = node.text?.toString() ?: ""
|
val text = node.text?.toString() ?: ""
|
||||||
if (text.contains("ل.س") || text.contains("SYP") || text.contains("AED") || text.contains("SP") || text.contains("SP.")) {
|
if (text.contains("ل.س") || text.contains("SYP") || text.contains("AED") || text.contains("SP") || text.contains("SP.") || text.contains("JOD") || text.contains("د.أ") || text.contains("JD")) {
|
||||||
Log.i(TAG, "Found price pattern dynamically: $text")
|
Log.i(TAG, "Found price pattern dynamically: $text")
|
||||||
submitPriceToServer(text)
|
submitPriceToServer(text)
|
||||||
return
|
return
|
||||||
@@ -385,6 +389,146 @@ class ScraperAccessibilityService : AccessibilityService() {
|
|||||||
return r * c
|
return r * c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleCareemAutomation(rootNode: android.view.accessibility.AccessibilityNodeInfo) {
|
||||||
|
val task = currentTask ?: return
|
||||||
|
Log.d(TAG, "Careem Automation event. State: $currentState")
|
||||||
|
when (currentState) {
|
||||||
|
BotState.SEARCHING_START -> {
|
||||||
|
val pickupEdit = findEditableNode(rootNode)
|
||||||
|
if (pickupEdit != null) {
|
||||||
|
val startLoc = task.optString("start_location", "Amman")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, startLoc)
|
||||||
|
}
|
||||||
|
pickupEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "Careem: Entered start: $startLoc")
|
||||||
|
currentState = BotState.SEARCHING_END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.SEARCHING_END -> {
|
||||||
|
val destEdit = findEditableNode(rootNode)
|
||||||
|
if (destEdit != null) {
|
||||||
|
val endLoc = task.optString("end_location", "Airport")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, endLoc)
|
||||||
|
}
|
||||||
|
destEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "Careem: Entered end: $endLoc")
|
||||||
|
currentState = BotState.READING_PRICE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.READING_PRICE -> {
|
||||||
|
searchPriceByCurrency(rootNode)
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleUberAutomation(rootNode: android.view.accessibility.AccessibilityNodeInfo) {
|
||||||
|
val task = currentTask ?: return
|
||||||
|
Log.d(TAG, "Uber Automation event. State: $currentState")
|
||||||
|
when (currentState) {
|
||||||
|
BotState.SEARCHING_START -> {
|
||||||
|
val pickupEdit = findEditableNode(rootNode)
|
||||||
|
if (pickupEdit != null) {
|
||||||
|
val startLoc = task.optString("start_location", "Amman")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, startLoc)
|
||||||
|
}
|
||||||
|
pickupEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "Uber: Entered start: $startLoc")
|
||||||
|
currentState = BotState.SEARCHING_END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.SEARCHING_END -> {
|
||||||
|
val destEdit = findEditableNode(rootNode)
|
||||||
|
if (destEdit != null) {
|
||||||
|
val endLoc = task.optString("end_location", "Airport")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, endLoc)
|
||||||
|
}
|
||||||
|
destEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "Uber: Entered end: $endLoc")
|
||||||
|
currentState = BotState.READING_PRICE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.READING_PRICE -> {
|
||||||
|
searchPriceByCurrency(rootNode)
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleTaxiFAutomation(rootNode: android.view.accessibility.AccessibilityNodeInfo) {
|
||||||
|
val task = currentTask ?: return
|
||||||
|
Log.d(TAG, "TaxiF Automation event. State: $currentState")
|
||||||
|
when (currentState) {
|
||||||
|
BotState.SEARCHING_START -> {
|
||||||
|
val pickupEdit = findEditableNode(rootNode)
|
||||||
|
if (pickupEdit != null) {
|
||||||
|
val startLoc = task.optString("start_location", "Amman")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, startLoc)
|
||||||
|
}
|
||||||
|
pickupEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "TaxiF: Entered start: $startLoc")
|
||||||
|
currentState = BotState.SEARCHING_END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.SEARCHING_END -> {
|
||||||
|
val destEdit = findEditableNode(rootNode)
|
||||||
|
if (destEdit != null) {
|
||||||
|
val endLoc = task.optString("end_location", "Airport")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, endLoc)
|
||||||
|
}
|
||||||
|
destEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "TaxiF: Entered end: $endLoc")
|
||||||
|
currentState = BotState.READING_PRICE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.READING_PRICE -> {
|
||||||
|
searchPriceByCurrency(rootNode)
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleJeenyAutomation(rootNode: android.view.accessibility.AccessibilityNodeInfo) {
|
||||||
|
val task = currentTask ?: return
|
||||||
|
Log.d(TAG, "Jeeny Automation event. State: $currentState")
|
||||||
|
when (currentState) {
|
||||||
|
BotState.SEARCHING_START -> {
|
||||||
|
val pickupEdit = findEditableNode(rootNode)
|
||||||
|
if (pickupEdit != null) {
|
||||||
|
val startLoc = task.optString("start_location", "Amman")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, startLoc)
|
||||||
|
}
|
||||||
|
pickupEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "Jeeny: Entered start: $startLoc")
|
||||||
|
currentState = BotState.SEARCHING_END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.SEARCHING_END -> {
|
||||||
|
val destEdit = findEditableNode(rootNode)
|
||||||
|
if (destEdit != null) {
|
||||||
|
val endLoc = task.optString("end_location", "Airport")
|
||||||
|
val arguments = android.os.Bundle().apply {
|
||||||
|
putCharSequence(android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, endLoc)
|
||||||
|
}
|
||||||
|
destEdit.performAction(android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
|
||||||
|
Log.i(TAG, "Jeeny: Entered end: $endLoc")
|
||||||
|
currentState = BotState.READING_PRICE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BotState.READING_PRICE -> {
|
||||||
|
searchPriceByCurrency(rootNode)
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onInterrupt() {
|
override fun onInterrupt() {
|
||||||
Log.w(TAG, "Accessibility Service Interrupted")
|
Log.w(TAG, "Accessibility Service Interrupted")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,22 +34,40 @@ CREATE TABLE IF NOT EXISTS competitor_prices (
|
|||||||
";
|
";
|
||||||
$con->exec($sql);
|
$con->exec($sql);
|
||||||
|
|
||||||
// 2. Ten Key Regions in Damascus
|
// 2. Ten Key Regions in Damascus (Syria) and Amman (Jordan)
|
||||||
$regions = [
|
$countriesConfig = [
|
||||||
['name' => 'Umayyad Square', 'lat' => 33.5138, 'lng' => 36.2765],
|
'SY' => [
|
||||||
['name' => 'Mezzeh', 'lat' => 33.5074, 'lng' => 36.2530],
|
'competitors' => ['yallago', 'zaken', 'tufaddal'],
|
||||||
['name' => 'Malki', 'lat' => 33.5220, 'lng' => 36.2840],
|
'regions' => [
|
||||||
['name' => 'Kafersouseh', 'lat' => 33.4981, 'lng' => 36.2730],
|
['name' => 'Umayyad Square', 'lat' => 33.5138, 'lng' => 36.2765],
|
||||||
['name' => 'Al-Midan', 'lat' => 33.4947, 'lng' => 36.2995],
|
['name' => 'Mezzeh', 'lat' => 33.5074, 'lng' => 36.2530],
|
||||||
['name' => 'Bab Tuma', 'lat' => 33.5126, 'lng' => 36.3150],
|
['name' => 'Malki', 'lat' => 33.5220, 'lng' => 36.2840],
|
||||||
['name' => 'Rukneddine', 'lat' => 33.5350, 'lng' => 36.2950],
|
['name' => 'Kafersouseh', 'lat' => 33.4981, 'lng' => 36.2730],
|
||||||
['name' => 'Dummar', 'lat' => 33.5385, 'lng' => 36.2250],
|
['name' => 'Al-Midan', 'lat' => 33.4947, 'lng' => 36.2995],
|
||||||
['name' => 'Baramkeh', 'lat' => 33.5100, 'lng' => 36.2885],
|
['name' => 'Bab Tuma', 'lat' => 33.5126, 'lng' => 36.3150],
|
||||||
['name' => 'Muhajireen', 'lat' => 33.5320, 'lng' => 36.2720],
|
['name' => 'Rukneddine', 'lat' => 33.5350, 'lng' => 36.2950],
|
||||||
|
['name' => 'Dummar', 'lat' => 33.5385, 'lng' => 36.2250],
|
||||||
|
['name' => 'Baramkeh', 'lat' => 33.5100, 'lng' => 36.2885],
|
||||||
|
['name' => 'Muhajireen', 'lat' => 33.5320, 'lng' => 36.2720],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'JO' => [
|
||||||
|
'competitors' => ['com.careem.acma', 'com.ubercab', 'com.taxif.passenger', 'me.com.easytaxi'],
|
||||||
|
'regions' => [
|
||||||
|
['name' => 'Abdoun', 'lat' => 31.9392, 'lng' => 35.8942],
|
||||||
|
['name' => 'Jabal Amman', 'lat' => 31.9511, 'lng' => 35.9189],
|
||||||
|
['name' => 'Sweileh', 'lat' => 32.0167, 'lng' => 35.8333],
|
||||||
|
['name' => 'Khalda', 'lat' => 31.9861, 'lng' => 35.8450],
|
||||||
|
['name' => 'Al-Jubaiha', 'lat' => 32.0194, 'lng' => 35.8753],
|
||||||
|
['name' => 'Tla Al-Ali', 'lat' => 31.9961, 'lng' => 35.8647],
|
||||||
|
['name' => 'Shmeisani', 'lat' => 31.9680, 'lng' => 35.9020],
|
||||||
|
['name' => 'Um Uthaina', 'lat' => 31.9610, 'lng' => 35.8770],
|
||||||
|
['name' => 'Jabal Al-Weibdeh', 'lat' => 31.9560, 'lng' => 35.9220],
|
||||||
|
['name' => 'Marj Al-Hamam', 'lat' => 31.9000, 'lng' => 35.8500],
|
||||||
|
]
|
||||||
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$competitors = ['yallago', 'zaken', 'tufaddal'];
|
|
||||||
|
|
||||||
// Helper to generate a random point within a radius (in km)
|
// Helper to generate a random point within a radius (in km)
|
||||||
function generateRandomPoint($lat, $lng, $radius) {
|
function generateRandomPoint($lat, $lng, $radius) {
|
||||||
$radiusInDegrees = $radius / 111.0; // 1 degree is ~111km
|
$radiusInDegrees = $radius / 111.0; // 1 degree is ~111km
|
||||||
@@ -72,39 +90,44 @@ function generateRandomPoint($lat, $lng, $radius) {
|
|||||||
|
|
||||||
$tasksCreated = 0;
|
$tasksCreated = 0;
|
||||||
|
|
||||||
foreach ($regions as $region) {
|
foreach ($countriesConfig as $countryCode => $config) {
|
||||||
// A. Generate Start Point (within 2km of region center)
|
$competitors = $config['competitors'];
|
||||||
$start = generateRandomPoint($region['lat'], $region['lng'], 2);
|
$regions = $config['regions'];
|
||||||
|
|
||||||
// B. Generate Short Trip (2-5 km from start)
|
foreach ($regions as $region) {
|
||||||
$shortDist = rand(20, 50) / 10.0;
|
// A. Generate Start Point (within 2km of region center)
|
||||||
$shortEnd = generateRandomPoint($start['lat'], $start['lng'], $shortDist);
|
$start = generateRandomPoint($region['lat'], $region['lng'], 2);
|
||||||
|
|
||||||
// C. Generate Long Trip (10-15 km from start)
|
// B. Generate Short Trip (2-5 km from start)
|
||||||
$longDist = rand(100, 150) / 10.0;
|
$shortDist = rand(20, 50) / 10.0;
|
||||||
$longEnd = generateRandomPoint($start['lat'], $start['lng'], $longDist);
|
$shortEnd = generateRandomPoint($start['lat'], $start['lng'], $shortDist);
|
||||||
|
|
||||||
$trips = [$shortEnd, $longEnd];
|
// C. Generate Long Trip (10-15 km from start)
|
||||||
|
$longDist = rand(100, 150) / 10.0;
|
||||||
|
$longEnd = generateRandomPoint($start['lat'], $start['lng'], $longDist);
|
||||||
|
|
||||||
foreach ($trips as $end) {
|
$trips = [$shortEnd, $longEnd];
|
||||||
foreach ($competitors as $app) {
|
|
||||||
$taskId = "prc_" . uniqid();
|
|
||||||
|
|
||||||
$taskData = [
|
foreach ($trips as $end) {
|
||||||
"task_id" => $taskId,
|
foreach ($competitors as $app) {
|
||||||
"type" => "price_check",
|
$taskId = "prc_" . uniqid();
|
||||||
"app" => $app,
|
|
||||||
"payload" => [
|
|
||||||
"start_lat" => $start['lat'],
|
|
||||||
"start_lng" => $start['lng'],
|
|
||||||
"end_lat" => $end['lat'],
|
|
||||||
"end_lng" => $end['lng']
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
// Push to Redis Queue
|
$taskData = [
|
||||||
$redis->lpush('queue:bot:tasks', json_encode($taskData));
|
"task_id" => $taskId,
|
||||||
$tasksCreated++;
|
"type" => "price_check",
|
||||||
|
"app" => $app,
|
||||||
|
"payload" => [
|
||||||
|
"start_lat" => $start['lat'],
|
||||||
|
"start_lng" => $start['lng'],
|
||||||
|
"end_lat" => $end['lat'],
|
||||||
|
"end_lng" => $end['lng']
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Push to Redis Queue
|
||||||
|
$redis->lpush('queue:bot:tasks', json_encode($taskData));
|
||||||
|
$tasksCreated++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -506,6 +506,10 @@ $scrapedResults = json_decode(file_get_contents(RESULTS_FILE), true);
|
|||||||
.app-yallago { background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); }
|
.app-yallago { background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); }
|
||||||
.app-zaken { background: rgba(16, 185, 129, 0.15); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); }
|
.app-zaken { background: rgba(16, 185, 129, 0.15); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); }
|
||||||
.app-tufaddal { background: rgba(245, 158, 11, 0.15); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); }
|
.app-tufaddal { background: rgba(245, 158, 11, 0.15); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); }
|
||||||
|
.app-careem { background: rgba(16, 185, 129, 0.15); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); }
|
||||||
|
.app-uber { background: rgba(255, 255, 255, 0.1); color: #f3f4f6; border: 1px solid rgba(255, 255, 255, 0.2); }
|
||||||
|
.app-taxif { background: rgba(239, 68, 68, 0.15); color: #f87171; border: 1px solid rgba(239, 68, 68, 0.3); }
|
||||||
|
.app-jeeny { background: rgba(139, 92, 246, 0.15); color: #a78bfa; border: 1px solid rgba(139, 92, 246, 0.3); }
|
||||||
|
|
||||||
.time-badge {
|
.time-badge {
|
||||||
font-size: 0.80rem;
|
font-size: 0.80rem;
|
||||||
@@ -601,6 +605,10 @@ $scrapedResults = json_decode(file_get_contents(RESULTS_FILE), true);
|
|||||||
<option value="ae.com.yalla.go.dubai.client">YallaGo (ae.com.yalla.go.dubai.client)</option>
|
<option value="ae.com.yalla.go.dubai.client">YallaGo (ae.com.yalla.go.dubai.client)</option>
|
||||||
<option value="com.zakinn.app">Zaken / Zakinn (com.zakinn.app)</option>
|
<option value="com.zakinn.app">Zaken / Zakinn (com.zakinn.app)</option>
|
||||||
<option value="com.bis.taxi">Tfadal (com.bis.taxi)</option>
|
<option value="com.bis.taxi">Tfadal (com.bis.taxi)</option>
|
||||||
|
<option value="com.careem.acma">Careem (com.careem.acma)</option>
|
||||||
|
<option value="com.ubercab">Uber (com.ubercab)</option>
|
||||||
|
<option value="com.taxif.passenger">TaxiF (com.taxif.passenger)</option>
|
||||||
|
<option value="me.com.easytaxi">Jeeny (me.com.easytaxi)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -664,7 +672,24 @@ $scrapedResults = json_decode(file_get_contents(RESULTS_FILE), true);
|
|||||||
<div class="empty-state">No pending tasks. Queue some tasks using the form on the left!</div>
|
<div class="empty-state">No pending tasks. Queue some tasks using the form on the left!</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($currentTasks as $task):
|
<?php foreach ($currentTasks as $task):
|
||||||
$appLabel = ($task['app'] === 'ae.com.yalla.go.dubai.client') ? 'yallago' : (($task['app'] === 'com.zakinn.app') ? 'zaken' : 'tufaddal');
|
$app = $task['app'] ?? '';
|
||||||
|
if ($app === 'ae.com.yalla.go.dubai.client') {
|
||||||
|
$appLabel = 'yallago';
|
||||||
|
} elseif ($app === 'com.zakinn.app') {
|
||||||
|
$appLabel = 'zaken';
|
||||||
|
} elseif ($app === 'com.bis.taxi') {
|
||||||
|
$appLabel = 'tufaddal';
|
||||||
|
} elseif ($app === 'com.careem.acma') {
|
||||||
|
$appLabel = 'careem';
|
||||||
|
} elseif ($app === 'com.ubercab') {
|
||||||
|
$appLabel = 'uber';
|
||||||
|
} elseif ($app === 'com.taxif.passenger') {
|
||||||
|
$appLabel = 'taxif';
|
||||||
|
} elseif ($app === 'me.com.easytaxi') {
|
||||||
|
$appLabel = 'jeeny';
|
||||||
|
} else {
|
||||||
|
$appLabel = 'unknown';
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<div class="list-item">
|
<div class="list-item">
|
||||||
<div class="task-info">
|
<div class="task-info">
|
||||||
@@ -702,7 +727,23 @@ $scrapedResults = json_decode(file_get_contents(RESULTS_FILE), true);
|
|||||||
<?php foreach ($scrapedResults as $res):
|
<?php foreach ($scrapedResults as $res):
|
||||||
$data = $res['result_data'];
|
$data = $res['result_data'];
|
||||||
$app = $data['app'] ?? 'unknown';
|
$app = $data['app'] ?? 'unknown';
|
||||||
$appLabel = (strpos($app, 'yalla') !== false) ? 'yallago' : ((strpos($app, 'zakinn') !== false || strpos($app, 'zaken') !== false) ? 'zaken' : 'tufaddal');
|
if (strpos($app, 'yalla') !== false) {
|
||||||
|
$appLabel = 'yallago';
|
||||||
|
} elseif (strpos($app, 'zakinn') !== false || strpos($app, 'zaken') !== false) {
|
||||||
|
$appLabel = 'zaken';
|
||||||
|
} elseif (strpos($app, 'bis.taxi') !== false || strpos($app, 'tufaddal') !== false) {
|
||||||
|
$appLabel = 'tufaddal';
|
||||||
|
} elseif (strpos($app, 'careem') !== false) {
|
||||||
|
$appLabel = 'careem';
|
||||||
|
} elseif (strpos($app, 'ubercab') !== false || strpos($app, 'uber') !== false) {
|
||||||
|
$appLabel = 'uber';
|
||||||
|
} elseif (strpos($app, 'taxif') !== false) {
|
||||||
|
$appLabel = 'taxif';
|
||||||
|
} elseif (strpos($app, 'easytaxi') !== false || strpos($app, 'jeeny') !== false) {
|
||||||
|
$appLabel = 'jeeny';
|
||||||
|
} else {
|
||||||
|
$appLabel = 'unknown';
|
||||||
|
}
|
||||||
$isSuccess = ($res['status'] === 'success');
|
$isSuccess = ($res['status'] === 'success');
|
||||||
$price = $data['price'] ?? 0;
|
$price = $data['price'] ?? 0;
|
||||||
$dist = $data['distance_km'] ?? 0;
|
$dist = $data['distance_km'] ?? 0;
|
||||||
@@ -718,7 +759,11 @@ $scrapedResults = json_decode(file_get_contents(RESULTS_FILE), true);
|
|||||||
</div>
|
</div>
|
||||||
<div class="price-text">
|
<div class="price-text">
|
||||||
<?php if ($isSuccess): ?>
|
<?php if ($isSuccess): ?>
|
||||||
<?php echo number_format($price, 0); ?> SYP
|
<?php
|
||||||
|
$currency = (in_array($appLabel, ['careem', 'uber', 'taxif', 'jeeny'])) ? 'JOD' : 'SYP';
|
||||||
|
$decimals = ($currency === 'JOD') ? 2 : 0;
|
||||||
|
echo number_format($price, $decimals) . ' ' . $currency;
|
||||||
|
?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<span style="color:var(--error-color); font-size:0.9rem;">Scrape Failed</span>
|
<span style="color:var(--error-color); font-size:0.9rem;">Scrape Failed</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|||||||
@@ -220,7 +220,9 @@ ALTER TABLE `car_tracks`
|
|||||||
-- Indexes for table `driver_behavior`
|
-- Indexes for table `driver_behavior`
|
||||||
--
|
--
|
||||||
ALTER TABLE `driver_behavior`
|
ALTER TABLE `driver_behavior`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`),
|
||||||
|
ADD KEY `idx_driver_id` (`driver_id`),
|
||||||
|
ADD KEY `idx_trip_id` (`trip_id`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `driver_daily_summary`
|
-- Indexes for table `driver_daily_summary`
|
||||||
@@ -233,26 +235,29 @@ ALTER TABLE `driver_daily_summary`
|
|||||||
-- Indexes for table `driver_daily_work`
|
-- Indexes for table `driver_daily_work`
|
||||||
--
|
--
|
||||||
ALTER TABLE `driver_daily_work`
|
ALTER TABLE `driver_daily_work`
|
||||||
ADD PRIMARY KEY (`driver_id`,`work_date`),
|
ADD PRIMARY KEY (`driver_id`,`work_date`);
|
||||||
ADD KEY `idx_driver_date` (`driver_id`,`work_date`);
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `driver_orders`
|
-- Indexes for table `driver_orders`
|
||||||
--
|
--
|
||||||
ALTER TABLE `driver_orders`
|
ALTER TABLE `driver_orders`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`),
|
||||||
|
ADD KEY `idx_driver_id` (`driver_id`),
|
||||||
|
ADD KEY `idx_order_id` (`order_id`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `login_attempts`
|
-- Indexes for table `login_attempts`
|
||||||
--
|
--
|
||||||
ALTER TABLE `login_attempts`
|
ALTER TABLE `login_attempts`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`),
|
||||||
|
ADD KEY `idx_ip_time` (`ip_address`,`attempt_time`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `login_attempts_drivers`
|
-- Indexes for table `login_attempts_drivers`
|
||||||
--
|
--
|
||||||
ALTER TABLE `login_attempts_drivers`
|
ALTER TABLE `login_attempts_drivers`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`),
|
||||||
|
ADD KEY `idx_ip_time` (`ip_address`,`attempt_time`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `places`
|
-- Indexes for table `places`
|
||||||
|
|||||||
Reference in New Issue
Block a user