web_crawler_callback.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. // web_crawler_callback.h
  2. static bool sent_get_request = false;
  3. static bool get_success = false;
  4. static bool already_success = false;
  5. static WebCrawlerApp *app_instance = NULL;
  6. // Forward declaration of callback functions
  7. static void web_crawler_setting_item_path_clicked(void *context, uint32_t index);
  8. static void web_crawler_setting_item_ssid_clicked(void *context, uint32_t index);
  9. static void web_crawler_setting_item_password_clicked(void *context, uint32_t index);
  10. static void web_crawler_view_draw_callback(Canvas *canvas, void *context)
  11. {
  12. UNUSED(context);
  13. WebCrawlerApp *app = app_instance;
  14. if (!app)
  15. {
  16. FURI_LOG_E(TAG, "App is NULL");
  17. return;
  18. }
  19. canvas_clear(canvas);
  20. canvas_set_font(canvas, FontSecondary);
  21. if (fhttp.state == INACTIVE)
  22. {
  23. canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
  24. canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
  25. canvas_draw_str(canvas, 0, 32, "If you board is connected,");
  26. canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
  27. canvas_draw_str(canvas, 0, 52, "your Dev Board with the");
  28. canvas_draw_str(canvas, 0, 62, "FlipperHTTP firmware.");
  29. return;
  30. }
  31. if (app->path)
  32. {
  33. if (!sent_get_request)
  34. {
  35. canvas_draw_str(canvas, 0, 10, "Sending GET request...");
  36. // Perform GET request and handle the response
  37. get_success = flipper_http_get_request(app->path);
  38. canvas_draw_str(canvas, 0, 20, "Sent!");
  39. if (get_success)
  40. {
  41. canvas_draw_str(canvas, 0, 30, "Receiving data...");
  42. get_success = true;
  43. }
  44. else
  45. {
  46. canvas_draw_str(canvas, 0, 30, "Failed.");
  47. }
  48. sent_get_request = true;
  49. }
  50. else
  51. {
  52. if (get_success && fhttp.state == RECEIVING)
  53. {
  54. canvas_draw_str(canvas, 0, 10, "Receiving and parsing data...");
  55. already_success = true;
  56. }
  57. else if (get_success && fhttp.state == IDLE)
  58. {
  59. already_success = true;
  60. canvas_draw_str(canvas, 0, 10, "Data saved to file.");
  61. canvas_draw_str(canvas, 0, 20, "Press BACK to return.");
  62. }
  63. else
  64. {
  65. if (fhttp.state == ISSUE)
  66. {
  67. if (strstr(fhttp.last_response, "[ERROR] Not connected to Wifi. Failed to reconnect.") != NULL)
  68. {
  69. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  70. canvas_draw_str(canvas, 0, 50, "Update your config settings.");
  71. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  72. }
  73. else if (strstr(fhttp.last_response, "[ERROR] Failed to connect to Wifi.") != NULL)
  74. {
  75. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  76. canvas_draw_str(canvas, 0, 50, "Update your config settings.");
  77. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  78. }
  79. else
  80. {
  81. canvas_draw_str(canvas, 0, 10, "[ERROR] Failed to sync data.");
  82. canvas_draw_str(canvas, 0, 30, "If this is your third attempt,");
  83. canvas_draw_str(canvas, 0, 40, "it's likely your URL is not");
  84. canvas_draw_str(canvas, 0, 50, "compabilbe or correct.");
  85. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  86. }
  87. }
  88. else
  89. {
  90. canvas_draw_str(canvas, 0, 10, "GET request failed.");
  91. canvas_draw_str(canvas, 0, 20, "Press BACK to return.");
  92. }
  93. get_success = false;
  94. }
  95. }
  96. }
  97. else
  98. {
  99. canvas_draw_str(canvas, 0, 10, "URL not set.");
  100. }
  101. }
  102. /**
  103. * @brief Navigation callback to handle exiting from other views to the submenu.
  104. * @param context The context - WebCrawlerApp object.
  105. * @return WebCrawlerViewSubmenu
  106. */
  107. static uint32_t web_crawler_back_to_main_callback(void *context)
  108. {
  109. UNUSED(context);
  110. sent_get_request = false;
  111. get_success = false;
  112. already_success = false;
  113. if (app_instance && app_instance->textbox)
  114. {
  115. widget_reset(app_instance->textbox);
  116. }
  117. return WebCrawlerViewSubmenu; // Return to the main submenu view
  118. }
  119. /**
  120. * @brief Navigation callback to handle returning to the Configure screen.
  121. * @param context The context - WebCrawlerApp object.
  122. * @return WebCrawlerViewConfigure
  123. */
  124. static uint32_t web_crawler_back_to_configure_callback(void *context)
  125. {
  126. UNUSED(context);
  127. return WebCrawlerViewConfigure; // Return to the Configure screen
  128. }
  129. /**
  130. * @brief Navigation callback to handle exiting the app from the main submenu.
  131. * @param context The context - unused
  132. * @return VIEW_NONE to exit the app
  133. */
  134. static uint32_t web_crawler_exit_app_callback(void *context)
  135. {
  136. UNUSED(context);
  137. return VIEW_NONE;
  138. }
  139. /**
  140. * @brief Handle submenu item selection.
  141. * @param context The context - WebCrawlerApp object.
  142. * @param index The WebCrawlerSubmenuIndex item that was clicked.
  143. */
  144. static void web_crawler_submenu_callback(void *context, uint32_t index)
  145. {
  146. WebCrawlerApp *app = (WebCrawlerApp *)context;
  147. furi_check(app);
  148. switch (index)
  149. {
  150. case WebCrawlerSubmenuIndexRun:
  151. sent_get_request = false; // Reset the flag
  152. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewRun);
  153. break;
  154. case WebCrawlerSubmenuIndexAbout:
  155. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewAbout);
  156. break;
  157. case WebCrawlerSubmenuIndexSetPath:
  158. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  159. break;
  160. case WebCrawlerSubmenuIndexData:
  161. if (!load_received_data())
  162. {
  163. if (app_instance->textbox)
  164. {
  165. widget_reset(app_instance->textbox);
  166. widget_add_text_scroll_element(
  167. app_instance->textbox,
  168. 0,
  169. 0,
  170. 128,
  171. 64, "File is empty.");
  172. }
  173. }
  174. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewData);
  175. break;
  176. default:
  177. FURI_LOG_E(TAG, "Unknown submenu index");
  178. break;
  179. }
  180. }
  181. /**
  182. * @brief Configuration enter callback to handle different items.
  183. * @param context The context - WebCrawlerApp object.
  184. * @param index The index of the item that was clicked.
  185. */
  186. static void web_crawler_config_enter_callback(void *context, uint32_t index)
  187. {
  188. switch (index)
  189. {
  190. case 0:
  191. web_crawler_setting_item_path_clicked(context, index);
  192. break;
  193. case 1:
  194. web_crawler_setting_item_ssid_clicked(context, index);
  195. break;
  196. case 2:
  197. web_crawler_setting_item_password_clicked(context, index);
  198. break;
  199. default:
  200. FURI_LOG_E(TAG, "Unknown configuration item index");
  201. break;
  202. }
  203. }
  204. /**
  205. * @brief Callback for when the user finishes entering the URL.
  206. * @param context The context - WebCrawlerApp object.
  207. */
  208. static void web_crawler_set_path_updated(void *context)
  209. {
  210. WebCrawlerApp *app = (WebCrawlerApp *)context;
  211. furi_check(app);
  212. // Store the entered URL from temp_buffer_path to path
  213. strncpy(app->path, app->temp_buffer_path, app->temp_buffer_size_path - 1);
  214. if (app->path_item)
  215. {
  216. variable_item_set_current_value_text(app->path_item, app->path);
  217. // Save the URL to the settings
  218. save_settings(app->path, app->ssid, app->password);
  219. // send to UART
  220. if (!flipper_http_save_wifi(app->ssid, app->password))
  221. {
  222. FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
  223. FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
  224. }
  225. FURI_LOG_D(TAG, "URL saved: %s", app->path);
  226. }
  227. // Return to the Configure view
  228. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  229. }
  230. /**
  231. * @brief Callback for when the user finishes entering the SSID.
  232. * @param context The context - WebCrawlerApp object.
  233. */
  234. static void web_crawler_set_ssid_updated(void *context)
  235. {
  236. WebCrawlerApp *app = (WebCrawlerApp *)context;
  237. furi_check(app);
  238. // Store the entered SSID from temp_buffer_ssid to ssid
  239. strncpy(app->ssid, app->temp_buffer_ssid, app->temp_buffer_size_ssid - 1);
  240. if (app->ssid_item)
  241. {
  242. variable_item_set_current_value_text(app->ssid_item, app->ssid);
  243. // Save the SSID to the settings
  244. save_settings(app->path, app->ssid, app->password);
  245. // send to UART
  246. if (!flipper_http_save_wifi(app->ssid, app->password))
  247. {
  248. FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
  249. FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
  250. }
  251. FURI_LOG_D(TAG, "SSID saved: %s", app->ssid);
  252. }
  253. // Return to the Configure view
  254. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  255. }
  256. /**
  257. * @brief Callback for when the user finishes entering the Password.
  258. * @param context The context - WebCrawlerApp object.
  259. */
  260. static void web_crawler_set_password_update(void *context)
  261. {
  262. WebCrawlerApp *app = (WebCrawlerApp *)context;
  263. furi_check(app);
  264. // Store the entered Password from temp_buffer_password to password
  265. strncpy(app->password, app->temp_buffer_password, app->temp_buffer_size_password - 1);
  266. if (app->password_item)
  267. {
  268. variable_item_set_current_value_text(app->password_item, app->password);
  269. // Save the Password to the settings
  270. save_settings(app->path, app->ssid, app->password);
  271. // send to UART
  272. if (!flipper_http_save_wifi(app->ssid, app->password))
  273. {
  274. FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
  275. FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
  276. }
  277. FURI_LOG_D(TAG, "Password saved: %s", app->password);
  278. }
  279. // Return to the Configure view
  280. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewConfigure);
  281. }
  282. /**
  283. * @brief Handler for Path configuration item click.
  284. * @param context The context - WebCrawlerApp object.
  285. * @param index The index of the item that was clicked.
  286. */
  287. static void web_crawler_setting_item_path_clicked(void *context, uint32_t index)
  288. {
  289. WebCrawlerApp *app = (WebCrawlerApp *)context;
  290. furi_check(app);
  291. UNUSED(index);
  292. // Set up the text input
  293. text_input_set_header_text(app->text_input_path, "Enter URL");
  294. // Initialize temp_buffer with existing path
  295. if (app->path)
  296. {
  297. strncpy(app->temp_buffer_path, app->path, app->temp_buffer_size_path - 1);
  298. }
  299. else
  300. {
  301. strncpy(app->temp_buffer_path, "https://www.google.com/", app->temp_buffer_size_path - 1);
  302. }
  303. app->temp_buffer_path[app->temp_buffer_size_path - 1] = '\0';
  304. // Configure the text input
  305. bool clear_previous_text = false;
  306. text_input_set_result_callback(
  307. app->text_input_path,
  308. web_crawler_set_path_updated,
  309. app,
  310. app->temp_buffer_path,
  311. app->temp_buffer_size_path,
  312. clear_previous_text);
  313. // Set the previous callback to return to Configure screen
  314. view_set_previous_callback(
  315. text_input_get_view(app->text_input_path),
  316. web_crawler_back_to_configure_callback);
  317. // Show text input dialog
  318. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewTextInput);
  319. }
  320. /**
  321. * @brief Handler for SSID configuration item click.
  322. * @param context The context - WebCrawlerApp object.
  323. * @param index The index of the item that was clicked.
  324. */
  325. static void web_crawler_setting_item_ssid_clicked(void *context, uint32_t index)
  326. {
  327. WebCrawlerApp *app = (WebCrawlerApp *)context;
  328. furi_check(app);
  329. UNUSED(index);
  330. // Set up the text input
  331. text_input_set_header_text(app->text_input_ssid, "Enter SSID");
  332. // Initialize temp_buffer with existing SSID
  333. if (app->ssid)
  334. {
  335. strncpy(app->temp_buffer_ssid, app->ssid, app->temp_buffer_size_ssid - 1);
  336. }
  337. else
  338. {
  339. strncpy(app->temp_buffer_ssid, "SSID-2G-", app->temp_buffer_size_ssid - 1);
  340. }
  341. app->temp_buffer_ssid[app->temp_buffer_size_ssid - 1] = '\0';
  342. // Configure the text input
  343. bool clear_previous_text = false;
  344. text_input_set_result_callback(
  345. app->text_input_ssid,
  346. web_crawler_set_ssid_updated,
  347. app,
  348. app->temp_buffer_ssid,
  349. app->temp_buffer_size_ssid,
  350. clear_previous_text);
  351. // Set the previous callback to return to Configure screen
  352. view_set_previous_callback(
  353. text_input_get_view(app->text_input_ssid),
  354. web_crawler_back_to_configure_callback);
  355. // Show text input dialog
  356. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewTextInputSSID);
  357. }
  358. /**
  359. * @brief Handler for Password configuration item click.
  360. * @param context The context - WebCrawlerApp object.
  361. * @param index The index of the item that was clicked.
  362. */
  363. static void web_crawler_setting_item_password_clicked(void *context, uint32_t index)
  364. {
  365. WebCrawlerApp *app = (WebCrawlerApp *)context;
  366. furi_check(app);
  367. UNUSED(index);
  368. // Set up the text input
  369. text_input_set_header_text(app->text_input_password, "Enter Password");
  370. // Initialize temp_buffer with existing password
  371. strncpy(app->temp_buffer_password, app->password, app->temp_buffer_size_password - 1);
  372. app->temp_buffer_password[app->temp_buffer_size_password - 1] = '\0';
  373. // Configure the text input
  374. bool clear_previous_text = false;
  375. text_input_set_result_callback(
  376. app->text_input_password,
  377. web_crawler_set_password_update,
  378. app,
  379. app->temp_buffer_password,
  380. app->temp_buffer_size_password,
  381. clear_previous_text);
  382. // Set the previous callback to return to Configure screen
  383. view_set_previous_callback(
  384. text_input_get_view(app->text_input_password),
  385. web_crawler_back_to_configure_callback);
  386. // Show text input dialog
  387. view_dispatcher_switch_to_view(app->view_dispatcher, WebCrawlerViewTextInputPassword);
  388. }