flowtask 5.8.4__cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. flowtask/__init__.py +93 -0
  2. flowtask/__main__.py +38 -0
  3. flowtask/bots/__init__.py +6 -0
  4. flowtask/bots/check.py +93 -0
  5. flowtask/bots/codebot.py +51 -0
  6. flowtask/components/ASPX.py +148 -0
  7. flowtask/components/AddDataset.py +352 -0
  8. flowtask/components/Amazon.py +523 -0
  9. flowtask/components/AutoTask.py +314 -0
  10. flowtask/components/Azure.py +80 -0
  11. flowtask/components/AzureUsers.py +106 -0
  12. flowtask/components/BaseAction.py +91 -0
  13. flowtask/components/BaseLoop.py +198 -0
  14. flowtask/components/BestBuy.py +800 -0
  15. flowtask/components/CSVToGCS.py +120 -0
  16. flowtask/components/CompanyScraper/__init__.py +1 -0
  17. flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
  18. flowtask/components/CompanyScraper/parsers/base.py +102 -0
  19. flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
  20. flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
  21. flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
  22. flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
  23. flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
  24. flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
  25. flowtask/components/CompanyScraper/scrapper.py +1054 -0
  26. flowtask/components/CopyTo.py +177 -0
  27. flowtask/components/CopyToBigQuery.py +243 -0
  28. flowtask/components/CopyToMongoDB.py +291 -0
  29. flowtask/components/CopyToPg.py +609 -0
  30. flowtask/components/CopyToRethink.py +207 -0
  31. flowtask/components/CreateGCSBucket.py +102 -0
  32. flowtask/components/CreateReport/CreateReport.py +228 -0
  33. flowtask/components/CreateReport/__init__.py +9 -0
  34. flowtask/components/CreateReport/charts/__init__.py +15 -0
  35. flowtask/components/CreateReport/charts/bar.py +51 -0
  36. flowtask/components/CreateReport/charts/base.py +66 -0
  37. flowtask/components/CreateReport/charts/pie.py +64 -0
  38. flowtask/components/CreateReport/utils.py +9 -0
  39. flowtask/components/CustomerSatisfaction.py +196 -0
  40. flowtask/components/DataInput.py +200 -0
  41. flowtask/components/DateList.py +255 -0
  42. flowtask/components/DbClient.py +163 -0
  43. flowtask/components/DialPad.py +146 -0
  44. flowtask/components/DocumentDBQuery.py +200 -0
  45. flowtask/components/DownloadFrom.py +371 -0
  46. flowtask/components/DownloadFromD2L.py +113 -0
  47. flowtask/components/DownloadFromFTP.py +181 -0
  48. flowtask/components/DownloadFromIMAP.py +315 -0
  49. flowtask/components/DownloadFromS3.py +198 -0
  50. flowtask/components/DownloadFromSFTP.py +265 -0
  51. flowtask/components/DownloadFromSharepoint.py +110 -0
  52. flowtask/components/DownloadFromSmartSheet.py +114 -0
  53. flowtask/components/DownloadS3File.py +229 -0
  54. flowtask/components/Dummy.py +59 -0
  55. flowtask/components/DuplicatePhoto.py +411 -0
  56. flowtask/components/EmployeeEvaluation.py +237 -0
  57. flowtask/components/ExecuteSQL.py +323 -0
  58. flowtask/components/ExtractHTML.py +178 -0
  59. flowtask/components/FileBase.py +178 -0
  60. flowtask/components/FileCopy.py +181 -0
  61. flowtask/components/FileDelete.py +82 -0
  62. flowtask/components/FileExists.py +146 -0
  63. flowtask/components/FileIteratorDelete.py +112 -0
  64. flowtask/components/FileList.py +194 -0
  65. flowtask/components/FileOpen.py +75 -0
  66. flowtask/components/FileRead.py +120 -0
  67. flowtask/components/FileRename.py +106 -0
  68. flowtask/components/FilterIf.py +284 -0
  69. flowtask/components/FilterRows/FilterRows.py +200 -0
  70. flowtask/components/FilterRows/__init__.py +10 -0
  71. flowtask/components/FilterRows/functions.py +4 -0
  72. flowtask/components/GCSToBigQuery.py +103 -0
  73. flowtask/components/GoogleA4.py +150 -0
  74. flowtask/components/GoogleGeoCoding.py +344 -0
  75. flowtask/components/GooglePlaces.py +315 -0
  76. flowtask/components/GoogleSearch.py +539 -0
  77. flowtask/components/HTTPClient.py +268 -0
  78. flowtask/components/ICIMS.py +146 -0
  79. flowtask/components/IF.py +179 -0
  80. flowtask/components/IcimsFolderCopy.py +173 -0
  81. flowtask/components/ImageFeatures/__init__.py +5 -0
  82. flowtask/components/ImageFeatures/process.py +233 -0
  83. flowtask/components/IteratorBase.py +251 -0
  84. flowtask/components/LangchainLoader/__init__.py +5 -0
  85. flowtask/components/LangchainLoader/loader.py +194 -0
  86. flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
  87. flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
  88. flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
  89. flowtask/components/LangchainLoader/loaders/docx.py +91 -0
  90. flowtask/components/LangchainLoader/loaders/html.py +119 -0
  91. flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
  92. flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
  93. flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
  94. flowtask/components/LangchainLoader/loaders/qa.py +67 -0
  95. flowtask/components/LangchainLoader/loaders/txt.py +55 -0
  96. flowtask/components/LeadIQ.py +650 -0
  97. flowtask/components/Loop.py +253 -0
  98. flowtask/components/Lowes.py +334 -0
  99. flowtask/components/MS365Usage.py +156 -0
  100. flowtask/components/MSTeamsMessages.py +320 -0
  101. flowtask/components/MarketClustering.py +1051 -0
  102. flowtask/components/MergeFiles.py +362 -0
  103. flowtask/components/MilvusOutput.py +87 -0
  104. flowtask/components/NearByStores.py +175 -0
  105. flowtask/components/NetworkNinja/__init__.py +6 -0
  106. flowtask/components/NetworkNinja/models/__init__.py +52 -0
  107. flowtask/components/NetworkNinja/models/abstract.py +177 -0
  108. flowtask/components/NetworkNinja/models/account.py +39 -0
  109. flowtask/components/NetworkNinja/models/client.py +19 -0
  110. flowtask/components/NetworkNinja/models/district.py +14 -0
  111. flowtask/components/NetworkNinja/models/events.py +101 -0
  112. flowtask/components/NetworkNinja/models/forms.py +499 -0
  113. flowtask/components/NetworkNinja/models/market.py +16 -0
  114. flowtask/components/NetworkNinja/models/organization.py +34 -0
  115. flowtask/components/NetworkNinja/models/photos.py +125 -0
  116. flowtask/components/NetworkNinja/models/project.py +44 -0
  117. flowtask/components/NetworkNinja/models/region.py +28 -0
  118. flowtask/components/NetworkNinja/models/store.py +203 -0
  119. flowtask/components/NetworkNinja/models/user.py +151 -0
  120. flowtask/components/NetworkNinja/router.py +854 -0
  121. flowtask/components/Odoo.py +175 -0
  122. flowtask/components/OdooInjector.py +192 -0
  123. flowtask/components/OpenFromXML.py +126 -0
  124. flowtask/components/OpenWeather.py +41 -0
  125. flowtask/components/OpenWithBase.py +616 -0
  126. flowtask/components/OpenWithPandas.py +715 -0
  127. flowtask/components/PGPDecrypt.py +199 -0
  128. flowtask/components/PandasIterator.py +187 -0
  129. flowtask/components/PandasToFile.py +189 -0
  130. flowtask/components/Paradox.py +339 -0
  131. flowtask/components/ParamIterator.py +117 -0
  132. flowtask/components/ParseHTML.py +84 -0
  133. flowtask/components/PlacerStores.py +249 -0
  134. flowtask/components/Pokemon.py +507 -0
  135. flowtask/components/PositiveBot.py +62 -0
  136. flowtask/components/PowerPointSlide.py +400 -0
  137. flowtask/components/PrintMessage.py +127 -0
  138. flowtask/components/ProductCompetitors/__init__.py +5 -0
  139. flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
  140. flowtask/components/ProductCompetitors/parsers/base.py +72 -0
  141. flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
  142. flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
  143. flowtask/components/ProductCompetitors/scrapper.py +155 -0
  144. flowtask/components/ProductCompliant.py +169 -0
  145. flowtask/components/ProductInfo/__init__.py +1 -0
  146. flowtask/components/ProductInfo/parsers/__init__.py +5 -0
  147. flowtask/components/ProductInfo/parsers/base.py +83 -0
  148. flowtask/components/ProductInfo/parsers/brother.py +97 -0
  149. flowtask/components/ProductInfo/parsers/canon.py +167 -0
  150. flowtask/components/ProductInfo/parsers/epson.py +118 -0
  151. flowtask/components/ProductInfo/parsers/hp.py +131 -0
  152. flowtask/components/ProductInfo/parsers/samsung.py +97 -0
  153. flowtask/components/ProductInfo/scraper.py +319 -0
  154. flowtask/components/ProductPricing.py +118 -0
  155. flowtask/components/QS.py +261 -0
  156. flowtask/components/QSBase.py +201 -0
  157. flowtask/components/QueryIterator.py +273 -0
  158. flowtask/components/QueryToInsert.py +327 -0
  159. flowtask/components/QueryToPandas.py +432 -0
  160. flowtask/components/RESTClient.py +195 -0
  161. flowtask/components/RethinkDBQuery.py +189 -0
  162. flowtask/components/Rsync.py +74 -0
  163. flowtask/components/RunSSH.py +59 -0
  164. flowtask/components/RunShell.py +71 -0
  165. flowtask/components/SalesForce.py +20 -0
  166. flowtask/components/SaveImageBank/__init__.py +257 -0
  167. flowtask/components/SchedulingVisits.py +592 -0
  168. flowtask/components/ScrapPage.py +216 -0
  169. flowtask/components/ScrapSearch.py +79 -0
  170. flowtask/components/SendNotify.py +257 -0
  171. flowtask/components/SentimentAnalysis.py +694 -0
  172. flowtask/components/ServiceScrapper/__init__.py +5 -0
  173. flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
  174. flowtask/components/ServiceScrapper/parsers/base.py +94 -0
  175. flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
  176. flowtask/components/ServiceScrapper/scrapper.py +199 -0
  177. flowtask/components/SetVariables.py +156 -0
  178. flowtask/components/SubTask.py +182 -0
  179. flowtask/components/SuiteCRM.py +48 -0
  180. flowtask/components/Switch.py +175 -0
  181. flowtask/components/TableBase.py +148 -0
  182. flowtask/components/TableDelete.py +312 -0
  183. flowtask/components/TableInput.py +143 -0
  184. flowtask/components/TableOutput/TableOutput.py +384 -0
  185. flowtask/components/TableOutput/__init__.py +3 -0
  186. flowtask/components/TableSchema.py +534 -0
  187. flowtask/components/Target.py +223 -0
  188. flowtask/components/ThumbnailGenerator.py +156 -0
  189. flowtask/components/ToPandas.py +67 -0
  190. flowtask/components/TransformRows/TransformRows.py +507 -0
  191. flowtask/components/TransformRows/__init__.py +9 -0
  192. flowtask/components/TransformRows/functions.py +559 -0
  193. flowtask/components/TransposeRows.py +176 -0
  194. flowtask/components/UPCDatabase.py +86 -0
  195. flowtask/components/UnGzip.py +171 -0
  196. flowtask/components/Uncompress.py +172 -0
  197. flowtask/components/UniqueRows.py +126 -0
  198. flowtask/components/Unzip.py +107 -0
  199. flowtask/components/UpdateOperationalVars.py +147 -0
  200. flowtask/components/UploadTo.py +299 -0
  201. flowtask/components/UploadToS3.py +136 -0
  202. flowtask/components/UploadToSFTP.py +160 -0
  203. flowtask/components/UploadToSharepoint.py +205 -0
  204. flowtask/components/UserFunc.py +122 -0
  205. flowtask/components/VivaTracker.py +140 -0
  206. flowtask/components/WSDLClient.py +123 -0
  207. flowtask/components/Wait.py +18 -0
  208. flowtask/components/Walmart.py +199 -0
  209. flowtask/components/Workplace.py +134 -0
  210. flowtask/components/XMLToPandas.py +267 -0
  211. flowtask/components/Zammad/__init__.py +41 -0
  212. flowtask/components/Zammad/models.py +0 -0
  213. flowtask/components/ZoomInfoScraper.py +409 -0
  214. flowtask/components/__init__.py +104 -0
  215. flowtask/components/abstract.py +18 -0
  216. flowtask/components/flow.py +530 -0
  217. flowtask/components/google.py +335 -0
  218. flowtask/components/group.py +221 -0
  219. flowtask/components/py.typed +0 -0
  220. flowtask/components/reviewscrap.py +132 -0
  221. flowtask/components/tAutoincrement.py +117 -0
  222. flowtask/components/tConcat.py +109 -0
  223. flowtask/components/tExplode.py +119 -0
  224. flowtask/components/tFilter.py +184 -0
  225. flowtask/components/tGroup.py +236 -0
  226. flowtask/components/tJoin.py +270 -0
  227. flowtask/components/tMap/__init__.py +9 -0
  228. flowtask/components/tMap/functions.py +54 -0
  229. flowtask/components/tMap/tMap.py +450 -0
  230. flowtask/components/tMelt.py +112 -0
  231. flowtask/components/tMerge.py +114 -0
  232. flowtask/components/tOrder.py +93 -0
  233. flowtask/components/tPandas.py +94 -0
  234. flowtask/components/tPivot.py +71 -0
  235. flowtask/components/tPluckCols.py +76 -0
  236. flowtask/components/tUnnest.py +82 -0
  237. flowtask/components/user.py +401 -0
  238. flowtask/conf.py +457 -0
  239. flowtask/download.py +102 -0
  240. flowtask/events/__init__.py +11 -0
  241. flowtask/events/events/__init__.py +20 -0
  242. flowtask/events/events/abstract.py +95 -0
  243. flowtask/events/events/alerts/__init__.py +362 -0
  244. flowtask/events/events/alerts/colfunctions.py +131 -0
  245. flowtask/events/events/alerts/functions.py +158 -0
  246. flowtask/events/events/dummy.py +12 -0
  247. flowtask/events/events/exec.py +124 -0
  248. flowtask/events/events/file/__init__.py +7 -0
  249. flowtask/events/events/file/base.py +51 -0
  250. flowtask/events/events/file/copy.py +23 -0
  251. flowtask/events/events/file/delete.py +16 -0
  252. flowtask/events/events/interfaces/__init__.py +9 -0
  253. flowtask/events/events/interfaces/client.py +67 -0
  254. flowtask/events/events/interfaces/credentials.py +28 -0
  255. flowtask/events/events/interfaces/notifications.py +58 -0
  256. flowtask/events/events/jira.py +122 -0
  257. flowtask/events/events/log.py +26 -0
  258. flowtask/events/events/logerr.py +52 -0
  259. flowtask/events/events/notify.py +59 -0
  260. flowtask/events/events/notify_event.py +160 -0
  261. flowtask/events/events/publish.py +54 -0
  262. flowtask/events/events/sendfile.py +104 -0
  263. flowtask/events/events/task.py +97 -0
  264. flowtask/events/events/teams.py +98 -0
  265. flowtask/events/events/webhook.py +58 -0
  266. flowtask/events/manager.py +287 -0
  267. flowtask/exceptions.c +39393 -0
  268. flowtask/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
  269. flowtask/extensions/__init__.py +3 -0
  270. flowtask/extensions/abstract.py +82 -0
  271. flowtask/extensions/logging/__init__.py +65 -0
  272. flowtask/hooks/__init__.py +9 -0
  273. flowtask/hooks/actions/__init__.py +22 -0
  274. flowtask/hooks/actions/abstract.py +66 -0
  275. flowtask/hooks/actions/dummy.py +23 -0
  276. flowtask/hooks/actions/jira.py +74 -0
  277. flowtask/hooks/actions/rest.py +320 -0
  278. flowtask/hooks/actions/sampledata.py +37 -0
  279. flowtask/hooks/actions/sensor.py +23 -0
  280. flowtask/hooks/actions/task.py +9 -0
  281. flowtask/hooks/actions/ticket.py +37 -0
  282. flowtask/hooks/actions/zammad.py +55 -0
  283. flowtask/hooks/hook.py +62 -0
  284. flowtask/hooks/models.py +17 -0
  285. flowtask/hooks/service.py +187 -0
  286. flowtask/hooks/step.py +91 -0
  287. flowtask/hooks/types/__init__.py +23 -0
  288. flowtask/hooks/types/base.py +129 -0
  289. flowtask/hooks/types/brokers/__init__.py +11 -0
  290. flowtask/hooks/types/brokers/base.py +54 -0
  291. flowtask/hooks/types/brokers/mqtt.py +35 -0
  292. flowtask/hooks/types/brokers/rabbitmq.py +82 -0
  293. flowtask/hooks/types/brokers/redis.py +83 -0
  294. flowtask/hooks/types/brokers/sqs.py +44 -0
  295. flowtask/hooks/types/fs.py +232 -0
  296. flowtask/hooks/types/http.py +49 -0
  297. flowtask/hooks/types/imap.py +200 -0
  298. flowtask/hooks/types/jira.py +279 -0
  299. flowtask/hooks/types/mail.py +205 -0
  300. flowtask/hooks/types/postgres.py +98 -0
  301. flowtask/hooks/types/responses/__init__.py +8 -0
  302. flowtask/hooks/types/responses/base.py +5 -0
  303. flowtask/hooks/types/sharepoint.py +288 -0
  304. flowtask/hooks/types/ssh.py +141 -0
  305. flowtask/hooks/types/tagged.py +59 -0
  306. flowtask/hooks/types/upload.py +85 -0
  307. flowtask/hooks/types/watch.py +71 -0
  308. flowtask/hooks/types/web.py +36 -0
  309. flowtask/interfaces/AzureClient.py +137 -0
  310. flowtask/interfaces/AzureGraph.py +839 -0
  311. flowtask/interfaces/Boto3Client.py +326 -0
  312. flowtask/interfaces/DropboxClient.py +173 -0
  313. flowtask/interfaces/ExcelHandler.py +94 -0
  314. flowtask/interfaces/FTPClient.py +131 -0
  315. flowtask/interfaces/GoogleCalendar.py +201 -0
  316. flowtask/interfaces/GoogleClient.py +133 -0
  317. flowtask/interfaces/GoogleDrive.py +127 -0
  318. flowtask/interfaces/GoogleGCS.py +89 -0
  319. flowtask/interfaces/GoogleGeocoding.py +93 -0
  320. flowtask/interfaces/GoogleLang.py +114 -0
  321. flowtask/interfaces/GooglePub.py +61 -0
  322. flowtask/interfaces/GoogleSheet.py +68 -0
  323. flowtask/interfaces/IMAPClient.py +137 -0
  324. flowtask/interfaces/O365Calendar.py +113 -0
  325. flowtask/interfaces/O365Client.py +220 -0
  326. flowtask/interfaces/OneDrive.py +284 -0
  327. flowtask/interfaces/Outlook.py +155 -0
  328. flowtask/interfaces/ParrotBot.py +130 -0
  329. flowtask/interfaces/SSHClient.py +378 -0
  330. flowtask/interfaces/Sharepoint.py +496 -0
  331. flowtask/interfaces/__init__.py +36 -0
  332. flowtask/interfaces/azureauth.py +119 -0
  333. flowtask/interfaces/cache.py +201 -0
  334. flowtask/interfaces/client.py +82 -0
  335. flowtask/interfaces/compress.py +525 -0
  336. flowtask/interfaces/credentials.py +124 -0
  337. flowtask/interfaces/d2l.py +239 -0
  338. flowtask/interfaces/databases/__init__.py +5 -0
  339. flowtask/interfaces/databases/db.py +223 -0
  340. flowtask/interfaces/databases/documentdb.py +55 -0
  341. flowtask/interfaces/databases/rethink.py +39 -0
  342. flowtask/interfaces/dataframes/__init__.py +11 -0
  343. flowtask/interfaces/dataframes/abstract.py +21 -0
  344. flowtask/interfaces/dataframes/arrow.py +71 -0
  345. flowtask/interfaces/dataframes/dt.py +69 -0
  346. flowtask/interfaces/dataframes/pandas.py +167 -0
  347. flowtask/interfaces/dataframes/polars.py +60 -0
  348. flowtask/interfaces/db.py +263 -0
  349. flowtask/interfaces/env.py +46 -0
  350. flowtask/interfaces/func.py +137 -0
  351. flowtask/interfaces/http.py +1780 -0
  352. flowtask/interfaces/locale.py +40 -0
  353. flowtask/interfaces/log.py +75 -0
  354. flowtask/interfaces/mask.py +143 -0
  355. flowtask/interfaces/notification.py +154 -0
  356. flowtask/interfaces/playwright.py +339 -0
  357. flowtask/interfaces/powerpoint.py +368 -0
  358. flowtask/interfaces/py.typed +0 -0
  359. flowtask/interfaces/qs.py +376 -0
  360. flowtask/interfaces/result.py +87 -0
  361. flowtask/interfaces/selenium_service.py +779 -0
  362. flowtask/interfaces/smartsheet.py +154 -0
  363. flowtask/interfaces/stat.py +39 -0
  364. flowtask/interfaces/task.py +96 -0
  365. flowtask/interfaces/template.py +118 -0
  366. flowtask/interfaces/vectorstores/__init__.py +1 -0
  367. flowtask/interfaces/vectorstores/abstract.py +133 -0
  368. flowtask/interfaces/vectorstores/milvus.py +669 -0
  369. flowtask/interfaces/zammad.py +107 -0
  370. flowtask/models.py +193 -0
  371. flowtask/parsers/__init__.py +15 -0
  372. flowtask/parsers/_yaml.c +11978 -0
  373. flowtask/parsers/_yaml.cpython-310-x86_64-linux-gnu.so +0 -0
  374. flowtask/parsers/argparser.py +235 -0
  375. flowtask/parsers/base.c +15155 -0
  376. flowtask/parsers/base.cpython-310-x86_64-linux-gnu.so +0 -0
  377. flowtask/parsers/json.c +11968 -0
  378. flowtask/parsers/json.cpython-310-x86_64-linux-gnu.so +0 -0
  379. flowtask/parsers/maps.py +49 -0
  380. flowtask/parsers/toml.c +11968 -0
  381. flowtask/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
  382. flowtask/plugins/__init__.py +16 -0
  383. flowtask/plugins/components/__init__.py +0 -0
  384. flowtask/plugins/handler/__init__.py +45 -0
  385. flowtask/plugins/importer.py +31 -0
  386. flowtask/plugins/sources/__init__.py +0 -0
  387. flowtask/runner.py +283 -0
  388. flowtask/scheduler/__init__.py +9 -0
  389. flowtask/scheduler/functions.py +493 -0
  390. flowtask/scheduler/handlers/__init__.py +8 -0
  391. flowtask/scheduler/handlers/manager.py +504 -0
  392. flowtask/scheduler/handlers/models.py +58 -0
  393. flowtask/scheduler/handlers/service.py +72 -0
  394. flowtask/scheduler/notifications.py +65 -0
  395. flowtask/scheduler/scheduler.py +993 -0
  396. flowtask/services/__init__.py +0 -0
  397. flowtask/services/bots/__init__.py +0 -0
  398. flowtask/services/bots/telegram.py +264 -0
  399. flowtask/services/files/__init__.py +11 -0
  400. flowtask/services/files/manager.py +522 -0
  401. flowtask/services/files/model.py +37 -0
  402. flowtask/services/files/service.py +767 -0
  403. flowtask/services/jira/__init__.py +3 -0
  404. flowtask/services/jira/jira_actions.py +191 -0
  405. flowtask/services/tasks/__init__.py +13 -0
  406. flowtask/services/tasks/launcher.py +213 -0
  407. flowtask/services/tasks/manager.py +323 -0
  408. flowtask/services/tasks/service.py +275 -0
  409. flowtask/services/tasks/task_manager.py +376 -0
  410. flowtask/services/tasks/tasks.py +155 -0
  411. flowtask/storages/__init__.py +16 -0
  412. flowtask/storages/exceptions.py +12 -0
  413. flowtask/storages/files/__init__.py +8 -0
  414. flowtask/storages/files/abstract.py +29 -0
  415. flowtask/storages/files/filesystem.py +66 -0
  416. flowtask/storages/tasks/__init__.py +19 -0
  417. flowtask/storages/tasks/abstract.py +26 -0
  418. flowtask/storages/tasks/database.py +33 -0
  419. flowtask/storages/tasks/filesystem.py +108 -0
  420. flowtask/storages/tasks/github.py +119 -0
  421. flowtask/storages/tasks/memory.py +45 -0
  422. flowtask/storages/tasks/row.py +25 -0
  423. flowtask/tasks/__init__.py +0 -0
  424. flowtask/tasks/abstract.py +526 -0
  425. flowtask/tasks/command.py +118 -0
  426. flowtask/tasks/pile.py +486 -0
  427. flowtask/tasks/py.typed +0 -0
  428. flowtask/tasks/task.py +778 -0
  429. flowtask/template/__init__.py +161 -0
  430. flowtask/tests.py +257 -0
  431. flowtask/types/__init__.py +8 -0
  432. flowtask/types/typedefs.c +11347 -0
  433. flowtask/types/typedefs.cpython-310-x86_64-linux-gnu.so +0 -0
  434. flowtask/utils/__init__.py +24 -0
  435. flowtask/utils/constants.py +117 -0
  436. flowtask/utils/encoders.py +21 -0
  437. flowtask/utils/executor.py +112 -0
  438. flowtask/utils/functions.cpp +14280 -0
  439. flowtask/utils/functions.cpython-310-x86_64-linux-gnu.so +0 -0
  440. flowtask/utils/json.cpp +13349 -0
  441. flowtask/utils/json.cpython-310-x86_64-linux-gnu.so +0 -0
  442. flowtask/utils/mail.py +63 -0
  443. flowtask/utils/parseqs.c +13324 -0
  444. flowtask/utils/parserqs.cpython-310-x86_64-linux-gnu.so +0 -0
  445. flowtask/utils/stats.py +308 -0
  446. flowtask/utils/transformations.py +74 -0
  447. flowtask/utils/uv.py +12 -0
  448. flowtask/utils/validators.py +97 -0
  449. flowtask/version.py +11 -0
  450. flowtask-5.8.4.dist-info/LICENSE +201 -0
  451. flowtask-5.8.4.dist-info/METADATA +209 -0
  452. flowtask-5.8.4.dist-info/RECORD +470 -0
  453. flowtask-5.8.4.dist-info/WHEEL +6 -0
  454. flowtask-5.8.4.dist-info/entry_points.txt +3 -0
  455. flowtask-5.8.4.dist-info/top_level.txt +2 -0
  456. plugins/components/CreateQR.py +39 -0
  457. plugins/components/TestComponent.py +28 -0
  458. plugins/components/Use1.py +13 -0
  459. plugins/components/Workplace.py +117 -0
  460. plugins/components/__init__.py +3 -0
  461. plugins/sources/__init__.py +0 -0
  462. plugins/sources/get_populartimes.py +78 -0
  463. plugins/sources/google.py +150 -0
  464. plugins/sources/hubspot.py +679 -0
  465. plugins/sources/icims.py +679 -0
  466. plugins/sources/mobileinsight.py +501 -0
  467. plugins/sources/newrelic.py +262 -0
  468. plugins/sources/uap.py +268 -0
  469. plugins/sources/venu.py +244 -0
  470. plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,140 @@
1
+ from pathlib import Path
2
+ from urllib.parse import urljoin
3
+ from bs4 import BeautifulSoup
4
+ import magic
5
+ import orjson
6
+ import pandas as pd
7
+ from ..exceptions import ComponentError
8
+ from .ASPX import ASPX
9
+ from ..conf import TASK_PATH
10
+
11
+
12
+ class VivaTracker(ASPX):
13
+ async def start(self, **kwargs):
14
+ directory = Path(TASK_PATH, self._program, "reports")
15
+ report_json_path = Path(directory).joinpath(self.report_filename)
16
+
17
+ try:
18
+ with open(report_json_path) as f:
19
+ report_values_dict = orjson.loads(f.read())
20
+ except FileNotFoundError as ex:
21
+ raise ComponentError(
22
+ f"Can't read the additional params file. Make sure there's a file {report_json_path}"
23
+ ) from ex
24
+
25
+ additional_component_attrs = {
26
+ "base_url": "https://mso.vivatracker.com",
27
+ "login_user_payload_key": "ctl00$ContentPlaceHolder1$txtEmail",
28
+ "login_password_payload_key": "ctl00$ContentPlaceHolder1$txtPassword",
29
+ "login_button_payload_key": "ctl00$ContentPlaceHolder1$btnSubmit",
30
+ "login_button_payload_value": "Login",
31
+ **report_values_dict,
32
+ }
33
+
34
+ for attr, value in additional_component_attrs.items():
35
+ self.__setattr__(attr, value)
36
+
37
+ self.additional_payload_params = self.process_mask("additional_payload_params")
38
+
39
+ self._report_url = urljoin(self.base_url, f"{self.report_path}.aspx")
40
+
41
+ return await super().start()
42
+
43
+ async def _go_to_report(self):
44
+ await self.aspx_session(self._report_url)
45
+
46
+ def _get_report_payload(self, btn_id, btn_value):
47
+ return {
48
+ **self._views,
49
+ **self.additional_payload_params,
50
+ f"ctl00$ContentPlaceHolder1${btn_id}": btn_value,
51
+ }
52
+
53
+ def _extract_additional_values(self, soup: BeautifulSoup):
54
+ """Extract additional values from the html report given a df column and
55
+ an element id present in the DOM
56
+
57
+ Args:
58
+ response (requests.Response): http response
59
+
60
+ Returns:
61
+ dict: key: dataframe column, value: value extracted
62
+
63
+
64
+ Example:
65
+
66
+ ```yaml
67
+ VivaTracker:
68
+ credentials:
69
+ username: VIVATRACKER_USERNAME
70
+ password: VIVATRACKER_PASSWORD
71
+ report_filename: sales_by_invoice_report.json
72
+ masks:
73
+ '{yesterday}':
74
+ - yesterday
75
+ - mask: '%m-%d-%Y'
76
+ '{today}':
77
+ - today
78
+ - mask: '%m-%d-%Y'
79
+ ```
80
+
81
+ """
82
+ self._extracted_additional_values = {}
83
+
84
+ if hasattr(self, "additional_values_to_extract"):
85
+ for _field, _elem_id in self.additional_values_to_extract.items():
86
+ s_elem = soup.find(id=_elem_id)
87
+
88
+ if s_elem:
89
+ self._extracted_additional_values[_field] = s_elem.get(
90
+ "value", s_elem.text
91
+ )
92
+
93
+ async def _get_report_html(self):
94
+ self._logger.info("Waiting for data to be displayed in html...")
95
+ report_payload = self._get_report_payload(
96
+ btn_id="btnSubmit", btn_value="Get Report"
97
+ )
98
+ payload = self._get_payload_with_views(**report_payload)
99
+ result = await self.aspx_session(self._report_url, method="post", data=payload)
100
+ self._extract_additional_values(result)
101
+
102
+ async def _extract_file_report(self) -> bytes:
103
+ self._logger.info("Downloading file...")
104
+ report_payload = self._get_report_payload(
105
+ btn_id=self.export_to_excel_btn_id,
106
+ btn_value="Export to Excel",
107
+ )
108
+ payload = self._get_payload_with_views(**report_payload)
109
+
110
+ self.accept = "application/xml"
111
+ result = await self.aspx_session(
112
+ self._report_url,
113
+ method="post",
114
+ data=payload,
115
+ follow_redirects=True,
116
+ )
117
+
118
+ return result
119
+
120
+ async def _get_df_from_report_bytes(self, result: bytes) -> pd.DataFrame:
121
+ if "text/html" in magic.from_buffer(result, mime=True):
122
+ df = pd.read_html(result, header=0)[0]
123
+ else:
124
+ df = pd.read_excel(result, header=0)
125
+
126
+ df = df.assign(**self._extracted_additional_values)
127
+ df.reset_index(drop=True, inplace=True)
128
+
129
+ return await self.create_dataframe(df)
130
+
131
+ async def run(self):
132
+ await self._go_to_report()
133
+ await self._get_report_html()
134
+ result = await self._extract_file_report()
135
+ df = await self._get_df_from_report_bytes(result)
136
+
137
+ await super().run()
138
+
139
+ self._result = df
140
+ return self._result
@@ -0,0 +1,123 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ # zeep integration
5
+ from zeep import Client, Settings, helpers
6
+ from zeep.transports import Transport
7
+ from ..exceptions import ComponentError
8
+ from .flow import FlowComponent
9
+
10
+
11
+ class WSDLClient(FlowComponent):
12
+ """
13
+ WSDLClient.
14
+
15
+ Client for WSDL SOAP Web Services using Zeep
16
+ """
17
+
18
+ transport = None
19
+ transport_options = {"timeout": 10}
20
+ method = ""
21
+ settings = None
22
+ settings_options = {"strict": True, "xml_huge_tree": False}
23
+ _wsdl = None
24
+ url: str = ""
25
+ raw_response = False
26
+ _filename: str = ""
27
+ _directory: str = ""
28
+ saving_xml = False
29
+
30
+ async def start(self, **kwargs):
31
+ """Obtain Pandas Dataframe."""
32
+ if self.previous:
33
+ self.data = self.input
34
+ # defining methods for WSDL Client
35
+ self.transport = Transport(**self.transport_options)
36
+ self.settings = Settings(**self.settings_options)
37
+ if not hasattr(self, "method"):
38
+ raise ComponentError(
39
+ "WSDL Error: You need to define a Method using *method* attribute"
40
+ )
41
+ if not self.url:
42
+ raise ComponentError(
43
+ "WSDL Error: You need to define a WSDL endpoint using the *url* attribute"
44
+ )
45
+ # creating a client:
46
+ self._wsdl = Client(self.url, settings=self.settings)
47
+ # check if we need to save to an xml file:
48
+ if hasattr(self, "to_file"):
49
+ self.saving_xml = True
50
+ self._directory = Path(self.to_file["directory"])
51
+ if "filename" in self.to_file:
52
+ self._filename = self.to_file["filename"]
53
+ else:
54
+ # using a pattern:
55
+ f = self.to_file["file"]
56
+ file = f["pattern"]
57
+ if hasattr(self, "masks"):
58
+ for mask, replace in self.masks.items():
59
+ if isinstance(replace, str):
60
+ m = mask.translate({ord("{"): None, ord("}"): None})
61
+ if m in self.params.keys():
62
+ # using params instead mask value
63
+ file = file.replace(mask, self.params[m])
64
+ else:
65
+ # replace inmediately
66
+ file = file.replace(mask, replace)
67
+ # else:
68
+ # file = file.replace(mask, convert(replace))
69
+ self._filename = file
70
+
71
+ @property
72
+ def client(self):
73
+ return self._wsdl
74
+
75
+ async def close(self):
76
+ """Method."""
77
+ self._wsdl = None
78
+
79
+ def saving_file(self, content):
80
+ if not self._directory.exists():
81
+ raise ComponentError(
82
+ f"Directory for saving XML file doesn't exists: {self._directory}"
83
+ )
84
+ path = self._directory.joinpath(self._filename)
85
+ if path.exists():
86
+ if "replace" in self.to_file:
87
+ os.remove(path)
88
+ with open(path, "w", encoding="utf-8") as f:
89
+ f.write(content)
90
+ if self._debug:
91
+ print(f"Saving XML File on: {path}")
92
+ # self._result = path
93
+
94
+ def queryMethod(self, method, **kwargs):
95
+ response = None
96
+ if not method:
97
+ method = self.method
98
+ try:
99
+ fn = getattr(self._wsdl.service, method)
100
+ response = fn(**kwargs)
101
+ except Exception as err:
102
+ raise ComponentError(
103
+ f"Error Calling method {method} over WSDL client, error: {err}"
104
+ ) from err
105
+ finally:
106
+ return response
107
+
108
+ async def run(self):
109
+ response = None
110
+ try:
111
+ with self._wsdl.settings(raw_response=self.raw_response):
112
+ obj = self.queryMethod(self.method, **self.params)
113
+ if obj:
114
+ if hasattr(self, "serialize"):
115
+ response = helpers.serialize_object(obj, dict)
116
+ else:
117
+ response = obj
118
+ self._result = response
119
+ return self._result
120
+ else:
121
+ return False
122
+ except (ComponentError, Exception) as err:
123
+ raise ComponentError(str(err)) from err
@@ -0,0 +1,18 @@
1
+ import asyncio
2
+ from .flow import FlowComponent
3
+
4
+
5
+ class Wait(FlowComponent):
6
+ async def start(self, **kwargs):
7
+ if self.previous:
8
+ self.data = self.input
9
+ return True
10
+
11
+ async def close(self):
12
+ pass
13
+
14
+ async def run(self):
15
+ await asyncio.sleep(self.wait)
16
+ self.add_metric("WAIT", self.wait)
17
+ self._result = self.data
18
+ return self._result
@@ -0,0 +1,199 @@
1
+ """
2
+ Scrapping a Web Page Using Selenium + ChromeDriver + BeautifulSoup.
3
+ """
4
+ import asyncio
5
+ from collections.abc import Callable
6
+ import random
7
+ import json
8
+ from urllib.parse import quote_plus
9
+ import httpx
10
+ import pandas as pd
11
+ import backoff
12
+ from ..interfaces.http import ua
13
+ from .reviewscrap import ReviewScrapper, bad_gateway_exception
14
+
15
+
16
+ class Walmart(ReviewScrapper):
17
+ """Walmart.
18
+
19
+ Combining API Key and Web Scrapping, this component will be able to extract
20
+ Walmart Information (reviews, etc).
21
+ """
22
+ def __init__(
23
+ self,
24
+ loop: asyncio.AbstractEventLoop = None,
25
+ job: Callable = None,
26
+ stat: Callable = None,
27
+ **kwargs,
28
+ ):
29
+ super(Walmart, self).__init__(
30
+ loop=loop,
31
+ job=job,
32
+ stat=stat,
33
+ **kwargs
34
+ )
35
+ # Always use proxies:
36
+ self.use_proxy: bool = True
37
+ self._free_proxy: bool = False
38
+ self.cookies = {
39
+ "_pxhd": "dbf5757b1f867196173eab3a4ab6377bbcd202cdd59b89b4372a1cf3f681b1aa:69fe9bd8-cfbd-11ef-9827-8c8dc170f864", # noqa
40
+ }
41
+ self.headers: dict = {
42
+ "Accept": "application/json",
43
+ "Accept-Encoding": "gzip, deflate, br, zstd",
44
+ "Accept-Language": "en-US",
45
+ "Content-Type": "application/json",
46
+ "Referer": "https://www.walmart.com/reviews/",
47
+ "Sec-CH-UA": '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
48
+ "Sec-CH-UA-Mobile": "?0",
49
+ "Sec-CH-UA-Platform": '"Linux"',
50
+ "Sec-Fetch-Dest": "empty",
51
+ "Sec-Fetch-Mode": "cors",
52
+ "Sec-Fetch-Site": "same-origin",
53
+ "Connection": "keep-alive",
54
+ "User-Agent": random.choice(ua),
55
+ }
56
+ self.semaphore = asyncio.Semaphore(10)
57
+
58
+ @backoff.on_exception(
59
+ backoff.expo,
60
+ (httpx.ConnectTimeout, httpx.HTTPStatusError),
61
+ max_tries=2,
62
+ giveup=lambda e: not bad_gateway_exception(e) and not isinstance(e, httpx.ConnectTimeout)
63
+ )
64
+ async def _product_reviews(self, idx, row, cookies):
65
+ async with self.semaphore:
66
+ # Prepare payload for the API request
67
+ sku = row['itemId']
68
+ max_pages = 2 # Maximum number of pages to fetch
69
+ all_reviews = []
70
+ total_reviews = 0
71
+ current_page = 1
72
+ try:
73
+ variables = {
74
+ "itemId": sku,
75
+ "page": 1, # Start with page 1
76
+ "sort": "submission-desc",
77
+ "limit": 10,
78
+ "filters": [],
79
+ "aspect": None,
80
+ "filterCriteria": {
81
+ "rating": [],
82
+ "reviewAttributes": [],
83
+ "aspectId": None
84
+ }
85
+ }
86
+ while True:
87
+ self.headers['Referer'] = f"https://www.walmart.com/reviews/product/{sku}?sort=submission-desc&page=1" # noqa
88
+ variables['page'] = current_page
89
+ variables_json = json.dumps(variables) # Proper JSON encoding
90
+ variables_encoded = quote_plus(variables_json)
91
+ url = f"https://www.walmart.com/orchestra/home/graphql/ReviewsById/{self.api_token}?variables={variables_encoded}" # noqa
92
+ print('URL > ', url)
93
+ result = await self.api_get(
94
+ url=url,
95
+ cookies=cookies,
96
+ headers=self.headers
97
+ )
98
+ if not result:
99
+ self._logger.warning(
100
+ f"No Product Reviews found for {sku}."
101
+ )
102
+ break
103
+ # Extract the reviews data from the API response
104
+ data = result.get('data', {})
105
+ reviews_data = data.get('reviews', {})
106
+ customer_reviews = reviews_data.get('customerReviews', [])
107
+ pagination = reviews_data.get('pagination', {})
108
+ # Update total_reviews
109
+ total_reviews = data.get('reviews', {}).get('totalReviewCount', 0)
110
+ if not customer_reviews:
111
+ self._logger.info(f"No more reviews found for itemId {row['itemId']} on page {current_page}.")
112
+ break
113
+
114
+ all_reviews.extend(customer_reviews)
115
+ if len(all_reviews) >= total_reviews:
116
+ self._logger.info(f"Fetched all reviews for itemId {row['itemId']}.")
117
+ break
118
+
119
+ current_page += 1
120
+ if current_page > max_pages:
121
+ self._logger.warning(f"Reached maximum page limit for itemId {row['itemId']}.")
122
+ break
123
+ except (httpx.TimeoutException, httpx.HTTPError) as ex:
124
+ self._logger.warning(f"Request failed: {ex}")
125
+ return []
126
+ except Exception as ex:
127
+ self._logger.error(f"An error occurred: {ex}")
128
+ return []
129
+
130
+ # Extract the reviews data from the API response
131
+ reviews = []
132
+ for item in all_reviews:
133
+ # Exclude certain keys
134
+ # Extract relevant fields
135
+ # Combine with original row data
136
+ review_data = row.to_dict()
137
+ review = {
138
+ **review_data,
139
+ "authorId": item.get("authorId"),
140
+ "userNickname": item.get("userNickname"),
141
+ "rating": item.get("rating"),
142
+ "reviewTitle": item.get("reviewTitle"),
143
+ "review": item.get("reviewText"),
144
+ "reviewSubmissionTime": item.get("reviewSubmissionTime"),
145
+ "clientResponses": item.get("clientResponses"),
146
+ "media": item.get("media"),
147
+ "itemId": sku,
148
+ "productName": row.get("productName"),
149
+ "productCategory": row.get("productCategory"),
150
+ }
151
+ review['total_reviews'] = total_reviews
152
+ reviews.append(review)
153
+ self._logger.info(
154
+ f"Fetched {len(reviews)} reviews for SKU {sku}."
155
+ )
156
+ return reviews
157
+
158
+ async def reviews(self):
159
+ """reviews.
160
+
161
+ Target Product Reviews.
162
+ """
163
+ httpx_cookies = httpx.Cookies()
164
+ for key, value in self.cookies.items():
165
+ httpx_cookies.set(
166
+ key, value,
167
+ domain='.walmart.com',
168
+ path='/'
169
+ )
170
+
171
+ # Iterate over each row in the DataFrame
172
+ print('starting ...')
173
+
174
+ tasks = [
175
+ self._product_reviews(
176
+ idx,
177
+ row,
178
+ httpx_cookies
179
+ ) for idx, row in self.data.iterrows()
180
+ ]
181
+ # Gather results concurrently
182
+ all_reviews_nested = await self._processing_tasks(tasks)
183
+
184
+ # Flatten the list of lists
185
+ all_reviews = [review for reviews in all_reviews_nested for review in reviews]
186
+
187
+ # Convert to DataFrame
188
+ reviews_df = pd.DataFrame(all_reviews)
189
+
190
+ # show the num of rows in final dataframe:
191
+ self._logger.notice(
192
+ f"Ending Product Reviews: {len(reviews_df)}"
193
+ )
194
+
195
+ # Override previous dataframe:
196
+ self.data = reviews_df
197
+
198
+ # return existing data
199
+ return self.data
@@ -0,0 +1,134 @@
1
+ from asyncdb.utils.types import SafeDict
2
+ from .user import UserComponent
3
+ from ..conf import WORKPLACE_ACCESS_TOKEN
4
+
5
+
6
+ class Workplace(UserComponent):
7
+ _messages_url = "https://graph.facebook.com/{thread_id}/messages?access_token={access_token}&limit=10&user={member_id}&fields=id,message,created_time,attachments,from,to,tags"
8
+ _attachments_url = "https://graph.facebook.com/v18.0/{message_id}?access_token={access_token}&limit=20&user={member_id}&fields=id,created_time,attachments"
9
+ _members_url = "https://graph.facebook.com/community/members?access_token={access_token}&limit=100&fields=member_id,first_name,last_name,name,email,title,organization,division,department,primary_phone,primary_address,picture,link,locale,updated_time,account_invite_time,account_claim_time,account_deactivate_time,external_id,start_date,about,cost_center,work_locale,frontline,active"
10
+ _member_threads = "https://graph.facebook.com/{member_id}/conversations/?access_token={access_token}&limit=100&fields=id,name,subject,participants,updated_time,messages"
11
+ accept = "application/json"
12
+
13
+ async def start(self, **kwargs):
14
+ ## Access Token
15
+ if hasattr(self, "access_token"):
16
+ access_token = self.access_token
17
+ else:
18
+ access_token = WORKPLACE_ACCESS_TOKEN
19
+ # Workplaces APIs.
20
+ if self.type == "messages":
21
+ self.member_id = self.set_variables(self.member_id)
22
+ self.thread_id = self.set_variables(self.thread_id)
23
+ self.messages_url = self._messages_url.format_map(
24
+ SafeDict(
25
+ access_token=access_token,
26
+ member_id=self.member_id,
27
+ thread_id=self.thread_id,
28
+ )
29
+ )
30
+ self._kwargs = {"url": self.messages_url, "method": "get"}
31
+ elif self.type == "attachments":
32
+ self.member_id = self.set_variables(self.member_id)
33
+ self.message_id = self.set_variables(self.message_id)
34
+ url = self._attachments_url.format_map(
35
+ SafeDict(
36
+ access_token=access_token,
37
+ message_id=self.message_id,
38
+ member_id=self.member_id,
39
+ )
40
+ )
41
+ self._kwargs = {"url": url, "method": "get"}
42
+ elif self.type == "members":
43
+ self.members_url = self._members_url.format_map(
44
+ SafeDict(access_token=access_token)
45
+ )
46
+ self._kwargs = {"url": self.members_url, "method": "get"}
47
+ elif self.type == "member_threads":
48
+ self.member_id = self.set_variables(self.member_id)
49
+ self.member_threads_url = self._member_threads.format_map(
50
+ SafeDict(access_token=access_token, member_id=self.member_id)
51
+ )
52
+ self._kwargs = {"url": self.member_threads_url, "method": "get"}
53
+
54
+ async def run(self):
55
+ results = []
56
+ result = await self.session(**self._kwargs)
57
+ if not result:
58
+ return False
59
+ if "data" in result:
60
+ results += result["data"]
61
+ elif isinstance(result, dict):
62
+ if self.type == "attachments":
63
+ if "attachments" not in result:
64
+ return False
65
+ results += [result]
66
+ else:
67
+ results += result
68
+ if "paging" in result:
69
+ url = result["paging"]["next"] if "next" in result["paging"] else None
70
+ while url is not None:
71
+ self._kwargs["url"] = url
72
+ resultset = await self.session(**self._kwargs)
73
+ results += resultset["data"]
74
+ if "paging" in result:
75
+ url = (
76
+ resultset["paging"]["next"]
77
+ if "next" in resultset["paging"]
78
+ else None
79
+ )
80
+ else:
81
+ url = None
82
+ # Iterate over a field to download more results:
83
+ if hasattr(self, "page_over"):
84
+ columns = self.page_over
85
+ for row in results:
86
+ for column in columns:
87
+ try:
88
+ rw = row[column]
89
+ except KeyError:
90
+ # there is no messages in this thread
91
+ continue
92
+ if "data" in rw:
93
+ # replacing "data" with current value of data:
94
+ row[column] = row[column]["data"]
95
+ if "paging" in row[column]:
96
+ url = (
97
+ row[column]["paging"]["next"]
98
+ if "next" in row[column]["paging"]
99
+ else None
100
+ )
101
+ while url is not None:
102
+ resultset = await self.session(url=url, method="get")
103
+ row[column] += resultset["data"]
104
+ if "paging" in result:
105
+ url = (
106
+ resultset["paging"]["next"]
107
+ if "next" in resultset["paging"]
108
+ else None
109
+ )
110
+ else:
111
+ url = None
112
+ if hasattr(self, "flatten_cols"):
113
+ columns = self.flatten_cols
114
+ for row in results:
115
+ for column in columns:
116
+ try:
117
+ if "data" in row[column]:
118
+ # replacing "data" with current value of data:
119
+ row[column] = row[column]["data"]
120
+ except KeyError:
121
+ # there is no column in this thread
122
+ continue
123
+ # Create a Dataframe from Results:
124
+ self._result = await self.create_dataframe(results)
125
+ if self.type == "member_threads":
126
+ # add the value of member_id over all rows:
127
+ self._result["member_id"] = self.member_id
128
+ elif self.type in ("messages"):
129
+ self._result["member_id"] = self.member_id
130
+ self._result["thread_id"] = self.thread_id
131
+ return self._result
132
+
133
+ async def close(self):
134
+ pass