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