mvmv 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mvmv.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Junegunn Choi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # Mvmv
2
+
3
+ Simple batch renaming script.
4
+
5
+ ## Installation
6
+
7
+ $ gem install mvmv
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ usage: mvmv [OPTIONS] <command> [<args>] <files>
13
+
14
+ commands:
15
+ mvmv prefix <prefix> <files>
16
+ mvmv suffix <suffix> <files>
17
+ mvmv name <name> <files>
18
+ mvmv name-suffix <suffix> <files>
19
+ mvmv ext <.extension> <files>
20
+ mvmv upper <files>
21
+ mvmv lower <files>
22
+
23
+ mvmv regexp <from> <to> <files>
24
+ mvmv regexpi <from> <to> <files>
25
+ mvmv name-regexp <from> <to> <files>
26
+ mvmv name-regexpi <from> <to> <files>
27
+
28
+ options:
29
+ -f, --force Force rename
30
+ --no-color Disable ANSI color codes
31
+ ```
32
+
33
+ ## Examples
34
+
35
+ ### Adding simple prefix and suffix to files
36
+
37
+ ```
38
+ mvmv prefix old_ *.txt
39
+ mvmv suffix .bak *.txt
40
+ ```
41
+
42
+ ### Numbering files
43
+
44
+ You can attach sequence numbers to files with a series of `#`s.
45
+ Depending on the number of `#`s, numbers will be padded with zeros.
46
+
47
+ ```
48
+ mvmv name Photo#### *.jpg *.gif *.png
49
+ mvmv name-suffix -## *.jpg
50
+ ```
51
+
52
+ ### Advanced renaming with regular expressions
53
+
54
+ `regexp` command performs regular expression substitutions. (`regexpi` is the case-insensitive version.)
55
+ `name-regexp` command performs regular expression subsitution only on the name parts of the given files.
56
+
57
+ ```
58
+ mvmv name-regexp '^(.*)_-_(.*)$' '\2 - \1' *.mp3
59
+ ```
60
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
data/bin/mvmv ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'mvmv'
4
+
5
+ options = {}
6
+ usage = "
7
+ usage: mvmv [OPTIONS] <command> [<args>] <files>
8
+
9
+ commands:
10
+ mvmv prefix <prefix> <files>
11
+ mvmv suffix <suffix> <files>
12
+ mvmv name <name> <files>
13
+ mvmv name-suffix <suffix> <files>
14
+ mvmv ext <.extension> <files>
15
+ mvmv upper <files>
16
+ mvmv lower <files>
17
+
18
+ mvmv regexp <from> <to> <files>
19
+ mvmv regexpi <from> <to> <files>
20
+ mvmv name-regexp <from> <to> <files>
21
+ mvmv name-regexpi <from> <to> <files>
22
+
23
+ options:
24
+ -f, --force Force rename
25
+ --no-color Disable ANSI color codes
26
+ ".strip
27
+
28
+ options = {}
29
+ while ARGV.first =~ /^-/
30
+ case ARGV.shift
31
+ when '-f', '--force'
32
+ options[:force] = true
33
+ when '--no-color'
34
+ options[:color] = false
35
+ end
36
+ end
37
+
38
+ if ARGV.length < 2
39
+ puts usage
40
+ exit 1
41
+ end
42
+
43
+ command = ARGV[0].to_s.gsub('-', '_').to_sym
44
+ args = ARGV[1..-1]
45
+ mvmv = Mvmv.new options.fetch(:color, true)
46
+ begin
47
+ if options[:force]
48
+ mvmv.rename! command, *args
49
+ else
50
+ mvmv.rename command, *args
51
+ end
52
+ rescue ArgumentError => e
53
+ puts opts
54
+ exit 1
55
+ rescue Exception => e
56
+ exit 1
57
+ end
data/lib/mvmv.rb ADDED
@@ -0,0 +1,134 @@
1
+ require 'mvmv/version'
2
+ require 'mvmv/command'
3
+ require 'ansi'
4
+
5
+ class Mvmv
6
+ def initialize color = true, outstream = $stdout, instream = $stdin
7
+ @color = color
8
+ @outstream = outstream
9
+ @instream = instream
10
+ end
11
+
12
+ def convert_filenames symb, *args
13
+ unless Mvmv::Command.respond_to?(symb)
14
+ error "Invalid command: #{symb}"
15
+ end
16
+
17
+ arg_arity = Mvmv::Command.method(symb).arity - 1
18
+ if arg_arity >= args.length
19
+ error "Invalid number of parameters for #{symb}", ArgumentError
20
+ end
21
+
22
+ files = args[arg_arity..-1]
23
+ files.zip Mvmv::Command.send(symb, *(args[0, arg_arity] + [files]))
24
+ end
25
+
26
+ def rename symb, *args
27
+ rename_impl false, symb, *args
28
+ end
29
+
30
+ def rename! symb, *args
31
+ rename_impl true, symb, *args
32
+ end
33
+
34
+ private
35
+ def rename_impl force, symb, *args
36
+ pairs = convert_filenames symb, *args
37
+
38
+ flen = pairs.map(&:first).map(&:length).max
39
+ tlen = pairs.map(&:last).map(&:length).max
40
+
41
+ pairs.each do |pair|
42
+ from, to = pair
43
+ next if from == to || to.empty?
44
+ skip = false
45
+ while true
46
+ log [
47
+ ansi('[', :bold),
48
+ from.ljust(flen),
49
+ ansi('=>', :bold),
50
+ ansi(to.ljust(tlen), :blue, :bold),
51
+ ansi(']', :bold),
52
+ force ? nil : ansi('(', :yellow) +
53
+ ansi('y', :yellow, :bold) +
54
+ ansi('/', :yellow) +
55
+ 'n' +
56
+ ansi(')? ', :yellow)
57
+ ].compact.join(' ')
58
+
59
+ unless force
60
+ case @instream.gets
61
+ when nil
62
+ puts
63
+ next
64
+ when /^n/i
65
+ skip = true
66
+ break
67
+ when /^[^y\n]/i
68
+ next
69
+ end
70
+ end
71
+
72
+ unless File.exists?(from)
73
+ error " File not found: #{from}"
74
+ break
75
+ end
76
+
77
+ if !force && File.exists?(to)
78
+ skip = true
79
+ while true
80
+ log ansi(" #{to} already exists. Overwrite " +
81
+ ansi('(', :yellow) +
82
+ 'y' +
83
+ ansi('/', :yellow) +
84
+ ansi('n', :yellow, :bold) +
85
+ ansi(')? ', :yellow)
86
+ )
87
+
88
+ unless
89
+ case $stdin.gets
90
+ when nil
91
+ puts
92
+ next
93
+ when /^[n\n]/i
94
+ break
95
+ when /^y/i
96
+ skip = false
97
+ break
98
+ else
99
+ next
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ unless skip
106
+ begin
107
+ File.rename from, to
108
+ logln " Renamed", :green
109
+ rescue Exception => e
110
+ error " Failed to rename #{from}"
111
+ end
112
+ end
113
+ break
114
+ end
115
+ end
116
+ end
117
+
118
+ def ansi msg, *colors
119
+ (@color && !colors.empty?) ? ANSI::Code.ansi(*colors) { msg } : msg
120
+ end
121
+
122
+ def log msg, *colors
123
+ @outstream.print ansi(msg, *colors)
124
+ end
125
+
126
+ def logln msg, *colors
127
+ @outstream.puts ansi(msg, *colors)
128
+ end
129
+
130
+ def error message, x = Exception
131
+ logln message, :red, :bold
132
+ raise x.new(message)
133
+ end
134
+ end
@@ -0,0 +1,83 @@
1
+ class Mvmv
2
+ module Command
3
+ class Sequencer
4
+ def initialize n = 1
5
+ @n = n - 1
6
+ end
7
+
8
+ def convert str
9
+ @n += 1
10
+ str.gsub(/#+/) { |x| @n.to_s.rjust(x.length, '0') }
11
+ end
12
+ end
13
+
14
+ class << self
15
+ def name n, files
16
+ seq = Sequencer.new
17
+ files.map { |file|
18
+ seq.convert(n) + File.extname(file)
19
+ }
20
+ end
21
+
22
+ def prefix p, files
23
+ seq = Sequencer.new
24
+ files.map { |file| seq.convert(p) + file }
25
+ end
26
+
27
+ def suffix s, files
28
+ seq = Sequencer.new
29
+ files.map { |file| file + seq.convert(s) }
30
+ end
31
+
32
+ def name_suffix s, files
33
+ seq = Sequencer.new
34
+ files.map { |file|
35
+ ext = File.extname(file)
36
+ file.chomp(ext) + seq.convert(s) + ext
37
+ }
38
+ end
39
+
40
+ def ext x, files
41
+ files.map { |file|
42
+ ext = File.extname(file)
43
+ file.chomp(ext) + x
44
+ }
45
+ end
46
+
47
+ def upper files
48
+ files.map(&:upcase)
49
+ end
50
+
51
+ def lower files
52
+ files.map(&:downcase)
53
+ end
54
+
55
+ def regexpi f, t, files
56
+ seq = Sequencer.new
57
+ files.map { |file|
58
+ seq.convert file.gsub(Regexp.compile(f, Regexp::IGNORECASE), t)
59
+ }
60
+ end
61
+
62
+ def regexp f, t, files
63
+ seq = Sequencer.new
64
+ files.map { |file|
65
+ seq.convert file.gsub(Regexp.compile(f), t)
66
+ }
67
+ end
68
+
69
+ def name_regexpi f, t, files
70
+ regexpi(f, t, files.map { |file|
71
+ file.chomp(File.extname file)
72
+ }).zip(files.map { |file| File.extname file }).map(&:join)
73
+ end
74
+
75
+ def name_regexp f, t, files
76
+ regexp(f, t, files.map { |file|
77
+ file.chomp(File.extname file)
78
+ }).zip(files.map { |file| File.extname file }).map(&:join)
79
+ end
80
+ end
81
+ end#Command
82
+ end
83
+
@@ -0,0 +1,3 @@
1
+ class Mvmv
2
+ VERSION = "0.1.0"
3
+ end
data/mvmv.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mvmv/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Junegunn Choi"]
6
+ gem.email = ["junegunn.c@gmail.com"]
7
+ gem.description = %q{Simple batch renaming}
8
+ gem.summary = %q{Simple batch renaming}
9
+ gem.homepage = "https://github.com/junegunn/mvmv"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mvmv"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mvmv::VERSION
17
+ gem.add_runtime_dependency 'ansi', '~> 1.4.2'
18
+ gem.add_development_dependency 'test-unit'
19
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # DISCLAIMER:
5
+ # Not a real test!
6
+ # Just a helper script for running scripts with local source
7
+
8
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
9
+ load File.join(File.dirname(__FILE__), '../bin/', File.basename(ARGV.shift))
data/test/test_mvmv.rb ADDED
@@ -0,0 +1,85 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ require 'mvmv'
5
+
6
+ class TestMvmv < Test::Unit::TestCase
7
+ def test_name_conversion
8
+ m = Mvmv.new
9
+ input = %w[aaa.jpg bbb.GIF ccc.jpg.png]
10
+ assert_equal input.zip(%w[photo001.jpg photo002.GIF photo003.png]), m.convert_filenames(:name, 'photo###', *input)
11
+ assert_equal input.zip(%w[old_aaa.jpg old_bbb.GIF old_ccc.jpg.png]), m.convert_filenames(:prefix, 'old_', *input)
12
+ assert_equal input.zip(%w[001-aaa.jpg 002-bbb.GIF 003-ccc.jpg.png]), m.convert_filenames(:prefix, '###-', *input)
13
+ assert_equal input.zip(%w[aaa.jpg.0001 bbb.GIF.0002 ccc.jpg.png.0003]), m.convert_filenames(:suffix, '.####', *input)
14
+ assert_equal input.zip(%w[aaa-0001.jpg bbb-0002.GIF ccc.jpg-0003.png]), m.convert_filenames(:name_suffix, '-####', *input)
15
+ assert_equal input.zip(%w[aaa.jpeg bbb.jpeg ccc.jpg.jpeg]), m.convert_filenames(:ext, '.jpeg', *input)
16
+ assert_equal input.zip(%w[AAA.JPG BBB.GIF CCC.JPG.PNG]), m.convert_filenames(:upper, *input)
17
+ assert_equal input.zip(%w[aaa.jpg bbb.gif ccc.jpg.png]), m.convert_filenames(:lower, *input)
18
+
19
+ input = %w[abc.jpg xyz.GIF ijk.jpg.png]
20
+ assert_equal input.zip(%w[cba01.jpg zyx02.GIF kji03.jpg.png]), m.convert_filenames(:regexp, '^([a-z])([a-z])([a-z])', '\3\2\1##', *input)
21
+ assert_equal input.zip(input), m.convert_filenames(:regexp, '^([A-Z])([A-Z])([A-Z])', '\3\2\1##', *input)
22
+ assert_equal input.zip(%w[cba01.jpg zyx02.GIF kji03.jpg.png]), m.convert_filenames(:regexpi, '^([A-Z])([a-z])([A-Z])', '\3\2\1##', *input)
23
+
24
+ assert_equal input.zip(%w[cba01.gpj01 zyx02.GIF kji03.gpj03.gnp03]), m.convert_filenames(:regexp, '([a-z])([a-z])([a-z])', '\3\2\1##', *input)
25
+
26
+ input = %w[Abc.jpg xyz.GIF ijk.jpg.png]
27
+ assert_equal input.zip(%w[Abc.jpg zyx02.GIF kji03.gpj03.png]), m.convert_filenames(:name_regexp, '([a-z])([a-z])([a-z])', '\3\2\1##', *input)
28
+ assert_equal input.zip(%w[cbA01.jpg zyx02.GIF kji03.gpj03.png]), m.convert_filenames(:name_regexpi, '([a-z])([a-z])([a-z])', '\3\2\1##', *input)
29
+ end
30
+
31
+ def test_rename!
32
+ m = Mvmv.new
33
+
34
+ input = %w[aaa.jpg bbb.gif ccc.jpg.png]
35
+ pairs = m.convert_filenames :ext, '.jpeg', *input
36
+
37
+ pairs.each do |pair|
38
+ system "rm -v #{pair.join ' '}"
39
+ end
40
+
41
+ input.each do |file|
42
+ system "touch #{file}"
43
+ end
44
+ system "touch #{pairs.last.last}"
45
+
46
+ pairs.each do |pair|
47
+ assert File.exist?(pair.first), 'File should exist'
48
+ assert !File.exist?(pair.last), 'File should not exist' unless pair.last == pairs.last.last
49
+ end
50
+
51
+ m.rename! :ext, '.jpeg', *input
52
+
53
+ pairs.each do |pair|
54
+ assert !File.exist?(pair.first), 'File should not exist'
55
+ assert File.exist?(pair.last), 'File should exist'
56
+ end
57
+
58
+ pairs.each do |pair|
59
+ system "rm -v #{pair.join ' '}"
60
+ end
61
+ end
62
+
63
+ def test_rename_dir
64
+ m = Mvmv.new
65
+
66
+ input = %w[aaa bbb ccc]
67
+ pairs = m.convert_filenames :name, '##', *input
68
+ pairs.each do |pair|
69
+ system "rm -rfv #{pair.join ' '}"
70
+ system "mkdir -pv #{pair.first}"
71
+ end
72
+
73
+ m.rename! :name, '##', *input
74
+
75
+ pairs.each do |pair|
76
+ assert !File.exist?(pair.first), 'Directory should not exist'
77
+ assert File.exist?(pair.last), 'Directory should exist'
78
+ assert File.directory?(pair.last), 'Should be a directory'
79
+ end
80
+
81
+ pairs.each do |pair|
82
+ system "rm -rfv #{pair.join ' '}"
83
+ end
84
+ end
85
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mvmv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Junegunn Choi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ansi
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.4.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.4.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: test-unit
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Simple batch renaming
47
+ email:
48
+ - junegunn.c@gmail.com
49
+ executables:
50
+ - mvmv
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE
57
+ - README.md
58
+ - Rakefile
59
+ - bin/mvmv
60
+ - lib/mvmv.rb
61
+ - lib/mvmv/command.rb
62
+ - lib/mvmv/version.rb
63
+ - mvmv.gemspec
64
+ - test/bin_helper.rb
65
+ - test/test_mvmv.rb
66
+ homepage: https://github.com/junegunn/mvmv
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.24
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Simple batch renaming
90
+ test_files:
91
+ - test/bin_helper.rb
92
+ - test/test_mvmv.rb