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,181 @@
1
+ """
2
+ DownloadFromSmartSheet
3
+ Download an Excel file from SmartSheet.
4
+
5
+
6
+ Example:
7
+
8
+ ```yaml
9
+ DownloadFromFTP:
10
+ host: trendmicro_host
11
+ port: trendmicro_port
12
+ use_tls: false
13
+ file:
14
+ pattern: '{monday}.*-Limited852StoreReport.{saturday}.csv'
15
+ values:
16
+ monday:
17
+ - date_dow
18
+ - day_of_week: monday
19
+ mask: '%Y%m%d'
20
+ saturday:
21
+ - date_diff_dow
22
+ - diff: 7
23
+ day_of_week: saturday
24
+ mask: '%Y-%m-%d'
25
+ directory: /Limited852Report
26
+ credentials:
27
+ user: trendmicro_user
28
+ password: trendmicro_password
29
+ download:
30
+ directory: /home/ubuntu/symbits/trendmicro/files/market_share/
31
+ ```
32
+
33
+ """
34
+ import re
35
+ import asyncio
36
+ from pathlib import Path
37
+ from ..exceptions import ComponentError, FileError
38
+ from .DownloadFrom import DownloadFromBase
39
+ from ..interfaces.FTPClient import FTPClient
40
+
41
+
42
+ class DownloadFromFTP(FTPClient, DownloadFromBase):
43
+ """
44
+ DownloadFromFTP
45
+
46
+ Overview
47
+
48
+ Downloads files from a remote FTP server using the functionality from DownloadFrom.
49
+
50
+ Properties
51
+
52
+ .. table:: Properties
53
+ :widths: auto
54
+
55
+ +--------------+----------+-----------+--------------------------------------------------------+
56
+ | Name | Required | Summary |
57
+ +--------------+----------+-----------+--------------------------------------------------------+
58
+ | credentials | Yes | Dictionary containing username and password for FTP authentication.|
59
+ | | | (default: {"user": str, "password": str}) |
60
+ +--------------+----------+-----------+--------------------------------------------------------+
61
+ | whole_dir | Yes | Boolean flag indicating whether to download the entire directory |
62
+ | | | or specific files. (default: False) |
63
+ +--------------+----------+-----------+--------------------------------------------------------+
64
+ | use_tls | Yes | Boolean for indicate if we need to use the TLS protocol |
65
+ +--------------+----------+-----------+--------------------------------------------------------+
66
+
67
+ Save the downloaded files on the new destination.
68
+ """
69
+ _credentials: dict = {"user": str, "password": str}
70
+
71
+ async def start(self, **kwargs):
72
+ await super().start(**kwargs)
73
+ self._path: str = None
74
+ self.whole_dir: bool = False
75
+ if hasattr(self, "source"):
76
+ if "algorithms" in self.source:
77
+ self.algorithms.append(self.source["algorithms"])
78
+ # change filosophy of source/destination
79
+ self.whole_dir = (
80
+ self.source["whole_dir"] if "whole_dir" in self.source else False
81
+ )
82
+ await super(DownloadFromFTP, self).start(**kwargs)
83
+ if hasattr(self, "download"):
84
+ self.directory = Path(self.download["directory"])
85
+ return True
86
+
87
+ async def download_files(self):
88
+ try:
89
+ self._connection = await self.init_connection(
90
+ self.host, self.port, credentials=self.credentials, ssl=self.ssl
91
+ )
92
+ except asyncio.CancelledError:
93
+ self._logger.info(f"{self.host} CANCELED~")
94
+ # break
95
+ except ComponentError:
96
+ raise
97
+ except (TimeoutError, asyncio.TimeoutError) as ex:
98
+ raise ComponentError(f"Timeout: {ex}") from ex
99
+ except Exception as err:
100
+ raise ComponentError(f"DownloadFromFTP Error: {err}") from err
101
+ if self._connection:
102
+ if not await self.directory_exists(self.source_dir):
103
+ raise ComponentError(f"FTP Directory doesn't exists: {self.source_dir}")
104
+ try:
105
+ await self.change_directory(self.source_dir)
106
+ except Exception as err:
107
+ raise ComponentError(
108
+ f"FTP Unable to connect to: {self.source_dir}, error: {err}"
109
+ ) from err
110
+ # getting stats for directory
111
+ filelist = []
112
+ files = []
113
+ stats = await self._connection.list(
114
+ self.source_dir, recursive=False, raw_command="MLSD"
115
+ )
116
+ pbar = self.start_pbar(total=len(stats))
117
+ if self.whole_dir is True:
118
+ await self.download_file(
119
+ file=self.source_dir, destination=self.directory
120
+ )
121
+ for path, info in stats:
122
+ if info["type"] == "file":
123
+ file = {"filename": path, **info}
124
+ # all files downloaded:
125
+ pbar.update(1)
126
+ files.append(file)
127
+ filelist.append(path)
128
+ self.add_metric("FTP_FILES", files)
129
+ pbar.close()
130
+ else:
131
+ if self.source_file is not None:
132
+ self._srcfiles = [self.source_file]
133
+ for file in self._srcfiles:
134
+ if not self.source_dir.endswith("/"):
135
+ self.source_dir = "{}/".format(self.source_dir)
136
+ pattern = re.compile(f"^{self.source_dir}{str(file)}+$")
137
+ self._logger.debug(f"Calculated Pattern for lookup {pattern}")
138
+ for path, info in stats:
139
+ if info["type"] == "file":
140
+ # first case, match the extension:
141
+ if hasattr(self, "source"):
142
+ if "suffix" in self.source:
143
+ # download all files match with suffix:
144
+ if path.suffix == self.source["suffix"]:
145
+ file = {"filename": path, **info}
146
+ await self.download_file(
147
+ file=path, destination=self.directory
148
+ )
149
+ files.append(file)
150
+ filelist.append(path)
151
+ elif pattern.match(str(path)):
152
+ self._logger.debug(f"Looking for matching file {path}")
153
+ file = {"filename": path, **info}
154
+ files.append(file)
155
+ filelist.append(path)
156
+ # using regex to check file
157
+ await self.download_file(
158
+ file=path, destination=self.directory
159
+ )
160
+ pbar.update(1)
161
+ pbar.set_description(f"Processing {path}")
162
+ self.add_metric("FTP_FILES", files)
163
+ pbar.close()
164
+ self._result = ["{}/{}".format(self.directory, v.name) for v in filelist]
165
+ print(self._result)
166
+ return True
167
+ else:
168
+ return False
169
+
170
+ async def run(self):
171
+ self._result = None
172
+ if self._debug:
173
+ self._logger.info(f"Downloading FTP files: {self._filenames}")
174
+ try:
175
+ status = await self.download_files()
176
+ except (ComponentError, Exception) as err:
177
+ self._logger.error(err)
178
+ raise
179
+ if not status:
180
+ raise FileError(f"File(s) Not Found: {self.source_file}")
181
+ return self._result
@@ -0,0 +1,315 @@
1
+ import asyncio
2
+ from collections.abc import Callable
3
+ import re
4
+ import fnmatch
5
+ from pathlib import Path, PurePath
6
+ import imaplib
7
+ import aiofiles
8
+ from ..conf import IMAP_RETRY_SELECT, FILES_PATH
9
+ from ..utils.mail import MailMessage
10
+ from ..exceptions import ComponentError, FileNotFound
11
+ from .DownloadFrom import DownloadFromBase
12
+ from ..interfaces.IMAPClient import IMAPClient
13
+
14
+
15
+ class DownloadFromIMAP(IMAPClient, DownloadFromBase):
16
+ """
17
+ DownloadFromIMAP.
18
+
19
+ Overview
20
+
21
+ Download emails from an IMAP mailbox using the functionality from DownloadFrom.
22
+
23
+ .. table:: Properties
24
+ :widths: auto
25
+
26
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
27
+ | Name | Required | Summary |
28
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
29
+ | credentials | Yes | Credentials to access the IMAP mailbox. |
30
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
31
+ | mailbox | Yes | The IMAP mailbox name (default: "INBOX"). |
32
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
33
+ | search_terms | Yes | Dictionary containing search criteria in IMAP format. |
34
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
35
+ | attachments | Yes | Dictionary specifying download configuration for attachments: |
36
+ | | | - directory (str): Path to save downloaded attachments. |
37
+ | | | - filename (str, optional): Filename pattern for selection (fnmatch). |
38
+ | | | - pattern (str, optional): Regular expression pattern for selection. |
39
+ | | | - expected_mime (str, optional): Expected MIME type filter. |
40
+ | | | - rename (str, optional): Template string for renaming attachments (uses "{filename}"). |
41
+ | | | - download_existing (bool, optional): Skip existing files (default: True). |
42
+ | | | - create_destination (bool, optional): Create download directory if it doesn't exist (default: True). |
43
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
44
+ | download_existing | no | Flag indicating whether to skip downloading existing files. |
45
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
46
+ | results | Yes | Dictionary containing download results: |
47
+ | | | - attachments: List of downloaded attachment file paths. |
48
+ | | | - messages: List of `MailMessage` objects representing downloaded emails. |
49
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
50
+ | use_ssl | Yes | Boolean for indicate if we need to use the TLS protocol |
51
+ +-------------------+----------+-----------+---------------------------------------------------------------------------------------------+
52
+
53
+ Save the downloaded files on the new destination.
54
+
55
+
56
+ Example:
57
+
58
+ ```yaml
59
+ DownloadFromIMAP:
60
+ credentials:
61
+ host: email_host
62
+ port: email_port
63
+ user: email_host_user
64
+ password: email_host_password
65
+ use_ssl: true
66
+ search_terms:
67
+ 'ON': '{search_today}'
68
+ SUBJECT: Custom Punch with Pay Codes - Excel
69
+ FROM: eet_application@adp.com
70
+ overwrite: true
71
+ attachments:
72
+ directory: /home/ubuntu/symbits/bose/files/worked_hours/
73
+ masks:
74
+ '{search_today}':
75
+ - today
76
+ - mask: '%d-%b-%Y'
77
+ ```
78
+
79
+ """ # noqa
80
+
81
+ def __init__(
82
+ self,
83
+ loop: asyncio.AbstractEventLoop = None,
84
+ job: Callable = None,
85
+ stat: Callable = None,
86
+ **kwargs,
87
+ ) -> None:
88
+ self.attachments = {"directory": None}
89
+ self.search_terms = None
90
+ super().__init__(
91
+ loop=loop, job=job, stat=stat, **kwargs
92
+ )
93
+
94
+ async def start(self, **kwargs): # pylint: disable=W0613
95
+ if hasattr(self, "attachments"):
96
+ # attachment directory
97
+ if "directory" not in self.attachments:
98
+ self.attachments["directory"] = FILES_PATH.joinpath(
99
+ self._program, "files", "download"
100
+ )
101
+ else:
102
+ self.attachments["directory"] = Path(
103
+ self.attachments["directory"]
104
+ ).resolve()
105
+ try:
106
+ directory = self.attachments["directory"]
107
+ if not directory.exists():
108
+ if self.create_destination is True:
109
+ directory.mkdir(parents=True, exist_ok=True)
110
+ else:
111
+ raise ComponentError(
112
+ f"DownloadFromIMAP: Error creating directory: {directory}"
113
+ )
114
+ except Exception as err:
115
+ self._logger.error(
116
+ f"IMAP: Error creating directory: {err}"
117
+ )
118
+ raise ComponentError(
119
+ f"IMAP: Error creating directory: {err}"
120
+ ) from err
121
+ # masking elements:
122
+ if hasattr(self, "masks"):
123
+ for mask, replace in self._mask.items():
124
+ for key, val in self.attachments.items():
125
+ value = str(val).replace(mask, str(replace))
126
+ if isinstance(val, PurePath):
127
+ self.attachments[key] = Path(value)
128
+ else:
129
+ self.attachments[key] = value
130
+ await super(DownloadFromIMAP, self).start(**kwargs)
131
+ return True
132
+
133
+ async def run(self):
134
+ self._result = None
135
+ filter_criteria = []
136
+ msgs = [""]
137
+ messages = []
138
+ files: list = []
139
+ try:
140
+ await self.open(self.host, self.port, self.credentials)
141
+ if not self._client:
142
+ raise ComponentError("IMAP Connection not Opened, exiting.")
143
+ except Exception as err:
144
+ self._logger.exception(err, stack_info=True)
145
+ raise
146
+ # getting search Terms
147
+ self.search_terms = self.process_mask("search_terms")
148
+ for term, value in self.search_terms.items():
149
+ try:
150
+ value = self.mask_replacement(value)
151
+ filter_criteria.append(f'({term} "{value}")')
152
+ except (ValueError, KeyError):
153
+ pass
154
+ self._logger.debug(f"FILTER CRITERIA: {filter_criteria}")
155
+ self.add_metric("SEARCH", filter_criteria)
156
+ try:
157
+ # getting the Mailbox
158
+ self._client.select(self.mailbox)
159
+ except Exception as err:
160
+ if "User is authenticated but not connected." in str(err):
161
+ tries = 0
162
+ while tries < IMAP_RETRY_SELECT:
163
+ self._client.logout()
164
+ await asyncio.sleep(10)
165
+ try:
166
+ await self.open(self.host, self.port, self.credentials)
167
+ if not self._client:
168
+ raise ComponentError(
169
+ "IMAP Connection not Opened, exiting."
170
+ ) from err
171
+ self._client.select(self.mailbox)
172
+ break
173
+ except Exception as exc:
174
+ self._logger.exception(exc, stack_info=True)
175
+ if tries < (IMAP_RETRY_SELECT - 1):
176
+ tries += 1
177
+ continue
178
+ else:
179
+ raise RuntimeError(
180
+ f"IMAP: Error opening Mailbox {self.mailbox}: {exc}"
181
+ ) from exc
182
+ try:
183
+ print("FILTER ", filter_criteria)
184
+ result, msgs = self._client.search(None, *filter_criteria)
185
+ if result == "NO" or result == "BAD":
186
+ self._logger.error(msgs[0])
187
+ raise ComponentError(
188
+ message=f"Error on Search: {msgs[0]}",
189
+ status=500
190
+ )
191
+ except imaplib.IMAP4.abort as err:
192
+ raise ComponentError(f"IMAP Illegal Search: {err}") from err
193
+ except Exception as err:
194
+ self._logger.exception(err, stack_info=True)
195
+ raise ComponentError(f"IMAP Error: {err}") from err
196
+ msgs = msgs[0].split()
197
+ i = 0
198
+ if not msgs:
199
+ raise FileNotFound("DownloadFromIMAP: File(s) doesn't exists")
200
+ if not isinstance(msgs, list):
201
+ raise ComponentError(f"DownloadFromIMAP: Invalid Email Response: {msgs}")
202
+ if "expected_mime" in self.attachments:
203
+ expected_mime = self.attachments["expected_mime"]
204
+ if expected_mime:
205
+ validate_mime = True
206
+ else:
207
+ validate_mime = False
208
+ else:
209
+ expected_mime = None
210
+ validate_mime = False
211
+ for emailid in msgs:
212
+ i += 1
213
+ resp, data = self._client.fetch(emailid.decode("utf-8"), "(RFC822)")
214
+ if resp == "OK": # mail was retrieved
215
+ msg = MailMessage(
216
+ self.attachments["directory"],
217
+ data[0][1].decode("utf-8"),
218
+ data[1],
219
+ validate_mime=validate_mime,
220
+ )
221
+ messages.append(msg)
222
+ for attachment in msg.attachments:
223
+ if expected_mime is not None:
224
+ # checking only for valid MIME types:
225
+ if expected_mime != attachment["content_type"]:
226
+ continue
227
+ if "filename" in self.attachments:
228
+ fname = self.attachments[
229
+ "filename"
230
+ ] # we only need to save selected files
231
+ if not fnmatch.fnmatch(attachment["filename"], fname):
232
+ continue
233
+ else:
234
+ if "rename" in self.attachments:
235
+ filename = self.attachments["rename"]
236
+ filename = filename.replace(
237
+ "{filename}", Path(attachment["filename"]).stem
238
+ )
239
+ self._logger.debug(f"NEW FILENAME IS {filename}")
240
+ file_path = self.attachments["directory"].joinpath(
241
+ filename
242
+ )
243
+ else:
244
+ file_path = self.attachments["directory"].joinpath(
245
+ attachment["filename"]
246
+ )
247
+ elif (
248
+ "pattern" in self.attachments
249
+ ): # only save files that match the pattern
250
+ fpattern = self.attachments["pattern"]
251
+ if bool(re.match(fpattern, attachment["filename"])):
252
+ file_path = self.attachments["directory"].joinpath(
253
+ attachment["filename"]
254
+ )
255
+ else:
256
+ continue
257
+ else:
258
+ # I need to save everything
259
+ if "rename" in self.attachments:
260
+ filename = self.attachments["rename"]
261
+ if hasattr(self, "masks"):
262
+ filename = self.mask_replacement(filename)
263
+ # for mask, replace in self._mask.items():
264
+ # filename = filename.replace(mask, replace)
265
+ filename = filename.replace(
266
+ "{filename}", Path(attachment["filename"]).stem
267
+ )
268
+ file_path = self.attachments["directory"].joinpath(filename)
269
+ else:
270
+ file_path = self.attachments["directory"].joinpath(
271
+ attachment["filename"]
272
+ )
273
+ # saving the filename in the attachment
274
+ attachment["filename"] = file_path
275
+ if "download_existing" in self.attachments:
276
+ if (
277
+ file_path.exists()
278
+ and self.attachments["download_existing"] is False
279
+ ):
280
+ # we don't need to download again
281
+ self._logger.info(f"File Exists {file_path!s}, skipping")
282
+ continue
283
+ if file_path.exists() and self.overwrite is False:
284
+ # TODO: before to save a new renamed file,
285
+ # we need to check if we have it (checksum)
286
+ file_name = file_path.name
287
+ # dir_name = file_path.absolute()
288
+ ext = file_path.suffix
289
+ # calculated new filepath
290
+ file_path = self.attachments["directory"].joinpath(
291
+ f"{file_name}_{i}{ext}"
292
+ )
293
+ if file_path.exists():
294
+ # TODO: more efficient way (while) to check if file exists
295
+ files.append(file_path)
296
+ continue
297
+ await self.save_attachment(file_path, attachment["attachment"])
298
+ # saving this file in the list of files:
299
+ files.append(file_path)
300
+ else:
301
+ raise ComponentError(f"File was not fetch: {resp}")
302
+ # saving the result:
303
+ self.add_metric("ATTACHMENTS", files)
304
+ self.add_metric("NUM_ATTACHMENTS", len(files))
305
+ self.add_metric('NUM_MESSAGES', len(messages))
306
+ self._result = {"messages": messages, "files": files}
307
+ return self._result
308
+
309
+ async def save_attachment(self, file_path, content):
310
+ try:
311
+ self._logger.info(f"IMAP: Saving attachment file: {file_path}")
312
+ async with aiofiles.open(file_path, mode="wb") as fp:
313
+ await fp.write(content)
314
+ except Exception as err:
315
+ raise ComponentError(f"File {file_path} was not saved: {err}") from err