flowtask 5.8.4__cp39-cp39-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-39-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-39-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/argparser.py +235 -0
- flowtask/parsers/base.c +15155 -0
- flowtask/parsers/base.cpython-39-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/json.c +11968 -0
- flowtask/parsers/json.cpython-39-x86_64-linux-gnu.so +0 -0
- flowtask/parsers/maps.py +49 -0
- flowtask/parsers/toml.c +11968 -0
- flowtask/parsers/toml.cpython-39-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-39-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-39-x86_64-linux-gnu.so +0 -0
- flowtask/utils/json.cpp +13349 -0
- flowtask/utils/json.cpython-39-x86_64-linux-gnu.so +0 -0
- flowtask/utils/mail.py +63 -0
- flowtask/utils/parseqs.c +13324 -0
- flowtask/utils/parserqs.cpython-39-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,130 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from navconfig.logging import logging
|
3
|
+
from parrot.bots.basic import BasicBot
|
4
|
+
from ..exceptions import ConfigError, ComponentError
|
5
|
+
|
6
|
+
class ParrotBot:
|
7
|
+
"""ParrotBot.
|
8
|
+
|
9
|
+
Interface for creating new chatbots to be used directly as Flowtask Components
|
10
|
+
|
11
|
+
"""
|
12
|
+
def __init__(self, *args, **kwargs):
|
13
|
+
self._bot_name = kwargs.get('bot_name', 'ParrotBot')
|
14
|
+
self._bot: Any = None
|
15
|
+
self._logger = logging.getLogger(f'Bot.{self._bot_name.lower()}')
|
16
|
+
self._prompt_file = kwargs.get('prompt_file', 'prompt.txt')
|
17
|
+
self._goal: str = kwargs.get('goal', 'Customer Satisfaction Analysis using Reviews')
|
18
|
+
self._rating_column: str = kwargs.get('rating_column', 'rating')
|
19
|
+
self._eval_column: str = kwargs.get('eval_column', 'evaluation')
|
20
|
+
self._desc_column: str = kwargs.get('description_column', 'description')
|
21
|
+
self.output_column: str = kwargs.get('output_column')
|
22
|
+
# System Prompt:
|
23
|
+
self.system_prompt = "Customer Satisfaction: "
|
24
|
+
super(ParrotBot, self).__init__(*args, **kwargs)
|
25
|
+
# TaskStorage
|
26
|
+
# Find in the taskstorage, the "prompts" directory.
|
27
|
+
prompt_path = self._taskstore.path.joinpath(self._program, 'prompts')
|
28
|
+
if not prompt_path.exists():
|
29
|
+
raise ConfigError(
|
30
|
+
f"{self.system_prompt} Prompts Path Not Found: {prompt_path}"
|
31
|
+
)
|
32
|
+
self.prompt_path = prompt_path
|
33
|
+
# is hardcoded to this particular Bot.
|
34
|
+
self.system_prompt_file = self._prompt_file
|
35
|
+
# Bot Object:
|
36
|
+
self._bot: Any = None
|
37
|
+
|
38
|
+
async def start(self, **kwargs):
|
39
|
+
"""
|
40
|
+
start
|
41
|
+
|
42
|
+
Overview
|
43
|
+
|
44
|
+
The start method is a method for starting the CustomerSatisfaction component.
|
45
|
+
|
46
|
+
Parameters
|
47
|
+
|
48
|
+
kwargs: dict
|
49
|
+
A dictionary containing the parameters for the CustomerSatisfaction component.
|
50
|
+
|
51
|
+
Return
|
52
|
+
|
53
|
+
True if the CustomerSatisfaction component started successfully.
|
54
|
+
|
55
|
+
"""
|
56
|
+
if self.previous:
|
57
|
+
self.data = self.input
|
58
|
+
else:
|
59
|
+
raise ComponentError(
|
60
|
+
f"{self._bot_name.lower()}: Data Was Not Found"
|
61
|
+
)
|
62
|
+
if not self.output_column:
|
63
|
+
raise ConfigError(
|
64
|
+
f"{self._bot_name.lower()}: output_column is required"
|
65
|
+
)
|
66
|
+
# check if Prompt File exists
|
67
|
+
prompt_file = self.prompt_path.joinpath(self.system_prompt_file)
|
68
|
+
if not prompt_file.exists():
|
69
|
+
raise ConfigError(
|
70
|
+
f"{self.system_prompt} Prompt File Not Found: {prompt_file}"
|
71
|
+
)
|
72
|
+
self.system_prompt_file = prompt_file.name
|
73
|
+
# read the prompt file as text:
|
74
|
+
with open(prompt_file, 'r') as f:
|
75
|
+
self.system_prompt = f.read()
|
76
|
+
# Set the Bot:
|
77
|
+
try:
|
78
|
+
self._bot = BasicBot(
|
79
|
+
name=self._bot_name,
|
80
|
+
system_prompt=self.system_prompt,
|
81
|
+
goal=self._goal,
|
82
|
+
use_llm=self.llm.get('name', 'name'),
|
83
|
+
model_name=self.llm.get('model_name', 'gemini-2.0-pro'),
|
84
|
+
)
|
85
|
+
# configure the bot:
|
86
|
+
await self._bot.configure()
|
87
|
+
except Exception as err:
|
88
|
+
raise ComponentError(
|
89
|
+
f"{self.system_prompt} Error Configuring Bot: {err}"
|
90
|
+
) from err
|
91
|
+
return True
|
92
|
+
|
93
|
+
async def bot_evaluation(self):
|
94
|
+
"""
|
95
|
+
bot_evaluation
|
96
|
+
|
97
|
+
Overview
|
98
|
+
|
99
|
+
The run method is a method for running the ParrotBot component.
|
100
|
+
|
101
|
+
Return
|
102
|
+
|
103
|
+
A Pandas Dataframe with the IA-based statistics.
|
104
|
+
|
105
|
+
"""
|
106
|
+
# Group reviews by product_name and aggregate them into a list
|
107
|
+
grouped = self.data.groupby(self._desc_column)[self._eval_column].apply(list).reset_index()
|
108
|
+
_evaluation = {}
|
109
|
+
for _, row in grouped.iterrows():
|
110
|
+
product_name = row[self._desc_column]
|
111
|
+
reviews = row[self._eval_column]
|
112
|
+
formatted_question = self.format_question(product_name, reviews)
|
113
|
+
result = await self._bot.question(
|
114
|
+
question=formatted_question,
|
115
|
+
return_docs=False
|
116
|
+
)
|
117
|
+
_evaluation[product_name] = {
|
118
|
+
"answer": result.answer
|
119
|
+
}
|
120
|
+
# Then, create a dataframe only with the columns in "self.columns" grouped.
|
121
|
+
grouped_df = self.data.groupby(self.columns).agg(
|
122
|
+
num_reviews=(self._eval_column, "count"),
|
123
|
+
avg_rating=(self._rating_column, "mean")
|
124
|
+
).reset_index()
|
125
|
+
# Add the Customer Satisfaction column, using the dictionary and match per product_name column
|
126
|
+
grouped_df[self.output_column] = grouped_df[self._desc_column].map(
|
127
|
+
lambda x: _evaluation[x]['answer']
|
128
|
+
)
|
129
|
+
# return the grouped dataframe
|
130
|
+
return grouped_df
|
@@ -0,0 +1,378 @@
|
|
1
|
+
import os
|
2
|
+
import asyncio
|
3
|
+
from typing import List, Union
|
4
|
+
from datetime import datetime
|
5
|
+
from pathlib import Path, PurePath
|
6
|
+
import asyncssh
|
7
|
+
from navconfig.logging import logging
|
8
|
+
from ..exceptions import ComponentError, FileNotFound, FileError
|
9
|
+
from .client import ClientInterface
|
10
|
+
|
11
|
+
class SSHClient(ClientInterface):
|
12
|
+
"""
|
13
|
+
SSHClient
|
14
|
+
|
15
|
+
Overview
|
16
|
+
|
17
|
+
The SSHClient class is a component for managing SSH and SFTP connections. It provides methods for establishing connections,
|
18
|
+
running commands, downloading, uploading, and copying files using SFTP. It supports various SSH algorithms and handles
|
19
|
+
errors gracefully.
|
20
|
+
|
21
|
+
.. table:: Properties
|
22
|
+
:widths: auto
|
23
|
+
|
24
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
25
|
+
| Name | Required | Description |
|
26
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
27
|
+
| block_size | No | The block size for file transfers, defaults to 16384 bytes. |
|
28
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
29
|
+
| max_requests | No | The maximum number of concurrent requests, defaults to 128. |
|
30
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
31
|
+
| algorithms | No | A list of supported SSH algorithms. |
|
32
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
33
|
+
| commands | No | A list of commands to run over SSH. |
|
34
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
35
|
+
| only_sftp | No | A flag indicating if only SFTP connections are allowed. |
|
36
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
37
|
+
| tunnel | Yes | Describes an SSH tunnel connection |
|
38
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
39
|
+
| _connection | Yes | The current SSH connection object. |
|
40
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
41
|
+
| _clientargs | Yes | Arguments for the SSH client configuration. |
|
42
|
+
+------------------+----------+-----------+--------------------------------------------------------------------------------------+
|
43
|
+
| client_keys | Yes | SSH public key |
|
44
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
45
|
+
| source | Yes | List of algorithms to be used in connection encryption |
|
46
|
+
+------------------+----------+--------------------------------------------------------------------------------------------------+
|
47
|
+
Return
|
48
|
+
|
49
|
+
The methods in this class facilitate SSH and SFTP operations, including establishing connections,
|
50
|
+
file transfers, command execution, and handling SSH tunnels. The class also manages environment settings
|
51
|
+
and provides error handling mechanisms specific to SSH and SFTP operations.
|
52
|
+
|
53
|
+
""" # noqa: E501
|
54
|
+
|
55
|
+
|
56
|
+
block_size: int = 16384
|
57
|
+
max_requests: int = 128
|
58
|
+
algorithms = [
|
59
|
+
"ssh-rsa",
|
60
|
+
"ssh-dss",
|
61
|
+
"sk-ssh-ed25519-cert-v01@openssh.com",
|
62
|
+
"sk-ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
63
|
+
"ssh-ed25519-cert-v01@openssh.com",
|
64
|
+
"ssh-ed448-cert-v01@openssh.com",
|
65
|
+
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
66
|
+
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
67
|
+
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
68
|
+
"ecdsa-sha2-1.3.132.0.10-cert-v01@openssh.com",
|
69
|
+
"ssh-rsa-cert-v01@openssh.com",
|
70
|
+
"ssh-dss-cert-v01@openssh.com",
|
71
|
+
"sk-ssh-ed25519@openssh.com",
|
72
|
+
"sk-ecdsa-sha2-nistp256@openssh.com",
|
73
|
+
"ssh-ed25519",
|
74
|
+
"ssh-ed448",
|
75
|
+
"ecdsa-sha2-nistp521",
|
76
|
+
"ecdsa-sha2-nistp384",
|
77
|
+
"ecdsa-sha2-nistp256",
|
78
|
+
"ecdsa-sha2-1.3.132.0.10",
|
79
|
+
"rsa-sha2-256",
|
80
|
+
"rsa-sha2-512",
|
81
|
+
]
|
82
|
+
_credentials: dict = {"username": str, "password": str}
|
83
|
+
|
84
|
+
def __init__(
|
85
|
+
self, *args, tunnel: dict = None, **kwargs
|
86
|
+
) -> None:
|
87
|
+
self.only_sftp: bool = False
|
88
|
+
self.commands: list = kwargs.pop('commands', [])
|
89
|
+
self.tunnel: dict = tunnel
|
90
|
+
self.max_requests = kwargs.pop('max_requests', 128)
|
91
|
+
kwargs['no_host'] = False
|
92
|
+
if "block_size" in kwargs:
|
93
|
+
self.block_size = kwargs["block_size"]
|
94
|
+
super(SSHClient, self).__init__(*args, **kwargs)
|
95
|
+
if getattr(self, '_debug', False) is True:
|
96
|
+
sshlog = logging.getLogger("asyncssh").setLevel(logging.DEBUG)
|
97
|
+
asyncssh.set_debug_level(1)
|
98
|
+
|
99
|
+
async def close(self, timeout: int = 1, reason: str = "Connection Ended."):
|
100
|
+
"""Close Method."""
|
101
|
+
try:
|
102
|
+
if self._connection:
|
103
|
+
await asyncio.wait_for(self._connection.wait_closed(), timeout=timeout)
|
104
|
+
except (asyncio.TimeoutError, asyncio.CancelledError):
|
105
|
+
self._connection.disconnect(
|
106
|
+
code=asyncssh.DISC_BY_APPLICATION, reason=reason, lang="en-US"
|
107
|
+
)
|
108
|
+
except OSError as err:
|
109
|
+
print(f"Error on SSH disconnection, reason: {err!s}")
|
110
|
+
except Exception as err:
|
111
|
+
raise ComponentError(f"SSH Connection Error: {err}") from err
|
112
|
+
|
113
|
+
async def open(self, host: str, port: int, credentials: dict, **kwargs):
|
114
|
+
"""
|
115
|
+
init an SSH connection
|
116
|
+
"""
|
117
|
+
algorithms = self.algorithms
|
118
|
+
if "algorithms" in self._clientargs and len(self._clientargs["algorithms"]) > 0:
|
119
|
+
try:
|
120
|
+
algorithms = algorithms.append(self._clientargs["algorithms"])
|
121
|
+
del self._clientargs["algorithms"]
|
122
|
+
except KeyError:
|
123
|
+
pass
|
124
|
+
self._clientargs["server_host_key_algs"] = algorithms
|
125
|
+
if hasattr(self, "use_public_key"):
|
126
|
+
if "client_keys" in self._clientargs:
|
127
|
+
file = Path(self._clientargs["client_keys"])
|
128
|
+
del self._clientargs["client_keys"]
|
129
|
+
if not file.exists() or not file.is_file():
|
130
|
+
client_key = os.path.expanduser("~/.ssh/id_rsa")
|
131
|
+
else:
|
132
|
+
client_key = str(file)
|
133
|
+
self._clientargs["client_keys"] = client_key
|
134
|
+
|
135
|
+
if "known_hosts" not in self._clientargs:
|
136
|
+
if "known_hosts" not in credentials:
|
137
|
+
self._clientargs["known_hosts"] = None
|
138
|
+
if self.tunnel:
|
139
|
+
self._clientargs = {**self._clientargs, **self.tunnel["credentials"]}
|
140
|
+
if "known_hosts" not in self._clientargs:
|
141
|
+
self._clientargs["known_hosts"] = None
|
142
|
+
try:
|
143
|
+
if self.tunnel:
|
144
|
+
tnl = await asyncssh.connect(
|
145
|
+
host=self.tunnel["host"],
|
146
|
+
port=int(self.tunnel["port"]),
|
147
|
+
**self._clientargs,
|
148
|
+
)
|
149
|
+
h = self.tunnel["host"]
|
150
|
+
result = await tnl.run(
|
151
|
+
f'echo "SSH tunnel connection to {h} successful"', check=False
|
152
|
+
)
|
153
|
+
print(result.stdout, end="")
|
154
|
+
try:
|
155
|
+
del self._clientargs["username"]
|
156
|
+
del self._clientargs["password"]
|
157
|
+
del self._clientargs["known_hosts"]
|
158
|
+
except KeyError:
|
159
|
+
pass
|
160
|
+
try:
|
161
|
+
del self._clientargs["locale"]
|
162
|
+
except KeyError:
|
163
|
+
pass
|
164
|
+
self._connection = await tnl.connect_ssh(
|
165
|
+
host=host, port=int(port), **credentials, **self._clientargs
|
166
|
+
)
|
167
|
+
else:
|
168
|
+
try:
|
169
|
+
del self._clientargs["username"]
|
170
|
+
del self._clientargs["password"]
|
171
|
+
# del self._clientargs['known_hosts']
|
172
|
+
except KeyError:
|
173
|
+
pass
|
174
|
+
try:
|
175
|
+
del self._clientargs["locale"]
|
176
|
+
except KeyError:
|
177
|
+
pass
|
178
|
+
self._connection = await asyncssh.connect(
|
179
|
+
host=host, port=int(port), **credentials, **self._clientargs
|
180
|
+
)
|
181
|
+
try:
|
182
|
+
result = await self._connection.run(
|
183
|
+
f'echo "SSH connection to {host} successful"', check=False
|
184
|
+
)
|
185
|
+
print(result.stderr)
|
186
|
+
if result.stdout == "This service allows sftp connections only.":
|
187
|
+
self.only_sftp = True
|
188
|
+
print("CONN:: ", result.stdout, end="")
|
189
|
+
except Exception as e:
|
190
|
+
self._logger.warning(f"{e}")
|
191
|
+
except asyncio.TimeoutError as exc:
|
192
|
+
self._logger.error(f"SSH Download Timeout on {self.host}:{self.port}")
|
193
|
+
raise ComponentError(
|
194
|
+
f"SSH Service Timeout on host {host}:{port}: {exc}"
|
195
|
+
) from exc
|
196
|
+
except asyncssh.misc.PermissionDenied as exc:
|
197
|
+
raise ComponentError(f"SSH Error: Permission Denied: {exc}") from exc
|
198
|
+
except (OSError, asyncssh.Error) as err:
|
199
|
+
raise ComponentError(f"SSH connection failed: {err}") from err
|
200
|
+
except ValueError as err:
|
201
|
+
raise ComponentError from err
|
202
|
+
except Exception as err:
|
203
|
+
raise ComponentError(f"SSH connection failed: {err!s}") from err
|
204
|
+
return self
|
205
|
+
|
206
|
+
async def set_env(self, lang: str = "en_US", collate: str = "C", **kwargs):
|
207
|
+
args = {"LANG": lang, "LC_COLLATE": collate, **kwargs}
|
208
|
+
result = await self._connection.run("env", env=args)
|
209
|
+
print(result.stdout, end="")
|
210
|
+
|
211
|
+
async def run_command(self, command, check: bool = True, **kwargs):
|
212
|
+
result = await self._connection.run(command, check=check, **kwargs)
|
213
|
+
return result
|
214
|
+
|
215
|
+
def err_handler(self, err, **kwargs):
|
216
|
+
# TODO: add future handler of many kind of errors
|
217
|
+
print(f"SSH Error: reason: {err}")
|
218
|
+
if isinstance(err, PermissionError):
|
219
|
+
raise FileError(f"File Error: {err}")
|
220
|
+
if isinstance(err, asyncssh.sftp.SFTPFailure):
|
221
|
+
if "EOF" in str(err):
|
222
|
+
self._logger.warning(
|
223
|
+
f"SSH: Server closed unexpectedly while trying to Copy File: {err}"
|
224
|
+
)
|
225
|
+
return False
|
226
|
+
raise ComponentError(f"SSH Error: {err!s}")
|
227
|
+
if (hasattr(err, "message") and "No matches found" in err.message) or (
|
228
|
+
hasattr(err, "reason") and "No matches found" in err.reason
|
229
|
+
):
|
230
|
+
raise FileNotFound(f"File Not Found: {err}")
|
231
|
+
elif isinstance(err, BaseException):
|
232
|
+
raise ComponentError(f"SSH Exception: {err!s}")
|
233
|
+
return False
|
234
|
+
|
235
|
+
async def sftp_client(self):
|
236
|
+
"""sftp_client.
|
237
|
+
Starts a SFTP client connection.
|
238
|
+
"""
|
239
|
+
return self._connection.start_sftp_client()
|
240
|
+
|
241
|
+
def client_progress(self, srcpath, dstpath, bytes_copied, total_bytes):
|
242
|
+
print(f"FILE PROCESSED: {srcpath}, {dstpath}")
|
243
|
+
self._pb.reset(total=total_bytes)
|
244
|
+
self._pb.update(bytes_copied)
|
245
|
+
self._pb.refresh()
|
246
|
+
|
247
|
+
async def download_files(
|
248
|
+
self,
|
249
|
+
file: Union[str, list[PurePath]],
|
250
|
+
destination: Union[str, PurePath],
|
251
|
+
preserve: bool = False,
|
252
|
+
recurse: bool = False,
|
253
|
+
):
|
254
|
+
"""download_file
|
255
|
+
|
256
|
+
Download a File from sFTP based on Path.
|
257
|
+
Args:
|
258
|
+
path (str): file to be downloaded
|
259
|
+
TODO: Support for write_into and Renaming Files.
|
260
|
+
"""
|
261
|
+
try:
|
262
|
+
self.start_progress(total=len(file))
|
263
|
+
async with self._connection.start_sftp_client() as sftp:
|
264
|
+
await sftp.mget(
|
265
|
+
file,
|
266
|
+
localpath=destination,
|
267
|
+
preserve=preserve,
|
268
|
+
recurse=recurse,
|
269
|
+
block_size=self.block_size,
|
270
|
+
max_requests=self.max_requests,
|
271
|
+
progress_handler=self.client_progress,
|
272
|
+
error_handler=self.err_handler,
|
273
|
+
)
|
274
|
+
self.close_progress()
|
275
|
+
except asyncio.TimeoutError as exc:
|
276
|
+
self._logger.warning(
|
277
|
+
f"SSH Download Timeout on {self.host}:{self.port}: {exc}"
|
278
|
+
)
|
279
|
+
# raise ComponentError(
|
280
|
+
# f'SSH Download Timeout on {self.host}:{self.port}'
|
281
|
+
# )
|
282
|
+
except asyncssh.misc.PermissionDenied as exc:
|
283
|
+
raise ComponentError(
|
284
|
+
f"SSH Error: Permission Denied over Remote: {exc}"
|
285
|
+
) from exc
|
286
|
+
except OSError as err:
|
287
|
+
raise ComponentError(f"SSH: Error saving files in local: {err}") from err
|
288
|
+
except asyncssh.sftp.SFTPError as err:
|
289
|
+
raise ComponentError(f"SSH: Server Error: {err}") from err
|
290
|
+
except Exception as err:
|
291
|
+
self._logger.error(f"sFTP DOWNLOAD ERROR: {err}")
|
292
|
+
raise ComponentError(f"SSH: Server Error: {err.__class__!s}.{err}") from err
|
293
|
+
|
294
|
+
async def upload_files(
|
295
|
+
self,
|
296
|
+
file: Union[str, list[PurePath]],
|
297
|
+
destination: Union[str, PurePath],
|
298
|
+
preserve: bool = False,
|
299
|
+
recurse: bool = False,
|
300
|
+
) -> bool:
|
301
|
+
"""upload_files.
|
302
|
+
|
303
|
+
Use can upload one or more files (or directories) recursively.
|
304
|
+
Args:
|
305
|
+
file (Union[str,List[PurePath]]): Path (purepath) or list of
|
306
|
+
paths for files or directories
|
307
|
+
destination (Purepath or str): remote destination of upload
|
308
|
+
preserve (bool, optional): preserve the original attributes. Defaults False.
|
309
|
+
recurse (bool, optional): copy recursively all directories. Defaults False.
|
310
|
+
Returns:
|
311
|
+
bool: file(s) or directorires were uploaded or not.
|
312
|
+
"""
|
313
|
+
try:
|
314
|
+
self.start_progress(total=len(file))
|
315
|
+
async with self._connection.start_sftp_client() as sftp:
|
316
|
+
await sftp.mput(
|
317
|
+
file,
|
318
|
+
remotepath=destination,
|
319
|
+
preserve=preserve,
|
320
|
+
recurse=recurse,
|
321
|
+
block_size=self.block_size,
|
322
|
+
max_requests=self.max_requests,
|
323
|
+
progress_handler=self.client_progress,
|
324
|
+
error_handler=self.err_handler,
|
325
|
+
)
|
326
|
+
self.close_progress()
|
327
|
+
except OSError as err:
|
328
|
+
raise ComponentError(f"SSH: Error reading local files: {err}") from err
|
329
|
+
except asyncssh.sftp.SFTPError as err:
|
330
|
+
raise ComponentError(f"SSH: Server Error: {err}") from err
|
331
|
+
except Exception as err:
|
332
|
+
self._logger.error(f"sFTP UPLOAD ERROR: {err}")
|
333
|
+
|
334
|
+
async def copy_files(
|
335
|
+
self,
|
336
|
+
file: Union[str, list[PurePath]],
|
337
|
+
destination: Union[str, PurePath],
|
338
|
+
preserve: bool = False,
|
339
|
+
recurse: bool = False,
|
340
|
+
) -> bool:
|
341
|
+
"""copy_files.
|
342
|
+
|
343
|
+
Use can copy/move one or more files (or directories) in server.
|
344
|
+
Args:
|
345
|
+
file (Union[str,List[PurePath]]): Path (purepath) or list of
|
346
|
+
paths for files or directories
|
347
|
+
destination (Purepath or str): remote destination of upload
|
348
|
+
preserve (bool, optional): preserve the original attributes. Defaults False.
|
349
|
+
recurse (bool, optional): copy recursively all directories. Defaults False.
|
350
|
+
Returns:
|
351
|
+
bool: file(s) or directorires were uploaded or not.
|
352
|
+
"""
|
353
|
+
try:
|
354
|
+
self.start_progress(total=len(file))
|
355
|
+
async with self._connection.start_sftp_client() as sftp:
|
356
|
+
await sftp.mcopy(
|
357
|
+
file,
|
358
|
+
dstpath=destination,
|
359
|
+
preserve=preserve,
|
360
|
+
recurse=recurse,
|
361
|
+
block_size=self.block_size,
|
362
|
+
max_requests=self.max_requests,
|
363
|
+
progress_handler=self.client_progress,
|
364
|
+
error_handler=self.err_handler,
|
365
|
+
)
|
366
|
+
self.close_progress()
|
367
|
+
except Exception as err:
|
368
|
+
self._logger.error(f"sFTP DOWNLOAD ERROR: {err}")
|
369
|
+
raise ComponentError(f"SSH: Server Error: {err.__class__!s}.{err}") from err
|
370
|
+
|
371
|
+
async def get_mtime_files(self, sftp, filename: str, mod_date: str) -> List:
|
372
|
+
filelist = []
|
373
|
+
for file in await sftp.glob(filename):
|
374
|
+
mstat = await sftp.getmtime(file)
|
375
|
+
mdate = datetime.fromtimestamp(mstat).strftime("%Y-%m-%d")
|
376
|
+
if mdate == mod_date:
|
377
|
+
filelist.append(file)
|
378
|
+
return filelist
|