Un script Powershell pour trier les photos
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

ArrangePictures.ps1 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. ##################################
  2. ###### CONSTANTS #########
  3. ##################################
  4. $global:FileTypePropIndex = 11
  5. $global:ImageCreationDatePropIndex = 12
  6. $global:VideoCreationDatePropIndex = 208
  7. ##################################
  8. ###### FUNCTIONS #########
  9. ##################################
  10. function Get-APImageVideoExtensions {
  11. param (
  12. [string] $sourceUrl = "https://cdn.jsdelivr.net/gh/jshttp/mime-db@v1.52.0/db.json"
  13. )
  14. $jsonData = (Invoke-RestMethod $sourceUrl).PSObject.Properties
  15. $extensions = @()
  16. foreach ($item in $jsonData) {
  17. if ($item.Name -match "^(image|video)") {
  18. $extensions += $item.Value.extensions
  19. }
  20. }
  21. $extensions = $extensions | Sort-Object -Unique
  22. return $extensions
  23. }
  24. function Get-APFileMetaData {
  25. param (
  26. [string] $filePath,
  27. [int] $propertyIndex
  28. )
  29. $folder = (New-Object -ComObject Shell.Application).NameSpace((Split-Path -Parent $filePath))
  30. $folderItem = $folder.ParseName((Split-Path -Leaf $filePath))
  31. $property = $folder.GetDetailsOf(
  32. $folderItem,
  33. $propertyIndex
  34. )
  35. return $property
  36. }
  37. function Get-APTemporaryDirectory {
  38. do {
  39. $tempDir = Join-Path -Path $env:TEMP -ChildPath ([System.IO.Path]::GetRandomFileName())
  40. } while (Test-Path $tempDir)
  41. return $tempDir
  42. }
  43. function Get-APDateFromJson {
  44. param (
  45. [string] $filePath
  46. )
  47. $jsonFilePath = $filePath + ".json"
  48. if (-not (Test-Path $jsonFilePath)) {
  49. return $null
  50. }
  51. $jsonContent = Get-Content -Path $jsonFilePath -Raw | ConvertFrom-Json
  52. $timestamp = [int64] $jsonContent.photoTakenTime.timestamp
  53. return [System.DateTimeOffset]::FromUnixTimeSeconds($timestamp).DateTime
  54. }
  55. function Get-APFileCreationDate {
  56. param (
  57. [string] $filePath,
  58. [string] $fileType
  59. )
  60. if ($fileType -ieq "vidéo") { $propIndex = $VideoCreationDatePropIndex }
  61. if ($fileType -ieq "image") { $propIndex = $ImageCreationDatePropIndex }
  62. $charWhiteList = '[^: \w\/]'
  63. $dateTaken = (Get-APFileMetaData -FilePath $filePath -PropertyIndex $propIndex) -replace $charWhiteList
  64. $culture = Get-Culture
  65. $dateTaken = try { [DateTime]::Parse($dateTaken, $culture) } catch { $null }
  66. return $dateTaken
  67. }
  68. function _subDirectoryFromDate {
  69. param (
  70. [string] $filePath,
  71. [Nullable[datetime]] $originalDate
  72. )
  73. if ($originalDate) {
  74. $year = $originalDate.Year
  75. $month = $originalDate.Month.ToString("D2")
  76. $monthName = Get-Culture | ForEach-Object { $_.DateTimeFormat.GetMonthName($month) }
  77. return "$year\$month - $monthName"
  78. } else {
  79. return "Non daté"
  80. }
  81. }
  82. ###########################################
  83. #### MAIN #####
  84. ###########################################
  85. if ($args[0] -and $args[1]) {
  86. $sourceDir = $args[0]
  87. $destinationDir = $args[1]
  88. } else {
  89. $sourceDir = Read-Host "Veuillez entrer le chemin du dossier source (ou une archive .zip)"
  90. $destinationDir = Read-Host "Veuillez entrer le chemin du dossier destination"
  91. }
  92. if ($sourceDir -imatch "\.zip$") {
  93. $tempDir = Get-APTemporaryDirectory
  94. try {
  95. Expand-Archive -LiteralPath $sourceDir -DestinationPath $tempDir
  96. $sourceDir = $tempDir
  97. }catch{
  98. Write-Host "L'archive n'a pas pu être décompressée."
  99. return
  100. }
  101. }
  102. Get-ChildItem -Path $sourceDir -Recurse -File | ForEach-Object {
  103. $filePath = $_.FullName
  104. $fileType = (Get-APFileMetaData -File $filePath -PropertyIndex $FileTypePropIndex)
  105. if (-not($fileType -match "vidéo|image")) {
  106. Write-Host "Fichier ignoré: $($filePath)"
  107. return
  108. }
  109. $creationDate = if ($value = Get-APDateFromJson -filePath $filePath) {
  110. $value
  111. } else {
  112. Get-APFileCreationDate -filePath $filePath -fileType $fileType
  113. }
  114. $subFolder = _subDirectoryFromDate -filePath $filePath -originalDate $creationDate
  115. $targetDir = Join-Path -Path $DestinationDir -ChildPath $subFolder
  116. if (-not (Test-Path $targetDir)) {
  117. New-Item -Path $targetDir -ItemType Directory | Out-Null
  118. }
  119. Copy-Item -Path $filePath -Destination $targetDir
  120. }
  121. if ($sourceDir -like "$env:TEMP\*") {
  122. Remove-Item -Path $sourceDir -Recurse -Force
  123. }