filerenamer 0.0.9 → 0.0.10
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 +4 -4
- data/CHANGES +8 -0
- data/VERSION +1 -1
- data/bin/renhash +2 -2
- data/bin/rennum +6 -5
- data/bin/renpad +3 -2
- data/bin/renpar +3 -2
- data/bin/renreg +3 -2
- data/bin/rensub +3 -2
- data/bin/rentime +15 -7
- data/example/rennum/1 +0 -0
- data/example/rennum/2 +0 -0
- data/example/rennum/3 +0 -0
- data/example/rennum/4 +0 -0
- data/example/rensub/aa +0 -0
- data/example/rensub/aaa +0 -0
- data/example/rensub/aaaa +0 -0
- data/example/rensub/aaaaa +0 -0
- data/lib/filerenamer.rb +1 -11
- data/lib/filerenamer/commander.rb +217 -207
- data/lib/filerenamer/optionparser.rb +2 -1
- data/lib/filerenamer/renameorderer.rb +153 -0
- data/test/commander/a.file +0 -0
- data/test/commander/b.file +0 -0
- data/test/renameorderer/01/0 +0 -0
- data/test/renameorderer/01/1 +0 -0
- data/test/renameorderer/012/0 +0 -0
- data/test/renameorderer/012/1 +0 -0
- data/test/renameorderer/012/2 +0 -0
- data/test/renameorderer/0123/0 +0 -0
- data/test/renameorderer/0123/1 +0 -0
- data/test/renameorderer/0123/2 +0 -0
- data/test/renameorderer/0123/3 +0 -0
- data/test/renameorderer/02/0 +0 -0
- data/test/renameorderer/02/2 +0 -0
- data/test/test_commander.rb +136 -72
- data/test/test_renameorderer.rb +123 -0
- metadata +26 -4
- data/filerenamer.gemspec +0 -126
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e838a2d6a783cce04970448bddc5fb3574aa95b2
|
4
|
+
data.tar.gz: de135ba52d266080dc0cfcbbf7e398c0ce6f83c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ab52c0bcf4209aef9fe09be8b7befe694bd4d503fb1865256b18b8d9f8a39f1df0e17a77f94f52243290827e1199b687245082a02882eb9dc5ad03d95e2c998
|
7
|
+
data.tar.gz: 46bbdb06d50e86f2bb20210a24ac9437e00c80306946fde25bd8c80a380da436ee974ee6f36c112d9afaed1bc34a21bdb2ce7f239bd8166f066dd7fba971bd40
|
data/CHANGES
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
<!-- Master -->
|
4
4
|
|
5
|
+
|
6
|
+
== Version 0.0.10 [2017-03-04] released
|
7
|
+
|
8
|
+
* Add RenameOrderer, a smart dependency resolver of rename processes.
|
9
|
+
* bin/rennum; --random option was renamed to --shuffle
|
10
|
+
* bin/rentime --jpg
|
11
|
+
* bin/rentime --tiff
|
12
|
+
|
5
13
|
== Version 0.0.9 [2016-07-12] released
|
6
14
|
|
7
15
|
* Add --git option
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.10
|
data/bin/renhash
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
4
|
require "pp"
|
5
|
-
gem "builtinextension"
|
5
|
+
#gem "builtinextension"
|
6
6
|
require "string/escapezsh.rb"
|
7
7
|
require "filerenamer.rb"
|
8
8
|
#require "filerenamer/commander.rb"
|
9
|
-
require "filerenamer/optionparser.rb"
|
9
|
+
#require "filerenamer/optionparser.rb"
|
10
10
|
|
11
11
|
OPTIONS = {}
|
12
12
|
op = FileRenamer::OptionParser.new
|
data/bin/rennum
CHANGED
@@ -6,8 +6,9 @@
|
|
6
6
|
# -i オプションで開始番号を指定
|
7
7
|
# -p : preserve old name 元のファイル名を残す。foo.txt -> 001-foo.txt
|
8
8
|
require 'pp'
|
9
|
-
require
|
10
|
-
require 'filerenamer/
|
9
|
+
require "filerenamer.rb"
|
10
|
+
#require 'filerenamer/commander.rb'
|
11
|
+
#require 'filerenamer/optionparser.rb'
|
11
12
|
|
12
13
|
|
13
14
|
OPTIONS = {}
|
@@ -18,8 +19,8 @@ op.on("-i num", "--initial", "Indicate initial number."){ |val|
|
|
18
19
|
op.on("-p", "--preserve", "Preserve old name."){
|
19
20
|
OPTIONS[:preserve] = true
|
20
21
|
}
|
21
|
-
op.on("
|
22
|
-
OPTIONS[:
|
22
|
+
op.on("--shuffle", "Shuffle number."){
|
23
|
+
OPTIONS[:shuffle] = true
|
23
24
|
}
|
24
25
|
op.parse!(ARGV)
|
25
26
|
|
@@ -29,7 +30,7 @@ files = FileRenamer::Commander.files(ARGV)
|
|
29
30
|
last_number = OPTIONS[:init].to_i + files.size - 1
|
30
31
|
width = last_number.to_s.size
|
31
32
|
|
32
|
-
files.shuffle! if OPTIONS[:
|
33
|
+
files.shuffle! if OPTIONS[:shuffle]
|
33
34
|
|
34
35
|
fr = FileRenamer::Commander.new(op.options, files)
|
35
36
|
|
data/bin/renpad
CHANGED
@@ -4,8 +4,9 @@
|
|
4
4
|
# Pad 0 onto the first numeric character series in filenames to become the same length.
|
5
5
|
|
6
6
|
require "pp"
|
7
|
-
require "filerenamer
|
8
|
-
require "filerenamer/
|
7
|
+
require "filerenamer.rb"
|
8
|
+
#require "filerenamer/commander.rb"
|
9
|
+
#require "filerenamer/optionparser.rb"
|
9
10
|
|
10
11
|
PATTERN = /^(\D*)(\d+)(.*)$/
|
11
12
|
|
data/bin/renpar
CHANGED
@@ -11,8 +11,9 @@ require "rubygems"
|
|
11
11
|
gem "builtinextension"
|
12
12
|
require "string/splitparens.rb"
|
13
13
|
|
14
|
-
require "filerenamer
|
15
|
-
require "filerenamer/
|
14
|
+
require "filerenamer.rb"
|
15
|
+
#require "filerenamer/commander.rb"
|
16
|
+
#require "filerenamer/optionparser.rb"
|
16
17
|
|
17
18
|
|
18
19
|
OPTIONS = {}
|
data/bin/renreg
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
require "filerenamer
|
5
|
-
require "filerenamer/
|
4
|
+
require "filerenamer.rb"
|
5
|
+
#require "filerenamer/commander.rb"
|
6
|
+
#require "filerenamer/optionparser.rb"
|
6
7
|
|
7
8
|
op = FileRenamer::OptionParser.new
|
8
9
|
op.parse!(ARGV)
|
data/bin/rensub
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
require "filerenamer
|
5
|
-
require "filerenamer/
|
4
|
+
require "filerenamer.rb"
|
5
|
+
#require "filerenamer/commander.rb"
|
6
|
+
#require "filerenamer/optionparser.rb"
|
6
7
|
|
7
8
|
OPTIONS = {}
|
8
9
|
op = FileRenamer::OptionParser.new
|
data/bin/rentime
CHANGED
@@ -4,27 +4,35 @@
|
|
4
4
|
require "pp"
|
5
5
|
require "filerenamer.rb"
|
6
6
|
require "optparse"
|
7
|
+
require "exifr"
|
7
8
|
|
8
9
|
## option analysis
|
9
10
|
OPTIONS = {}
|
10
|
-
op = OptionParser.new
|
11
|
+
op = FileRenamer::OptionParser.new
|
11
12
|
#op.banner = [
|
12
13
|
# "Usage: #{File.basename("#{__FILE__}")}",
|
13
14
|
#].join("\n")
|
14
|
-
op.on("-p"
|
15
|
-
op.
|
16
|
-
|
17
|
-
op =
|
15
|
+
op.on("-p", "--preserve", "preserve old name"){OPTIONS[:preserve] = true}
|
16
|
+
op.on("-j", "--jpg" , "exif date_time_original from JPG"){OPTIONS[:jpg] = true}
|
17
|
+
op.on("-t", "--tiff", "exif date_time_original from TIFF"){OPTIONS[:tiff] = true} # Canon CR2, Nikon NEF
|
18
|
+
op.on("-s char", "--separator=char", "Separator like '/' in 'YY/MM/DD/'"){|v| OPTIONS[:separator] = v}
|
18
19
|
op.parse!(ARGV)
|
20
|
+
s = OPTIONS[:separator]
|
19
21
|
|
20
22
|
fr = FileRenamer::Commander.new(op.options, ARGV)
|
21
23
|
fr.execute do |filename|
|
22
24
|
extname = File.extname filename
|
23
25
|
old_base = filename.sub(/#{extname}$/, "")
|
24
26
|
dirname = File.dirname filename
|
25
|
-
|
27
|
+
if OPTIONS[:jpg]
|
28
|
+
date = EXIFR::JPEG.new(filename).date_time
|
29
|
+
elsif OPTIONS[:tiff]
|
30
|
+
date = EXIFR::TIFF.new(filename).date_time
|
31
|
+
else
|
32
|
+
date = File.mtime(filename)
|
33
|
+
end
|
26
34
|
|
27
|
-
new_basename = dirname + date.strftime("/%Y%m%d
|
35
|
+
new_basename = dirname + date.strftime("/%Y#{s.to_s}%m#{s.to_s}%d#{s || '-'}%H%M%S")
|
28
36
|
new_basename += "-#{old_base}" if OPTIONS[:preserve]
|
29
37
|
newname = new_basename + extname
|
30
38
|
newname
|
data/example/rennum/1
ADDED
File without changes
|
data/example/rennum/2
ADDED
File without changes
|
data/example/rennum/3
ADDED
File without changes
|
data/example/rennum/4
ADDED
File without changes
|
data/example/rensub/aa
ADDED
File without changes
|
data/example/rensub/aaa
ADDED
File without changes
|
data/example/rensub/aaaa
ADDED
File without changes
|
File without changes
|
data/lib/filerenamer.rb
CHANGED
@@ -1,16 +1,6 @@
|
|
1
1
|
require "fileutils"
|
2
2
|
require "filerenamer/commander.rb"
|
3
3
|
require "filerenamer/optionparser.rb"
|
4
|
-
|
5
|
-
#require "filerenamer/manipulation/mv.rb"
|
6
|
-
#require "filerenamer/manipulation/cp.rb"
|
7
|
-
#require "filerenamer/manipulation/ln.rb"
|
8
|
-
#require "filerenamer/manipulation/lns.rb"
|
9
|
-
##require "filerenamer/manipulation/rm.rb"
|
10
|
-
#require "filerenamer/manipulationqueue.rb"
|
11
|
-
##require "filerenamer/manipulation/mkdirp.rb" not prepare due to ambiguous behavior.
|
12
|
-
##require "filerenamer/manipulation/rmdirp.rb" not prepare due to ambiguous behavior.
|
13
|
-
#require "filerenamer/filetreesimulator.rb"
|
14
|
-
#require "filerenamer/filetreesimulator/file.rb"
|
4
|
+
require "filerenamer/renameorderer.rb"
|
15
5
|
|
16
6
|
module FileRenamer; end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
+
#gem "builtinextension"
|
5
|
+
require "filerenamer/optionparser.rb"
|
6
|
+
require "fileutils"
|
7
|
+
require "optparse"
|
4
8
|
require "rubygems"
|
5
|
-
gem "builtinextension"
|
6
9
|
require "string/escapezsh.rb"
|
7
10
|
require "string/width.rb"
|
8
|
-
|
9
|
-
require
|
10
|
-
require "optparse"
|
11
|
-
require "filerenamer/optionparser.rb"
|
11
|
+
require 'tmpdir'
|
12
|
+
require 'pathname'
|
12
13
|
|
13
14
|
# ファイル群の名前変更を一括して行うためのクラス。
|
14
15
|
# 他のアプリケーションからも使えるけれど、
|
@@ -29,7 +30,7 @@ require "filerenamer/optionparser.rb"
|
|
29
30
|
# 途中まで変換してから interrupt されたときに
|
30
31
|
# 中にあるファイルごと消される可能性がありそう。
|
31
32
|
# そのため、メソッド内で自分で temporary directory を作成する。
|
32
|
-
#
|
33
|
+
#
|
33
34
|
# 没案
|
34
35
|
# rename_rule メソッドをデフォルトで例外にしておいて、
|
35
36
|
# コマンドスクリプト側で定義するという方法は、
|
@@ -37,234 +38,243 @@ require "filerenamer/optionparser.rb"
|
|
37
38
|
# 自由度が少なくなる。
|
38
39
|
# たとえば old_str, new_str を渡したい時と、
|
39
40
|
# 更新時刻でリネームしたいときでは必要な引数の数が異なる。
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
41
|
+
class FileRenamer::Commander
|
42
|
+
attr_reader :files
|
43
|
+
|
44
|
+
class NoRenameRuleError < StandardError; end
|
45
|
+
class OptionError < StandardError; end
|
46
|
+
class ModeError < StandardError; end
|
47
|
+
|
48
|
+
def self.files(strs)
|
49
|
+
if strs.empty?
|
50
|
+
return Dir::glob("*").sort
|
51
|
+
else
|
52
|
+
return strs
|
53
53
|
end
|
54
|
+
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if (@options[:yes] && @options[:no])
|
64
|
-
raise OptionError,
|
65
|
-
"Conflict options: --yes and --no."
|
66
|
-
end
|
56
|
+
#:yes と :no が両方 true ならば例外。
|
57
|
+
#:copy, :move, :hardlink, :symlink, :git のうち、1つ以下が true。
|
58
|
+
#全て nil ならば :move が true になる。
|
59
|
+
#:quiet が true ならば自動的に :yes が立てられる。
|
60
|
+
#:quiet が true で :no も true ならば例外。
|
61
|
+
def initialize(options, files)
|
62
|
+
@options = options
|
67
63
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
# 1つもなければ :move に。
|
73
|
-
@options[:move] = true if fileProcessModes == []
|
74
|
-
# 2つ以上あれば例外。
|
75
|
-
if fileProcessModes.size > 1
|
76
|
-
raise OptionError,
|
77
|
-
"File process modes duplicate: #{fileProcessModes.join(", ")}"
|
78
|
-
end
|
79
|
-
@command = "mv" if @options[:move]
|
80
|
-
@command = "cp -r" if @options[:copy]
|
81
|
-
@command = "ln" if @options[:hardlink]
|
82
|
-
@command = "ln -s" if @options[:symlink]
|
83
|
-
@command = "git mv" if @options[:git]
|
84
|
-
|
85
|
-
# :quiet ならば自動的に :yes
|
86
|
-
@options[:yes] = true if @options[:quiet]
|
87
|
-
|
88
|
-
# :quiet と同時に :no なら例外
|
89
|
-
if @options[:quiet] && @options[:no]
|
90
|
-
raise OptionError,
|
91
|
-
"Conflict options: --quiet and --no"
|
92
|
-
end
|
64
|
+
if (@options[:yes] && @options[:no])
|
65
|
+
raise OptionError, "Conflict options: --yes and --no."
|
66
|
+
end
|
93
67
|
|
94
|
-
|
68
|
+
fileProcessModes = []
|
69
|
+
[:move, :copy, :hardlink, :symlink, :git].each do |mode|
|
70
|
+
fileProcessModes << mode if @options[mode]
|
71
|
+
end
|
72
|
+
# mode が1つもなければ :move に。
|
73
|
+
@options[:move] = true if fileProcessModes == []
|
74
|
+
# 2つ以上あれば例外。
|
75
|
+
if fileProcessModes.size > 1
|
76
|
+
raise OptionError,
|
77
|
+
"File process modes duplicate: #{fileProcessModes.join(", ")}"
|
95
78
|
end
|
96
79
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
ok_files.keys.sort.each do |old|
|
113
|
-
printf(" %s %s%s %s\n",
|
114
|
-
@command, old, " " * (max_width - old.width), ok_files[old]
|
115
|
-
)
|
116
|
-
end
|
117
|
-
end
|
80
|
+
@mode = :move if @options[:move]
|
81
|
+
@mode = :copy if @options[:copy]
|
82
|
+
@mode = :hardlink if @options[:hardlink]
|
83
|
+
@mode = :symlink if @options[:symlink]
|
84
|
+
@mode = :git if @options[:git]
|
85
|
+
|
86
|
+
case @mode
|
87
|
+
when :move ; then; @command = "mv"
|
88
|
+
when :copy ; then; @command = "cp -r"
|
89
|
+
when :hardlink ; then; @command = "ln"
|
90
|
+
when :symlink ; then; @command = "ln -s"
|
91
|
+
when :git ; then; @command = "git mv"
|
92
|
+
else
|
93
|
+
raise ModeError, "Unknown mode: #{@mode}"
|
94
|
+
end
|
118
95
|
|
119
|
-
|
120
|
-
puts "Unable files:"
|
121
|
-
max_width = ng_files.keys.max_by{|file| file.width}.width
|
122
|
-
ng_files.keys.sort.each do |old|
|
123
|
-
printf(" %s %s%s %s\n",
|
124
|
-
@command, old, " " * (max_width - old.width), ng_files[old]
|
125
|
-
)
|
126
|
-
end
|
127
|
-
puts
|
128
|
-
end
|
129
|
-
end
|
96
|
+
@options[:yes] = true if @options[:quiet] # :quiet ならば自動的に :yes
|
130
97
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
elsif @options[:no]
|
135
|
-
puts "Execute? no"
|
136
|
-
return
|
137
|
-
end
|
98
|
+
if @options[:quiet] && @options[:no] # :quiet と同時に :no なら例外
|
99
|
+
raise OptionError, "Conflict options: --quiet and --no"
|
100
|
+
end
|
138
101
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
102
|
+
@files = self.class.files(files)
|
103
|
+
end
|
104
|
+
|
105
|
+
# 変更される名前のリストを表示し、ユーザの指示に従って実行する。
|
106
|
+
# ユーザの入力は [y|Y] で始まる文字列ならば実行、
|
107
|
+
# それ以外なら実行しない。
|
108
|
+
# 新しい名前の生成方法をブロックで渡す。
|
109
|
+
# ブロックがなければ例外 FileRenamerNoRenameRuleError
|
110
|
+
def execute(&block)
|
111
|
+
new_names = make_new_names(&block)
|
112
|
+
|
113
|
+
if @mode == :move || @mode == :git
|
114
|
+
ro = FileRenamer::RenameOrderer.new(new_names)
|
115
|
+
ok_files = ro.rename_processes
|
116
|
+
ng_files = ro.unable_processes
|
117
|
+
else
|
118
|
+
ok_files = []
|
119
|
+
ng_files = []
|
120
|
+
new_names.each do |old, new|
|
121
|
+
if File.exist? new
|
122
|
+
ng_files << [old, new]
|
123
|
+
else
|
124
|
+
ok_files << [old, new]
|
125
|
+
end
|
146
126
|
end
|
147
127
|
end
|
148
128
|
|
149
|
-
|
129
|
+
show_conversions(ok_files, "Enable files:")
|
130
|
+
#show_conversions(ng_files, "Unable files:")
|
131
|
+
|
132
|
+
(puts "Execute? no"; return) if @options[:no]
|
150
133
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
@files.each { |i| results[i] = yield i }
|
155
|
-
return results
|
134
|
+
if ok_files.empty?
|
135
|
+
puts "Done. No executable files." unless @options[:quiet]
|
136
|
+
return
|
156
137
|
end
|
157
138
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
# - 新しい名前が古い名前リストに含まれないこと。
|
164
|
-
# - 新しい名前が新しい名前リストに1つ(自分)のみしかないこと。
|
165
|
-
# - 新しい名前のファイルが既に存在しないこと。
|
166
|
-
#
|
167
|
-
# 没案
|
168
|
-
# 新しい名前が変換されない古い名前であれば、
|
169
|
-
# これも NG リストに追加する。(表示用)
|
170
|
-
# このルールにすると、変換に順序依存が生じる可能性があり、
|
171
|
-
# temporary directory を経由する必要ができる。
|
172
|
-
# その結果、リネーム過程で深い temporary directory を
|
173
|
-
# 作成したり削除したりしなければならなくなる。
|
174
|
-
def check_new_names(old_new_hash)
|
175
|
-
ok_files = {}
|
176
|
-
ng_files = {}
|
177
|
-
|
178
|
-
old_new_hash.each do |old, new|
|
179
|
-
# 変化がない場合はスルー
|
180
|
-
next if old == new
|
181
|
-
|
182
|
-
# 新しい名前に nil が定義されていてもスルー
|
183
|
-
next if new == nil
|
184
|
-
|
185
|
-
# 既に存在していれば、既に存在するファイルごと NG に登録。
|
186
|
-
if FileTest.exist?(new)
|
187
|
-
ng_files[old] = new
|
188
|
-
ng_files[new] = new
|
189
|
-
next
|
190
|
-
end
|
139
|
+
if @options[:yes]
|
140
|
+
puts "Execute? yes" unless @options[:quiet]
|
141
|
+
elsif (! ask_yes?)
|
142
|
+
return
|
143
|
+
end
|
191
144
|
|
192
|
-
|
193
|
-
|
194
|
-
ng_files[old] = new
|
195
|
-
next
|
196
|
-
end
|
145
|
+
convert( ok_files)
|
146
|
+
end
|
197
147
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
148
|
+
private
|
149
|
+
|
150
|
+
def show_conversions(conversions, heading)
|
151
|
+
#STDOUT.puts conversions
|
152
|
+
return if conversions.size == 0
|
153
|
+
return if @options[:quiet]
|
154
|
+
puts heading
|
155
|
+
max_width = conversions.max_by{|old, new| old.width}[0].width
|
156
|
+
conversions.each do |old, new|
|
157
|
+
printf(" %s %s%s %s\n",
|
158
|
+
@command, old, " " * (max_width - old.width), new
|
159
|
+
)
|
160
|
+
end
|
161
|
+
puts
|
162
|
+
end
|
203
163
|
|
204
|
-
|
164
|
+
def make_new_names(&block)
|
165
|
+
results = {}
|
166
|
+
@files.each { |i| results[i] = yield i }
|
167
|
+
return results
|
168
|
+
end
|
205
169
|
|
206
|
-
|
207
|
-
|
208
|
-
|
170
|
+
## 新しい名前リストを受け取り、問題なくリネームできるものと
|
171
|
+
## できないものを選別する。
|
172
|
+
## OK, NG の順に2つの配列を返す。
|
173
|
+
##def ok_new_names(old_new_hash)
|
174
|
+
##end
|
175
|
+
##def ng_new_names(old_new_hash)
|
176
|
+
#def check_new_names(old_new_hash)
|
177
|
+
# ok_files = {}
|
178
|
+
# ng_files = {}
|
179
|
+
|
180
|
+
# old_new_hash.each do |old, new|
|
181
|
+
# next if old == new # 変化がない場合は無視
|
182
|
+
# next if new == nil # 新しい名前に nil が定義されていたら無視
|
183
|
+
|
184
|
+
# #宛先が、宛先リスト内で重複していると、NG リスト入り
|
185
|
+
# if (old_new_hash.values.select{|name| name == new}.size > 1)
|
186
|
+
# ng_files[old] = new
|
187
|
+
# next
|
188
|
+
# end
|
189
|
+
|
190
|
+
# # 宛先パスにファイルが既存、かつ、元ファイル名リストに含まれていなければ、NG
|
191
|
+
# if FileTest.exist?(new) && ! old_new_hash.keys.include?(new)
|
192
|
+
# ng_files[old] = new
|
193
|
+
# next
|
194
|
+
# end
|
195
|
+
|
196
|
+
# ok_files[old] = new # 上記以外の場合ならば OK
|
197
|
+
# end
|
198
|
+
# return ok_files, ng_files
|
199
|
+
#end
|
200
|
+
|
201
|
+
# ユーザに判断を求める。
|
202
|
+
# 標準入力から文字列を受け取り、
|
203
|
+
# [y|Y] から始まる文字列なら true を、
|
204
|
+
# それ以外なら false を返す。
|
205
|
+
def ask_yes?
|
206
|
+
puts "Execute?"
|
207
|
+
if /^y/i =~ $stdin.gets
|
208
|
+
return true
|
209
|
+
else
|
210
|
+
return false
|
209
211
|
end
|
212
|
+
end
|
210
213
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
214
|
+
# コマンドを表示しつつ実行。
|
215
|
+
# 既にファイルチェックされているはずなので、チェックはしない。
|
216
|
+
# ディレクトリが必要になればここで作成。
|
217
|
+
# ディレクトリが不要になればここで削除。
|
218
|
+
def convert(conversions)
|
219
|
+
#tmpdir = Dir.mktmpdir('rename', './')
|
220
|
+
|
221
|
+
#int_paths = {} #intermediate paths
|
222
|
+
#conversions.each { |old, new| int_paths[old] = tmpdir + '/' + old }
|
223
|
+
#conversions.each { |old, new| int_paths[old] = tmpdir + '/' + old }
|
224
|
+
#int_paths.each { |old, int| transplant(old, int) }
|
225
|
+
#int_paths.each { |old, int| rmdir_p old }
|
226
|
+
|
227
|
+
conversions.each { |old, new| transplant(old, new) }
|
228
|
+
#int_paths.each { |old, int| rmdir_p int }
|
229
|
+
end
|
230
|
+
|
231
|
+
# Move from root to root.
|
232
|
+
# src_path and tgt_path are paths.
|
233
|
+
def transplant(src_path, tgt_path)
|
234
|
+
#pp src_path, tgt_path;exit
|
235
|
+
# 変換先のディレクトリがなければ生成
|
236
|
+
tgt_dir = File.dirname(tgt_path)
|
237
|
+
unless FileTest.exist?(tgt_dir)
|
238
|
+
#puts " make directory: #{tgt_dir}" unless @options[:quiet]
|
239
|
+
FileUtils.mkdir_p(tgt_dir)
|
223
240
|
end
|
224
241
|
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
end
|
242
|
+
# 変換の実行
|
243
|
+
command = " #{@command} #{src_path.escape_zsh} #{tgt_path.escape_zsh}"
|
244
|
+
#puts command unless @options[:quiet]
|
245
|
+
system(command)
|
246
|
+
|
247
|
+
##STDIN.gets
|
248
|
+
# 変換元のディレクトリが空になっていれば削除
|
249
|
+
src_dir = File.dirname(src_path)
|
250
|
+
#pp Dir.entries(src_dir)
|
251
|
+
if Dir.entries(src_dir).size == 2 # . と .. のみ
|
252
|
+
#puts " remove directory: #{src_dir}" unless @options[:quiet]
|
253
|
+
rmdir_p(src_dir)
|
254
|
+
end
|
255
|
+
end
|
240
256
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
puts " remove directory: #{directory}" unless @options[:quiet]
|
251
|
-
Dir.rmdir(directory)
|
252
|
-
end
|
253
|
-
end
|
257
|
+
# パスに含まれるディレクトリ名を、階層ごとに切り分けたソート済配列にして返す。
|
258
|
+
# 最後の要素は含まない。
|
259
|
+
# e.g. foo/bar/baz.txt => ["foo", "foo/bar"]
|
260
|
+
# e.g. /foo/bar/baz.txt => ["/foo", "foo/bar"]
|
261
|
+
def paths(path)
|
262
|
+
dirs = path.split("/")
|
263
|
+
results = []
|
264
|
+
(dirs.size - 1).times do |i|
|
265
|
+
results << dirs[0..i].join("/")
|
254
266
|
end
|
267
|
+
results.delete_at(0) if results[0] == ""
|
268
|
+
return results
|
269
|
+
end
|
255
270
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
results = []
|
263
|
-
(dirs.size - 1).times do |i|
|
264
|
-
results << dirs[0..i].join("/")
|
271
|
+
def rmdir_p(path)
|
272
|
+
Pathname.new(path).ascend do |p_path|
|
273
|
+
begin
|
274
|
+
Dir.rmdir p_path
|
275
|
+
rescue
|
276
|
+
break
|
265
277
|
end
|
266
|
-
results.delete_at(0) if results[0] == ""
|
267
|
-
return results
|
268
278
|
end
|
269
279
|
end
|
270
280
|
end
|