rfuse_symbolic_fs 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.
- data/bin/rfuse_symbolic_fs +15 -0
- data/lib/amaras_fs.rb +144 -0
- data/lib/rfuse_symbolic_fs.rb +88 -0
- data/lib/rfuse_symbolic_fs_opts.rb +72 -0
- data/lib/test_fuse.rb +74 -0
- metadata +86 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rfuse_symbolic_fs'
|
5
|
+
require 'rfuse_symbolic_fs_opts'
|
6
|
+
|
7
|
+
options = RFuseSymbolicFSOpts.parse(ARGV)
|
8
|
+
|
9
|
+
filesystem = RFuseSymbolicFS.new(options)
|
10
|
+
FuseFS.set_root( filesystem )
|
11
|
+
|
12
|
+
# Mount under a directory given on the command line.
|
13
|
+
FuseFS.mount_under options.mountpoint
|
14
|
+
FuseFS.run
|
15
|
+
|
data/lib/amaras_fs.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
class AmarasFS
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
start_time = Time.now
|
7
|
+
begin
|
8
|
+
@root = args[0]
|
9
|
+
|
10
|
+
@partitions = Array.new
|
11
|
+
(1...(args.size)).each_with_index do |x, index|
|
12
|
+
@partitions << args[x]
|
13
|
+
#puts args[x]
|
14
|
+
end
|
15
|
+
puts
|
16
|
+
puts
|
17
|
+
|
18
|
+
puts
|
19
|
+
puts "Starting Linking"
|
20
|
+
@partitions.each do |y|
|
21
|
+
build_links( @root, y )
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
rescue => e
|
27
|
+
puts
|
28
|
+
puts "ERROR caught Exception"
|
29
|
+
puts $!
|
30
|
+
puts e.inspect
|
31
|
+
puts e.backtrace
|
32
|
+
puts
|
33
|
+
end
|
34
|
+
puts "Run Time #{start_time - Time.now}"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_links( root, y , spacer=' ')
|
42
|
+
#puts "build_links( root, y )"
|
43
|
+
puts "#{spacer}build_links( #{root}, #{y})"
|
44
|
+
|
45
|
+
files = Dir.glob(y + '/*')
|
46
|
+
|
47
|
+
pp files
|
48
|
+
|
49
|
+
#puts "Iterating of SubFiles"
|
50
|
+
files.each do |x|
|
51
|
+
|
52
|
+
#TODO validation that link does not already exist
|
53
|
+
|
54
|
+
new_link = x.dup
|
55
|
+
new_link[y] = ""
|
56
|
+
new_link = root + new_link
|
57
|
+
|
58
|
+
puts
|
59
|
+
puts "#{spacer}Thinking about linking #{new_link} "
|
60
|
+
#puts " sub file #{x}"
|
61
|
+
|
62
|
+
#Verify that new_link does not exists
|
63
|
+
if not File.exist?( new_link )
|
64
|
+
puts "#{spacer}Mode :1 INFO : File.symlink(#{x}, #{new_link} )"
|
65
|
+
File.symlink(x, new_link)
|
66
|
+
|
67
|
+
elsif ( ( File.symlink?(new_link)) and ( File.readlink(new_link) == x))
|
68
|
+
#readlink rasies exception if called on non links so check is a link first
|
69
|
+
#Link exists but points to location we tried to set
|
70
|
+
puts "#{spacer}Mode :2 INFO : Link Exists & correct"
|
71
|
+
elsif ( ( File.symlink?(new_link)) and ( not File.readlink(new_link) == x ))
|
72
|
+
test_folder(new_link)
|
73
|
+
|
74
|
+
puts "#{spacer}Mode :3 ERROR : #{new_link} already exists"
|
75
|
+
puts "#{spacer} This section requires programming"
|
76
|
+
|
77
|
+
current_pointer = File.readlink(new_link)
|
78
|
+
|
79
|
+
puts "current_pointer #{current_pointer}"
|
80
|
+
puts " #{root}"
|
81
|
+
puts " #{x}"
|
82
|
+
puts " #{y}"
|
83
|
+
|
84
|
+
pos = current_pointer.rindex(File::SEPARATOR)
|
85
|
+
extra_bit = current_pointer[pos...(current_pointer.size)]
|
86
|
+
|
87
|
+
puts "extra_bit #{extra_bit}"
|
88
|
+
|
89
|
+
#/A/1/x
|
90
|
+
#/A/1/Y
|
91
|
+
#/B/1/z
|
92
|
+
#
|
93
|
+
# current_pointer = /A/1
|
94
|
+
|
95
|
+
#current pointer already has the extra_bit
|
96
|
+
new_root = root + extra_bit
|
97
|
+
next_pointer = x + extra_bit
|
98
|
+
|
99
|
+
puts "File Maintenance"
|
100
|
+
|
101
|
+
FileUtils.rm( new_root )
|
102
|
+
FileUtils.mkdir( new_root )
|
103
|
+
|
104
|
+
build_links(new_root , x, spacer+' ')
|
105
|
+
build_links(new_root , current_pointer, spacer+' ')
|
106
|
+
|
107
|
+
|
108
|
+
elsif File.directory?(new_link)
|
109
|
+
#new_link already exists as folder
|
110
|
+
# this implies it already exists on another drive
|
111
|
+
# just recurse on this lower level
|
112
|
+
puts "#{spacer}Mode :4 INFO : Doing recursive call to build links"
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
new_root = x.dup
|
117
|
+
new_root[y] = ""
|
118
|
+
new_root = root + new_root
|
119
|
+
|
120
|
+
build_links(new_root, x, spacer+' ' )
|
121
|
+
else
|
122
|
+
#Link does exist and points to different Location
|
123
|
+
# What could have caused this?
|
124
|
+
# 1) Data has been completely moved to another Drive
|
125
|
+
# 2) Drive was running out of room and this folder has been split across 2 or more drives
|
126
|
+
#
|
127
|
+
# To resolve this copy current link location if it exists save location for later
|
128
|
+
# Create this folder and link in contnents from new drive then repeat for original location
|
129
|
+
|
130
|
+
puts "#{spacer}Mode :5 ERROR : #{new_link} already exists"
|
131
|
+
puts "#{spacer} This section requires programming"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
def test_folder(path)
|
138
|
+
puts "File #{File.file?(path)}"
|
139
|
+
puts "Folder #{File.directory?(path)}"
|
140
|
+
puts "Symlink #{File.symlink?(path)}"
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'fusefs'
|
3
|
+
require 'rfuse_symbolic_fs_opts'
|
4
|
+
|
5
|
+
|
6
|
+
class RFuseSymbolicFS
|
7
|
+
# contents( path )
|
8
|
+
# file?( path )
|
9
|
+
# directory?( path )
|
10
|
+
# read_file( path )
|
11
|
+
# size( path )
|
12
|
+
#
|
13
|
+
# save
|
14
|
+
# touch( path )
|
15
|
+
# can_write?(path)
|
16
|
+
# write_to(path,body)
|
17
|
+
#
|
18
|
+
# can_delete?(path)
|
19
|
+
# delete( path )
|
20
|
+
#
|
21
|
+
# can_mkdir?( path )
|
22
|
+
# mkdir( path )
|
23
|
+
# can_rmdir( path )
|
24
|
+
# rmdir( path )
|
25
|
+
#
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
def initialize( options )
|
30
|
+
@base_dir = options.input
|
31
|
+
end
|
32
|
+
|
33
|
+
def contents(path)
|
34
|
+
n_path = File.expand_path( @base_dir + path )
|
35
|
+
Dir.chdir(n_path)
|
36
|
+
|
37
|
+
files = Dir.glob('*')
|
38
|
+
#Added command to OS X Finder not to index.
|
39
|
+
files << 'metadata_never_index'
|
40
|
+
|
41
|
+
return files
|
42
|
+
end
|
43
|
+
|
44
|
+
def file?(path)
|
45
|
+
#If path ends with metadata_never_index it is a file
|
46
|
+
if path =~ /metadata_never_index$/
|
47
|
+
return true
|
48
|
+
end
|
49
|
+
|
50
|
+
return (not File.directory?( @base_dir + path ))
|
51
|
+
end
|
52
|
+
|
53
|
+
def directory?(path)
|
54
|
+
File.directory?(@base_dir + path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def read_file(path)
|
58
|
+
|
59
|
+
#puts "read file #{path}"
|
60
|
+
if File.exists?( @base_dir + path )
|
61
|
+
return File.new(@base_dir + path , "r").read
|
62
|
+
end
|
63
|
+
return "ERROR, file not found\n"
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def size(path)
|
69
|
+
if File.exists?( @base_dir + path )
|
70
|
+
return File.size( @base_dir + path )
|
71
|
+
else
|
72
|
+
return 16
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
if $0 == __FILE__
|
79
|
+
|
80
|
+
options = RFuseSymbolicFSOpts.parse(ARGV)
|
81
|
+
filesystem = RFuseSymbolicFS.new( options )
|
82
|
+
FuseFS.set_root( filesystem )
|
83
|
+
|
84
|
+
# Mount under a directory given on the command line.
|
85
|
+
FuseFS.mount_under options.mountpoint
|
86
|
+
FuseFS.run
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'optparse/time'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
class RFuseSymbolicFSOpts
|
6
|
+
|
7
|
+
|
8
|
+
#
|
9
|
+
# Return a structure describing the options.
|
10
|
+
#
|
11
|
+
def self.parse(args)
|
12
|
+
@VERSION = "0.0.1"
|
13
|
+
|
14
|
+
# The options specified on the command line will be collected in *options*.
|
15
|
+
# We set default values here.
|
16
|
+
options = OpenStruct.new
|
17
|
+
|
18
|
+
options.verbose = false
|
19
|
+
options.mountpoint = ""
|
20
|
+
options.input = ""
|
21
|
+
|
22
|
+
|
23
|
+
opts = OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: #{__FILE__} [options]"
|
25
|
+
opts.separator ""
|
26
|
+
opts.separator "Common options:"
|
27
|
+
|
28
|
+
# No argument, shows at tail. This will print an options summary.
|
29
|
+
opts.on("-h", "--help", "Show this message") do
|
30
|
+
puts opts
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
# Another typical switch to print the version.
|
35
|
+
opts.on("--version", "Show version") do
|
36
|
+
#puts OptionParser::Version.join('.')
|
37
|
+
puts "Version #{@VERSION}"
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
|
41
|
+
# Boolean switch.
|
42
|
+
#opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
43
|
+
# options.verbose = v
|
44
|
+
#end
|
45
|
+
|
46
|
+
opts.separator ""
|
47
|
+
opts.separator "Specific options:"
|
48
|
+
|
49
|
+
|
50
|
+
# Cast 'delay' argument to a Float.
|
51
|
+
opts.on("--mountpoint path", String, "Root of new Filesystem") do |n|
|
52
|
+
options.mountpoint = n
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on("--input N", String, "Folder FS will point to") do |n|
|
56
|
+
options.input = n
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
options.leftovers = opts.parse!(args)
|
63
|
+
|
64
|
+
if (options.mountpoint == "") and (options.input == "") and (options.leftovers.size==2)
|
65
|
+
options.mountpoint = options.leftovers[0]
|
66
|
+
options.input = options.leftovers[1]
|
67
|
+
end
|
68
|
+
return options
|
69
|
+
end # parse()
|
70
|
+
|
71
|
+
end # class OptparseExample
|
72
|
+
|
data/lib/test_fuse.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'fusefs'
|
3
|
+
|
4
|
+
class HelloDir
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@base_dir = '/Users/morgy/Movies'
|
8
|
+
end
|
9
|
+
|
10
|
+
def contents(path)
|
11
|
+
n_path = File.expand_path( @base_dir + path )
|
12
|
+
Dir.chdir(n_path)
|
13
|
+
|
14
|
+
files = Dir.glob('*')
|
15
|
+
files << 'hello.txt'
|
16
|
+
files << 'metadata_never_index'
|
17
|
+
end
|
18
|
+
|
19
|
+
def file?(path)
|
20
|
+
if path == '/hello.txt'
|
21
|
+
return true
|
22
|
+
end
|
23
|
+
|
24
|
+
if path == '/metadata_never_index'
|
25
|
+
return true
|
26
|
+
end
|
27
|
+
|
28
|
+
if File.exists?(@base_dir + path )
|
29
|
+
#puts "file? #{@base_dir}#{path} "
|
30
|
+
if File.directory?(@base_dir + path )
|
31
|
+
return false
|
32
|
+
else
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def directory?(path)
|
40
|
+
File.directory?(@base_dir + path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_file(path)
|
44
|
+
puts "read file #{path}"
|
45
|
+
if path == '/hello.txt'
|
46
|
+
return "Hello, World!\n"
|
47
|
+
end
|
48
|
+
puts "exists?"
|
49
|
+
if File.exists?( @base_dir + path )
|
50
|
+
puts " true #{@base_dir}#{path}"
|
51
|
+
return File.new(@base_dir + path , "r").read
|
52
|
+
else
|
53
|
+
puts " fail #{@base_dir}#{path}"
|
54
|
+
end
|
55
|
+
return "ERROR, file not found\n"
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def size(path)
|
60
|
+
if File.exists?( @base_dir + path )
|
61
|
+
return File.size( @base_dir + path )
|
62
|
+
else
|
63
|
+
return 16
|
64
|
+
end
|
65
|
+
#read_file(path).size
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
hellodir = HelloDir.new
|
70
|
+
FuseFS.set_root( hellodir )
|
71
|
+
|
72
|
+
# Mount under a directory given on the command line.
|
73
|
+
FuseFS.mount_under ARGV.shift
|
74
|
+
FuseFS.run
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfuse_symbolic_fs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Morgan Prior
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-07 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: fusefs
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 7
|
33
|
+
- 0
|
34
|
+
version: 0.7.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Virtual Filesystem Written in Ruby Fuse, which acts like a symbolic link
|
38
|
+
email: rfuse_symbolic_fs_gem@amaras-tech.co.uk
|
39
|
+
executables:
|
40
|
+
- rfuse_symbolic_fs
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- bin/rfuse_symbolic_fs
|
47
|
+
- lib/amaras_fs.rb
|
48
|
+
- lib/rfuse_symbolic_fs.rb
|
49
|
+
- lib/rfuse_symbolic_fs_opts.rb
|
50
|
+
- lib/test_fuse.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://amaras-tech.co.uk/software/rfuse_symbolic_fs
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message: To use 'rfuse_symbolic_fs' as a standalone application your gems folder must be on your path
|
56
|
+
rdoc_options: []
|
57
|
+
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
requirements: []
|
79
|
+
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.3.7
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: Ruby Fuse, Filesystem which basically is a soft link on Mac OS X, Linux and Unix.
|
85
|
+
test_files: []
|
86
|
+
|