odisk 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.
@@ -0,0 +1,45 @@
1
+
2
+ module ODisk
3
+ # Just a way to keep the data associated with a remote site together one
4
+ # Object.
5
+ class Remote
6
+ attr_accessor :user
7
+ attr_accessor :host
8
+ attr_accessor :dir
9
+ attr_accessor :pass_file
10
+
11
+ def initialize()
12
+ @user = nil
13
+ @host = nil
14
+ @dir = nil
15
+ @pass_file = nil
16
+ end
17
+
18
+ # Expects a string as input of the form user@remote.com:dir:passphrase_file
19
+ def update(str)
20
+ u, x = str.strip().split('@')
21
+ h, t, p = x.split(':')
22
+ @user = u if @user.nil? && u.is_a?(String) && !u.empty?
23
+ @host = h if @host.nil? && h.is_a?(String) && !h.empty?
24
+ @dir = t if @dir.nil? && t.is_a?(String) && !t.empty?
25
+ @pass_file = p if @pass_file.nil? && p.is_a?(String) && !p.empty?
26
+ end
27
+
28
+ def complete?()
29
+ !(@user.nil? || @host.nil? || @dir.nil? || @pass_file.nil?)
30
+ end
31
+
32
+ def okay?()
33
+ !(@user.nil? || @host.nil? || @dir.nil?)
34
+ end
35
+
36
+ def encrypt?()
37
+ !@pass_file.nil?
38
+ end
39
+
40
+ def to_s()
41
+ "#{user}@#{host}:#{@dir}:#{@pass_file}"
42
+ end
43
+
44
+ end # Remote
45
+ end # ODisk
@@ -0,0 +1,102 @@
1
+
2
+ module ODisk
3
+ class StatFixer < ::Opee::Collector
4
+
5
+ def initialize(options={})
6
+ super(options)
7
+ end
8
+
9
+ def set_options(options)
10
+ super(options)
11
+ @dir_queue = options[:dir_queue]
12
+ @copy_queue = options[:copy_queue]
13
+ @crypt_queue = options[:crypt_queue]
14
+ @inputs = options[:inputs]
15
+ @fixer = options[:fixer]
16
+ end
17
+
18
+ private
19
+
20
+ def job_key(job)
21
+ if job.is_a?(StatJob)
22
+ job.key()
23
+ elsif job.is_a?(String)
24
+ ::File.dirname(job)
25
+ else
26
+ raise "Invalid path for StatFixer"
27
+ end
28
+ end
29
+
30
+ def update_token(job, token, path_id)
31
+ # StatJob or String (a file path) can be received
32
+ if job.is_a?(StatJob)
33
+ if token.nil?
34
+ job.digest.entries.each do |e|
35
+ fix_stats(::File.join(job.path, e.name), e) unless job.mods.include?(e.name)
36
+ end
37
+ elsif token.is_a?(Array)
38
+ until (path = token.pop).nil?
39
+ name = ::File.basename(path)
40
+ fix_stats(path, job.digest.entries[name])
41
+ job.mods.delete(name)
42
+ end
43
+ else
44
+ raise "Expected StatFixer token to be an Array or nil"
45
+ end
46
+ token = job
47
+ else
48
+ if token.nil?
49
+ token = [job]
50
+ elsif token.is_a?(Array)
51
+ token << job
52
+ elsif token.is_a?(StatJob)
53
+ name = ::File.basename(job)
54
+ fix_stats(job, token.digest[name])
55
+ token.mods.delete(name)
56
+ else
57
+ raise "Expected StatFixer token to be an Array, StatJob, or nil"
58
+ end
59
+ end
60
+ token
61
+ end
62
+
63
+ def complete?(job, token)
64
+ result = token.is_a?(StatJob) ? token.complete?(token) : false
65
+ ::Opee::Env.info("complete?(#{job}, #{token}) => #{result}")
66
+ result
67
+ end
68
+
69
+ def keep_going(job)
70
+ # done, nothing left to do
71
+ # TBD tell progress about the completion
72
+ end
73
+
74
+ def fix_stats(path, info)
75
+ e = Digest.create_info(path)
76
+ diff = Diff.new(e, info)
77
+ unless e == info
78
+ h = {}
79
+ diff.fill_hash(nil, h, true)
80
+ h.each do |attr,val|
81
+ case attr
82
+ when :mtime
83
+ ::File.utime(info.mtime, info.mtime, path) unless info.is_a?(::ODisk::Link)
84
+ when :owner
85
+ owner = Etc.getpwnam(info.owner).uid
86
+ group = Etc.getgrnam(info.group).gid
87
+ ::File::lchown(owner, group, path)
88
+ when :group
89
+ owner = Etc.getpwnam(info.owner).uid
90
+ group = Etc.getgrnam(info.group).gid
91
+ ::File::lchown(owner, group, path)
92
+ when :mode
93
+ ::File::lchmod(val[1], path)
94
+ else
95
+ # ignore?
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ end # StatFixer
102
+ end # ODisk
@@ -0,0 +1,32 @@
1
+
2
+ module ODisk
3
+ class StatJob < ::Opee::Job
4
+
5
+ attr_reader :path
6
+ attr_reader :mods
7
+ attr_accessor :digest
8
+
9
+ def initialize(path, digest)
10
+ @path = path
11
+ @digest = digest
12
+ @mods = []
13
+ end
14
+
15
+ def add_mod(name)
16
+ @mods << name
17
+ end
18
+
19
+ def key()
20
+ @path
21
+ end
22
+
23
+ def complete?(token)
24
+ @mods.empty?
25
+ end
26
+
27
+ def to_s()
28
+ "<StatJob:#{@path} [#{@mods.join(',')}]>"
29
+ end
30
+
31
+ end # StatJob
32
+ end # ODisk
@@ -0,0 +1,25 @@
1
+
2
+ module ODisk
3
+ class SyncJob < ::Opee::Job
4
+
5
+ STATS = 0
6
+ REMOVE = 1
7
+ COPY = 2
8
+
9
+ # location of master
10
+ OREFS = 0 # encrypted master
11
+ LOCAL = 1
12
+ REMOTE = 2
13
+
14
+ attr_reader :path
15
+ attr_reader :master
16
+ attr_reader :op
17
+
18
+ def initialize(rel_path, master, op)
19
+ @path = rel_path
20
+ @master = master
21
+ @op = op
22
+ end
23
+
24
+ end # SyncJob
25
+ end # ODisk
@@ -0,0 +1,37 @@
1
+
2
+ module ODisk
3
+ class SyncStarter < ::Opee::Actor
4
+
5
+ def initialize(options={})
6
+ @digester = nil
7
+ @fetcher = nil
8
+ super(options)
9
+ @dir_queue.ask(:ready, self)
10
+ end
11
+
12
+ def set_options(options)
13
+ super(options)
14
+ @dir_queue = options[:dir_queue]
15
+ @digester = options[:digester]
16
+ @fetcher = options[:fetcher]
17
+ @collector = options[:collector]
18
+ end
19
+
20
+ private
21
+
22
+ def start(path)
23
+ ::Opee::Env.info("start sync for #{path}")
24
+ job = DirSyncJob.new(path)
25
+ @fetcher.ask(:fetch, job) unless @fetcher.nil?
26
+ @digester.ask(:create, job) unless @digester.nil?
27
+
28
+ top = (path.nil? || path.empty?) ? $local_top : ::File.join($local_top, path)
29
+ prev_path = ::File.join(top, '.odisk', 'digest.json')
30
+ job.previous_digest = ::Oj.load_file(prev_path, mode: :object) if ::File.file?(prev_path)
31
+ @collector.ask(:collect, job, :starter) unless @collector.nil?
32
+ # ready for another
33
+ @dir_queue.ask(:ready, self)
34
+ end
35
+
36
+ end # SyncStarter
37
+ end # ODisk
@@ -0,0 +1,5 @@
1
+
2
+ module ODisk
3
+ # Current version of the module.
4
+ VERSION = '0.2.0'
5
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: odisk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Peter Ohler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: opee
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: oj
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: net-ssh
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: net-sftp
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Remote Encrypted File Synchronization, oDisk
79
+ email: peter@ohler.com
80
+ executables:
81
+ - odisk
82
+ extensions: []
83
+ extra_rdoc_files:
84
+ - README.md
85
+ files:
86
+ - lib/odisk/copier.rb
87
+ - lib/odisk/crypter.rb
88
+ - lib/odisk/diff.rb
89
+ - lib/odisk/digest.rb
90
+ - lib/odisk/digester.rb
91
+ - lib/odisk/dir.rb
92
+ - lib/odisk/dirsyncjob.rb
93
+ - lib/odisk/fetcher.rb
94
+ - lib/odisk/file.rb
95
+ - lib/odisk/info.rb
96
+ - lib/odisk/link.rb
97
+ - lib/odisk/planner.rb
98
+ - lib/odisk/remote.rb
99
+ - lib/odisk/statfixer.rb
100
+ - lib/odisk/statjob.rb
101
+ - lib/odisk/syncjob.rb
102
+ - lib/odisk/syncstarter.rb
103
+ - lib/odisk/version.rb
104
+ - lib/odisk.rb
105
+ - LICENSE
106
+ - README.md
107
+ - bin/odisk
108
+ homepage: http://www.ohler.com/odisk
109
+ licenses: []
110
+ post_install_message:
111
+ rdoc_options:
112
+ - --main
113
+ - README.md
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project: odisk
130
+ rubygems_version: 1.8.23
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Remote Encrypted File Synchronization, oDisk
134
+ test_files: []
135
+ has_rdoc: true