From 54baaf52e7c5f09e4257f4ea42f1d3b1876f4661 Mon Sep 17 00:00:00 2001 From: blance Date: Mon, 29 Jun 2026 19:47:38 -0500 Subject: [PATCH] Use today's YYYYMMDD subfolder for PDFs, archive whole folder on success --- README.md | 73 ++++++++++++++++++++++++++++------------------------- run-all.ps1 | 27 +++++++++++++------- upload.ps1 | 51 ++++++++++++++++++++++--------------- 3 files changed, 87 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index a649071..34e35fc 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,46 @@ # PDF FTP Uploader -This tool sends PDF files to a server automatically. Just drop your PDFs in the right folder and double-click to upload. Done. +This tool sends PDF files to a server automatically. Just put your PDFs in today's folder and double-click to upload. Done. --- ## How to use it every day -1. Drop your PDF files into the practice folder (e.g. `Acme Dental\`) -2. Double-click **upload.bat** inside that folder -3. A window will open showing the progress -4. When it says **Done**, close the window — your files have been sent and moved to the `archive` folder automatically +1. Inside the practice folder, create a folder named with **today's date** (example: `20260629`) +2. Drop your PDF files into that date folder +3. Double-click **upload.bat** inside the practice folder +4. A window will open showing the progress +5. When it says **Done**, close the window — your files have been sent and the date folder moved to `archive\` automatically To upload **all practices at once**, double-click **run-all.bat** in the main folder instead. --- +## Folder layout + +``` +Main Folder\ + run-all.bat ← uploads all practices at once + run-all.ps1 + Acme Dental\ + upload.bat ← uploads just this practice + upload.ps1 + ftp-config.ini ← this practice's server details (set up once) + 20260629\ ← today's date folder — put PDFs here + report1.pdf + report2.pdf + archive\ + 20260628\ ← yesterday's folder, already uploaded + Bright Smiles\ + upload.bat + upload.ps1 + ftp-config.ini + 20260629\ + ... +``` + +--- + ## First-time setup for a new practice You only do this once per practice. @@ -27,41 +53,20 @@ You only do this once per practice. 3. Open `ftp-config.ini` in Notepad and fill in the details: ``` -host= ← the FTP server address (given to you by the practice) -port=21 ← leave this as 21 unless told otherwise -username= ← your FTP username -password= ← your FTP password -remote_path=← the folder on their server (e.g. /incoming) — leave as / if unsure -tls=false ← change to true if the practice uses FTPS (secure FTP) +host= ← the FTP server address (given to you by the practice) +port=21 ← leave as 21 unless told otherwise +username= ← your FTP username +password= ← your FTP password +remote_path= ← the folder on their server (e.g. /incoming) — leave as / if unsure +tls=false ← change to true if the practice uses secure FTP (FTPS) ``` 4. Save the file and you're ready to go --- -## Folder layout - -``` -Main Folder\ - run-all.bat ← uploads everything at once - run-all.ps1 - Acme Dental\ - upload.bat ← uploads just this practice - upload.ps1 - ftp-config.ini ← this practice's server details - report1.pdf - archive\ ← uploaded files go here automatically - Bright Smiles\ - upload.bat - upload.ps1 - ftp-config.ini - ... -``` - ---- - ## Something went wrong? -- **A file failed to upload** — it stays in the folder. Just double-click upload.bat again to retry. +- **A file failed to upload** — the date folder stays in place. Fix the issue and double-click upload.bat again to retry. - **The window closed too fast** — right-click `upload.bat`, choose *Run as administrator* and try again. -- **Not sure if it worked** — check the `archive` folder. Files only move there after a successful upload. +- **Not sure if it worked** — check the `archive` folder. The date folder only moves there after every file uploads successfully. diff --git a/run-all.ps1 b/run-all.ps1 index 1704583..bd4f417 100644 --- a/run-all.ps1 +++ b/run-all.ps1 @@ -1,7 +1,8 @@ # Run FTP upload for every practice folder found under this root. -# Searches recursively for ftp-config.ini and uploads PDFs from each folder. +# Searches recursively for ftp-config.ini and uploads PDFs from today's date folder in each. $rootDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$today = Get-Date -Format "yyyyMMdd" $configs = Get-ChildItem -Path $rootDir -Recurse -Filter "ftp-config.ini" if ($configs.Count -eq 0) { @@ -10,6 +11,7 @@ if ($configs.Count -eq 0) { } Write-Host "" +Write-Host "Date: $today" Write-Host "Found $($configs.Count) practice folder(s)" -ForegroundColor Cyan Write-Host ("=" * 50) @@ -20,10 +22,17 @@ $totalSkip = 0 foreach ($configFile in $configs) { $folderDir = $configFile.DirectoryName $folderName = Split-Path -Leaf $folderDir + $dateDir = Join-Path $folderDir $today Write-Host "" Write-Host "[ $folderName ]" -ForegroundColor Cyan + if (-not (Test-Path $dateDir)) { + Write-Host " No folder for today ($today) — skipping." -ForegroundColor Gray + $totalSkip++ + continue + } + # Parse config $config = @{} foreach ($line in Get-Content $configFile.FullName) { @@ -50,10 +59,10 @@ foreach ($configFile in $configs) { New-Item -ItemType Directory -Path $archiveDir | Out-Null } - $pdfs = Get-ChildItem -Path $folderDir -Filter "*.pdf" -File + $pdfs = Get-ChildItem -Path $dateDir -Filter "*.pdf" -File if ($pdfs.Count -eq 0) { - Write-Host " No PDFs to upload." -ForegroundColor Gray + Write-Host " No PDFs in $today\ — skipping." -ForegroundColor Gray $totalSkip++ continue } @@ -85,7 +94,6 @@ foreach ($configFile in $configs) { $resp = $req.GetResponse() $resp.Close() - Move-Item -Path $pdf.FullName -Destination (Join-Path $archiveDir $pdf.Name) -Force Write-Host " uploaded" -ForegroundColor Green $ok++ } @@ -98,17 +106,18 @@ foreach ($configFile in $configs) { $totalOk += $ok $totalFail += $fail - if ($fail -eq 0) { - Write-Host " $ok file(s) uploaded." -ForegroundColor Green - } else { - Write-Host " $ok uploaded, $fail failed." -ForegroundColor Yellow + if ($fail -eq 0 -and $ok -gt 0) { + Move-Item -Path $dateDir -Destination (Join-Path $archiveDir $today) -Force + Write-Host " $ok file(s) uploaded. Folder $today\ archived." -ForegroundColor Green + } elseif ($fail -gt 0) { + Write-Host " $ok uploaded, $fail failed (left in $today\ for retry)." -ForegroundColor Yellow } } Write-Host "" Write-Host ("=" * 50) if ($totalFail -eq 0) { - Write-Host "All done: $totalOk file(s) uploaded across $($configs.Count) folder(s)." -ForegroundColor Green + Write-Host "All done: $totalOk file(s) uploaded across $($configs.Count - $totalSkip) folder(s)." -ForegroundColor Green } else { Write-Host "Done: $totalOk uploaded, $totalFail failed, $totalSkip skipped." -ForegroundColor Yellow } diff --git a/upload.ps1 b/upload.ps1 index 6a4ff56..9c384b3 100644 --- a/upload.ps1 +++ b/upload.ps1 @@ -1,16 +1,23 @@ # FTP/FTPS PDF Uploader -# Place this script and ftp-config.ini in the same folder as your PDFs. +# Place this script and ftp-config.ini in the practice folder. +# PDFs should be in a subfolder named with today's date (YYYYMMDD). # Run via upload.bat (double-click). -$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $configFile = Join-Path $scriptDir "ftp-config.ini" +$today = Get-Date -Format "yyyyMMdd" +$dateDir = Join-Path $scriptDir $today if (-not (Test-Path $configFile)) { Write-Host "ERROR: ftp-config.ini not found." -ForegroundColor Red - Write-Host "Create ftp-config.ini in the same folder as this script." -ForegroundColor Red exit 1 } +if (-not (Test-Path $dateDir)) { + Write-Host "No folder for today ($today) found in this practice folder." -ForegroundColor Yellow + exit 0 +} + # Parse config $config = @{} foreach ($line in Get-Content $configFile) { @@ -36,16 +43,16 @@ if (-not (Test-Path $archiveDir)) { New-Item -ItemType Directory -Path $archiveDir | Out-Null } -$pdfs = Get-ChildItem -Path $scriptDir -Filter "*.pdf" -File +$pdfs = Get-ChildItem -Path $dateDir -Filter "*.pdf" -File if ($pdfs.Count -eq 0) { - Write-Host "No PDF files found in this folder." -ForegroundColor Yellow + Write-Host "No PDF files found in $today\" -ForegroundColor Yellow exit 0 } $protocol = if ($useTls) { "ftps" } else { "ftp" } Write-Host "" -Write-Host "Uploading $($pdfs.Count) PDF(s) to $protocol://$ftpHost$remotePath" -ForegroundColor Cyan +Write-Host "Uploading $($pdfs.Count) PDF(s) from $today\ to $protocol://$ftpHost$remotePath" -ForegroundColor Cyan Write-Host "" $ok = 0 @@ -58,24 +65,23 @@ foreach ($pdf in $pdfs) { Write-Host " $($pdf.Name) ..." -NoNewline try { - $req = [System.Net.FtpWebRequest]::Create($uri) - $req.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile - $req.Credentials = New-Object System.Net.NetworkCredential($username, $password) - $req.EnableSsl = $useTls - $req.UseBinary = $true - $req.UsePassive = $true - $req.KeepAlive = $false + $req = [System.Net.FtpWebRequest]::Create($uri) + $req.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile + $req.Credentials = New-Object System.Net.NetworkCredential($username, $password) + $req.EnableSsl = $useTls + $req.UseBinary = $true + $req.UsePassive = $true + $req.KeepAlive = $false - $bytes = [System.IO.File]::ReadAllBytes($pdf.FullName) - $req.ContentLength = $bytes.Length - $stream = $req.GetRequestStream() + $bytes = [System.IO.File]::ReadAllBytes($pdf.FullName) + $req.ContentLength = $bytes.Length + $stream = $req.GetRequestStream() $stream.Write($bytes, 0, $bytes.Length) $stream.Close() $resp = $req.GetResponse() $resp.Close() - Move-Item -Path $pdf.FullName -Destination (Join-Path $archiveDir $pdf.Name) -Force Write-Host " uploaded" -ForegroundColor Green $ok++ } @@ -86,8 +92,11 @@ foreach ($pdf in $pdfs) { } Write-Host "" -if ($fail -eq 0) { - Write-Host "Done: $ok file(s) uploaded and archived." -ForegroundColor Green -} else { - Write-Host "Done: $ok uploaded, $fail failed (left in place for retry)." -ForegroundColor Yellow + +# Archive the whole dated folder if everything succeeded +if ($fail -eq 0 -and $ok -gt 0) { + Move-Item -Path $dateDir -Destination (Join-Path $archiveDir $today) -Force + Write-Host "Done: $ok file(s) uploaded. Folder $today\ moved to archive." -ForegroundColor Green +} elseif ($fail -gt 0) { + Write-Host "Done: $ok uploaded, $fail failed (left in $today\ for retry)." -ForegroundColor Yellow }