diff --git a/.gitignore b/.gitignore index b6f91ad..eb63246 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,15 @@ Thumbs.db components/*.go !components/components.go +components/providers/source/*.go +!components/providers/source/source.go + +components/providers/destination/*.go +!components/providers/destination/destination.go + +components/providers/common/*.go +!components/providers/common/common.go + # Ignore the data directory data/ @@ -56,9 +65,10 @@ tmp/ configs/ # Ignore Dirs -source/ -destination/ -archive/ +/source/ +/destination/ + +/archive/ # Ignore binaries gomft diff --git a/components/config_form.templ b/components/config_form.templ index a38525e..4eb9632 100644 --- a/components/config_form.templ +++ b/components/config_form.templ @@ -4,6 +4,9 @@ import ( "fmt" "github.com/starfleetcptn/gomft/internal/db" "context" + "github.com/starfleetcptn/gomft/components/providers/source" + "github.com/starfleetcptn/gomft/components/providers/destination" + "github.com/starfleetcptn/gomft/components/providers/common" ) type ConfigFormData struct { @@ -19,6 +22,7 @@ func getConfigFormTitle(isNew bool) string { } func getInitialData(config *db.TransferConfig) string { + // Default values for a new configuration name := "" sourceType := "local" sourcePath := "" @@ -27,24 +31,23 @@ func getInitialData(config *db.TransferConfig) string { sourceUser := "" sourcePassword := "" sourceKeyFile := "" - // S3 fields + sourceAuthType := "password" sourceBucket := "" sourceRegion := "" sourceAccessKey := "" sourceSecretKey := "" sourceEndpoint := "" - // SMB fields sourceShare := "" sourceDomain := "" - // FTP fields - sourcePassiveMode := true - // OneDrive and Google Drive fields + sourcePassiveMode := false sourceClientId := "" sourceClientSecret := "" sourceDriveId := "" sourceTeamDrive := "" - filePattern := "*" - outputPattern := "" + + filePattern := "" + outputPattern := "${filename}" + destinationType := "local" destinationPath := "" destHost := "" @@ -52,27 +55,26 @@ func getInitialData(config *db.TransferConfig) string { destUser := "" destPassword := "" destKeyFile := "" - // S3 fields + destAuthType := "password" destBucket := "" destRegion := "" destAccessKey := "" destSecretKey := "" destEndpoint := "" - // SMB fields destShare := "" destDomain := "" - // FTP fields - destPassiveMode := true - // OneDrive and Google Drive fields + destPassiveMode := false destClientId := "" destClientSecret := "" destDriveId := "" destTeamDrive := "" + archivePath := "" archiveEnabled := false deleteAfterTransfer := false rcloneFlags := "" + // If editing an existing config, populate with those values if config != nil { name = config.Name sourceType = config.SourceType @@ -82,24 +84,25 @@ func getInitialData(config *db.TransferConfig) string { sourceUser = config.SourceUser sourcePassword = config.SourcePassword sourceKeyFile = config.SourceKeyFile - // S3 fields + if sourceKeyFile != "" && sourcePassword == "" { + sourceAuthType = "key" + } sourceBucket = config.SourceBucket sourceRegion = config.SourceRegion sourceAccessKey = config.SourceAccessKey sourceSecretKey = config.SourceSecretKey sourceEndpoint = config.SourceEndpoint - // SMB fields sourceShare = config.SourceShare sourceDomain = config.SourceDomain - // FTP fields sourcePassiveMode = config.SourcePassiveMode - // OneDrive and Google Drive fields sourceClientId = config.SourceClientID sourceClientSecret = config.SourceClientSecret sourceDriveId = config.SourceDriveID sourceTeamDrive = config.SourceTeamDrive + filePattern = config.FilePattern outputPattern = config.OutputPattern + destinationType = config.DestinationType destinationPath = config.DestinationPath destHost = config.DestHost @@ -107,28 +110,29 @@ func getInitialData(config *db.TransferConfig) string { destUser = config.DestUser destPassword = config.DestPassword destKeyFile = config.DestKeyFile - // S3 fields + if destKeyFile != "" && destPassword == "" { + destAuthType = "key" + } destBucket = config.DestBucket destRegion = config.DestRegion destAccessKey = config.DestAccessKey destSecretKey = config.DestSecretKey destEndpoint = config.DestEndpoint - // SMB fields destShare = config.DestShare destDomain = config.DestDomain - // FTP fields destPassiveMode = config.DestPassiveMode - // OneDrive and Google Drive fields destClientId = config.DestClientID destClientSecret = config.DestClientSecret destDriveId = config.DestDriveID destTeamDrive = config.DestTeamDrive + archivePath = config.ArchivePath archiveEnabled = config.ArchiveEnabled deleteAfterTransfer = config.DeleteAfterTransfer rcloneFlags = config.RcloneFlags } + // Return the JSON-formatted string with all the data return fmt.Sprintf(`{ name: '%s', sourceType: '%s', @@ -138,6 +142,7 @@ func getInitialData(config *db.TransferConfig) string { sourceUser: '%s', sourcePassword: '%s', sourceKeyFile: '%s', + sourceAuthType: '%s', sourceBucket: '%s', sourceRegion: '%s', sourceAccessKey: '%s', @@ -150,8 +155,10 @@ func getInitialData(config *db.TransferConfig) string { sourceClientSecret: '%s', sourceDriveId: '%s', sourceTeamDrive: '%s', + filePattern: '%s', outputPattern: '%s', + destinationType: '%s', destinationPath: '%s', destHost: '%s', @@ -159,1825 +166,180 @@ func getInitialData(config *db.TransferConfig) string { destUser: '%s', destPassword: '%s', destKeyFile: '%s', - // S3 fields + destAuthType: '%s', destBucket: '%s', destRegion: '%s', destAccessKey: '%s', destSecretKey: '%s', destEndpoint: '%s', - // SMB fields destShare: '%s', destDomain: '%s', - // FTP fields destPassiveMode: %v, - // OneDrive and Google Drive fields destClientId: '%s', destClientSecret: '%s', destDriveId: '%s', destTeamDrive: '%s', - // Existing fields + archivePath: '%s', archiveEnabled: %v, deleteAfterTransfer: %v, rcloneFlags: '%s', - loading: false, - - validate() { - if (this.sourceType === 'sftp') { - if (!this.sourceHost || !this.sourceUser || (!this.sourcePassword && !this.sourceKeyFile)) { - return false; - } - } else if (this.sourceType === 's3') { - if (!this.sourceBucket || !this.sourceRegion || !this.sourceAccessKey || !this.sourceSecretKey) { - return false; - } - } else if (this.sourceType === 'minio') { - if (!this.sourceBucket || !this.sourceEndpoint || !this.sourceAccessKey || !this.sourceSecretKey) { - return false; - } - } else if (this.sourceType === 'b2') { - if (!this.sourceBucket || !this.sourceAccessKey || !this.sourceSecretKey) { - return false; - } - } else if (this.sourceType === 'smb') { - if (!this.sourceHost || !this.sourceShare || !this.sourceUser || !this.sourcePassword) { - return false; - } - } else if (this.sourceType === 'ftp') { - if (!this.sourceHost || !this.sourceUser || !this.sourcePassword) { - return false; - } - } else if (this.sourceType === 'webdav') { - if (!this.sourceHost || !this.sourceUser || !this.sourcePassword) { - return false; - } - } else if (this.sourceType === 'nextcloud') { - if (!this.sourceHost || !this.sourceUser || !this.sourcePassword) { - return false; - } - } else if (this.sourceType === 'onedrive') { - if (!this.sourceClientId || !this.sourceClientSecret) { - return false; - } - } else if (this.sourceType === 'google_drive') { - if (!this.sourceClientId || !this.sourceClientSecret) { - return false; - } - } - - if (this.destinationType === 'sftp') { - if (!this.destHost || !this.destUser || (!this.destPassword && !this.destKeyFile)) { - return false; - } - } else if (this.destinationType === 's3') { - if (!this.destBucket || !this.destRegion || !this.destAccessKey || !this.destSecretKey) { - return false; - } - } else if (this.destinationType === 'minio') { - if (!this.destBucket || !this.destEndpoint || !this.destAccessKey || !this.destSecretKey) { - return false; - } - } else if (this.destinationType === 'b2') { - if (!this.destBucket || !this.destAccessKey || !this.destSecretKey) { - return false; - } - } else if (this.destinationType === 'smb') { - if (!this.destHost || !this.destShare || !this.destUser || !this.destPassword) { - return false; - } - } else if (this.destinationType === 'ftp') { - if (!this.destHost || !this.destUser || !this.destPassword) { - return false; - } - } else if (this.destinationType === 'webdav') { - if (!this.destHost || !this.destUser || !this.destPassword) { - return false; - } - } else if (this.destinationType === 'nextcloud') { - if (!this.destHost || !this.destUser || !this.destPassword) { - return false; - } - } else if (this.destinationType === 'onedrive') { - if (!this.destClientId || !this.destClientSecret) { - return false; - } - } else if (this.destinationType === 'google_drive') { - if (!this.destClientId || !this.destClientSecret) { - return false; - } - } - return this.name && this.sourcePath && this.filePattern && this.destinationPath && (!this.archiveEnabled || this.archivePath); - } - }`, name, sourceType, sourcePath, sourceHost, sourcePort, sourceUser, sourcePassword, sourceKeyFile, - sourceBucket, sourceRegion, sourceAccessKey, sourceSecretKey, sourceEndpoint, - sourceShare, sourceDomain, sourcePassiveMode, - sourceClientId, sourceClientSecret, sourceDriveId, sourceTeamDrive, - filePattern, outputPattern, destinationType, destinationPath, destHost, destPort, destUser, destPassword, destKeyFile, - destBucket, destRegion, destAccessKey, destSecretKey, destEndpoint, - destShare, destDomain, destPassiveMode, - destClientId, destClientSecret, destDriveId, destTeamDrive, - archivePath, archiveEnabled, deleteAfterTransfer, rcloneFlags) + }`, + name, sourceType, sourcePath, sourceHost, sourcePort, sourceUser, sourcePassword, sourceKeyFile, sourceAuthType, + sourceBucket, sourceRegion, sourceAccessKey, sourceSecretKey, sourceEndpoint, sourceShare, sourceDomain, sourcePassiveMode, + sourceClientId, sourceClientSecret, sourceDriveId, sourceTeamDrive, + filePattern, outputPattern, + destinationType, destinationPath, destHost, destPort, destUser, destPassword, destKeyFile, destAuthType, + destBucket, destRegion, destAccessKey, destSecretKey, destEndpoint, destShare, destDomain, destPassiveMode, + destClientId, destClientSecret, destDriveId, destTeamDrive, + archivePath, archiveEnabled, deleteAfterTransfer, rcloneFlags) } templ ConfigForm(ctx context.Context, data ConfigFormData) { @LayoutWithContext(getConfigFormTitle(data.IsNew), ctx) { -
Set up your file transfer configuration
-- - Configure your file transfer settings carefully for optimal performance -
-+ Set up your file transfer configuration +
+ +Configure your file transfer settings carefully for optimal performance
++ Glob pattern for files to transfer. Leave empty to transfer all files. +
++ Pattern for output filename. Use variables like ${`filename`}, ${`timestamp`}, ${`date`} +
+
+ Pattern for filenames. Available variables:
+ ${`filename`} - Original filename without extension (e.g., "report")
+ ${`ext`} - Original file extension (e.g., "csv")
+ ${`date:format`} - Current date using Go's time format:
+ • 2006-01-02 → YYYY-MM-DD
+ • 20060102 → YYYYMMDD
+ • 2006-01-02 15:04:05 → YYYY-MM-DD_HH:MM:SS
+ Example: ${`filename`}_${`date:2006-01-02`}_${`ext`} → "report_2023-03-01.csv"
+
Archive files after successful transfer
+Delete source files after successful transfer
++ Optional: Additional rclone flags for fine-tuning the transfer. +
+Enable passive mode for FTP connection
++ Optional. If specified, files will be uploaded to this path in the bucket. +
++ Optional. If specified, files will be uploaded to this path in the bucket. +
++ Optional. Subdirectory within the share. +
++ Optional. Windows domain for authentication. +
++ Optional. Relative to the WebDAV URL. +
+Enable passive mode for FTP connection
++ Optional. If specified, only files in this path will be processed. +
++ Optional. If left empty, root directory will be used. +
++ Optional. If specified, only files in this path will be processed. +
++ Optional. Subdirectory within the share. +
++ Optional. Windows domain for authentication. +
++ Optional. Relative to the WebDAV URL. +
+