mvb 0.0.1

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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/exe/mvb +96 -0
  3. data/lib/mvb/version.rb +4 -0
  4. data/lib/mvb.rb +111 -0
  5. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b9a9dd9a37c9202b5016f54508d32d876b2baa95ab86f90355d9763427a6e79f
4
+ data.tar.gz: f40d7182c62000bcbd455d7e3a7c51d47ecc79ad17b1767ed20d88da1fd4c1a1
5
+ SHA512:
6
+ metadata.gz: ac6bcf8e1d406b49e1a40b72fbaa6e1f1c3eed1e539b1a5e58b2e06d848e06f651ee1f077c4ee7445add1e884bbf8cc328920160fda21ee027a6c14992ccf472
7
+ data.tar.gz: 35388f1ba151d170dda9e4aa18f4bce064f02519a9c913f42a3411c932397c64d6c6ae66fc5eddeccf4da1a411f34eeea5f3c54dbfa70e7f6f8e04242bd1d87d
data/exe/mvb ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env ruby
2
+ # Tienes una nota en Joplin. Léela.
3
+
4
+ require 'optparse'
5
+ require_relative '../lib/mvb'
6
+
7
+ positional_args = []
8
+ search = nil
9
+ replacement = nil
10
+ pattern = nil
11
+ force_rename = false
12
+ steps = 1
13
+
14
+ banner = <<~EOM
15
+ Usage:
16
+ mvb [-s,--search] "PATTERN" [-r,--replacement] ["STRING"] [-f,--force]
17
+
18
+ You can enter the arguments by option tags or by position. Tag options get precedence over positions.
19
+ In positional options, first argument corresponds to the search pattern, and second, the replacement.
20
+
21
+ The only required argument is the search pattern. If replacement is not given,
22
+ the output is a list of the matched files.
23
+
24
+ If both options are given (search and replacement), the output will consists
25
+ of two columns: first column lists the current filenames matched by the search patterns,
26
+ and second column their replacement counterpart. This will be a dry-run, though; no rename
27
+ will be executed
28
+
29
+ To execute the rename, add the --force (or -f) option.
30
+
31
+ IMPORTANT: if you are going to use regex as pattern, it is strongly recommended
32
+ to enclose it in double quotes in order to avoid conflicts between the regex
33
+ special characters and the wildcards of the shell.
34
+
35
+ SEQUENTIAL NUMBERING:
36
+ On replacement string, you can introduce sequential numbering by using a "#" as placeholder along
37
+ with an integer which will be the starting point. For example, if you use "image-#1" as replacement,
38
+ the output will consist of: image-1, image-2, image-3, etc. until reached the last replacement item.
39
+ You can use the option `-i` to set the steps of increments.
40
+
41
+ EOM
42
+
43
+ opt_parser = OptionParser.new do |opts|
44
+
45
+ opts.banner = banner
46
+
47
+ opts.on("-s", "--search PATTERN", "Search for files that match with PATTERN. If no replace PATTERN is given,
48
+ just list the matched files. Argument required, option tag is not required.") do |argument|
49
+ search = argument
50
+ end
51
+
52
+ opts.on("-r", "--replacement PATTERN", "Replace the matched files with given PATTERN. Optional.") do |argument|
53
+ replacement = argument
54
+ end
55
+
56
+ opts.on("-f", "--force", "Execute renaming") do
57
+ force_rename = true
58
+ end
59
+
60
+ opts.on("-i STEPS", "--steps=STEPS", "Steps of increment on sequential numbering." ) do |argument|
61
+ steps = argument.to_i if argument.to_i != 0
62
+ end
63
+
64
+ opts.on("-h", "--help", "Show this help message.") do
65
+ puts opts
66
+ exit
67
+ end
68
+
69
+ end
70
+
71
+ # Parse the options and store remaining arguments as positional
72
+ begin
73
+ opt_parser.parse!
74
+
75
+ # Error handling
76
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
77
+ puts e.message
78
+ puts opt_parser
79
+ exit 1
80
+ end
81
+
82
+ # Set remaining arguments are positional
83
+ positional_args = ARGV
84
+
85
+ unless positional_args.empty?
86
+ unless search
87
+ search = positional_args[0]
88
+ end
89
+ unless replacement
90
+ replacement = positional_args[1]
91
+ end
92
+ end
93
+
94
+ pattern = /#{search}/ if search
95
+
96
+ Mvb.rename_files(pattern, replacement, force_rename, steps)
@@ -0,0 +1,4 @@
1
+
2
+ module Mvb
3
+ VERSION = "0.0.1"
4
+ end
data/lib/mvb.rb ADDED
@@ -0,0 +1,111 @@
1
+
2
+ require_relative "mvb/version"
3
+
4
+ module Mvb
5
+ COLOR_RED = "\e[31m"
6
+ COLOR_GREEN = "\e[32m"
7
+ COLOR_RESET = "\e[0m"
8
+ PH = "#" # for "PlaceHolder"
9
+
10
+ # Find array of matching filenames based on regex parttern
11
+ def self.find_matching_files(pattern)
12
+ return [] if pattern.nil?
13
+ Dir.glob('*').select { |filename| filename.match?(pattern) }
14
+ end
15
+
16
+ # Print array of filenames
17
+ def self.print_filenames(filenames)
18
+ if filenames.empty?
19
+ puts "No match found."
20
+ return
21
+ end
22
+ filenames.each { |filename| puts "#{filename}"}
23
+ end
24
+
25
+ # Rename matched files according to search (regex) parttern, replacement, and force flag
26
+ # if force flag is not given, provide just a list (i.e dry-run)
27
+ def self.rename_files(search_pattern, replacement=nil, force_rename=false, steps=1)
28
+
29
+ # No search pattern given? Return nothing
30
+ if search_pattern == nil
31
+ puts "You have to provide at least one regex pattern.\nPlease check 'mvb --help' for command usage."
32
+ return
33
+ end
34
+
35
+ # Get array with matched files based on regex pattern
36
+ matched_files = find_matching_files(search_pattern)
37
+
38
+ # No match found on search pattern? Return nothing
39
+ if matched_files.empty?
40
+ puts "No match found."
41
+ return
42
+ end
43
+
44
+ # No replacement string given? Print only the matched filenames
45
+ if replacement == nil
46
+ print_filenames(matched_files)
47
+ return
48
+ end
49
+
50
+ # If replacement include the "#" placeholder, define the starting point (index)
51
+ if replacement.include?(PH)
52
+ placeholder_present = true
53
+ new_filenames = []
54
+
55
+ # The index will be equal to the number that is after the placeholder, e.g. "#2", index = 2
56
+ index = replacement[/(?<=#{PH})\d+/]
57
+ index = index.to_i
58
+
59
+ steps = 1 if steps == 0 or steps == nil # Just in case
60
+ end
61
+
62
+ # Here is where the renaming (or dry-run) happens...
63
+
64
+ puts "\n" # insert blank line between the command and the list of filenames
65
+
66
+ matched_files.each do |filename|
67
+ # Remember: "filename.gsub(...)" returns a copy of the filename with all the occurrences of a
68
+ # given regex pattern substituted for the second argument
69
+ new_filename = filename.gsub(search_pattern,replacement)
70
+
71
+ # If placeholder is present in new_filename, execute sequential numbering
72
+ if new_filename.include?(PH)
73
+ if new_filename[/#{PH}\d+/] != nil
74
+ new_filename.gsub!(/#{PH}\d+/,index.to_s)
75
+ else
76
+ new_filename.gsub!(PH,index.to_s)
77
+ end
78
+ index = index + steps
79
+ end
80
+
81
+ # List every filename along with their possible replacement
82
+ puts "#{COLOR_RED}#{filename}#{COLOR_RESET} --> #{COLOR_GREEN}#{new_filename}#{COLOR_RESET}"
83
+
84
+ # If force flag is given, execute rename
85
+ if force_rename
86
+ if placeholder_present
87
+ new_filename = new_filename + "_"
88
+ File.rename(filename,new_filename)
89
+ new_filenames.push(new_filename)
90
+ else
91
+ File.rename(filename,new_filename)
92
+ end
93
+ end
94
+ end
95
+
96
+ if placeholder_present and force_rename
97
+ new_filenames.each do |filename|
98
+ File.rename(filename,filename.chomp("_"))
99
+ end
100
+ end
101
+
102
+
103
+ # Provide message if files were renamed or if it was a dry-run
104
+ if force_rename
105
+ puts "\nFiles renamed!"
106
+ else
107
+ puts "\nThis is a dry-run. No file has been renamed."
108
+ end
109
+ end
110
+
111
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mvb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Manuel Fuenmayor
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-10-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem to rename batch of files, with sequential numbering feature
14
+ email: manuel.fuenmayor98@gmail.com
15
+ executables:
16
+ - mvb
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - exe/mvb
21
+ - lib/mvb.rb
22
+ - lib/mvb/version.rb
23
+ homepage:
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.5.20
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: A script to rename batch of files
46
+ test_files: []