media2import.sh 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #
  2. # This is simple script for importing media files from source (such as memory cards)
  3. # to destination (such as local storage), creating date directories and renaming them by timestamp
  4. # of given file in desired format. Other features of script: integrity check (using sha256sum).
  5. #
  6. #
  7. #
  8. # Author: Anton TETERIN (https://og2k.com)
  9. # Source: https://github.com/InstallAndUse/Graphics
  10. #
  11. # History:
  12. # 2023-05-07 * init /A
  13. # 2023-05-08 + read flags from CLI /A
  14. # 2023-05-16 * moved from rsync to file 'for' itiration /A
  15. # 2023-06-27 * upgrading /A
  16. # 2023-06-28 * path with spaces variables /A
  17. # 2023-06-29 + hash comparison /A
  18. # + removal on successful integrity verification /A
  19. # 2023-06-30 + add note to subdir, if specified /A
  20. #
  21. function ts() {
  22. # change d
  23. ts=$(date)
  24. echo $(date )
  25. }
  26. # default help
  27. usage () {
  28. echo "Usage: $0 -s - source, -d destination, -n note";
  29. exit 1;
  30. }
  31. # TODO: skip files which specified extensions (*.LRV, *.THM)
  32. # TODO: remove files with specififed extensions (*.LRV, *.THM)
  33. # read flags
  34. while getopts s:d:n: flag
  35. do
  36. case "${flag}" in
  37. s) src=${OPTARG};;
  38. d) dst=${OPTARG};;
  39. n) note=${OPTARG};;
  40. ?) usage;;
  41. esac
  42. done
  43. # read source path, by default current path (if not given)
  44. # assuming not recursive, only in-directory files will be imported
  45. if [ -z $src ]; then
  46. read -p "[ $(ts) ]: Source [$(pwd)]: " src
  47. if [ -z ${src} ]; then
  48. src="$(pwd)"
  49. fi
  50. fi
  51. # read destination path, by default current path (if not given)
  52. if [ -z $dst ]; then
  53. read -p "[ $(ts) ]: Destination [$(pwd)]: " dst
  54. if [ -z ${dst} ]; then
  55. dst="$(pwd)"
  56. fi
  57. fi
  58. # read noteription, by default empty
  59. if [ -z $note ]; then
  60. read -p "[ $(ts) ]: Note of session/event: " note
  61. if [ -z ${note} ]; then
  62. note=""
  63. else
  64. # adding hyphen before note, if it is not empty
  65. note=" - ${note}"
  66. fi
  67. fi
  68. # source and destination can not be the same, exit
  69. if [ ${src} = ${dst} ]; then
  70. echo "[ $(ts) ]: Source and destination are the same, exiting..."
  71. exit 2
  72. fi
  73. # # itirating files
  74. # # calculate total size for source files, as they will be copied (not recursive for directory)
  75. # done
  76. # echo "The size of all NN files is YY bytes (YY/1024 MB = YY/1024/104) GB."
  77. echo "[ $(ts) ]: ----- [ Transfer details ] ---------------------------------------------"
  78. # check that source directory exists, otherwise - exit
  79. if [ -d "$src" ]; then
  80. # TODO: src, dst total and free disk space before transfer
  81. files_src_total_amount=0
  82. files_src_total_size=0
  83. for file in "$src"/*; do
  84. file_size="$( stat -f %z "$file" )"
  85. # echo "[ $(ts) ]: file: ${file} adding file_size: $(( $file_size/1024/1024 )) MB."
  86. files_src_total_size=$(( $files_src_total_size+$file_size ))
  87. files_src_total_amount=$(( $files_src_total_amount+1 ))
  88. done
  89. echo "[ $(ts) ]: Source: [${src}]"
  90. # TODO: add nice GB figures (need to use awk or bc)
  91. echo "[ $(ts) ]: Total of $files_src_total_amount src files, total size is $(( $files_src_total_size/1024/1024 )) MB)."
  92. else
  93. echo "[ $(ts) ]: src dir does not exist, exiting..."
  94. exit 2
  95. fi
  96. echo "[ $(ts) ]: Destination: [${dst}]"
  97. echo "[ $(ts) ]: Note: [${note}]"
  98. # confirm
  99. read -p "[ $(ts) ]: Confirm (Y): " confirm
  100. if [ ${confirm} = "Y" ]; then
  101. echo "[ $(ts) ]: Preparing to transfer..."
  102. # check and create destination directory, if needed
  103. if ! [ -d "$dst" ]; then
  104. read -p "[ $(ts) ]: dst dir does not exist, do you want to create?" confirm
  105. if [ ${confirm} = "Y" ]; then
  106. mkdir -v -p -m 700 "$dst"
  107. echo "[ $(ts) ]: dst dir created."
  108. fi
  109. fi
  110. files_copied_filename=()
  111. files_copied_total_size=0
  112. files_error_filename=()
  113. # itirating files
  114. for file in "$src"/*; do
  115. # echo "[ $(ts) ]: src dir: ["$src"]"
  116. filename="$(basename "$file")"
  117. # figure out when is the creation date
  118. file_mdate="$( stat -f %Sm -t %Y-%m-%d "$file" )"
  119. file_size="$( stat -f %z "$file" )"
  120. # appending note, if specified
  121. if [ -z "$note" ]; then
  122. dst_subdir="${file_mdate}"
  123. else
  124. dst_subdir="${file_mdate}${note}"
  125. fi
  126. # create subdirectory for creation date
  127. mkdir -p "$dst"/"$dst_subdir"
  128. # TODO: echo 'show which file is being copied out of total' in the same status line below
  129. echo "[ $(ts) ]: src dst: ["$src"], file: [${filename}], modification date is: ${file_mdate}, ( $(( ${file_size}/1024/1024 )) MB )"
  130. # TODO: linux/BSD check for shasum function, if it does not run properly on linux
  131. # calulating src hash sum
  132. src_hash=$( shasum -a 256 "$file" | cut -d ' ' -f 1)
  133. # echo "[ $(ts) ]: src sha256sum: [${src_hash}]"
  134. echo "[ $(ts) ]: dst subdir: ["$dst"/"$dst_subdir"]"
  135. # main operation
  136. # echo "[ $(ts) ] copying.."
  137. cp "$file" "$dst"/"$dst_subdir"
  138. # calulating dst hash sum
  139. dst_hash=$( shasum -a 256 "${dst}/${dst_subdir}/${filename}" | cut -d ' ' -f 1)
  140. # echo "[ $(ts) ]: dst sha256sum: [${dst_hash}]"
  141. # if shasum is the same, add to statistics and remove file
  142. if [ ${src_hash} = ${dst_hash} ]; then
  143. # add to files_copied array
  144. files_copied_filename+=("$filename")
  145. files_copied_total_size+=$file_size
  146. # TODO: add summarize sized of copied file ${file_size}
  147. # echo "[ $(ts) ]: src and dst hashes are the same, removing src file"
  148. rm "${file}"
  149. else
  150. echo "[ $(ts) ]: src and dst hashes are different, src file will not be removed."
  151. files_error_filename+=("$file")
  152. fi
  153. # TODO: add original file with fullpath to array:
  154. # files_src[]="${file}]"
  155. # TODO: add copied file with fullpath to array:
  156. # files_dst[]="$dst"/"$dst_subdir"/${filename}
  157. done
  158. # TODO: src, dst total and free disk space before transfer
  159. # TODO: src, dst total and free disk space after copy
  160. # TODO: time taken to transfer
  161. # TODO: avarage transfer speed
  162. # TODO: unmount src disk ?
  163. # diskutil unmount /Volumes/empty
  164. # TODO: open latest directory created?
  165. # TODO: output total amount of files and size
  166. # itirate files
  167. # read creation date of file
  168. #dst_subdir="${dst}/${file_creation_date}${note}"
  169. # TODO: list subdirs, that created (in order to see, where to files are transferred)
  170. else
  171. # not confirmed
  172. echo "[ $(ts) ]: Operation is not confirmed."
  173. exit 1
  174. fi