organisir 0.1.2 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b5a8a59f69fe29c8aad7552739f29e6ad21605ea00a0eee59978a489cf4b46f
4
- data.tar.gz: 55ad2e84a64eb396d6b2838528da475822c36f0fc7b4f01372d48394cffd6e51
3
+ metadata.gz: abf576cbeedcd8e6deb19d7f17a6685ae24d77f9931619aa3d17724d7e507f68
4
+ data.tar.gz: 4d1aa92d804d682b84232a31b820e4c8ac6fda9e094b0cd42f4509457166eacc
5
5
  SHA512:
6
- metadata.gz: 9f266331405326ed542974a62fb3ac7a6d6a4b2397351f55a265df52bff5ddb5a2675ce0e16d36266ac10bb71d8fafcad1c5e75a516f3d84761e0830e44a534b
7
- data.tar.gz: f1c19c78a5d7ff7ca4d54f17a6ddbab0aa9b619109937203564ddd7abfaf120ae2b301f78ce8f37d40f89fd56f837ce5e6915d520d9726dea9cbc9db7620a449
6
+ metadata.gz: e96291f37be80c0d0415e77e5feccd74f4b08b2524ba23f9043db4206523e039f908c0cbb48d029d2321e2ecf86e368674df11751fa1ee1402558bacd9de6473
7
+ data.tar.gz: 3868b591ed62f2b312abbbddc1a857e03fee292477f2ae921c88b0ebb0a11d5cb8797151a7ad960539725f92d83d71e72c5ff89c18985e0de7f8a8ef19bc43fc
data/.gitignore CHANGED
@@ -7,4 +7,4 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /.idea
10
- organisir-*.gem
10
+ note
data/Gemfile CHANGED
@@ -12,3 +12,5 @@ gem "rubocop", "~> 0.80"
12
12
  gem "thor", "~> 1.0"
13
13
 
14
14
  gem "colorize", "~> 0.8.1"
15
+
16
+ gem "pry", "~> 0.13.1"
@@ -1,16 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- organisir (0.1.2)
4
+ organisir (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.1)
10
+ coderay (1.1.3)
10
11
  colorize (0.8.1)
12
+ method_source (1.0.0)
11
13
  parallel (1.20.1)
12
14
  parser (2.7.2.0)
13
15
  ast (~> 2.4.1)
16
+ pry (0.13.1)
17
+ coderay (~> 1.1)
18
+ method_source (~> 1.0)
14
19
  rainbow (3.0.0)
15
20
  rake (13.0.1)
16
21
  regexp_parser (2.0.0)
@@ -36,6 +41,7 @@ PLATFORMS
36
41
  DEPENDENCIES
37
42
  colorize (~> 0.8.1)
38
43
  organisir!
44
+ pry (~> 0.13.1)
39
45
  rake (~> 13.0)
40
46
  rubocop (~> 0.80)
41
47
  thor (~> 1.0)
@@ -3,16 +3,19 @@
3
3
  require "fileutils"
4
4
  require "thor"
5
5
  require "colorize"
6
-
6
+ require "pathname"
7
+ require "pry"
7
8
 
8
9
  module Organisir
9
10
  end
10
11
 
11
- # require "organisir/"
12
12
  require "organisir/cli"
13
- require "organisir/client"
14
- require "organisir/file_op"
13
+ require "organisir/commands/clean_symlinks"
14
+ require "organisir/commands/move_files"
15
+ require "organisir/commands/multi_symlink_files"
16
+ require "organisir/commands/symlink_files"
15
17
  require "organisir/rule"
16
18
  require "organisir/symlink_rule"
19
+ require "organisir/util"
17
20
  require "organisir/validator"
18
21
  require "organisir/version"
@@ -8,36 +8,71 @@ module Organisir
8
8
  true
9
9
  end
10
10
 
11
- desc "start source destination", "Move files from source to destination directory"
11
+ desc "move source destination", "Move files from source to destination directory"
12
12
  option :source, aliases: :s, required: true, type: :string
13
13
  option :destination, aliases: :d, required: true, type: :string
14
14
  option :commit, type: :boolean, default: false
15
15
 
16
- def start
16
+ def move
17
17
  if options[:commit]
18
18
  say "Preparing to move files in 5 seconds. Cancel the command by pressing Ctrl-C"
19
19
  sleep(5)
20
20
  else
21
- say "Start command always runs in non-commit mode. Use --commit true to permanently move files.", :red
21
+ say "move command always runs in non-commit mode. Use --commit true to permanently move files.", :red
22
22
  end
23
- pwd = Dir.pwd
24
- Organisir::Client.new.start(options[:source], options[:destination], pwd, options[:commit])
23
+ Organisir::Commands::MoveFiles.new(options[:source], options[:destination], Dir.pwd, options[:commit]).move
24
+ say "Process completed"
25
25
  rescue Interrupt
26
26
  say "Exiting organisir...", :green
27
27
  end
28
28
 
29
- desc "symlink", "Symlink files in nested directories to matching sub-directories within the given directory"
29
+ desc "symlink source destination[optional]", "Symlink files in nested directories to matching sub-directories within the given directory"
30
30
  option :source, aliases: :s, required: true, type: :string
31
31
  option :commit, type: :boolean, default: false
32
32
  def symlink
33
33
  if options[:commit]
34
34
  say "Preparing to symlink files in 5 seconds. Cancel the command by pressing Ctrl-C"
35
- # sleep(5)
35
+ sleep(5)
36
+ else
37
+ say "symlink command always runs in non-commit mode. Use --commit true to symlink files.", :red
38
+ end
39
+ Organisir::Commands::SymlinkFiles.new(options[:source], Dir.pwd, options[:commit]).link
40
+ say "Process completed"
41
+ rescue Interrupt
42
+ say "Exiting organisir...", :green
43
+ end
44
+
45
+ desc "multi_symlink source destination",
46
+ "Symlink files present in a source directory to matching sub-directories within the given destination directory"
47
+ option :source, aliases: :s, required: true, type: :string
48
+ option :destination, aliases: :d, required: true, type: :string
49
+ option :commit, type: :boolean, default: false
50
+ def multi_symlink
51
+ if options[:commit]
52
+ say "Preparing to symlink files in 5 seconds. Cancel the command by pressing Ctrl-C"
53
+ sleep(5)
54
+ else
55
+ say "multi_symlink command always runs in non-commit mode. Use --commit true to symlink files.", :red
56
+ end
57
+ Organisir::Commands::MultiSymlinkFiles.new(options[:source], options[:destination], Dir.pwd, options[:commit]).link
58
+ say "Process completed"
59
+ rescue Interrupt
60
+ say "Exiting organisir...", :green
61
+ end
62
+
63
+ desc "clean_symlinks source", "Removes all symlinks inside directory and its subdirectories"
64
+ option :source, aliases: :s, required: true, type: :string
65
+ option :commit, type: :boolean, default: false
66
+ option :all, type: :boolean, default: false
67
+ def clean_symlinks
68
+ if options[:commit]
69
+ say "Preparing to remove all symlinks in 5 seconds. Cancel the command by pressing Ctrl-C"
70
+ sleep(5)
36
71
  else
37
- say "Symlink command always runs in non-commit mode. Use --commit true to symlink files.", :red
72
+ say "clean_symlinks command always runs in non-commit mode. Use --commit true to remove symlinks.", :red
38
73
  end
39
- pwd = Dir.pwd
40
- Organisir::Client.new.symlink(options[:source], pwd, options[:commit])
74
+ Organisir::Commands::CleanSymlinks.new(options[:source], Dir.pwd, options[:commit], options[:all]).clean
75
+ say "Process completed"
41
76
  rescue Interrupt
42
77
  say "Exiting organisir...", :green
43
78
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Organisir
4
+ module Commands
5
+ class CleanSymlinks
6
+ def initialize(source_dir, pwd, commit, all)
7
+ @abs_source_dir = File.join(pwd, source_dir)
8
+ @verbose = !commit
9
+ @all = all
10
+ end
11
+
12
+ def clean
13
+ fetch_all_symlinks.each do |sym|
14
+ print "Delete symlink #{sym.to_s.colorize(:red)}.\n"
15
+ File.delete(sym) unless @verbose
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def fetch_all_symlinks
22
+ Dir.glob(File.join(@abs_source_dir, "**", "*")).filter do |f|
23
+ @all ? File.symlink?(f) : File.symlink?(f) && File.exist?(f)
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Organisir
4
+ module Commands
5
+ class MoveFiles
6
+ def initialize(source_dir, dest_dir, pwd, commit)
7
+ @abs_source_dir = File.join(pwd, source_dir)
8
+ @abs_dest_dir = File.join(pwd, dest_dir)
9
+ Validator.validate_start(@abs_source_dir, @abs_dest_dir)
10
+
11
+ @verbose = !commit
12
+ @pwd = pwd
13
+ end
14
+
15
+ def move
16
+ sub_dirs = Util.get_sub_dirs(@abs_dest_dir)
17
+
18
+ print("Scanned #{sub_dirs.length} directories in #{@abs_dest_dir}\n")
19
+ src_files = get_src_files(@abs_source_dir)
20
+ print("Scanned #{src_files.length} files in #{@abs_source_dir}\n")
21
+
22
+ rule = Rule.new(sub_dirs)
23
+ src_files.each do |f|
24
+ match_dir = rule.match(f).try(:min)
25
+ next if match_dir.nil? || match_dir.empty?
26
+
27
+ process(f, match_dir)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def get_src_files(dir)
34
+ Dir.entries(dir).reject { |f| File.directory? f }
35
+ end
36
+
37
+ def process(filename, dirname)
38
+ print "Rule matched file #{filename.to_s.colorize(:red)} moved to directory #{dirname.to_s.colorize(:red)}\n"
39
+ return if @verbose
40
+
41
+ src = File.join(@abs_source_dir, filename)
42
+ dest = File.join(File.join(@abs_dest_dir, dirname), filename)
43
+ FileUtils.move(src, dest, force: false, verbose: false)
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Organisir
4
+ module Commands
5
+ class MultiSymlinkFiles
6
+
7
+ def initialize(source_dir, destination_dir, pwd, commit)
8
+ @abs_source_dir = File.join(pwd, source_dir)
9
+ @abs_destination_dir = File.join(pwd, destination_dir)
10
+ @verbose = !commit
11
+ end
12
+
13
+ def link
14
+ sub_dirs = Util.get_sub_dirs(@abs_destination_dir)
15
+ print("Scanned #{files.length} files inside #{sub_dirs.length} directories in #{@abs_dest_dir}\n")
16
+ rule = Rule.new(sub_dirs)
17
+ files.each do |f|
18
+ match_dirs = rule.match(f)
19
+ next if match_dirs.nil? || match_dirs.empty?
20
+
21
+ process(f, match_dirs)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def files
28
+ Dir.glob(File.join(@abs_source_dir, "**", "*"))
29
+ .reject { |f| File.directory?(f) || File.symlink?(f) || File.zero?(f) }
30
+ end
31
+
32
+ def process(file, dirs)
33
+ print "Rule matched file #{file.to_s.colorize(:red)} symlinked to directory(s) #{dirs.join(", ").to_s.colorize(:red)}\n"
34
+ return if @verbose
35
+
36
+ dirs.each do |d|
37
+ begin
38
+ dest = File.join(@abs_destination_dir, d)
39
+ relative_path = Pathname.new(file).relative_path_from(dest)
40
+ FileUtils.ln_s(relative_path, dest, force: false, verbose: false)
41
+ rescue Errno::EEXIST
42
+ nil
43
+ end
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Organisir
4
+ module Commands
5
+ class SymlinkFiles
6
+ def initialize(source_dir, pwd, commit)
7
+ @abs_source_dir = File.join(pwd, source_dir)
8
+ @verbose = !commit
9
+ end
10
+
11
+ def link
12
+ sub_dirs = Util.get_sub_dirs(@abs_source_dir)
13
+ files = Dir.glob(File.join(@abs_source_dir, "*", "*.*"))
14
+ .reject { |f| File.directory?(f) || File.symlink?(f) || File.zero?(f) }
15
+ print("Scanned #{files.length} files inside #{sub_dirs.length} directories in #{@abs_dest_dir}\n")
16
+
17
+ rule = SymlinkRule.new(sub_dirs)
18
+ files.each do |f|
19
+ match_dirs = rule.match(f)
20
+ next if match_dirs.nil? || match_dirs.empty?
21
+
22
+ process(f, match_dirs)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def process(src_file, destination_dirs)
29
+ print "Rule matched file #{src_file.to_s.colorize(:red)} symlinked to directory(s) #{destination_dirs.join(", ").to_s.colorize(:red)}\n"
30
+ return if @verbose
31
+
32
+ destination_dirs.each do |d|
33
+ begin
34
+ dest = File.join(@abs_source_dir, d)
35
+ relative_path = Pathname.new(src_file).relative_path_from(dest)
36
+ FileUtils.ln_s(relative_path, dest, force: false, verbose: false)
37
+ rescue Errno::EEXIST
38
+ nil
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -6,7 +6,7 @@ module Organisir
6
6
  @dirs = dirs
7
7
  @dir_map = {}
8
8
  @dirs.map do |dir|
9
- @dir_map[dir] = gen_regex_for_dir_name(dir)
9
+ @dir_map[dir] = Util.gen_regex_for_dir_name(dir)
10
10
  end
11
11
  end
12
12
 
@@ -16,15 +16,8 @@ module Organisir
16
16
  resp << k if file.downcase.match(@dir_map[k])
17
17
  end
18
18
 
19
- resp.min unless resp.empty?
19
+ resp
20
20
  end
21
21
 
22
- private
23
-
24
- def gen_regex_for_dir_name(dir)
25
- tokens = dir.downcase.split
26
- name_token = tokens.join('\\b.*\\b')
27
- Regexp.new("\\b#{name_token}\\b", Regexp::EXTENDED | Regexp::IGNORECASE)
28
- end
29
22
  end
30
23
  end
@@ -6,29 +6,21 @@ module Organisir
6
6
  @dirs = dirs
7
7
  @dir_map = {}
8
8
  @dirs.map do |dir|
9
- @dir_map[dir] = gen_regex_for_dir_name(dir)
9
+ @dir_map[dir] = Util.gen_regex_for_dir_name(dir)
10
10
  end
11
11
  end
12
12
 
13
13
  def match(file)
14
14
  resp = []
15
- filename = file.split("/").last.downcase
16
- file_dir = file.split("/").fetch(-2)
15
+ filename = File.basename(file).downcase
16
+ file_dir = File.basename(File.dirname(file))
17
17
  @dirs.each do |d|
18
18
  next if file_dir.include? d
19
19
 
20
- resp << d if filename.downcase.match? @dir_map[d]
20
+ resp << d if filename.downcase.match?(@dir_map[d])
21
21
  end
22
22
  resp
23
23
  end
24
24
 
25
- private
26
-
27
- def gen_regex_for_dir_name(dir)
28
- tokens = dir.downcase.split
29
- name_token = tokens.join('\\b.*\\b')
30
- Regexp.new("\\b#{name_token}\\b", Regexp::EXTENDED | Regexp::IGNORECASE)
31
- end
32
-
33
25
  end
34
26
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Organisir
4
+ class Util
5
+
6
+ class << self
7
+ def get_sub_dirs(dir)
8
+ Dir.chdir(dir) do
9
+ Dir["*"].select { |o| File.directory?(o) }
10
+ end
11
+ end
12
+
13
+ def gen_regex_for_dir_name(dir)
14
+ tokens = dir.downcase.split
15
+ # TODO: Verify if this regex rule can be deprecated
16
+ # name_token = tokens.join('\\b.*\\b')
17
+ # Regexp.new("\\b#{name_token}\\b", Regexp::EXTENDED | Regexp::IGNORECASE)
18
+ name_token = tokens.join(".*")
19
+ Regexp.new(".*#{name_token}.*", Regexp::EXTENDED | Regexp::IGNORECASE)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Organisir
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: organisir
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - anujchandra
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-01 00:00:00.000000000 Z
11
+ date: 2020-12-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Gem to organise files based on their filename
14
14
  email:
@@ -29,10 +29,13 @@ files:
29
29
  - exe/organisir
30
30
  - lib/organisir.rb
31
31
  - lib/organisir/cli.rb
32
- - lib/organisir/client.rb
33
- - lib/organisir/file_op.rb
32
+ - lib/organisir/commands/clean_symlinks.rb
33
+ - lib/organisir/commands/move_files.rb
34
+ - lib/organisir/commands/multi_symlink_files.rb
35
+ - lib/organisir/commands/symlink_files.rb
34
36
  - lib/organisir/rule.rb
35
37
  - lib/organisir/symlink_rule.rb
38
+ - lib/organisir/util.rb
36
39
  - lib/organisir/validator.rb
37
40
  - lib/organisir/version.rb
38
41
  - organisir.gemspec
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Organisir
4
- class Client
5
- def start(source_dir, dest_dir, pwd, commit)
6
- @abs_source_dir = File.join(pwd, source_dir)
7
- @abs_dest_dir = File.join(pwd, dest_dir)
8
- Validator.validate_start(@abs_source_dir, @abs_dest_dir)
9
-
10
- @verbose = !commit
11
- @pwd = pwd
12
- @file_op = FileOp.new(pwd, source_dir)
13
- execute_start
14
- end
15
-
16
- def symlink(source_dir, pwd, commit)
17
- @abs_source_dir = File.join(pwd, source_dir)
18
- @verbose = !commit
19
- @pwd = pwd
20
- @file_op = FileOp.new(pwd, source_dir)
21
-
22
- execute_symlink
23
- end
24
-
25
- private
26
-
27
- def execute_start
28
- sub_dirs = get_sub_dirs(@abs_dest_dir)
29
- # print sub_dirs
30
- print("Scanned #{sub_dirs.length} directories in #{@abs_dest_dir}\n")
31
- src_files = get_src_files(@abs_source_dir)
32
- print("Scanned #{src_files.length} files in #{@abs_source_dir}\n")
33
-
34
- rule = Rule.new(sub_dirs)
35
- src_files.each do |f|
36
- match_dir = rule.match(f)
37
- next if match_dir.nil?
38
-
39
- move_file(f, match_dir)
40
- end
41
- print "Process completed\n"
42
- end
43
-
44
- def execute_symlink
45
- sub_dirs = get_sub_dirs(@abs_source_dir)
46
- files = Dir.glob(File.join(@abs_source_dir, "*", "*.*"))
47
- .reject { |f| File.directory?(f) || File.symlink?(f) || File.zero?(f) }
48
- print("Scanned #{files.length} files inside #{sub_dirs.length} directories in #{@abs_dest_dir}\n")
49
-
50
- rule = SymlinkRule.new(sub_dirs)
51
- files.each do |f|
52
- match_dirs = rule.match(f)
53
- next if match_dirs.nil? || match_dirs.empty?
54
-
55
- symlink_file(f, match_dirs)
56
- end
57
- print "Process completed\n"
58
- end
59
-
60
- def move_file(filename, dirname)
61
- print "Rule matched file #{filename.to_s.colorize(:red)} moved to directory #{dirname.to_s.colorize(:red)}\n"
62
- return if @verbose
63
-
64
- @file_op.move(filename, @abs_source_dir, File.join(@abs_dest_dir, dirname))
65
- end
66
-
67
- def symlink_file(file, match_dirs)
68
- print "Rule matched file #{file.to_s.colorize(:red)} symlinked to directories #{match_dirs.join(", ").to_s.colorize(:red)}\n"
69
- return if @verbose
70
-
71
- @file_op.symlink(file, match_dirs)
72
- end
73
-
74
- def get_sub_dirs(dir)
75
- Dir.chdir(dir)
76
- sub_dirs = Dir["*"].select { |o| File.directory?(o) }
77
- Dir.chdir(@pwd)
78
- sub_dirs
79
- end
80
-
81
- def get_src_files(dir)
82
- Dir.entries(dir).reject { |f| File.directory? f }
83
- end
84
- end
85
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "fileutils"
4
-
5
- module Organisir
6
- class FileOp
7
- def initialize(root_dir, source_dir)
8
- @root_dir = root_dir
9
- @source_dir = source_dir
10
- end
11
-
12
- def move(filename, source_path, destination_path)
13
- src = File.join(source_path, filename)
14
- dest = File.join(destination_path, filename)
15
- FileUtils.move(src, dest, force: false, verbose: false)
16
- end
17
-
18
- def symlink(src_file, destination_dirs)
19
- filename = File.basename(src_file)
20
- destns = destination_dirs.map do |p|
21
- File.join(@root_dir, @source_dir, p, filename)
22
- end
23
- destns.each do |d|
24
- begin
25
- FileUtils.ln_s(src_file,d , force: false, verbose: false)
26
- rescue Errno::EEXIST
27
- nil
28
- end
29
- end
30
- end
31
-
32
- def clean(link, path)
33
- src = File.join(@root_dir, path, link)
34
- # Last explicit check to see if the file indeed is a symlink
35
- return unless File.symlink?(src)
36
-
37
- FileUtils.remove(src)
38
- end
39
- end
40
- end