odisk 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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.1
28
+ ### Release 0.2.2
29
29
 
30
- - Fixed symlink sync.
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 exclusion of file and directories
44
- - specify on command line and create .odisk/exclude file
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 excludes to digest creation
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 changes by mode, owner, or group changes
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
- # Walk up the directory tree looking for .odisk directories and a remote.json
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
@@ -1,5 +1,5 @@
1
1
 
2
2
  module ODisk
3
3
  # Current version of the module.
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
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.1
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-06 00:00:00.000000000 Z
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
- - !binary |-
108
- YmluL29kaXNr
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.21
132
+ rubygems_version: 1.8.23
132
133
  signing_key:
133
134
  specification_version: 3
134
135
  summary: Remote Encrypted File Synchronization, oDisk