flowtask 5.8.4__cp312-cp312-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.
- flowtask/__init__.py +93 -0
- flowtask/__main__.py +38 -0
- flowtask/bots/__init__.py +6 -0
- flowtask/bots/check.py +93 -0
- flowtask/bots/codebot.py +51 -0
- flowtask/components/ASPX.py +148 -0
- flowtask/components/AddDataset.py +352 -0
- flowtask/components/Amazon.py +523 -0
- flowtask/components/AutoTask.py +314 -0
- flowtask/components/Azure.py +80 -0
- flowtask/components/AzureUsers.py +106 -0
- flowtask/components/BaseAction.py +91 -0
- flowtask/components/BaseLoop.py +198 -0
- flowtask/components/BestBuy.py +800 -0
- flowtask/components/CSVToGCS.py +120 -0
- flowtask/components/CompanyScraper/__init__.py +1 -0
- flowtask/components/CompanyScraper/parsers/__init__.py +6 -0
- flowtask/components/CompanyScraper/parsers/base.py +102 -0
- flowtask/components/CompanyScraper/parsers/explorium.py +192 -0
- flowtask/components/CompanyScraper/parsers/leadiq.py +206 -0
- flowtask/components/CompanyScraper/parsers/rocket.py +133 -0
- flowtask/components/CompanyScraper/parsers/siccode.py +109 -0
- flowtask/components/CompanyScraper/parsers/visualvisitor.py +130 -0
- flowtask/components/CompanyScraper/parsers/zoominfo.py +118 -0
- flowtask/components/CompanyScraper/scrapper.py +1054 -0
- flowtask/components/CopyTo.py +177 -0
- flowtask/components/CopyToBigQuery.py +243 -0
- flowtask/components/CopyToMongoDB.py +291 -0
- flowtask/components/CopyToPg.py +609 -0
- flowtask/components/CopyToRethink.py +207 -0
- flowtask/components/CreateGCSBucket.py +102 -0
- flowtask/components/CreateReport/CreateReport.py +228 -0
- flowtask/components/CreateReport/__init__.py +9 -0
- flowtask/components/CreateReport/charts/__init__.py +15 -0
- flowtask/components/CreateReport/charts/bar.py +51 -0
- flowtask/components/CreateReport/charts/base.py +66 -0
- flowtask/components/CreateReport/charts/pie.py +64 -0
- flowtask/components/CreateReport/utils.py +9 -0
- flowtask/components/CustomerSatisfaction.py +196 -0
- flowtask/components/DataInput.py +200 -0
- flowtask/components/DateList.py +255 -0
- flowtask/components/DbClient.py +163 -0
- flowtask/components/DialPad.py +146 -0
- flowtask/components/DocumentDBQuery.py +200 -0
- flowtask/components/DownloadFrom.py +371 -0
- flowtask/components/DownloadFromD2L.py +113 -0
- flowtask/components/DownloadFromFTP.py +181 -0
- flowtask/components/DownloadFromIMAP.py +315 -0
- flowtask/components/DownloadFromS3.py +198 -0
- flowtask/components/DownloadFromSFTP.py +265 -0
- flowtask/components/DownloadFromSharepoint.py +110 -0
- flowtask/components/DownloadFromSmartSheet.py +114 -0
- flowtask/components/DownloadS3File.py +229 -0
- flowtask/components/Dummy.py +59 -0
- flowtask/components/DuplicatePhoto.py +411 -0
- flowtask/components/EmployeeEvaluation.py +237 -0
- flowtask/components/ExecuteSQL.py +323 -0
- flowtask/components/ExtractHTML.py +178 -0
- flowtask/components/FileBase.py +178 -0
- flowtask/components/FileCopy.py +181 -0
- flowtask/components/FileDelete.py +82 -0
- flowtask/components/FileExists.py +146 -0
- flowtask/components/FileIteratorDelete.py +112 -0
- flowtask/components/FileList.py +194 -0
- flowtask/components/FileOpen.py +75 -0
- flowtask/components/FileRead.py +120 -0
- flowtask/components/FileRename.py +106 -0
- flowtask/components/FilterIf.py +284 -0
- flowtask/components/FilterRows/FilterRows.py +200 -0
- flowtask/components/FilterRows/__init__.py +10 -0
- flowtask/components/FilterRows/functions.py +4 -0
- flowtask/components/GCSToBigQuery.py +103 -0
- flowtask/components/GoogleA4.py +150 -0
- flowtask/components/GoogleGeoCoding.py +344 -0
- flowtask/components/GooglePlaces.py +315 -0
- flowtask/components/GoogleSearch.py +539 -0
- flowtask/components/HTTPClient.py +268 -0
- flowtask/components/ICIMS.py +146 -0
- flowtask/components/IF.py +179 -0
- flowtask/components/IcimsFolderCopy.py +173 -0
- flowtask/components/ImageFeatures/__init__.py +5 -0
- flowtask/components/ImageFeatures/process.py +233 -0
- flowtask/components/IteratorBase.py +251 -0
- flowtask/components/LangchainLoader/__init__.py +5 -0
- flowtask/components/LangchainLoader/loader.py +194 -0
- flowtask/components/LangchainLoader/loaders/__init__.py +22 -0
- flowtask/components/LangchainLoader/loaders/abstract.py +362 -0
- flowtask/components/LangchainLoader/loaders/basepdf.py +50 -0
- flowtask/components/LangchainLoader/loaders/docx.py +91 -0
- flowtask/components/LangchainLoader/loaders/html.py +119 -0
- flowtask/components/LangchainLoader/loaders/pdfblocks.py +146 -0
- flowtask/components/LangchainLoader/loaders/pdfmark.py +79 -0
- flowtask/components/LangchainLoader/loaders/pdftables.py +135 -0
- flowtask/components/LangchainLoader/loaders/qa.py +67 -0
- flowtask/components/LangchainLoader/loaders/txt.py +55 -0
- flowtask/components/LeadIQ.py +650 -0
- flowtask/components/Loop.py +253 -0
- flowtask/components/Lowes.py +334 -0
- flowtask/components/MS365Usage.py +156 -0
- flowtask/components/MSTeamsMessages.py +320 -0
- flowtask/components/MarketClustering.py +1051 -0
- flowtask/components/MergeFiles.py +362 -0
- flowtask/components/MilvusOutput.py +87 -0
- flowtask/components/NearByStores.py +175 -0
- flowtask/components/NetworkNinja/__init__.py +6 -0
- flowtask/components/NetworkNinja/models/__init__.py +52 -0
- flowtask/components/NetworkNinja/models/abstract.py +177 -0
- flowtask/components/NetworkNinja/models/account.py +39 -0
- flowtask/components/NetworkNinja/models/client.py +19 -0
- flowtask/components/NetworkNinja/models/district.py +14 -0
- flowtask/components/NetworkNinja/models/events.py +101 -0
- flowtask/components/NetworkNinja/models/forms.py +499 -0
- flowtask/components/NetworkNinja/models/market.py +16 -0
- flowtask/components/NetworkNinja/models/organization.py +34 -0
- flowtask/components/NetworkNinja/models/photos.py +125 -0
- flowtask/components/NetworkNinja/models/project.py +44 -0
- flowtask/components/NetworkNinja/models/region.py +28 -0
- flowtask/components/NetworkNinja/models/store.py +203 -0
- flowtask/components/NetworkNinja/models/user.py +151 -0
- flowtask/components/NetworkNinja/router.py +854 -0
- flowtask/components/Odoo.py +175 -0
- flowtask/components/OdooInjector.py +192 -0
- flowtask/components/OpenFromXML.py +126 -0
- flowtask/components/OpenWeather.py +41 -0
- flowtask/components/OpenWithBase.py +616 -0
- flowtask/components/OpenWithPandas.py +715 -0
- flowtask/components/PGPDecrypt.py +199 -0
- flowtask/components/PandasIterator.py +187 -0
- flowtask/components/PandasToFile.py +189 -0
- flowtask/components/Paradox.py +339 -0
- flowtask/components/ParamIterator.py +117 -0
- flowtask/components/ParseHTML.py +84 -0
- flowtask/components/PlacerStores.py +249 -0
- flowtask/components/Pokemon.py +507 -0
- flowtask/components/PositiveBot.py +62 -0
- flowtask/components/PowerPointSlide.py +400 -0
- flowtask/components/PrintMessage.py +127 -0
- flowtask/components/ProductCompetitors/__init__.py +5 -0
- flowtask/components/ProductCompetitors/parsers/__init__.py +7 -0
- flowtask/components/ProductCompetitors/parsers/base.py +72 -0
- flowtask/components/ProductCompetitors/parsers/bestbuy.py +86 -0
- flowtask/components/ProductCompetitors/parsers/lowes.py +103 -0
- flowtask/components/ProductCompetitors/scrapper.py +155 -0
- flowtask/components/ProductCompliant.py +169 -0
- flowtask/components/ProductInfo/__init__.py +1 -0
- flowtask/components/ProductInfo/parsers/__init__.py +5 -0
- flowtask/components/ProductInfo/parsers/base.py +83 -0
- flowtask/components/ProductInfo/parsers/brother.py +97 -0
- flowtask/components/ProductInfo/parsers/canon.py +167 -0
- flowtask/components/ProductInfo/parsers/epson.py +118 -0
- flowtask/components/ProductInfo/parsers/hp.py +131 -0
- flowtask/components/ProductInfo/parsers/samsung.py +97 -0
- flowtask/components/ProductInfo/scraper.py +319 -0
- flowtask/components/ProductPricing.py +118 -0
- flowtask/components/QS.py +261 -0
- flowtask/components/QSBase.py +201 -0
- flowtask/components/QueryIterator.py +273 -0
- flowtask/components/QueryToInsert.py +327 -0
- flowtask/components/QueryToPandas.py +432 -0
- flowtask/components/RESTClient.py +195 -0
- flowtask/components/RethinkDBQuery.py +189 -0
- flowtask/components/Rsync.py +74 -0
- flowtask/components/RunSSH.py +59 -0
- flowtask/components/RunShell.py +71 -0
- flowtask/components/SalesForce.py +20 -0
- flowtask/components/SaveImageBank/__init__.py +257 -0
- flowtask/components/SchedulingVisits.py +592 -0
- flowtask/components/ScrapPage.py +216 -0
- flowtask/components/ScrapSearch.py +79 -0
- flowtask/components/SendNotify.py +257 -0
- flowtask/components/SentimentAnalysis.py +694 -0
- flowtask/components/ServiceScrapper/__init__.py +5 -0
- flowtask/components/ServiceScrapper/parsers/__init__.py +1 -0
- flowtask/components/ServiceScrapper/parsers/base.py +94 -0
- flowtask/components/ServiceScrapper/parsers/costco.py +93 -0
- flowtask/components/ServiceScrapper/scrapper.py +199 -0
- flowtask/components/SetVariables.py +156 -0
- flowtask/components/SubTask.py +182 -0
- flowtask/components/SuiteCRM.py +48 -0
- flowtask/components/Switch.py +175 -0
- flowtask/components/TableBase.py +148 -0
- flowtask/components/TableDelete.py +312 -0
- flowtask/components/TableInput.py +143 -0
- flowtask/components/TableOutput/TableOutput.py +384 -0
- flowtask/components/TableOutput/__init__.py +3 -0
- flowtask/components/TableSchema.py +534 -0
- flowtask/components/Target.py +223 -0
- flowtask/components/ThumbnailGenerator.py +156 -0
- flowtask/components/ToPandas.py +67 -0
- flowtask/components/TransformRows/TransformRows.py +507 -0
- flowtask/components/TransformRows/__init__.py +9 -0
- flowtask/components/TransformRows/functions.py +559 -0
- flowtask/components/TransposeRows.py +176 -0
- flowtask/components/UPCDatabase.py +86 -0
- flowtask/components/UnGzip.py +171 -0
- flowtask/components/Uncompress.py +172 -0
- flowtask/components/UniqueRows.py +126 -0
- flowtask/components/Unzip.py +107 -0
- flowtask/components/UpdateOperationalVars.py +147 -0
- flowtask/components/UploadTo.py +299 -0
- flowtask/components/UploadToS3.py +136 -0
- flowtask/components/UploadToSFTP.py +160 -0
- flowtask/components/UploadToSharepoint.py +205 -0
- flowtask/components/UserFunc.py +122 -0
- flowtask/components/VivaTracker.py +140 -0
- flowtask/components/WSDLClient.py +123 -0
- flowtask/components/Wait.py +18 -0
- flowtask/components/Walmart.py +199 -0
- flowtask/components/Workplace.py +134 -0
- flowtask/components/XMLToPandas.py +267 -0
- flowtask/components/Zammad/__init__.py +41 -0
- flowtask/components/Zammad/models.py +0 -0
- flowtask/components/ZoomInfoScraper.py +409 -0
- flowtask/components/__init__.py +104 -0
- flowtask/components/abstract.py +18 -0
- flowtask/components/flow.py +530 -0
- flowtask/components/google.py +335 -0
- flowtask/components/group.py +221 -0
- flowtask/components/py.typed +0 -0
- flowtask/components/reviewscrap.py +132 -0
- flowtask/components/tAutoincrement.py +117 -0
- flowtask/components/tConcat.py +109 -0
- flowtask/components/tExplode.py +119 -0
- flowtask/components/tFilter.py +184 -0
- flowtask/components/tGroup.py +236 -0
- flowtask/components/tJoin.py +270 -0
- flowtask/components/tMap/__init__.py +9 -0
- flowtask/components/tMap/functions.py +54 -0
- flowtask/components/tMap/tMap.py +450 -0
- flowtask/components/tMelt.py +112 -0
- flowtask/components/tMerge.py +114 -0
- flowtask/components/tOrder.py +93 -0
- flowtask/components/tPandas.py +94 -0
- flowtask/components/tPivot.py +71 -0
- flowtask/components/tPluckCols.py +76 -0
- flowtask/components/tUnnest.py +82 -0
- flowtask/components/user.py +401 -0
- flowtask/conf.py +457 -0
- flowtask/download.py +102 -0
- flowtask/events/__init__.py +11 -0
- flowtask/events/events/__init__.py +20 -0
- flowtask/events/events/abstract.py +95 -0
- flowtask/events/events/alerts/__init__.py +362 -0
- flowtask/events/events/alerts/colfunctions.py +131 -0
- flowtask/events/events/alerts/functions.py +158 -0
- flowtask/events/events/dummy.py +12 -0
- flowtask/events/events/exec.py +124 -0
- flowtask/events/events/file/__init__.py +7 -0
- flowtask/events/events/file/base.py +51 -0
- flowtask/events/events/file/copy.py +23 -0
- flowtask/events/events/file/delete.py +16 -0
- flowtask/events/events/interfaces/__init__.py +9 -0
- flowtask/events/events/interfaces/client.py +67 -0
- flowtask/events/events/interfaces/credentials.py +28 -0
- flowtask/events/events/interfaces/notifications.py +58 -0
- flowtask/events/events/jira.py +122 -0
- flowtask/events/events/log.py +26 -0
- flowtask/events/events/logerr.py +52 -0
- flowtask/events/events/notify.py +59 -0
- flowtask/events/events/notify_event.py +160 -0
- flowtask/events/events/publish.py +54 -0
- flowtask/events/events/sendfile.py +104 -0
- flowtask/events/events/task.py +97 -0
- flowtask/events/events/teams.py +98 -0
- flowtask/events/events/webhook.py +58 -0
- flowtask/events/manager.py +287 -0
- flowtask/exceptions.c +39393 -0
- flowtask/exceptions.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/extensions/__init__.py +3 -0
- flowtask/extensions/abstract.py +82 -0
- flowtask/extensions/logging/__init__.py +65 -0
- flowtask/hooks/__init__.py +9 -0
- flowtask/hooks/actions/__init__.py +22 -0
- flowtask/hooks/actions/abstract.py +66 -0
- flowtask/hooks/actions/dummy.py +23 -0
- flowtask/hooks/actions/jira.py +74 -0
- flowtask/hooks/actions/rest.py +320 -0
- flowtask/hooks/actions/sampledata.py +37 -0
- flowtask/hooks/actions/sensor.py +23 -0
- flowtask/hooks/actions/task.py +9 -0
- flowtask/hooks/actions/ticket.py +37 -0
- flowtask/hooks/actions/zammad.py +55 -0
- flowtask/hooks/hook.py +62 -0
- flowtask/hooks/models.py +17 -0
- flowtask/hooks/service.py +187 -0
- flowtask/hooks/step.py +91 -0
- flowtask/hooks/types/__init__.py +23 -0
- flowtask/hooks/types/base.py +129 -0
- flowtask/hooks/types/brokers/__init__.py +11 -0
- flowtask/hooks/types/brokers/base.py +54 -0
- flowtask/hooks/types/brokers/mqtt.py +35 -0
- flowtask/hooks/types/brokers/rabbitmq.py +82 -0
- flowtask/hooks/types/brokers/redis.py +83 -0
- flowtask/hooks/types/brokers/sqs.py +44 -0
- flowtask/hooks/types/fs.py +232 -0
- flowtask/hooks/types/http.py +49 -0
- flowtask/hooks/types/imap.py +200 -0
- flowtask/hooks/types/jira.py +279 -0
- flowtask/hooks/types/mail.py +205 -0
- flowtask/hooks/types/postgres.py +98 -0
- flowtask/hooks/types/responses/__init__.py +8 -0
- flowtask/hooks/types/responses/base.py +5 -0
- flowtask/hooks/types/sharepoint.py +288 -0
- flowtask/hooks/types/ssh.py +141 -0
- flowtask/hooks/types/tagged.py +59 -0
- flowtask/hooks/types/upload.py +85 -0
- flowtask/hooks/types/watch.py +71 -0
- flowtask/hooks/types/web.py +36 -0
- flowtask/interfaces/AzureClient.py +137 -0
- flowtask/interfaces/AzureGraph.py +839 -0
- flowtask/interfaces/Boto3Client.py +326 -0
- flowtask/interfaces/DropboxClient.py +173 -0
- flowtask/interfaces/ExcelHandler.py +94 -0
- flowtask/interfaces/FTPClient.py +131 -0
- flowtask/interfaces/GoogleCalendar.py +201 -0
- flowtask/interfaces/GoogleClient.py +133 -0
- flowtask/interfaces/GoogleDrive.py +127 -0
- flowtask/interfaces/GoogleGCS.py +89 -0
- flowtask/interfaces/GoogleGeocoding.py +93 -0
- flowtask/interfaces/GoogleLang.py +114 -0
- flowtask/interfaces/GooglePub.py +61 -0
- flowtask/interfaces/GoogleSheet.py +68 -0
- flowtask/interfaces/IMAPClient.py +137 -0
- flowtask/interfaces/O365Calendar.py +113 -0
- flowtask/interfaces/O365Client.py +220 -0
- flowtask/interfaces/OneDrive.py +284 -0
- flowtask/interfaces/Outlook.py +155 -0
- flowtask/interfaces/ParrotBot.py +130 -0
- flowtask/interfaces/SSHClient.py +378 -0
- flowtask/interfaces/Sharepoint.py +496 -0
- flowtask/interfaces/__init__.py +36 -0
- flowtask/interfaces/azureauth.py +119 -0
- flowtask/interfaces/cache.py +201 -0
- flowtask/interfaces/client.py +82 -0
- flowtask/interfaces/compress.py +525 -0
- flowtask/interfaces/credentials.py +124 -0
- flowtask/interfaces/d2l.py +239 -0
- flowtask/interfaces/databases/__init__.py +5 -0
- flowtask/interfaces/databases/db.py +223 -0
- flowtask/interfaces/databases/documentdb.py +55 -0
- flowtask/interfaces/databases/rethink.py +39 -0
- flowtask/interfaces/dataframes/__init__.py +11 -0
- flowtask/interfaces/dataframes/abstract.py +21 -0
- flowtask/interfaces/dataframes/arrow.py +71 -0
- flowtask/interfaces/dataframes/dt.py +69 -0
- flowtask/interfaces/dataframes/pandas.py +167 -0
- flowtask/interfaces/dataframes/polars.py +60 -0
- flowtask/interfaces/db.py +263 -0
- flowtask/interfaces/env.py +46 -0
- flowtask/interfaces/func.py +137 -0
- flowtask/interfaces/http.py +1780 -0
- flowtask/interfaces/locale.py +40 -0
- flowtask/interfaces/log.py +75 -0
- flowtask/interfaces/mask.py +143 -0
- flowtask/interfaces/notification.py +154 -0
- flowtask/interfaces/playwright.py +339 -0
- flowtask/interfaces/powerpoint.py +368 -0
- flowtask/interfaces/py.typed +0 -0
- flowtask/interfaces/qs.py +376 -0
- flowtask/interfaces/result.py +87 -0
- flowtask/interfaces/selenium_service.py +779 -0
- flowtask/interfaces/smartsheet.py +154 -0
- flowtask/interfaces/stat.py +39 -0
- flowtask/interfaces/task.py +96 -0
- flowtask/interfaces/template.py +118 -0
- flowtask/interfaces/vectorstores/__init__.py +1 -0
- flowtask/interfaces/vectorstores/abstract.py +133 -0
- flowtask/interfaces/vectorstores/milvus.py +669 -0
- flowtask/interfaces/zammad.py +107 -0
- flowtask/models.py +193 -0
- flowtask/parsers/__init__.py +15 -0
- flowtask/parsers/_yaml.c +11978 -0
- flowtask/parsers/_yaml.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/argparser.py +235 -0
- flowtask/parsers/base.c +15155 -0
- flowtask/parsers/base.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/json.c +11968 -0
- flowtask/parsers/json.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/maps.py +49 -0
- flowtask/parsers/toml.c +11968 -0
- flowtask/parsers/toml.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/plugins/__init__.py +16 -0
- flowtask/plugins/components/__init__.py +0 -0
- flowtask/plugins/handler/__init__.py +45 -0
- flowtask/plugins/importer.py +31 -0
- flowtask/plugins/sources/__init__.py +0 -0
- flowtask/runner.py +283 -0
- flowtask/scheduler/__init__.py +9 -0
- flowtask/scheduler/functions.py +493 -0
- flowtask/scheduler/handlers/__init__.py +8 -0
- flowtask/scheduler/handlers/manager.py +504 -0
- flowtask/scheduler/handlers/models.py +58 -0
- flowtask/scheduler/handlers/service.py +72 -0
- flowtask/scheduler/notifications.py +65 -0
- flowtask/scheduler/scheduler.py +993 -0
- flowtask/services/__init__.py +0 -0
- flowtask/services/bots/__init__.py +0 -0
- flowtask/services/bots/telegram.py +264 -0
- flowtask/services/files/__init__.py +11 -0
- flowtask/services/files/manager.py +522 -0
- flowtask/services/files/model.py +37 -0
- flowtask/services/files/service.py +767 -0
- flowtask/services/jira/__init__.py +3 -0
- flowtask/services/jira/jira_actions.py +191 -0
- flowtask/services/tasks/__init__.py +13 -0
- flowtask/services/tasks/launcher.py +213 -0
- flowtask/services/tasks/manager.py +323 -0
- flowtask/services/tasks/service.py +275 -0
- flowtask/services/tasks/task_manager.py +376 -0
- flowtask/services/tasks/tasks.py +155 -0
- flowtask/storages/__init__.py +16 -0
- flowtask/storages/exceptions.py +12 -0
- flowtask/storages/files/__init__.py +8 -0
- flowtask/storages/files/abstract.py +29 -0
- flowtask/storages/files/filesystem.py +66 -0
- flowtask/storages/tasks/__init__.py +19 -0
- flowtask/storages/tasks/abstract.py +26 -0
- flowtask/storages/tasks/database.py +33 -0
- flowtask/storages/tasks/filesystem.py +108 -0
- flowtask/storages/tasks/github.py +119 -0
- flowtask/storages/tasks/memory.py +45 -0
- flowtask/storages/tasks/row.py +25 -0
- flowtask/tasks/__init__.py +0 -0
- flowtask/tasks/abstract.py +526 -0
- flowtask/tasks/command.py +118 -0
- flowtask/tasks/pile.py +486 -0
- flowtask/tasks/py.typed +0 -0
- flowtask/tasks/task.py +778 -0
- flowtask/template/__init__.py +161 -0
- flowtask/tests.py +257 -0
- flowtask/types/__init__.py +8 -0
- flowtask/types/typedefs.c +11347 -0
- flowtask/types/typedefs.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/__init__.py +24 -0
- flowtask/utils/constants.py +117 -0
- flowtask/utils/encoders.py +21 -0
- flowtask/utils/executor.py +112 -0
- flowtask/utils/functions.cpp +14280 -0
- flowtask/utils/functions.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/json.cpp +13349 -0
- flowtask/utils/json.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/mail.py +63 -0
- flowtask/utils/parseqs.c +13324 -0
- flowtask/utils/parserqs.cpython-312-x86_64-linux-gnu.so +0 -0
- flowtask/utils/stats.py +308 -0
- flowtask/utils/transformations.py +74 -0
- flowtask/utils/uv.py +12 -0
- flowtask/utils/validators.py +97 -0
- flowtask/version.py +11 -0
- flowtask-5.8.4.dist-info/LICENSE +201 -0
- flowtask-5.8.4.dist-info/METADATA +209 -0
- flowtask-5.8.4.dist-info/RECORD +470 -0
- flowtask-5.8.4.dist-info/WHEEL +6 -0
- flowtask-5.8.4.dist-info/entry_points.txt +3 -0
- flowtask-5.8.4.dist-info/top_level.txt +2 -0
- plugins/components/CreateQR.py +39 -0
- plugins/components/TestComponent.py +28 -0
- plugins/components/Use1.py +13 -0
- plugins/components/Workplace.py +117 -0
- plugins/components/__init__.py +3 -0
- plugins/sources/__init__.py +0 -0
- plugins/sources/get_populartimes.py +78 -0
- plugins/sources/google.py +150 -0
- plugins/sources/hubspot.py +679 -0
- plugins/sources/icims.py +679 -0
- plugins/sources/mobileinsight.py +501 -0
- plugins/sources/newrelic.py +262 -0
- plugins/sources/uap.py +268 -0
- plugins/sources/venu.py +244 -0
- plugins/sources/vocinity.py +314 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
import os
|
2
|
+
import asyncio
|
3
|
+
import logging
|
4
|
+
from collections.abc import Callable
|
5
|
+
from pathlib import Path
|
6
|
+
from tqdm import tqdm
|
7
|
+
from threading import Semaphore
|
8
|
+
from asyncdb.exceptions import ProviderError
|
9
|
+
from ..exceptions import ComponentError, NotSupported, FileNotFound
|
10
|
+
from ..utils import check_empty
|
11
|
+
from .IteratorBase import IteratorBase, ThreadJob
|
12
|
+
|
13
|
+
|
14
|
+
class FileList(IteratorBase):
|
15
|
+
"""
|
16
|
+
FileList with optional Parallelization Support.
|
17
|
+
|
18
|
+
Overview
|
19
|
+
|
20
|
+
This component iterates through a specified directory and returns a list of files based on a provided pattern or individual files.
|
21
|
+
It supports asynchronous processing and offers options for managing empty results and detailed error handling.
|
22
|
+
|
23
|
+
|
24
|
+
.. table:: Properties
|
25
|
+
:widths: auto
|
26
|
+
|
27
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
28
|
+
| Name | Required | Description |
|
29
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
30
|
+
| directory (str) | Yes | Path to the directory containing the files to be listed. |
|
31
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
32
|
+
| pattern (str) | No | Optional glob pattern for filtering files (overrides individual files if provided). |
|
33
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
34
|
+
| filename (str) | No | Name of the files |
|
35
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
36
|
+
| iterate (bool) | No | Flag indicating whether to iterate through the files and process them sequentially (defaults to True).|
|
37
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
38
|
+
| generator (bool) | No | Flag controlling the output format: `True` returns a generator, `False` (default) returns a list. |
|
39
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
40
|
+
| file (dict) | No | A dictionary containing two values, "pattern" and "value", "pattern" and "value", |
|
41
|
+
| | | "pattern" contains the path of the file on the server, If it contains the mask "{value}", |
|
42
|
+
| | | then "value" is used to set the value of that mask |
|
43
|
+
+---------------------+----------+-----------+-------------------------------------------------------------------------------------------+
|
44
|
+
| parallelize | No | If True, the iterator will process rows in parallel. Default is False. |
|
45
|
+
+---------------------+----------+-----------+-------------------------------------------------------------------------------------------+
|
46
|
+
| num_threads | No | Number of threads to use if parallelize is True. Default is 10. |
|
47
|
+
+---------------------+----------+-----------+-------------------------------------------------------------------------------------------+
|
48
|
+
|
49
|
+
Return the list of files in a Directory
|
50
|
+
|
51
|
+
|
52
|
+
Example:
|
53
|
+
|
54
|
+
```yaml
|
55
|
+
FileList:
|
56
|
+
directory: /home/ubuntu/symbits/bayardad/files/job_advertising/bulk/
|
57
|
+
pattern: '*.csv'
|
58
|
+
iterate: true
|
59
|
+
```
|
60
|
+
|
61
|
+
""" # noqa
|
62
|
+
|
63
|
+
def __init__(
|
64
|
+
self,
|
65
|
+
loop: asyncio.AbstractEventLoop = None,
|
66
|
+
job: Callable = None,
|
67
|
+
stat: Callable = None,
|
68
|
+
**kwargs,
|
69
|
+
):
|
70
|
+
"""Init Method."""
|
71
|
+
self.generator: bool = False
|
72
|
+
self._path = None
|
73
|
+
self.pattern = None
|
74
|
+
self.data = None
|
75
|
+
self.directory: str = None
|
76
|
+
self._num_threads: int = kwargs.pop("num_threads", 10)
|
77
|
+
self._parallelize: bool = kwargs.pop("parallelize", False)
|
78
|
+
super(FileList, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
79
|
+
|
80
|
+
async def start(self, **kwargs):
|
81
|
+
"""Check if Directory exists."""
|
82
|
+
await super(FileList, self).start()
|
83
|
+
if not self.directory:
|
84
|
+
raise ComponentError("Error: need to specify a Directory")
|
85
|
+
if isinstance(self.directory, str) and "{" in self.directory:
|
86
|
+
self.directory = self.mask_replacement(self.directory)
|
87
|
+
print(f"Directory: {self.directory}")
|
88
|
+
# check if directory exists
|
89
|
+
p = Path(self.directory)
|
90
|
+
if p.exists() and p.is_dir():
|
91
|
+
self._path = p
|
92
|
+
else:
|
93
|
+
raise ComponentError("Error: Directory doesn't exist!")
|
94
|
+
return True
|
95
|
+
|
96
|
+
def get_filelist(self):
|
97
|
+
if self.pattern:
|
98
|
+
value = self.pattern
|
99
|
+
if "{" in value:
|
100
|
+
value = self.mask_replacement(value)
|
101
|
+
if self._variables:
|
102
|
+
value = value.format(**self._variables)
|
103
|
+
files = (f for f in self._path.glob(value))
|
104
|
+
elif hasattr(self, "file"):
|
105
|
+
# using pattern/file version
|
106
|
+
value = self.get_filepattern()
|
107
|
+
files = (f for f in self._path.glob(value) if f.is_file())
|
108
|
+
else:
|
109
|
+
files = (f for f in self._path.iterdir() if f.is_file())
|
110
|
+
files = sorted(files, key=os.path.getmtime)
|
111
|
+
return files
|
112
|
+
|
113
|
+
async def run(self):
|
114
|
+
status = False
|
115
|
+
if not self._path:
|
116
|
+
return False
|
117
|
+
if self.iterate:
|
118
|
+
files = list(self.get_filelist())
|
119
|
+
step, target, params = self.get_step()
|
120
|
+
step_name = step.name
|
121
|
+
if self._parallelize:
|
122
|
+
# Parallelized execution
|
123
|
+
threads = []
|
124
|
+
semaphore = Semaphore(self._num_threads)
|
125
|
+
with tqdm(total=len(files)) as pbar:
|
126
|
+
for file in files:
|
127
|
+
self._result = file
|
128
|
+
params["filename"] = file
|
129
|
+
params["directory"] = self.directory
|
130
|
+
job = self.get_job(target, **params)
|
131
|
+
if job:
|
132
|
+
pbar.set_description(f"Processing {file.name}")
|
133
|
+
thread = ThreadJob(job, step_name, semaphore)
|
134
|
+
threads.append(thread)
|
135
|
+
thread.start()
|
136
|
+
# wait for all threads to finish
|
137
|
+
results = []
|
138
|
+
for thread in threads:
|
139
|
+
thread.join()
|
140
|
+
# check if thread raised any exceptions
|
141
|
+
if thread.exc:
|
142
|
+
raise thread.exc
|
143
|
+
pbar.update(1)
|
144
|
+
results.append(thread.result)
|
145
|
+
if check_empty(results):
|
146
|
+
return False
|
147
|
+
else:
|
148
|
+
self._result = results
|
149
|
+
return self._result
|
150
|
+
else:
|
151
|
+
# generate and iterator
|
152
|
+
with tqdm(total=len(files)) as pbar:
|
153
|
+
for file in files:
|
154
|
+
self._result = file
|
155
|
+
params["filename"] = file
|
156
|
+
params["directory"] = self.directory
|
157
|
+
logging.debug(f" :: Loading File: {file}")
|
158
|
+
status = False
|
159
|
+
job = self.get_job(target, **params)
|
160
|
+
if job:
|
161
|
+
pbar.set_description(f"Processing {file.name}")
|
162
|
+
try:
|
163
|
+
status = await self.async_job(job, step_name)
|
164
|
+
pbar.update(1)
|
165
|
+
except (ProviderError, ComponentError, NotSupported) as err:
|
166
|
+
raise NotSupported(
|
167
|
+
f"Error running Component {step_name}, error: {err}"
|
168
|
+
) from err
|
169
|
+
except Exception as err:
|
170
|
+
raise ComponentError(
|
171
|
+
f"Generic Component Error on {step_name}, error: {err}"
|
172
|
+
) from err
|
173
|
+
if check_empty(status):
|
174
|
+
return False
|
175
|
+
else:
|
176
|
+
return status
|
177
|
+
else:
|
178
|
+
files = self.get_filelist()
|
179
|
+
if files:
|
180
|
+
if self.generator is False:
|
181
|
+
self._result = list(files)
|
182
|
+
else:
|
183
|
+
self._result = files
|
184
|
+
if len(self._result) < 100:
|
185
|
+
self.add_metric("FILE_LIST", self._result)
|
186
|
+
self.add_metric(
|
187
|
+
"FILE_LIST_COUNT", len(self._result)
|
188
|
+
)
|
189
|
+
return self._result
|
190
|
+
else:
|
191
|
+
raise FileNotFound(f"FileList: No files found {files}")
|
192
|
+
|
193
|
+
async def close(self):
|
194
|
+
pass
|
@@ -0,0 +1,75 @@
|
|
1
|
+
from pathlib import Path, PurePath
|
2
|
+
import io
|
3
|
+
import aiofiles
|
4
|
+
from ..exceptions import FileNotFound, FileError
|
5
|
+
|
6
|
+
from .FileBase import FileBase
|
7
|
+
|
8
|
+
|
9
|
+
class FileOpen(FileBase):
|
10
|
+
"""
|
11
|
+
FileOpen.
|
12
|
+
|
13
|
+
**Overview**
|
14
|
+
|
15
|
+
This component opens one or more files asynchronously and returns their contents as streams.
|
16
|
+
It supports handling both individual filenames and lists of filenames.
|
17
|
+
It provides error handling for missing files or invalid file types.
|
18
|
+
|
19
|
+
|
20
|
+
.. table:: Properties
|
21
|
+
:widths: auto
|
22
|
+
|
23
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
24
|
+
| Name | Required | Description |
|
25
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
26
|
+
| directory (str) | Yes | Path to the directory containing the files to be listed. |
|
27
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
28
|
+
| pattern (str) | No | Optional glob pattern for filtering files (overrides individual files if provided). |
|
29
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
30
|
+
| filename (str) | No | Name of the files |
|
31
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
32
|
+
| file (dict) | No | A dictionary containing two values, "pattern" and "value", "pattern" and "value", |
|
33
|
+
| | | "pattern" contains the path of the file on the server, If it contains the mask "{value}", |
|
34
|
+
| | | then "value" is used to set the value of that mask |
|
35
|
+
+---------------------+----------+-----------+-------------------------------------------------------------------------------------------+
|
36
|
+
|
37
|
+
""" # noqa
|
38
|
+
|
39
|
+
async def run(self):
|
40
|
+
"""Run File checking."""
|
41
|
+
self._result = {}
|
42
|
+
file = None
|
43
|
+
if isinstance(self._filenames, list) and len(self._filenames) > 0:
|
44
|
+
# concatenate all files in one result:
|
45
|
+
for file in self._filenames:
|
46
|
+
if isinstance(file, str):
|
47
|
+
file = Path(file)
|
48
|
+
if file.exists() and file.is_file():
|
49
|
+
async with aiofiles.open(file, "r+") as afp:
|
50
|
+
content = await afp.read()
|
51
|
+
stream = io.StringIO(content)
|
52
|
+
stream.seek(0)
|
53
|
+
self._result[file.name] = stream
|
54
|
+
else:
|
55
|
+
self._logger.error(f"FileExists: File doesn't exists: {file}")
|
56
|
+
elif hasattr(self, "filename"):
|
57
|
+
if isinstance(self.filename, str):
|
58
|
+
file = Path(file)
|
59
|
+
elif isinstance(self.filename, PurePath):
|
60
|
+
file = self.filename.resolve()
|
61
|
+
else:
|
62
|
+
raise FileError(
|
63
|
+
f"FileExists: unrecognized type for Filename: {type(self.filename)}"
|
64
|
+
)
|
65
|
+
if file.exists() and file.is_file():
|
66
|
+
async with aiofiles.open(file, "r+") as afp:
|
67
|
+
content = await afp.read()
|
68
|
+
stream = io.StringIO(content)
|
69
|
+
stream.seek(0)
|
70
|
+
self._result[file.name] = stream
|
71
|
+
else:
|
72
|
+
raise FileNotFound(f"FileExists: Empty result: {self._filenames}")
|
73
|
+
# add metric:
|
74
|
+
self.add_metric("FILENAME", self._filenames)
|
75
|
+
return self._result
|
@@ -0,0 +1,120 @@
|
|
1
|
+
from collections.abc import Callable
|
2
|
+
import asyncio
|
3
|
+
from pathlib import Path, PurePath
|
4
|
+
import io
|
5
|
+
import aiofiles
|
6
|
+
from ..exceptions import FileNotFound, FileError
|
7
|
+
from ..utils.json import json_decoder
|
8
|
+
from .FileBase import FileBase
|
9
|
+
from ..interfaces.dataframes.pandas import PandasDataframe
|
10
|
+
|
11
|
+
|
12
|
+
class FileRead(FileBase, PandasDataframe):
|
13
|
+
"""
|
14
|
+
FileRead.
|
15
|
+
|
16
|
+
**Overview**
|
17
|
+
|
18
|
+
Read an String File and returned as string (non-binary)
|
19
|
+
|
20
|
+
|
21
|
+
.. table:: Properties
|
22
|
+
:widths: auto
|
23
|
+
|
24
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
25
|
+
| Name | Required | Description |
|
26
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
27
|
+
| directory (str) | Yes | Path to the directory containing the files to be listed. |
|
28
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
29
|
+
| pattern (str) | No | Optional glob pattern for filtering files (overrides individual files if provided). |
|
30
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
31
|
+
| filename (str) | No | Name of the files |
|
32
|
+
+---------------------+----------+-------------------------------------------------------------------------------------------------------+
|
33
|
+
| file (dict) | No | A dictionary containing two values, "pattern" and "value", "pattern" and "value", |
|
34
|
+
| | | "pattern" contains the path of the file on the server, If it contains the mask "{value}", |
|
35
|
+
| | | then "value" is used to set the value of that mask |
|
36
|
+
+---------------------+----------+-----------+-------------------------------------------------------------------------------------------+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
Example:
|
41
|
+
|
42
|
+
```yaml
|
43
|
+
FileRead:
|
44
|
+
file: recap_response_payloads.json
|
45
|
+
directory: recaps/
|
46
|
+
is_json: true
|
47
|
+
```
|
48
|
+
|
49
|
+
""" # noqa
|
50
|
+
|
51
|
+
def __init__(
|
52
|
+
self,
|
53
|
+
loop: asyncio.AbstractEventLoop = None,
|
54
|
+
job: Callable = None,
|
55
|
+
stat: Callable = None,
|
56
|
+
**kwargs,
|
57
|
+
):
|
58
|
+
self._use_taskstorage = kwargs.get('use_taskstorage', False)
|
59
|
+
super(FileRead, self).__init__(loop=loop, job=job, stat=stat, **kwargs)
|
60
|
+
|
61
|
+
async def close(self):
|
62
|
+
"""Method."""
|
63
|
+
|
64
|
+
async def start(self, **kwargs):
|
65
|
+
"""Check for File and Directory information."""
|
66
|
+
if not hasattr(self, "directory"):
|
67
|
+
if self._use_taskstorage:
|
68
|
+
self.directory = self._taskstore.get_path().joinpath(self._program, 'files')
|
69
|
+
else:
|
70
|
+
self.directory = self._filestore.get_directory('')
|
71
|
+
await super().start(**kwargs)
|
72
|
+
return True
|
73
|
+
|
74
|
+
async def run(self):
|
75
|
+
"""Run File checking."""
|
76
|
+
self._result = {}
|
77
|
+
file = None
|
78
|
+
result = ""
|
79
|
+
if isinstance(self._filenames, list) and len(self._filenames) > 0:
|
80
|
+
# concatenate all files in one result:
|
81
|
+
for file in self._filenames:
|
82
|
+
if isinstance(file, str):
|
83
|
+
file = Path(file)
|
84
|
+
if file.exists() and file.is_file():
|
85
|
+
async with aiofiles.open(file, "r+") as afp:
|
86
|
+
content = await afp.read()
|
87
|
+
result += content
|
88
|
+
else:
|
89
|
+
self._logger.error(
|
90
|
+
f"FileExists: File doesn't exists: {file}"
|
91
|
+
)
|
92
|
+
elif hasattr(self, "filename"):
|
93
|
+
if isinstance(self.filename, str):
|
94
|
+
file = Path(file)
|
95
|
+
elif isinstance(self.filename, PurePath):
|
96
|
+
file = self.filename.resolve()
|
97
|
+
else:
|
98
|
+
raise FileError(
|
99
|
+
f"FileExists: unrecognized type for Filename: {type(self.filename)}"
|
100
|
+
)
|
101
|
+
if file.exists() and file.is_file():
|
102
|
+
async with aiofiles.open(file, "r+") as afp:
|
103
|
+
content = await afp.read()
|
104
|
+
result = result + content
|
105
|
+
else:
|
106
|
+
raise FileNotFound(f"FileExists: Empty result: {self._filenames}")
|
107
|
+
# add metric:
|
108
|
+
if hasattr(self, 'is_json'):
|
109
|
+
try:
|
110
|
+
result = json_decoder(result)
|
111
|
+
except Exception as exc:
|
112
|
+
self._logger.error(
|
113
|
+
f":: Error decoding JSON: {exc}"
|
114
|
+
)
|
115
|
+
return None
|
116
|
+
if getattr(self, 'as_dataframe', False):
|
117
|
+
result = await self.create_dataframe(result)
|
118
|
+
self._result = result
|
119
|
+
self.add_metric("FILENAMES", self._filenames)
|
120
|
+
return self._result
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import os
|
2
|
+
import asyncio
|
3
|
+
from pathlib import Path
|
4
|
+
from ..exceptions import FileNotFound, FileError, ComponentError
|
5
|
+
from .FileBase import FileBase
|
6
|
+
|
7
|
+
|
8
|
+
class FileRename(FileBase):
|
9
|
+
"""
|
10
|
+
FileRename.
|
11
|
+
|
12
|
+
**Overview**
|
13
|
+
|
14
|
+
This component renames a file asynchronously based on provided source and destination paths.
|
15
|
+
It supports handling missing files and offers optional behavior for ignoring missing source files.
|
16
|
+
It performs basic validation to ensure the destination doesn't overwrite existing files.
|
17
|
+
|
18
|
+
|
19
|
+
.. table:: Properties
|
20
|
+
:widths: auto
|
21
|
+
|
22
|
+
+--------------------------+----------+---------------------------------------------------------------------------------------------------+
|
23
|
+
| Name | Required | Description |
|
24
|
+
+--------------------------+----------+---------------------------------------------------------------------------------------------------+
|
25
|
+
| directory (str) | Yes | Path to the directory containing the source file. |
|
26
|
+
+--------------------------+----------+-----------+---------------------------------------------------------------------------------------+
|
27
|
+
| destination (str) | Yes | New filename (with optional variable replacement using `set_variables` and `mask_replacement`) |
|
28
|
+
| | | for the file. |
|
29
|
+
+--------------------------+----------+-----------+---------------------------------------------------------------------------------------+
|
30
|
+
| ignore_missing (bool) | No | Flag indicating whether to ignore missing source files (defaults to False). |
|
31
|
+
+--------------------------+----------+---------------------------------------------------------------------------------------------------+
|
32
|
+
| source (str) | Yes | Filename (with optional variable replacement using `set_variables` and `mask_replacement`) |
|
33
|
+
| | | of the file to rename. |
|
34
|
+
+--------------------------+----------+-----------+---------------------------------------------------------------------------------------+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
Example:
|
40
|
+
|
41
|
+
```yaml
|
42
|
+
FileRename:
|
43
|
+
Group: ICIMSRename
|
44
|
+
ignore_missing: true
|
45
|
+
directory: /home/ubuntu/symbits/icims/files/forms/
|
46
|
+
source: '{form_id}_{form_data_id}.txt'
|
47
|
+
destination: '{form_id}_{form_data_id}_{associate_id} - {full_name}.txt'
|
48
|
+
```
|
49
|
+
|
50
|
+
""" # noqa
|
51
|
+
|
52
|
+
async def start(self, **kwargs) -> bool:
|
53
|
+
"""Check for File and Directory information."""
|
54
|
+
self._source: str = None
|
55
|
+
self._destination: str = None
|
56
|
+
if not hasattr(self, "ignore_missing"):
|
57
|
+
self.ignore_missing = False
|
58
|
+
if not hasattr(self, "directory"):
|
59
|
+
raise ComponentError("Missing Source Directory.")
|
60
|
+
if isinstance(self.directory, str):
|
61
|
+
self.directory = Path(self.directory).resolve()
|
62
|
+
if hasattr(self, "source"):
|
63
|
+
# processing source
|
64
|
+
filename = self.set_variables(self.mask_replacement(self.source))
|
65
|
+
self._logger.notice(f"Source File {filename}")
|
66
|
+
path = self.directory.joinpath(filename)
|
67
|
+
if "*" in filename:
|
68
|
+
raise ComponentError(
|
69
|
+
"FileRename: Cannot Support wildcard on filenames."
|
70
|
+
)
|
71
|
+
else:
|
72
|
+
if path.is_file():
|
73
|
+
self._logger.debug(f"Source Filename: {filename}")
|
74
|
+
self._source = path
|
75
|
+
else:
|
76
|
+
if self.ignore_missing is False:
|
77
|
+
raise FileNotFound(f"File {path} was not found.")
|
78
|
+
else:
|
79
|
+
raise ComponentError("FileRename: Missing Source information.")
|
80
|
+
if hasattr(self, "destination"):
|
81
|
+
# processing destination
|
82
|
+
filename = self.set_variables(self.mask_replacement(self.destination))
|
83
|
+
path = self.directory.joinpath(filename)
|
84
|
+
if (
|
85
|
+
self._source and path.exists()
|
86
|
+
): # we cannot rename a file overwriting another.
|
87
|
+
raise FileError(f"Cannot Rename to {filename}, file Exists")
|
88
|
+
self._destination = path
|
89
|
+
else:
|
90
|
+
raise FileNotFound("FileRename: Missing Destination.")
|
91
|
+
await super(FileRename, self).start(**kwargs)
|
92
|
+
return True
|
93
|
+
|
94
|
+
async def run(self):
|
95
|
+
"""Delete File(s)."""
|
96
|
+
self._result = {}
|
97
|
+
if self._source is not None and self._source.exists():
|
98
|
+
await asyncio.to_thread(os.rename, self._source, self._destination)
|
99
|
+
self._result[self._source] = self._destination
|
100
|
+
self.add_metric("FILE_RENAMED", self._result)
|
101
|
+
if self.ignore_missing is False:
|
102
|
+
raise FileNotFound(f"Source File {self._source} was not found.")
|
103
|
+
return self._result
|
104
|
+
|
105
|
+
async def close(self):
|
106
|
+
"""Method."""
|