phtools 0.11.2 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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.