odisk 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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