Un script Powershell pour trier les photos
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }