From 152d4df0fc0d1aa3928c8929e8e7cd8badb9263e Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Tue, 30 Jun 2026 02:33:51 +0300 Subject: [PATCH] Update: 2026-06-30 02:33:51 --- .../executionHistory/executionHistory.bin | Bin 905733 -> 905733 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .../.gradle/8.13/fileHashes/fileHashes.bin | Bin 72665 -> 72665 bytes .../.gradle/8.13/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../8.13/fileHashes/resourceHashesCache.bin | Bin 21591 -> 21761 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../service/ScraperAccessibilityService.kt | 128 ++++-------------- backend/bot/standalone_worker.php | 42 +++--- 8 files changed, 45 insertions(+), 125 deletions(-) diff --git a/android_bot/.gradle/8.13/executionHistory/executionHistory.bin b/android_bot/.gradle/8.13/executionHistory/executionHistory.bin index 66eeb691f58df8008b2c0f363287e9c8928a6f2f..8292756cad2e5901b52ccec0e7da583189aa18ea 100644 GIT binary patch delta 2877 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 pd2A;=ecyX;wx>q7 zr$!h3d=gpKZ#Vi^E;urZU11LfryrqEAQAnKnSi1h4H)<)I~p-GzdAGRzh`O3_QrDq z_SU`EK&U`MKym?aJZC*aL`MaSLC85KrpmU_LB@~i$=#U6evOoNC$qwgd!)vR(9rJy z%XAaq4QK|afc&Oc1d_5%Kr-O@+zm&c^1hG0{CZP_wd_vbo~dFJcid#51ODLP(^5U> zmUXY4V2hdX56U;A*@j5$R0Y-ohPRpkIEO|>1V zNre9wOVqMXhw94A$ za({lw&|9quFe+fetH&DCdozwS#hqE|5h0`8nsgY>Wx@ku_Y3XgX5H~ep{}s~?WSJ_ zfn5OuNb*=n_E488S2=K<&K^}5yIW?FP@}peeCPr}J_nc!S@6Mhx8eSE{suO$ThXMZ z9p@+W*eqmvb!MFijA!QW;8w<_S^0h#(FO^V4fXhYT5leH7W0Zrt(u=E%IU#f{=t*U z;k8@PT(&f;`u`N&(jA+1$UUles+}wF&ZjYYUEb(;+OxCXpX3;0FHe7|hcBsIXS=QJ zx20B=%ws2Xj7|peo`I8i<+1rJ_-Dy)4r+AdKehTptF=|v0)dDJWCbkHCSqW+f*1&P zlFVqE(bp|FbT$-XEY?A2b!zw+6gi4#+6khy<~0ZRU@pJYtq(TWDM;bf zJ$qq4pNuwWE`+c&6xI>DuD>WLZ%;Gyc=-Nb{&KBc1K5|{@`*DKN^}TPjEz{hw6^ab zctQeKiP9+eF`Ir6xsELo*T2J-^s3s%&$WTwudW=0}? z-f`N*2*_0q1RG5NT4ahXE~i6q!_u*~x`SI%;!7{K@99&0Bx$MUT;!ciL{;75IVI;#EEzxypHb z*|!V0D{32lGT8c(fPBgb$S4PYPrG>g=*PSE9t!AFE~%bih|bO-ZC4SBxv3!Oyck)i zA2a`ju|xH}-PJAbQE@#a6h=Tj2e5S&J0qy5Z-cOq1u@|(5F|C~O5s;sn)4&SHH5qf zzCxjb0VN>5deTa6X+o0Ql}asa6BZ-S>2Lhgi>UB613ZGJ8I17sWADPsAY5)KL delta 1767 zcmZXVc~lcu6vk&r0#u6{wu}kLAS%TTgM_lEV1ZI&00*H~pasQ>79m&_6=hRYtQBG( zFu{m17=;8Ifv8Z9l12p=>cIsln-;W!Tj>FU2#D<@nRo=>IdAgE{e9of{mz}FwUXLe zNi7@8K`rZxtwVc)25vO343)X|dq5B@w!$}uK)O?&0&E3I=)>bK!I^u8FCFWk+P=sx zuFye38$AO((g4nx*)*}0kcES&Gfd@>V2%+Qp^+&wJ6p}GU-~F2xbxY14J%(SvZ@F6 zhb+Ju%{4Hl{irf?_{bw5h!dq!)ZXEAw%`xWqglkW@?}NTA7M zAkF@PPbM#>+%AnPzao+htu;6Tbs-ZxKg|H)dF9C2$j<1ju#W0=oED7D|8B@&0_X)y zWQHPRtH&&lMOi7Kjq}baYTrBbCiki0>3*Rp4*2uc>ZBTEK^P2>Vv8QM@QE*zH!l z)WM}8;eC;a5abX+Bnw%{ZtQW?>#l_jZnRvg>bk7W&=U|*qB*~Zbw8V)Jo6f5Ah=$J zeM%O|l#Gsm9$^w;6`!1WJ z;yXCDJT(-xxj+z|Xgo0<4kzKr(e+Q>o(%PRvxnN*^wdOvCrFniS3FG(K{n)m~Do)gGA8Hg?$88iM7?TIU0!#jE} zPw{R%2&d{CXNXzIL3?4A)vAip02kMbW3XIm0F{{75=Q)f2!DBAw7qb+zc6O1>mfU` zYNC5T@KYO*rQWT~OX^LLT@Iba3tLw1GRSqn0?Ew~Oyw37T$3T8^HRNH7q7cb0yO<- zP}s*w-R#MJaG)k)=WBb<@7ezuw;C+<3fL9|6qTSh;m_yr&x$B_*z?p*^#r3|UUD5= zW&$kG0+gMwR=S_If)W0J{Wgcnu0xG&*6$X*^)(~u$-2GBm!_egiz@$!kRRJ9O{tx= zH@l+L0O)&8?@)5i;1s(%|MYmik_O!|PW1j2kEiM(JHkzS1WUln62Fk2*L>66U27q0 z6s%}Jt1L;T*3IWKFm7ovAl#WTi z$ef|R$kpkB_B68hYCUwfOu0fH8&471sc;bsW+KN^;xLQ>C0yri>z#75nM~a-AAib# zQ_*v5|Db5iut##*k*TPC{7{12* diff --git a/android_bot/.gradle/8.13/fileHashes/fileHashes.lock b/android_bot/.gradle/8.13/fileHashes/fileHashes.lock index 926142d78277036f8abf5ce2f19c3e84deb2c777..42c78729469391f778619902b215b4d5a2aadd59 100644 GIT binary patch literal 17 VcmZQpDUVz8=j>v01~A}T4*)e31qlEE literal 17 VcmZQpDUVz8=j>v01~A|&1pqYK1kV5f diff --git a/android_bot/.gradle/8.13/fileHashes/resourceHashesCache.bin b/android_bot/.gradle/8.13/fileHashes/resourceHashesCache.bin index e4f3e863340dff9cb410022c28c1bc3d1f411190..edff224ee07449b984146de94aed48391a90540a 100644 GIT binary patch delta 194 zcmcbo5~b2^1rD1G%;H$6DkTW@yHnir6qw_5QGKFURU!UdG^c5Zu6gs;%8&iCwKc-h-e;G WxoEq>Tl8Fo&&Er?dS?Pv$^ifkyFOw7 delta 54 zcmV-60LlM>ssY!i0kAX}0b7$b7}%2~85omQ8F;hh8K45Qog8TavmPEH0|E${u_5>u Mu`qxSvq4A}3>}#gtpET3 diff --git a/android_bot/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/android_bot/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 1df63993002fba26d40fa0541763031f3b8e2c15..b3ed153215b9125e740aea4eaa476b6bb1fee474 100644 GIT binary patch literal 17 VcmZSn@TkOm3HOb23}C<^4gfu)1oZ#_ literal 17 VcmZSn@TkOm3HOb23}C>14FEo11+xGE diff --git a/android_bot/app/src/main/java/com/siro/android_bot/service/ScraperAccessibilityService.kt b/android_bot/app/src/main/java/com/siro/android_bot/service/ScraperAccessibilityService.kt index 18cdc66f..2403efa1 100644 --- a/android_bot/app/src/main/java/com/siro/android_bot/service/ScraperAccessibilityService.kt +++ b/android_bot/app/src/main/java/com/siro/android_bot/service/ScraperAccessibilityService.kt @@ -42,11 +42,6 @@ class ScraperAccessibilityService : AccessibilityService() { private val taxiFCollectedPrices = mutableListOf>() private var taxiFPriceScrollAttempts = 0 - // Multi-trip batch fields - private val taxiFMultiTripTrips = mutableListOf() - private var taxiFMultiTripIndex = 0 - private var taxiFPriceSubmitTime = 0L - companion object { private val TAXIF_EXCLUDED_TEXTS = setOf( "JOD", "ECO", "TaxiF", "SUV", "EV", "Mini", "Female", "Van", @@ -90,25 +85,11 @@ class ScraperAccessibilityService : AccessibilityService() { currentTask = task currentAppName = task.optString("app") val taskId = task.optString("task_id") - val taskType = task.optString("type", "price_check") - Log.i(TAG, "Received Task: $taskId for App: $currentAppName, Type: $taskType") + Log.i(TAG, "Received Task: $taskId for App: $currentAppName") taxiFPickupDone = false taxiFDestinationDone = false - taxiFMultiTripTrips.clear() - taxiFMultiTripIndex = 0 - taxiFPriceSubmitTime = 0L - - if (taskType == "batch_multi_trip") { - val tripsJson = task.optJSONArray("trips") - if (tripsJson != null) { - for (i in 0 until tripsJson.length()) { - taxiFMultiTripTrips.add(tripsJson.getJSONObject(i)) - } - } - Log.i(TAG, "TaxiF: Batch multi-trip loaded with ${taxiFMultiTripTrips.size} trips") - } currentState = BotState.LAUNCHING_APP // Launch the App @@ -384,26 +365,17 @@ class ScraperAccessibilityService : AccessibilityService() { val task = currentTask ?: return val taskId = task.optString("task_id") - val startLat: Double - val startLng: Double - val endLat: Double - val endLng: Double - - val tripCoords = getCurrentTripLatLng() - if (tripCoords != null) { - startLat = tripCoords.first[0] - startLng = tripCoords.first[1] - endLat = tripCoords.second[0] - endLng = tripCoords.second[1] - } else { - val payload = task.optJSONObject("payload") - startLat = payload?.optDouble("start_lat", 0.0) ?: 0.0 - startLng = payload?.optDouble("start_lng", 0.0) ?: 0.0 - endLat = payload?.optDouble("end_lat", 0.0) ?: 0.0 - endLng = payload?.optDouble("end_lng", 0.0) ?: 0.0 - } + // Extract nested payload object where coordinates reside + val payload = task.optJSONObject("payload") + val startLat = payload?.optDouble("start_lat", 0.0) ?: 0.0 + val startLng = payload?.optDouble("start_lng", 0.0) ?: 0.0 + val endLat = payload?.optDouble("end_lat", 0.0) ?: 0.0 + val endLng = payload?.optDouble("end_lng", 0.0) ?: 0.0 + // Calculate distance val distanceKm = calculateDistanceInKm(startLat, startLng, endLat, endLng) + + // Extract numeric digits from price val numericPrice = rawPrice.replace(Regex("[^0-9.]"), "").toDoubleOrNull() ?: 0.0 serviceScope.launch { @@ -424,6 +396,10 @@ class ScraperAccessibilityService : AccessibilityService() { } else { Log.e(TAG, "Failed to submit price.") } + + // Go back to IDLE + currentState = BotState.IDLE + currentTask = null } } @@ -510,10 +486,7 @@ class ScraperAccessibilityService : AccessibilityService() { private fun handleTaxiFAutomation(rootNode: android.view.accessibility.AccessibilityNodeInfo) { val task = currentTask ?: return - // 3-second cool-down between multi-trips - if ((System.currentTimeMillis() - taxiFPriceSubmitTime) < 3000) return - Log.d(TAG, "TaxiF Automation event. State: $currentState" + - if (taxiFMultiTripTrips.isNotEmpty()) " Trip ${taxiFMultiTripIndex + 1}/${taxiFMultiTripTrips.size}" else "") + Log.d(TAG, "TaxiF Automation event. State: $currentState") when (currentState) { BotState.NAVIGATING_HOME -> { if (hasJustClickedHome()) return @@ -539,7 +512,7 @@ class ScraperAccessibilityService : AccessibilityService() { BotState.SEARCHING_START -> { if (detectTaxiFPriceScreen(rootNode)) { if (hasJustClickedLocation() || hasJustClickedSuggestion()) return - if (!taxiFPickupDone && shouldEditLocation(rootNode, isPickup = true)) { + if (!taxiFPickupDone && shouldEditLocation(rootNode, task, isPickup = true)) { clickLocationRow(rootNode, isPickup = true) taxiFLocationClickTime = System.currentTimeMillis() return @@ -548,7 +521,7 @@ class ScraperAccessibilityService : AccessibilityService() { currentState = BotState.SEARCHING_END return } - if (!taxiFPickupDone && handleTaxiFSearchScreen(rootNode, getCurrentStartLocation())) { + if (!taxiFPickupDone && handleTaxiFSearchScreen(rootNode, task.optString("start_location", "Amman"))) { taxiFPickupDone = true Log.i(TAG, "TaxiF: Handled pickup search, waiting for price screen") } @@ -556,7 +529,7 @@ class ScraperAccessibilityService : AccessibilityService() { BotState.SEARCHING_END -> { if (detectTaxiFPriceScreen(rootNode)) { if (hasJustClickedLocation() || hasJustClickedSuggestion()) return - if (!taxiFDestinationDone && shouldEditLocation(rootNode, isPickup = false)) { + if (!taxiFDestinationDone && shouldEditLocation(rootNode, task, isPickup = false)) { clickLocationRow(rootNode, isPickup = false) taxiFLocationClickTime = System.currentTimeMillis() return @@ -567,7 +540,7 @@ class ScraperAccessibilityService : AccessibilityService() { taxiFPriceScrollAttempts = 0 return } - if (!taxiFDestinationDone && handleTaxiFSearchScreen(rootNode, getCurrentEndLocation())) { + if (!taxiFDestinationDone && handleTaxiFSearchScreen(rootNode, task.optString("end_location", "Airport"))) { taxiFDestinationDone = true Log.i(TAG, "TaxiF: Handled dest search, waiting for price screen") } @@ -593,30 +566,6 @@ class ScraperAccessibilityService : AccessibilityService() { return (System.currentTimeMillis() - taxiFSuggestionClickTime) < 1500 } - private fun getCurrentStartLocation(): String { - return if (taxiFMultiTripTrips.isNotEmpty() && taxiFMultiTripIndex < taxiFMultiTripTrips.size) - taxiFMultiTripTrips[taxiFMultiTripIndex].optString("start_location", "Amman") - else - currentTask?.optString("start_location", "Amman") ?: "Amman" - } - - private fun getCurrentEndLocation(): String { - return if (taxiFMultiTripTrips.isNotEmpty() && taxiFMultiTripIndex < taxiFMultiTripTrips.size) - taxiFMultiTripTrips[taxiFMultiTripIndex].optString("end_location", "Airport") - else - currentTask?.optString("end_location", "Airport") ?: "Airport" - } - - private fun getCurrentTripLatLng(): Pair? { - return if (taxiFMultiTripTrips.isNotEmpty() && taxiFMultiTripIndex < taxiFMultiTripTrips.size) { - val trip = taxiFMultiTripTrips[taxiFMultiTripIndex] - Pair( - doubleArrayOf(trip.optDouble("start_lat", 0.0), trip.optDouble("start_lng", 0.0)), - doubleArrayOf(trip.optDouble("end_lat", 0.0), trip.optDouble("end_lng", 0.0)) - ) - } else null - } - private fun getLocationTexts(node: android.view.accessibility.AccessibilityNodeInfo?): List { val texts = mutableListOf() collectLocationTexts(node, texts) @@ -636,9 +585,9 @@ class ScraperAccessibilityService : AccessibilityService() { } } - private fun shouldEditLocation(rootNode: android.view.accessibility.AccessibilityNodeInfo, isPickup: Boolean): Boolean { + private fun shouldEditLocation(rootNode: android.view.accessibility.AccessibilityNodeInfo, task: JSONObject, isPickup: Boolean): Boolean { val locationTexts = getLocationTexts(rootNode) - val taskLoc = if (isPickup) getCurrentStartLocation() else getCurrentEndLocation() + val taskLoc = if (isPickup) task.optString("start_location", "") else task.optString("end_location", "") if (taskLoc.isEmpty()) return false val matchFound = locationTexts.any { text -> text.contains(taskLoc, ignoreCase = true) || taskLoc.contains(text, ignoreCase = true) @@ -776,40 +725,13 @@ class ScraperAccessibilityService : AccessibilityService() { Log.i(TAG, "TaxiF: Found price option: ${label.take(50)} = $price JOD") } val cheapest = prices.minByOrNull { it.first } ?: prices.first() - val tripLabel = if (taxiFMultiTripTrips.isNotEmpty()) - "Trip ${taxiFMultiTripIndex + 1}/${taxiFMultiTripTrips.size}: " else "" - Log.i(TAG, "TaxiF: ${tripLabel}Cheapest price: ${cheapest.first} JOD") + Log.i(TAG, "TaxiF: Submitting cheapest price: ${cheapest.second.take(50)} = ${cheapest.first} JOD") submitPriceToServer("${cheapest.first} JOD") - advanceToNextTaxiFTrip() } else { - Log.w(TAG, "TaxiF: No JOD prices found${if (taxiFMultiTripTrips.isNotEmpty()) " for trip ${taxiFMultiTripIndex + 1}" else ""}") - if (taxiFMultiTripTrips.isEmpty()) { - searchPriceByCurrency(rootNode) - currentState = BotState.IDLE - } - } - } - - private fun advanceToNextTaxiFTrip() { - taxiFPriceSubmitTime = System.currentTimeMillis() - if (taxiFMultiTripTrips.isNotEmpty()) { - taxiFMultiTripIndex++ - taxiFPickupDone = false - taxiFDestinationDone = false - - if (taxiFMultiTripIndex < taxiFMultiTripTrips.size) { - Log.i(TAG, "TaxiF: 3s cool-down then trip ${taxiFMultiTripIndex + 1}/${taxiFMultiTripTrips.size}") - currentState = BotState.SEARCHING_START - } else { - Log.i(TAG, "TaxiF: All ${taxiFMultiTripTrips.size} trips completed!") - currentState = BotState.IDLE - currentTask = null - taxiFMultiTripTrips.clear() - taxiFMultiTripIndex = 0 - } - } else { - currentState = BotState.IDLE + Log.w(TAG, "TaxiF: No JOD prices found, falling back to generic search") + searchPriceByCurrency(rootNode) } + currentState = BotState.IDLE } private fun findHorizontalRecyclerView(node: android.view.accessibility.AccessibilityNodeInfo?): android.view.accessibility.AccessibilityNodeInfo? { diff --git a/backend/bot/standalone_worker.php b/backend/bot/standalone_worker.php index 50a2227d..1c9fbc34 100644 --- a/backend/bot/standalone_worker.php +++ b/backend/bot/standalone_worker.php @@ -198,33 +198,31 @@ if (isset($_POST['action'])) { [5, 11], // Tla Al-Ali → Hashmi (~5km) ]; - $trips = []; + $tasks = json_decode(file_get_contents(TASKS_FILE), true); + $count = 0; foreach ($tripPairs as $i => $pair) { $start = $ammanLocations[$pair[0]]; $end = $ammanLocations[$pair[1]]; - $trips[] = [ - 'trip_index' => $i, + $taskId = "prc_" . uniqid(); + + $newTask = [ + 'task_id' => $taskId, + 'type' => 'price_check', + 'app' => $app, 'start_location' => $start['name'], 'end_location' => $end['name'], - 'start_lat' => $start['lat'], - 'start_lng' => $start['lng'], - 'end_lat' => $end['lat'], - 'end_lng' => $end['lng'], + 'payload' => [ + 'start_lat' => $start['lat'], + 'start_lng' => $start['lng'], + 'end_lat' => $end['lat'], + 'end_lng' => $end['lng'], + ], ]; + $tasks[] = $newTask; + $count++; } - - $taskId = "batch_" . uniqid(); - $batchTask = [ - 'task_id' => $taskId, - 'type' => 'batch_multi_trip', - 'app' => $app, - 'trips' => $trips, - ]; - - $tasks = json_decode(file_get_contents(TASKS_FILE), true); - $tasks[] = $batchTask; file_put_contents(TASKS_FILE, json_encode($tasks, JSON_PRETTY_PRINT)); - $message = "Batch task with 10 trips generated! Task ID: $taskId"; + $message = "Generated $count standard tasks (one per trip) for TaxiF!"; } elseif ($_POST['action'] === 'clear_tasks') { file_put_contents(TASKS_FILE, json_encode([])); $message = "Task queue cleared successfully."; @@ -712,10 +710,10 @@ $scrapedResults = json_decode(file_get_contents(RESULTS_FILE), true);
-

Batch Multi-Trip Generator

+

Generate 10 Amman Trips

- Generates 1 batch task containing 10 varied Amman trips (2–17 km) for TaxiF. - The bot processes all 10 trips without reopening the app. + Queues 10 separate standard tasks (one per trip) with varied distances (2–17 km) for TaxiF. + The bot processes each trip individually through normal polling.