phtools 0.11.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 88b9383b08dbf6122708f49f7dca05848094b9e8
4
- data.tar.gz: 2600e31ae1221ac0f354ea5d27b1d3ab88e49664
3
+ metadata.gz: 50c505c8d68963e5316f8d25a73ebff6c36522af
4
+ data.tar.gz: 1537c9723b68f2f413bb15f0bdee7df181a1f379
5
5
  SHA512:
6
- metadata.gz: febc61babbd310c24de54f41b67b673694296b2114d0bcd3fe6d2d1b2bda3868255fe11c0b37ac881f323ac0808e938f34806390f9c2b4d2967bf4c02298a9a1
7
- data.tar.gz: aeebf94c79f56643b229886c91b301e93d91b7a73fbe6418e40588be668264008d329e4546fbed250591def80d502b1f49033b4d4b602ab9a7fea9ac6548f616
6
+ metadata.gz: 589135775c85fb42c059b097207ad2f8d4f7e2c89d63c2e29cb2e96f9301ad18e0084ad68fb26a98f16cb2e30fdd11996d073229f4b3e03338dda2d95d04c087
7
+ data.tar.gz: ca264e71b619e5c63ce81e28ac1b0a6d36740bcc9e0cadeec8d3b3628dfe9aea7c4288e191a3e21bfdd3968e4146e96c6daf719aeb9226b3401bd227fdad0732
@@ -8,9 +8,9 @@ AllCops:
8
8
  - 'Guardfile'
9
9
  TargetRubyVersion: 2.3
10
10
 
11
- Style/Encoding:
12
- EnforcedStyle: when_needed
13
- Enabled: true
11
+ # Style/Encoding:
12
+ # EnforcedStyle: when_needed
13
+ # Enabled: true
14
14
 
15
15
  #Style/FrozenStringLiteralComment:
16
16
  # EnforcedStyle: always
@@ -24,6 +24,9 @@ Metrics/ClassLength:
24
24
  Metrics/MethodLength:
25
25
  Enabled: false
26
26
 
27
+ Metrics/BlockNesting:
28
+ Enabled: false
29
+
27
30
  Metrics/CyclomaticComplexity:
28
31
  Enabled: false
29
32
 
@@ -39,5 +42,11 @@ Style/Documentation:
39
42
  Style/SignalException:
40
43
  Enabled: false
41
44
 
42
- Style/AccessorMethodName:
45
+ Style/DateTime:
46
+ Enabled: false
47
+
48
+ Style/UnneededInterpolation:
49
+ Enabled: false
50
+
51
+ Naming/AccessorMethodName:
43
52
  Enabled: false
data/TODO.md CHANGED
@@ -7,6 +7,7 @@
7
7
  - [x] phls: use init method to initialize variables
8
8
  - [x] phls: change -r to -R
9
9
  - [ ] phls: make it work with .folders (like ftls did)
10
+ - [x] phls: sort files in alphabet order
10
11
 
11
12
  ### phmove
12
13
  - [x] phmove: create phmove tool based on ftarrange code (see ftools repo)
@@ -23,9 +24,11 @@
23
24
  - [x] phrename: make it safe and smart. Once the file was renamed to PHTOOL standard, re-run of phrename should not change the date-time info unless options -t or -s are used. If user wants to reset file name using exif tag - 1st clean it `phrename --clean`, then rename `phrename -a anb`
24
25
  - [ ] phrename: make new usage mode: `phrename -t TAG`. Useful if user wants to re-set date-time using TAG keeping author-nickname unchanged
25
26
  - [ ] phrename: add QuickTime.CreationDate into analysis when calculate date-time-in-the-name (useful for iOS mov files). In iOS QuickTime.CreateDate is wrong (always in Grinvich zone), while QuickTime.CreationDate is Ok
27
+ - [ ] phrename: new mode 'manual rename' renames files using given date-time template, author name and prefix. Good for mass renaming of the scanned films and photos (when date-time is not set in the tags and only human knows the real date-time)
26
28
 
27
29
  ### phgettags
28
30
  - [x] create phgettags (based on ftmtags)
31
+ - [ ] support option -e --composite of exiftool
29
32
 
30
33
  ### phfixfmd
31
34
  - [x] create phfixfmd - fix FileModifyDate to get equal to date-time-in-the-name
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,25 +9,25 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} copies the input file to backup directory.
16
- Optimized to be used with other *phtools* via pipes.
17
- Example: phls | #{tool_name} | phrename ...
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} copies the input file to backup directory.
17
+ Optimized to be used with other *phtools* via pipes.
18
+ Example: phls | #{tool_name} | phrename ...
18
19
 
19
- Usage:
20
- #{tool_name} [--backup DIR] [-D]
21
- #{tool_name} -h | --help
22
- #{tool_name} -v | --version
20
+ Usage:
21
+ #{tool_name} [--backup DIR] [-D]
22
+ #{tool_name} -h | --help
23
+ #{tool_name} -v | --version
23
24
 
24
- Options:
25
- -b DIR --backup=DIR Sets the backup directory [Default: ./backup]
26
- -D --debug Turn on debugging (verbose) mode
27
- -h --help Show this screen.
28
- -v --version Show version.
29
- DOCOPT
25
+ Options:
26
+ -b DIR --backup=DIR Sets the backup directory [Default: ./backup]
27
+ -D --debug Turn on debugging (verbose) mode
28
+ -h --help Show this screen.
29
+ -v --version Show version.
30
+ DOCOPT
30
31
 
31
32
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
32
33
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,36 +9,36 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} updates the input file's DateTimeOriginal (CreateDate) tags with
16
- the date-time encoded in the filename (date-time-in-the-name). The file should
17
- be renamed to phtools Standard Name before using this command (use phrename for
18
- this).
19
- This program uses external utility ExifTool created by Phil Harvey
20
- (http://www.sno.phy.queensu.ca/~phil/exiftool/).
21
- #{tool_name} acts as a 'sink' program meaning it expects the input files
22
- to be passed to STDIN, does its job on the files and produces no useful
23
- (for other pipe-optimized programs) output.
24
- In other words this command is intended to be used with other programs
25
- connected via input pipes as a last command in the pipe chain, e.g.:
26
- phls | phrename - a anb | #{tool_name}
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} updates the input file's DateTimeOriginal (CreateDate) tags with
17
+ the date-time encoded in the filename (date-time-in-the-name). The file should
18
+ be renamed to phtools Standard Name before using this command (use phrename for
19
+ this).
20
+ This program uses external utility ExifTool created by Phil Harvey
21
+ (http://www.sno.phy.queensu.ca/~phil/exiftool/).
22
+ #{tool_name} acts as a 'sink' program meaning it expects the input files
23
+ to be passed to STDIN, does its job on the files and produces no useful
24
+ (for other pipe-optimized programs) output.
25
+ In other words this command is intended to be used with other programs
26
+ connected via input pipes as a last command in the pipe chain, e.g.:
27
+ phls | phrename - a anb | #{tool_name}
27
28
 
28
- Usage:
29
- #{tool_name} [-N] [-D]
30
- #{tool_name} -h | --help
31
- #{tool_name} -v | --version
29
+ Usage:
30
+ #{tool_name} [-N] [-D]
31
+ #{tool_name} -h | --help
32
+ #{tool_name} -v | --version
32
33
 
33
- Options:
34
- -N --no_run Dry-run mode means no run exiftool command, only generate script
35
- file 'exif_tagger_dto.txt'. User can check the script and
36
- manually run the command: `exiftool -@ exif_tagger_dto.txt`
37
- -D --debug Turn on debugging (verbose) mode
38
- -h --help Show this screen.
39
- -v --version Show version.
40
- DOCOPT
34
+ Options:
35
+ -N --no_run Dry-run mode means no run exiftool command, only generate script
36
+ file 'exif_tagger_dto.txt'. User can check the script and
37
+ manually run the command: `exiftool -@ exif_tagger_dto.txt`
38
+ -D --debug Turn on debugging (verbose) mode
39
+ -h --help Show this screen.
40
+ -v --version Show version.
41
+ DOCOPT
41
42
 
42
43
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
43
44
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,29 +9,29 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} changes an input file's modify-date according to the date encoded
16
- in the filename (date-time-in-the-name). Therefore the file should be renamed
17
- to phtools Standard Name before using this command (use phrename for this).
18
- #{tool_name} acts as a 'filter' program meaning it expects the input files
19
- to be passed to STDIN and after the job is done it produces STDOUT with the list
20
- of processed files. In other words this command is intended to be used with
21
- other programs connected via pipes, e.g.:
22
- phls | phrename -a anb | #{tool_name} | phmove ~/targed/folder
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} changes an input file's modify-date according to the date encoded
17
+ in the filename (date-time-in-the-name). Therefore the file should be renamed
18
+ to phtools Standard Name before using this command (use phrename for this).
19
+ #{tool_name} acts as a 'filter' program meaning it expects the input files
20
+ to be passed to STDIN and after the job is done it produces STDOUT with the list
21
+ of processed files. In other words this command is intended to be used with
22
+ other programs connected via pipes, e.g.:
23
+ phls | phrename -a anb | #{tool_name} | phmove ~/targed/folder
23
24
 
24
- Usage:
25
- #{tool_name} [-D]
26
- #{tool_name} -h | --help
27
- #{tool_name} -v | --version
25
+ Usage:
26
+ #{tool_name} [-D]
27
+ #{tool_name} -h | --help
28
+ #{tool_name} -v | --version
28
29
 
29
- Options:
30
- -D --debug Turn on debugging (verbose) mode
31
- -h --help Show this screen.
32
- -v --version Show version.
33
- DOCOPT
30
+ Options:
31
+ -D --debug Turn on debugging (verbose) mode
32
+ -h --help Show this screen.
33
+ -v --version Show version.
34
+ DOCOPT
34
35
 
35
36
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
36
37
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,33 +9,33 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} extracts the list of tags stored inside the given file.
16
-
17
- #{tool_name} acts as a 'sink' program meaning it expects the input files
18
- to be passed to STDIN, does its job on the input files and produces no useful
19
- (for other pipe-optimized programs) output.
20
- In other words this command is intended to be used with other programs
21
- connected via input pipes as a last command in the pipe chain, e.g.:
22
- phls | #{tool_name}
23
-
24
- This program uses external utility ExifTool created by Phil Harvey
25
- (http://www.sno.phy.queensu.ca/~phil/exiftool/).
26
-
27
- Usage:
28
- #{tool_name} [-f] [-D]
29
- #{tool_name} -h | --help
30
- #{tool_name} -v | --version
31
-
32
- Options:
33
- -f --full_dump Print all tags
34
- -D --debug Turn on debugging (verbose) mode
35
- -h --help Show this screen.
36
- -v --version Show version.
37
- DOCOPT
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} extracts the list of tags stored inside the given file.
17
+
18
+ #{tool_name} acts as a 'sink' program meaning it expects the input files
19
+ to be passed to STDIN, does its job on the input files and produces no useful
20
+ (for other pipe-optimized programs) output.
21
+ In other words this command is intended to be used with other programs
22
+ connected via input pipes as a last command in the pipe chain, e.g.:
23
+ phls | #{tool_name}
24
+
25
+ This program uses external utility ExifTool created by Phil Harvey
26
+ (http://www.sno.phy.queensu.ca/~phil/exiftool/).
27
+
28
+ Usage:
29
+ #{tool_name} [-f] [-D]
30
+ #{tool_name} -h | --help
31
+ #{tool_name} -v | --version
32
+
33
+ Options:
34
+ -f --full_dump Print all tags
35
+ -D --debug Turn on debugging (verbose) mode
36
+ -h --help Show this screen.
37
+ -v --version Show version.
38
+ DOCOPT
38
39
 
39
40
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
40
41
  end
data/exe/phls CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,37 +9,37 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} scans given directories and generates list of files to standard
16
- output. In short it acts like a smart 'ls' command (or 'dir' in Windows).
17
- Set DIRs to be scanned as a parameters. If no DIRs are set - current dir (.)
18
- will be scanned. Set FILEMASKs as a parameters - and only files matching the
19
- masks will be processed. If no FILEMASK is set '*.*' will be used by-default.
20
- To avoid unnessesary mask extraction by OS - put it in ''.
21
- Note, #{tool_name} works only with phtools-friendly file types: #{file_type * ','}
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} scans given directories and generates list of files to standard
17
+ output. In short it acts like a smart 'ls' command (or 'dir' in Windows).
18
+ Set DIRs to be scanned as a parameters. If no DIRs are set - current dir (.)
19
+ will be scanned. Set FILEMASKs as a parameters - and only files matching the
20
+ masks will be processed. If no FILEMASK is set '*.*' will be used by-default.
21
+ To avoid unnessesary mask extraction by OS - put it in ''.
22
+ Note, #{tool_name} works only with phtools-friendly file types: #{file_type * ','}
22
23
 
23
- #{tool_name} acts as a 'source' program meaning it does not require any input
24
- from STDIN, it generates list of files based on input parameters and send it
25
- to STDOUT.
26
- In other words this command is intended to be used with other programs
27
- connected via pipes as a 1st command in the pipe chain, e.g.:
28
- #{tool_name} abc '*aaa*' | phrename -a anb => scans 'abc' folder and
29
- sends all found phtools friendly files filtered with *aaa* to phrename command.
24
+ #{tool_name} acts as a 'source' program meaning it does not require any input
25
+ from STDIN, it generates list of files based on input parameters and send it
26
+ to STDOUT.
27
+ In other words this command is intended to be used with other programs
28
+ connected via pipes as a 1st command in the pipe chain, e.g.:
29
+ #{tool_name} abc '*aaa*' | phrename -a anb => scans 'abc' folder and
30
+ sends all found phtools friendly files filtered with *aaa* to phrename command.
30
31
 
31
- Usage:
32
- #{tool_name} [-D] [-R] [DIR_OR_FILEMASK...]
33
- #{tool_name} -h | --help
34
- #{tool_name} -v | --version
32
+ Usage:
33
+ #{tool_name} [-D] [-R] [DIR_OR_FILEMASK...]
34
+ #{tool_name} -h | --help
35
+ #{tool_name} -v | --version
35
36
 
36
- Options:
37
- -D --debug Turn on debugging (verbose) mode
38
- -R --recursive Recursively scan directories
39
- -h --help Show this screen.
40
- -v --version Show version.
41
- DOCOPT
37
+ Options:
38
+ -D --debug Turn on debugging (verbose) mode
39
+ -R --recursive Recursively scan directories
40
+ -h --help Show this screen.
41
+ -v --version Show version.
42
+ DOCOPT
42
43
 
43
44
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
44
45
  end
data/exe/phmove CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,32 +9,32 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} moves input file(s) into TARGET_FOLDER.
16
- If TARGET_FOLDER is not set - current folder (.) will be used as a target.
17
- If --arrange option is set it separates photo files, RAW photo files and VIDEO files
18
- to corresponding subfolders.
19
- phtools friendly files: #{file_type * ','}
20
-
21
- Optimized to be used with other *phtools* via pipes.
22
- Example: phls | phrename -a anb | #{tool_name} -a target/folder
23
-
24
-
25
- Usage:
26
- #{tool_name} [-D] [-a] [TARGET_FOLDER]
27
- #{tool_name} -h | --help
28
- #{tool_name} -v | --version
29
-
30
- Options:
31
- -a --arrange Move photos to TARGET_FOLDER, videos to TARGET_FOLDER/VIDEO
32
- raw-files to TARGET_FOLDER/RAW
33
- -D --debug Turn on debugging (verbose) mode
34
- -h --help Show this screen.
35
- -v --version Show version.
36
- DOCOPT
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} moves input file(s) into TARGET_FOLDER.
17
+ If TARGET_FOLDER is not set - current folder (.) will be used as a target.
18
+ If --arrange option is set it separates photo files, RAW photo files and VIDEO files
19
+ to corresponding subfolders.
20
+ phtools friendly files: #{file_type * ','}
21
+
22
+ Optimized to be used with other *phtools* via pipes.
23
+ Example: phls | phrename -a anb | #{tool_name} -a target/folder
24
+
25
+
26
+ Usage:
27
+ #{tool_name} [-D] [-a] [TARGET_FOLDER]
28
+ #{tool_name} -h | --help
29
+ #{tool_name} -v | --version
30
+
31
+ Options:
32
+ -a --arrange Move photos to TARGET_FOLDER, videos to TARGET_FOLDER/VIDEO
33
+ raw-files to TARGET_FOLDER/RAW
34
+ -D --debug Turn on debugging (verbose) mode
35
+ -h --help Show this screen.
36
+ -v --version Show version.
37
+ DOCOPT
37
38
 
38
39
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
39
40
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  module PhTools
@@ -8,68 +9,80 @@ module PhTools
8
9
  require tool_name.to_s
9
10
 
10
11
  file_type = FILE_TYPE_IMAGE + FILE_TYPE_VIDEO + FILE_TYPE_AUDIO
11
- usage = <<DOCOPT
12
- ***************************************************
13
- phtools - *Keep Your Photos In Order* (c) ANB
14
- ***************************************************
15
- #{tool_name} renames the input file to Standard Name:
16
- YYYYmmdd-HHMMSS_AAA ORIGINAL.EXT, where:
17
- YYYYmmdd-HHMMSS - Date-Time of photo creation,
18
- AAA - the author nickname,
19
- ORIGINAL.EXT - the photo name given by digital camera.
20
- By default date-time information will be taken from EXIF area as the 1st non-zero
21
- value of the tags (shown in the order the program scans values):
22
- EXIF:DateTimeOriginal -> IPTC:DateCreated + IPTC:TimeCreated -> XMP:DateCreated ->
23
- -> EXIF:CreateDate -> XMP:CreateDate -> IPTC:DigitalCreationDate + IPTC:DigitalCreationTime ->
24
- -> FileModifyDate
25
- Example: input file DSC03455.JPG will be renamed to 20130108-124145_ANB DSC03455.JPG
12
+ usage = <<~DOCOPT
13
+ ***************************************************
14
+ phtools - *Keep Your Photos In Order* (c) ANB
15
+ ***************************************************
16
+ #{tool_name} renames the input file to Standard Name:
17
+ YYYYmmdd-HHMMSS_AAA ORIGINAL.EXT, where:
18
+ YYYYmmdd-HHMMSS - Date-Time of photo creation,
19
+ AAA - the author nickname,
20
+ ORIGINAL.EXT - the photo name given by digital camera.
21
+ By default date-time information will be taken from EXIF area as the 1st non-zero
22
+ value of the tags (shown in the order the program scans values):
23
+ EXIF:DateTimeOriginal -> IPTC:DateCreated + IPTC:TimeCreated -> XMP:DateCreated ->
24
+ -> EXIF:CreateDate -> XMP:CreateDate -> IPTC:DigitalCreationDate + IPTC:DigitalCreationTime ->
25
+ -> FileModifyDate
26
+ Example: input file DSC03455.JPG will be renamed to 20130108-124145_ANB DSC03455.JPG
27
+
28
+ Input file should be one of the supported types: #{file_type * ','}.
29
+ #{tool_name} acts as a 'filter' meaning it expects the input files to be passed
30
+ to STDIN and after the job is done it produces STDOUT with the list of renamed
31
+ files. In other words this command is intended to be used with other programs
32
+ connected via pipes, e.g.:
33
+ phls | #{tool_name} -a anb | phmove ~/targed/folder
34
+
35
+ The program is designed to be safe to re-run on the same file several times
36
+ - every re-run produces the same result (idempotent behaviour).
37
+ Once the file was renamed to Standard Name, the date-time kept in the name
38
+ is considered as a master date-time of the photo creation and will not be
39
+ changed by re-running #{tool_name} unless user explicitly sets '-t' or '-s' option.
26
40
 
27
- Input file should be one of the supported types: #{file_type * ','}.
28
- #{tool_name} acts as a 'filter' meaning it expects the input files to be passed
29
- to STDIN and after the job is done it produces STDOUT with the list of renamed
30
- files. In other words this command is intended to be used with other programs
31
- connected via pipes, e.g.:
32
- phls | #{tool_name} -a anb | phmove ~/targed/folder
41
+ This program uses external utility ExifTool created by Phil Harvey
42
+ (http://www.sno.phy.queensu.ca/~phil/exiftool/).
33
43
 
34
- The program is designed to be safe to re-run on the same file several times
35
- - every re-run produces the same result (idempotent behaviour).
36
- Once the file was renamed to Standard Name, the date-time kept in the name
37
- is considered as a master date-time of the photo creation and will not be
38
- changed by re-running #{tool_name} unless user explicitly sets '-t' or '-s' option.
44
+ Usage:
45
+ #{tool_name} -a NICK [-t TAG] [-D]
46
+ #{tool_name} -s DELTA [-D]
47
+ #{tool_name} -m DT -a NICK [-s DELTA] [-H HEADER][-D]
48
+ #{tool_name} -c [-H HEADER][-D]
49
+ #{tool_name} -h | --help
50
+ #{tool_name} -v | --version
39
51
 
40
- This program uses external utility ExifTool created by Phil Harvey
41
- (http://www.sno.phy.queensu.ca/~phil/exiftool/).
52
+ Options:
53
+ -a NICK --author=NICK Author nickname size should be #{PhFile::NICKNAME_SIZE} chars,
54
+ supports only latin ASCII chars (e.g. ANB).
55
+ No digits, no spaces, no other non-word chars allowed.
42
56
 
43
- Usage:
44
- #{tool_name} -a NICK [-t TAG] [-D]
45
- #{tool_name} -s DELTA [-D]
46
- #{tool_name} -c [-D]
47
- #{tool_name} -h | --help
48
- #{tool_name} -v | --version
57
+ -t TAG --tag_date=TAG Force program to use TAG as a Date-Time creation
58
+ info instead of standard phtools tags.
59
+ You can retreive all existing tags using command:
60
+ `phls filename|phgettags -f` OR
61
+ `exiftool -s filename`
49
62
 
50
- Options:
51
- -a NICK --author=NICK Author nickname size should be #{PhFile::NICKNAME_SIZE} chars,
52
- supports only latin ASCII chars (e.g. ANB).
53
- No digits, no spaces, no other non-word chars allowed.
63
+ -s DELTA --shift_time=DELTA DELTA (in seconds) will be added to Date-Time value
64
+ kept in the name. If DELTA is positive the photo
65
+ will become yonger: e.g. 20140720-100005, DELTA = 65
66
+ result = 20140720-100110. If DELTA is negative the photo
67
+ will get DELTA seconds older.
68
+ In manual_date mode -s DELTA is used increment
69
+ date-time-in-the-name for every processed file
54
70
 
55
- -t TAG --tag_date=TAG Force program to use TAG as a Date-Time creation
56
- info instead of standard phtools tags.
57
- You can retreive all existing tags using command:
58
- `phls filename|phgettags -f` OR
59
- `exiftool -s filename`
71
+ -m DT --manual_date=DT Force program to use given date-time to rename files.
72
+ DT should comply with phtools standard. Example:
73
+ '20171029-204805'
60
74
 
61
- -s DELTA --shift_time=DELTA DELTA (in seconds) will be added to Date-Time value
62
- kept in the name. If DELTA is positive the photo
63
- will become yonger: e.g. 20140720-100005, DELTA = 65
64
- result = 20140720-100110. If DELTA is negative the photo
65
- will get DELTA seconds older.
75
+ -H HEADER --header=HEADER In manual_date mode adds HEADER to the begining
76
+ of the original basename.
77
+ In clean mode removes HEADER from the beginning of
78
+ the original basename.
66
79
 
67
- -c --clean Rename file back to it's original name
80
+ -c --clean Rename file back to it's original name
68
81
 
69
- -D --debug Turn on debugging (verbose) mode
70
- -h --help Show this screen.
71
- -v --version Show version.
72
- DOCOPT
82
+ -D --debug Turn on debugging (verbose) mode
83
+ -h --help Show this screen.
84
+ -v --version Show version.
85
+ DOCOPT
73
86
 
74
87
  PhTools.const_get(tool_name.capitalize).new(usage, file_type).run!
75
88
  end
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  require 'phtools'
7
8
 
8
- puts PhTools::about
9
+ puts PhTools.about
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  require 'phtools/runner'
@@ -14,13 +15,14 @@ module PhTools
14
15
  def run!
15
16
  @dirs_to_scan.each do |dir|
16
17
  fmask = File.join(dir, @options_cli['--recursive'] ? '**' : '', "{#{@filemasks * ','}}")
17
- Dir.glob(fmask, File::FNM_CASEFOLD).each { |f| output_file(PhFile.new(f)) if File.file?(f) }
18
+ files = Dir.glob(fmask, File::FNM_CASEFOLD)
19
+ files_sorted = files.sort_by(&:downcase)
20
+ files_sorted.each { |f| output_file(PhFile.new(f)) if File.file?(f) }
18
21
  end
19
-
20
22
  rescue SignalException
21
23
  PhTools.puts_error 'EXIT on user interrupt Ctrl-C'
22
24
  exit 1
23
- rescue => e
25
+ rescue StandardError => e
24
26
  PhTools.puts_error "FATAL: #{e.message}", e
25
27
  exit 1
26
28
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  require 'date'
@@ -16,14 +17,27 @@ module PhTools
16
17
  private
17
18
 
18
19
  def validate_options
19
- if @options_cli['--author']
20
+ if @options_cli['--manual_date']
21
+ @mode = :manual_rename
22
+ @manual_date = PhFile.get_date_time(@options_cli['--manual_date'])
23
+ fail PhTools::Error, '--manual_date value is incorrect' if @manual_date == PhFile::ZERO_DATE
24
+ @author = @options_cli['--author'].upcase
25
+ ok, msg = PhFile.validate_author(@author)
26
+ fail PhTools::Error, msg unless ok
27
+ @shift_seconds = @options_cli['--shift_time'].to_i
28
+ @header = @options_cli['--header'].to_s.strip
29
+
30
+ elsif @options_cli['--author']
20
31
  @mode = :rename
21
32
  @author = @options_cli['--author'].upcase
22
33
  ok, msg = PhFile.validate_author(@author)
23
34
  fail PhTools::Error, msg unless ok
24
35
  @user_tag_date = @options_cli['--tag_date'] || ''
36
+
25
37
  elsif @options_cli['--clean']
26
38
  @mode = :clean
39
+ @header = @options_cli['--header'].to_s.strip
40
+
27
41
  elsif @options_cli['--shift_time']
28
42
  @mode = :shift_time
29
43
  @shift_seconds = @options_cli['--shift_time'].to_i
@@ -39,7 +53,7 @@ module PhTools
39
53
  if phfile_out.basename_is_standard? && @user_tag_date.empty?
40
54
  # change only author, keeping date-time safe
41
55
  phfile_out.standardize!(author: @author)
42
- info_msg = "'#{phfile.basename + phfile.extname}' already standard name. Keeping date-time part unchanged"
56
+ info_msg = "'#{phfile.basename + phfile.extname}' already standard name. Keeping date-time-in-name unchanged"
43
57
  else # full rename
44
58
  begin
45
59
  tags = MiniExiftool.new(phfile.filename,
@@ -52,45 +66,45 @@ module PhTools
52
66
  if @user_tag_date.empty?
53
67
  # searching for DateTime stamp value in the tags using priority:
54
68
  # EXIF:DateTimeOriginal -> IPTC:DateCreated + IPTC:TimeCreated -> XMP:DateCreated -> EXIF:CreateDate -> XMP:CreateDate -> IPTC:DigitalCreationDate + IPTC:DigitalCreationTime -> FileModifyDate
55
- if !tags.date_time_original.nil? && tags.date_time_original.kind_of?(DateTime)
69
+ if !tags.date_time_original.nil? && tags.date_time_original.is_a?(DateTime)
56
70
  # EXIF:DateTimeOriginal or IPTC:DateCreated + IPTC:TimeCreated
57
71
  dto = tags.date_time_original
58
- tag_used = "DateTimeOriginal"
72
+ tag_used = 'DateTimeOriginal'
59
73
 
60
- elsif !tags.date_created.nil? && tags.date_created.kind_of?(DateTime)
74
+ elsif !tags.date_created.nil? && tags.date_created.is_a?(DateTime)
61
75
  # XMP:DateCreated
62
76
  dto = tags.date_created
63
- tag_used = "DateCreated"
77
+ tag_used = 'DateCreated'
64
78
 
65
- elsif !tags.create_date.nil? && tags.create_date.kind_of?(DateTime)
79
+ elsif !tags.create_date.nil? && tags.create_date.is_a?(DateTime)
66
80
  # EXIF:CreateDate or XMP:CreateDate or! QuickTime:CreateDate
67
81
  dto = tags.create_date
68
- tag_used = "CreateDate"
82
+ tag_used = 'CreateDate'
69
83
 
70
84
  elsif !tags.digital_creation_date.nil? &&
71
85
  !tags.digital_creation_time.nil? &&
72
- tags.digital_creation_date.kind_of?(String) &&
73
- tags.digital_creation_time.kind_of?(String)
86
+ tags.digital_creation_date.is_a?(String) &&
87
+ tags.digital_creation_time.is_a?(String)
74
88
  # IPTC:DigitalCreationDate + IPTC:DigitalCreationTime
75
- dcdt = tags.digital_creation_date + " " + tags.digital_creation_time
89
+ dcdt = tags.digital_creation_date + ' ' + tags.digital_creation_time
76
90
  begin
77
91
  s = dcdt.sub(/^(\d+):(\d+):/, '\1-\2-')
78
92
  dto = DateTime.parse(s)
79
93
  rescue ArgumentError
80
94
  dto = PhFile::ZERO_DATE
81
95
  end
82
- tag_used = "DigitalCreationDate + DigitalCreationTime"
96
+ tag_used = 'DigitalCreationDate + DigitalCreationTime'
83
97
 
84
98
  else
85
99
  # FileModifyDate
86
100
  dto = File.mtime(phfile.filename).to_datetime
87
- tag_used = "FileModifyDate"
101
+ tag_used = 'FileModifyDate'
88
102
  end
89
103
 
90
104
  else
91
105
  # tag is set by the user
92
106
  fail PhTools::Error, "tag #{@user_tag_date} is not found in a file" unless tags[@user_tag_date]
93
- fail PhTools::Error, "tag #{@user_tag_date} is not a DateTime type" unless tags[@user_tag_date].kind_of?(DateTime)
107
+ fail PhTools::Error, "tag #{@user_tag_date} is not a DateTime type" unless tags[@user_tag_date].is_a?(DateTime)
94
108
  dto = tags[@user_tag_date] || PhFile::ZERO_DATE
95
109
  tag_used = "#{@user_tag_date}"
96
110
  end
@@ -99,18 +113,27 @@ module PhTools
99
113
  end
100
114
 
101
115
  when :clean
102
- phfile_out.cleanse!
116
+ phfile_out.cleanse!(basename_clean: phfile_out.basename_clean.sub(/^#{@header}/, ''))
103
117
 
104
118
  when :shift_time
105
119
  fail PhTools::Error, 'non-standard file name' unless phfile_out.basename_is_standard?
106
120
  phfile_out.standardize!(date_time: phfile_out.date_time + @shift_seconds * (1.0 / 86_400))
121
+
122
+ when :manual_rename
123
+ if phfile_out.basename_is_standard?
124
+ # keeping date-time safe
125
+ info_msg = "'#{phfile.basename + phfile.extname}' already standard name. Keeping date-time-in-name unchanged"
126
+ else # renaming
127
+ basename_clean = (@header.empty? ? '' : @header) + phfile_out.basename_clean
128
+ phfile_out.standardize!(date_time: @manual_date, author: @author, basename_clean: basename_clean)
129
+ @manual_date += @shift_seconds * (1.0 / 86_400)
130
+ end
107
131
  end
108
132
 
109
133
  FileUtils.mv(phfile.filename, phfile_out.filename, verbose: PhTools.debug) unless phfile == phfile_out
110
134
  PhTools.puts_error info_msg unless info_msg.empty?
111
135
  phfile_out
112
-
113
- rescue => e
136
+ rescue StandardError => e
114
137
  raise PhTools::Error, 'file renaming - ' + e.message
115
138
  end
116
139
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  require 'phtools/error'
@@ -9,11 +10,11 @@ require 'fileutils'
9
10
 
10
11
  module PhTools
11
12
  # media type constants
12
- FILE_TYPE_IMAGE_NORMAL = %w(jpg jpeg tif tiff png).freeze
13
- FILE_TYPE_IMAGE_RAW = %w(orf arw dng).freeze
13
+ FILE_TYPE_IMAGE_NORMAL = %w[jpg jpeg tif tiff png].freeze
14
+ FILE_TYPE_IMAGE_RAW = %w[orf arw dng].freeze
14
15
  FILE_TYPE_IMAGE = FILE_TYPE_IMAGE_NORMAL + FILE_TYPE_IMAGE_RAW
15
- FILE_TYPE_VIDEO = %w(avi mp4 mpg mts dv mov mkv m2t m2ts 3gp).freeze
16
- FILE_TYPE_AUDIO = %w(wav).freeze
16
+ FILE_TYPE_VIDEO = %w[avi mp4 mpg mts dv mov mkv m2t m2ts 3gp].freeze
17
+ FILE_TYPE_AUDIO = %w[wav].freeze
17
18
 
18
19
  # phtools file name operations
19
20
  class PhFile
@@ -49,6 +50,13 @@ module PhTools
49
50
  [true, '']
50
51
  end
51
52
 
53
+ def self.get_date_time(date_string)
54
+ /^(?<date>\d{8})-(?<time>\d{6})/ =~ date_string
55
+ DateTime.parse("#{Regexp.last_match(:date)}T#{Regexp.last_match(:time)}")
56
+ rescue ArgumentError
57
+ PhFile::ZERO_DATE
58
+ end
59
+
52
60
  attr_reader :filename, :dirname, :extname, :type, :basename, :basename_part,
53
61
  :basename_clean, :date_time, :author
54
62
 
@@ -181,7 +189,6 @@ module PhTools
181
189
 
182
190
  return ZERO_DATE if strptime_string.empty?
183
191
  DateTime.strptime(strptime_string, strptime_template)
184
-
185
192
  rescue ArgumentError
186
193
  return ZERO_DATE
187
194
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
  # encoding: UTF-8
4
+
4
5
  # (c) ANB Andrew Bizyaev
5
6
 
6
7
  require 'phtools/utils/ruby_version.rb'
@@ -28,11 +29,10 @@ module PhTools
28
29
  PhTools.debug = true if @options_cli['--debug']
29
30
 
30
31
  validate_options
31
-
32
32
  rescue Docopt::Exit => e
33
33
  STDERR.puts e.message
34
34
  exit 1
35
- rescue => e
35
+ rescue StandardError => e
36
36
  PhTools.puts_error "FATAL: #{e.message}", e
37
37
  exit 1
38
38
  ensure
@@ -59,29 +59,25 @@ module PhTools
59
59
  end
60
60
 
61
61
  process_after
62
-
63
62
  rescue SignalException
64
63
  PhTools.puts_error 'EXIT on user interrupt Ctrl-C'
65
64
  exit 1
66
- rescue => e
65
+ rescue StandardError => e
67
66
  PhTools.puts_error "FATAL: #{e.message}", e
68
67
  exit 1
69
68
  end
70
69
 
71
70
  private
72
71
 
73
- def validate_options
74
- end
72
+ def validate_options; end
75
73
 
76
- def process_before
77
- end
74
+ def process_before; end
78
75
 
79
76
  def process_file(file)
80
77
  file
81
78
  end
82
79
 
83
- def process_after
84
- end
80
+ def process_after; end
85
81
 
86
82
  def context
87
83
  instance_variables.map do |item|
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  # encoding: UTF-8
4
+
3
5
  # (c) ANB Andrew Bizyaev
4
6
 
5
- RUBY_VERSION_WANTED = '2.0.0'
7
+ RUBY_VERSION_WANTED = '2.4.0'
6
8
 
7
9
  begin
8
10
  fail "Ruby version must be >= #{RUBY_VERSION_WANTED}" if
9
11
  RUBY_VERSION < RUBY_VERSION_WANTED
10
- rescue => e
12
+ rescue StandardError => e
11
13
  STDERR.puts e.message
12
14
  exit 1
13
15
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PhTools
4
- VERSION = '0.11.2'
4
+ VERSION = '0.14.0'
5
5
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'phtools/version'
@@ -8,13 +7,12 @@ Gem::Specification.new do |spec|
8
7
 
9
8
  spec.name = 'phtools'
10
9
  spec.version = PhTools::VERSION
11
- # spec.date = '2016-08-23'
12
10
  spec.authors = ["Andrew Bizyaev"]
13
11
  spec.email = ["andrew.bizyaev@gmail.com"]
14
12
  spec.license = 'MIT'
15
13
 
16
- spec.summary = %q{A set of usefull tools to manipulate photo-video files.}
17
- spec.description = %q{A bundle of small CLI tools for arranging, renaming, tagging of the photo and video files. Helps to keep your photo-video assets in order.}
14
+ spec.summary = %q(A set of usefull tools to manipulate photo-video files.)
15
+ spec.description = %q(A bundle of small CLI tools for arranging, renaming, tagging of the photo and video files. Helps to keep your photo-video assets in order.)
18
16
  spec.homepage = "https://github.com/AndrewBiz/phtools.git"
19
17
 
20
18
  spec.requirements = %q{ExifTool by Phil Harvey (http://www.sno.phy.queensu.ca/~phil/exiftool/)}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phtools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Bizyaev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-01 00:00:00.000000000 Z
11
+ date: 2017-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -344,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
344
344
  requirements:
345
345
  - ExifTool by Phil Harvey (http://www.sno.phy.queensu.ca/~phil/exiftool/)
346
346
  rubyforge_project:
347
- rubygems_version: 2.6.6
347
+ rubygems_version: 2.6.13
348
348
  signing_key:
349
349
  specification_version: 4
350
350
  summary: A set of usefull tools to manipulate photo-video files.