odisk 0.2.1 → 0.2.2
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/README.md +6 -6
- data/bin/odisk +2 -30
- data/bin/odisk_forget +122 -0
- data/lib/odisk.rb +35 -0
- data/lib/odisk/version.rb +1 -1
- metadata +6 -5
data/README.md
CHANGED
@@ -25,9 +25,9 @@ which utilizes an alternative approach to dealing with multiple threads.
|
|
25
25
|
|
26
26
|
## <a name="release">Release Notes</a>
|
27
27
|
|
28
|
-
### Release 0.2.
|
28
|
+
### Release 0.2.2
|
29
29
|
|
30
|
-
-
|
30
|
+
- Added odisk_forget which removes remote entries causing a file or directory to look like a new file or directory.
|
31
31
|
|
32
32
|
# Plans and Notes
|
33
33
|
|
@@ -40,10 +40,10 @@ files has not been implemented yet and changing ownership or mode only take
|
|
40
40
|
effect if the file is touched as well. Feel free to give it a try and let me
|
41
41
|
know when you run into bugs.
|
42
42
|
|
43
|
-
- Support
|
44
|
-
- specify on command line and create .odisk/
|
43
|
+
- Support ignore of file and directories
|
44
|
+
- specify on command line and create .odisk/ignore file
|
45
45
|
- use ::File.fnmatch(pattern, path, ::File::FNM_DOTMATCH)
|
46
|
-
- pass array of
|
46
|
+
- pass array of ignores to digest creation
|
47
47
|
- loosen up current restriction on any file that begins with .
|
48
48
|
|
49
49
|
- Support file removal
|
@@ -54,7 +54,7 @@ know when you run into bugs.
|
|
54
54
|
|
55
55
|
- Handle changes in mode, owner, and group
|
56
56
|
- Compare to previous digest to detect changes
|
57
|
-
- File modification times are not
|
57
|
+
- File modification times are not changed by mode, owner, or group changes
|
58
58
|
- Note conflicts if modifications are more recent than remote
|
59
59
|
- Use a script to pick change or keep local version
|
60
60
|
|
data/bin/odisk
CHANGED
@@ -67,39 +67,11 @@ if 1 != dirs.size
|
|
67
67
|
end
|
68
68
|
$local_top = ::File.expand_path(dirs[0])
|
69
69
|
|
70
|
-
|
71
|
-
# in that directory. If the directory does not exist then stop the walk. If
|
72
|
-
# not found check the ~/.odisk/remotes.json file for a matching top.
|
73
|
-
top = $local_top
|
74
|
-
if $ruser.nil? || $rhost.nil? || $rtop.nil?
|
75
|
-
while ::File.directory?(::File.join(top, '.odisk'))
|
76
|
-
rfile = ::File.join(top, '.odisk', 'remote')
|
77
|
-
if ::File.file?(rfile)
|
78
|
-
rstr = ::File.read(rfile).strip()
|
79
|
-
#$remote.pass_file = ::File.expand_path($remote.pass_file) unless $remote.pass_file.nil? || $remote.pass_file.empty?
|
80
|
-
orig_pass_file = $remote.pass_file
|
81
|
-
$remote.update(rstr)
|
82
|
-
$remote.pass_file = ::File.expand_path($remote.pass_file) unless $remote.pass_file.nil? || $remote.pass_file.empty?
|
83
|
-
if !$remote.dir.nil? && !$remote.dir.empty? && top != $local_top
|
84
|
-
$remote.dir = $remote.dir + $local_top[top.size..-1]
|
85
|
-
end
|
86
|
-
if $remote.pass_file != orig_pass_file && !::File.file?($remote.pass_file)
|
87
|
-
$remote.pass_file = ::File.join(top, '.odisk', $remote.pass_file)
|
88
|
-
end
|
89
|
-
break
|
90
|
-
end
|
91
|
-
top = ::File.dirname(top)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
ODisk.info_from_remotes($local_top, $remote) unless $remote.complete?
|
96
|
-
$remote.user = ENV['USER'] if $remote.user.nil?
|
97
|
-
$remote.pass_file = nil if $plain
|
98
|
-
unless $remote.okay?
|
99
|
-
puts "*** user@host:top_dir not specified on command line, in local .odisk/remote file, or in ~/.odisk/remotes"
|
70
|
+
unless ODisk.gather_remote_info($local_top, $remote)
|
100
71
|
puts opts.help
|
101
72
|
Process.exit!(0)
|
102
73
|
end
|
74
|
+
$remote.pass_file = nil if $plain
|
103
75
|
|
104
76
|
Thread.current[:name] = 'main'
|
105
77
|
::Opee::Env.logger.formatter = proc { |s,t,p,m|
|
data/bin/odisk_forget
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby -wW1
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
while (i = ARGV.index('-I'))
|
5
|
+
x,path = ARGV.slice!(i, 2)
|
6
|
+
$: << path
|
7
|
+
end
|
8
|
+
|
9
|
+
# TBD tmp for testing
|
10
|
+
$: << ::File.join(::File.dirname(__FILE__), "../../oj/lib")
|
11
|
+
$: << ::File.join(::File.dirname(__FILE__), "../../oj/ext")
|
12
|
+
$: << ::File.join(::File.dirname(__FILE__), "../../opee/lib")
|
13
|
+
$: << ::File.join(::File.dirname(__FILE__), "../lib")
|
14
|
+
|
15
|
+
require 'optparse'
|
16
|
+
begin
|
17
|
+
v = $VERBOSE
|
18
|
+
$VERBOSE = false
|
19
|
+
require 'net/ssh'
|
20
|
+
require 'net/sftp'
|
21
|
+
$VERBOSE = v
|
22
|
+
end
|
23
|
+
require 'opee'
|
24
|
+
require 'oj'
|
25
|
+
require 'odisk'
|
26
|
+
|
27
|
+
$verbose = Logger::WARN
|
28
|
+
$dry_run = false
|
29
|
+
$dir = '.'
|
30
|
+
$master = nil
|
31
|
+
$remote = ::ODisk::Remote.new()
|
32
|
+
|
33
|
+
opts = OptionParser.new(%{Usage: odisk_forget [options] <local_directory> <relative_forget_path>
|
34
|
+
|
35
|
+
Will remove data for the file or directory specified on the remote server. The local file or directory
|
36
|
+
will not be removed but the local digest will no longer includes that entry. This make the file or
|
37
|
+
directory look new as far as oDisk is concerned.
|
38
|
+
})
|
39
|
+
opts.on('-s', 'decrease verbosity') { $verbose += 1 unless 5 == $verbose }
|
40
|
+
opts.on('-v', 'increase verbosity') { $verbose -= 1 unless 0 == $verbose }
|
41
|
+
opts.on('-n', 'dry run / no modifications') { $dry_run = true }
|
42
|
+
opts.on('-r', '--remote [user@host:dir:pass_file]',
|
43
|
+
String, 'remote user, host, directory, passphrase file for gpg') { |r|
|
44
|
+
$remote.update(r)
|
45
|
+
}
|
46
|
+
opts.on('-h', '--help', 'Show this display') { puts opts.help; Process.exit!(0) }
|
47
|
+
dirs = opts.parse(ARGV)
|
48
|
+
|
49
|
+
if 2 != dirs.size
|
50
|
+
puts opts.help
|
51
|
+
Process.exit!(0)
|
52
|
+
end
|
53
|
+
$local_top = ::File.expand_path(dirs[0])
|
54
|
+
$forget_me = dirs[1] # relative path from top
|
55
|
+
|
56
|
+
unless ODisk.gather_remote_info($local_top, $remote)
|
57
|
+
puts opts.help
|
58
|
+
Process.exit!(0)
|
59
|
+
end
|
60
|
+
$remote.pass_file = nil if $plain
|
61
|
+
|
62
|
+
Thread.current[:name] = 'main'
|
63
|
+
::Opee::Env.logger.formatter = proc { |s,t,p,m|
|
64
|
+
s = '' if s.nil?
|
65
|
+
"#{s[0]} [#{t.strftime('%Y-%m-%dT%H:%M:%S.%6N')} ##{p}]: #{m}\n"
|
66
|
+
}
|
67
|
+
::Opee::Env.logger.severity = $verbose
|
68
|
+
|
69
|
+
if Logger::INFO >= $verbose
|
70
|
+
if $digests_only
|
71
|
+
::Opee::Env.info(%{
|
72
|
+
Generate Local Digests
|
73
|
+
local directory: #{::File.expand_path($local_top)}
|
74
|
+
})
|
75
|
+
else
|
76
|
+
::Opee::Env.info(%{
|
77
|
+
Forget "#{$forget_me}"
|
78
|
+
remote host: #{$remote.host}
|
79
|
+
remote user: #{$remote.user}
|
80
|
+
remote directory: #{$remote.dir}
|
81
|
+
local: #{::File.expand_path($local_top)}
|
82
|
+
dry run: #{$dry_run}
|
83
|
+
})
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# If $local_top/.odisk/remote does not exist or is different that what is in $remote, replace it.
|
88
|
+
remote_str = $remote.to_s
|
89
|
+
top_remote_path = ::File.join($local_top, '.odisk', 'remote')
|
90
|
+
if !::File.file?(top_remote_path) || ::File.read(top_remote_path).strip() != remote_str
|
91
|
+
::Opee::Env.info("Writing #{top_remote_path}")
|
92
|
+
unless $dry_run
|
93
|
+
`mkdir -p #{::File.join($local_top, '.odisk')}`
|
94
|
+
::File.open(top_remote_path, 'w') { |f| f.write(remote_str + "\n") }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
path = ::File.join($local_top, $forget_me)
|
99
|
+
local_digest_path = ::File.join(::File.dirname(path), '.odisk', 'digest.json')
|
100
|
+
forget_name = ::File.basename(path)
|
101
|
+
remote_path = ::File.join($remote.dir, $forget_me)
|
102
|
+
remote_digest_path = ::File.join(::File.dirname(remote_path), '.odisk', 'digest.json')
|
103
|
+
|
104
|
+
# Remove forget_me from local digest.
|
105
|
+
digest = Oj.load_file(local_digest_path, mode: :object)
|
106
|
+
digest.delete(forget_name)
|
107
|
+
Oj.to_file(local_digest_path, digest, indent: 2) unless $dry_run
|
108
|
+
|
109
|
+
# Remove forget_me from remote digest
|
110
|
+
Net::SSH.start($remote.host, $remote.user) do |ssh|
|
111
|
+
ssh.exec!(%{rm -rf "#{remote_path}.gpg"})
|
112
|
+
ssh.exec!(%{rm -rf "#{remote_path}"})
|
113
|
+
end
|
114
|
+
|
115
|
+
# Update the remote digest by removing the forget_me entry.
|
116
|
+
Net::SFTP.start($remote.host, $remote.user) do |ftp|
|
117
|
+
json = ftp.download!(remote_digest_path)
|
118
|
+
digest = Oj.load(json, mode: :object)
|
119
|
+
digest.delete(forget_name)
|
120
|
+
json = Oj.dump(digest, indent: 2)
|
121
|
+
ftp.open!(remote_digest_path, 'w') { |res| ftp.write!(res[:handle], 0, json) }
|
122
|
+
end
|
data/lib/odisk.rb
CHANGED
@@ -1,6 +1,41 @@
|
|
1
1
|
|
2
2
|
module ODisk
|
3
3
|
|
4
|
+
# Walk up the directory tree looking for .odisk directories and a
|
5
|
+
# remote.json in that directory. If the directory does not exist then stop
|
6
|
+
# the walk. If not found check the ~/.odisk/remotes.json file for a matching
|
7
|
+
# top.
|
8
|
+
def self.gather_remote_info(local_dir, remote)
|
9
|
+
top = local_dir
|
10
|
+
if remote.user.nil? || remote.host.nil? || remote.dir.nil?
|
11
|
+
while ::File.directory?(::File.join(top, '.odisk'))
|
12
|
+
rfile = ::File.join(top, '.odisk', 'remote')
|
13
|
+
if ::File.file?(rfile)
|
14
|
+
rstr = ::File.read(rfile).strip()
|
15
|
+
#remote.pass_file = ::File.expand_path(remote.pass_file) unless remote.pass_file.nil? || remote.pass_file.empty?
|
16
|
+
orig_pass_file = remote.pass_file
|
17
|
+
remote.update(rstr)
|
18
|
+
remote.pass_file = ::File.expand_path(remote.pass_file) unless remote.pass_file.nil? || remote.pass_file.empty?
|
19
|
+
if !remote.dir.nil? && !remote.dir.empty? && top != $local_top
|
20
|
+
remote.dir = remote.dir + local_dir[top.size..-1]
|
21
|
+
end
|
22
|
+
if remote.pass_file != orig_pass_file && !::File.file?(remote.pass_file)
|
23
|
+
remote.pass_file = ::File.join(top, '.odisk', remote.pass_file)
|
24
|
+
end
|
25
|
+
break
|
26
|
+
end
|
27
|
+
top = ::File.dirname(top)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
info_from_remotes(local_dir, remote) unless remote.complete?
|
31
|
+
remote.user = ENV['USER'] if remote.user.nil?
|
32
|
+
unless remote.okay?
|
33
|
+
puts "*** user@host:top_dir not specified on command line, in local .odisk/remote file, or in ~/.odisk/remotes"
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
4
39
|
def self.info_from_remotes(local_dir, remote)
|
5
40
|
orig_pass_file = remote.pass_file
|
6
41
|
local_dir = ::File.expand_path(local_dir)
|
data/lib/odisk/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: odisk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: opee
|
@@ -79,6 +79,7 @@ description: Remote Encrypted File Synchronization, oDisk
|
|
79
79
|
email: peter@ohler.com
|
80
80
|
executables:
|
81
81
|
- odisk
|
82
|
+
- odisk_forget
|
82
83
|
extensions: []
|
83
84
|
extra_rdoc_files:
|
84
85
|
- README.md
|
@@ -104,8 +105,8 @@ files:
|
|
104
105
|
- lib/odisk.rb
|
105
106
|
- LICENSE
|
106
107
|
- README.md
|
107
|
-
-
|
108
|
-
|
108
|
+
- bin/odisk
|
109
|
+
- bin/odisk_forget
|
109
110
|
homepage: http://www.ohler.com/odisk
|
110
111
|
licenses: []
|
111
112
|
post_install_message:
|
@@ -128,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
129
|
version: '0'
|
129
130
|
requirements: []
|
130
131
|
rubyforge_project: odisk
|
131
|
-
rubygems_version: 1.8.
|
132
|
+
rubygems_version: 1.8.23
|
132
133
|
signing_key:
|
133
134
|
specification_version: 3
|
134
135
|
summary: Remote Encrypted File Synchronization, oDisk
|