dropbox-sync 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +69 -0
- data/Rakefile +2 -0
- data/bin/dropbox-sync +8 -0
- data/dropbox-sync.gemspec +27 -0
- data/lib/dropbox_sync.rb +5 -0
- data/lib/dropbox_sync/cli.rb +90 -0
- data/lib/dropbox_sync/entry.rb +143 -0
- data/lib/dropbox_sync/version.rb +3 -0
- data/test +0 -0
- metadata +109 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
= dropbox-sync
|
2
|
+
|
3
|
+
dropbox-sync is a simple command line tool to setup syncing files and directories outside of your Dropbox folders using symlinks.
|
4
|
+
This is especially useful for applications for which you want to synchronize data between different machines, but the application
|
5
|
+
expects it files to be on a certain location. This tool will create a symlink in your <tt>~/Dropbox/Sync</tt> folder to any path
|
6
|
+
you specify. Dropbox will follow this link and synchronize the contents of the original location. This tool can then setup these
|
7
|
+
links easily on other machines as well to complete your synchronization setup.
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
gem install dropbox-sync
|
12
|
+
|
13
|
+
== Warnings
|
14
|
+
|
15
|
+
This tool is tested on Mac OSX 10.6. It should work on other OSX versions and Linux too, but this is untested. Before using the
|
16
|
+
tool, always wait until Dropbox finishes syncing everything, and then close the Dropbox application. This will make sure Dropbox
|
17
|
+
does not interfere with this tools operations and the other way around.
|
18
|
+
|
19
|
+
Final note: not every application is suitable for this synchronization using Dropbox.
|
20
|
+
|
21
|
+
== Usage example
|
22
|
+
|
23
|
+
Say, you want to synchronize your Address Book contacts on Mac OS X. First, use this tool to synchronize the Address Book
|
24
|
+
folder: <tt>~/Library/Application Support/AddressBook</tt>. Run the following command:
|
25
|
+
|
26
|
+
dropbox-sync sync "~/Library/Application Support/AddressBook"
|
27
|
+
|
28
|
+
This will create a symlink <tt>~/Dropbox/Sync/AddressBook</tt>. Dropbox will start uploading the contents of the folder to
|
29
|
+
your Dropbox account.
|
30
|
+
|
31
|
+
On the other machine, wait until Dropbox finishes synchronizing and then quit the application. Instead of a symlink, Dropbox
|
32
|
+
will have created a folder called <tt>~/Dropbox/Sync/AddressBook</tt> with all the contents in it. The folder needs to be
|
33
|
+
moved to the original location in <tt>~/Library</tt> so Address Book picks it up. Moreover, we also want to create a
|
34
|
+
symlink on this machine, so any changes on this machine will be synced to Dropbox as well. Run the following command:
|
35
|
+
|
36
|
+
dropbox-sync setup
|
37
|
+
|
38
|
+
This will move the folder fro the <tt>~/Dropbox/Sync</tt> folder to the original location and create a symlink instead.
|
39
|
+
Note that usually, there will already a local AddressBook folder around in <tt>~/Library/Application Support</tt>. This
|
40
|
+
folder will be moved to <tt>~/Library/Application Support/AddressBook.local_backup</tt> so you won't lose it. You can
|
41
|
+
always move this folder back into it's original location to get your local Address Book back.
|
42
|
+
|
43
|
+
The setup command can be run every time there is a change to your Dropbox configuration. It will only setup links that
|
44
|
+
have not yet been set up before on the machine.
|
45
|
+
|
46
|
+
== Other commands and options
|
47
|
+
|
48
|
+
=== <tt>dropbox-sync list</tt>
|
49
|
+
|
50
|
+
This will display a list of all the files and directories that are currently being synced.
|
51
|
+
|
52
|
+
=== <tt>dropbox-sync unsync <path></tt>
|
53
|
+
|
54
|
+
This will "forget" the sync link between your local path and the Dropbox path. The files will be kept both locally
|
55
|
+
and on Dropbox.
|
56
|
+
|
57
|
+
=== <tt>dropbox-sync destroy <path></tt>
|
58
|
+
|
59
|
+
This will destroy the sync link between your local path and the Dropbox path. Your local files will be kept around,
|
60
|
+
but they will be removed from Dropbox.
|
61
|
+
|
62
|
+
=== <tt>--dropbox-dir <path></tt>
|
63
|
+
|
64
|
+
If you are not using the default <tt>~/Dropbox</tt> folder on your system, you should provide the <tt>--dropbox-dir
|
65
|
+
<dropbox-path></tt> option to every command.
|
66
|
+
|
67
|
+
== License
|
68
|
+
|
69
|
+
MIT.
|
data/Rakefile
ADDED
data/bin/dropbox-sync
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/dropbox_sync/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "dropbox-sync"
|
6
|
+
s.version = DropboxSync::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Willem van Bergen']
|
9
|
+
s.email = ['willem@railsdoctors.com']
|
10
|
+
s.homepage = "http://github.com/wvanbergen/dropbox-sync"
|
11
|
+
s.summary = "Tool to synchronize folders between machiens using Dropbox and symbolic links."
|
12
|
+
s.description = <<-D
|
13
|
+
This tool will create symbolic links in the Dropbox folder to synchronize paths outside of it. This
|
14
|
+
will cause Dropbox to synchronize the content with your Dropbox account. This tool can then be used
|
15
|
+
on a different machine (with the same Dropbox account) to recreate the symbolic links and setup
|
16
|
+
synchronization between your machines.
|
17
|
+
D
|
18
|
+
|
19
|
+
s.required_rubygems_version = ">= 1.3.6"
|
20
|
+
|
21
|
+
s.add_runtime_dependency "thor"
|
22
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
26
|
+
s.require_path = 'lib'
|
27
|
+
end
|
data/lib/dropbox_sync.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
class DropboxSync::CLI < Thor
|
5
|
+
|
6
|
+
class_option "dropbox-dir", :type => :string, :banner => "The location of the Dropbox folder.", :default => '~/Dropbox'
|
7
|
+
|
8
|
+
def initialize(*)
|
9
|
+
super
|
10
|
+
setup_infrastructure!
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
desc 'list', "Lists the paths that are currently being synced by Dropbox"
|
15
|
+
def list
|
16
|
+
DropboxSync::Entry.each do |entry|
|
17
|
+
shell.say entry.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'sync PATH [NAME]', "Creates a symbolic link in the dropbox folder to a file or directory."
|
22
|
+
def sync(path, name = nil)
|
23
|
+
DropboxSync::Entry.create(name || File.basename(path), path)
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'unsync NAME', "Removes symlink, but keep all files around, locally and on Dropbox."
|
27
|
+
def unsync(name)
|
28
|
+
entry = DropboxSync::Entry[name]
|
29
|
+
if entry.applied?
|
30
|
+
entry.unapply!
|
31
|
+
shell.say "#{entry.name} is now no longer syncing with Dropbox."
|
32
|
+
else
|
33
|
+
raise "Can only unsync entries that are set up correctly!"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'destroy NAME', "Removes symlink if it exists, and removes files from Dropbox. Keeps local files around."
|
38
|
+
def destroy(name)
|
39
|
+
entry = DropboxSync::Entry[name]
|
40
|
+
entry.destroy!
|
41
|
+
shell.say "#{entry.name} is now deleted from Dropbox."
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'setup', "Sets up the synced files and folders on this machine."
|
45
|
+
def setup
|
46
|
+
DropboxSync::Entry.each do |entry|
|
47
|
+
shell.say "#{entry.name}"
|
48
|
+
|
49
|
+
if entry.applied?
|
50
|
+
shell.say " - Syncing is already set up."
|
51
|
+
|
52
|
+
elsif entry.applyable?
|
53
|
+
|
54
|
+
if entry.target_exist?
|
55
|
+
entry.backup_target!
|
56
|
+
shell.say " - Backed up current version of #{entry.path} as #{entry.backup_path}."
|
57
|
+
end
|
58
|
+
|
59
|
+
entry.apply!
|
60
|
+
shell.say " - Dropbox version moved to #{entry.target_path}."
|
61
|
+
shell.say " - Created link #{entry.sync_path} to enable dropbox syncing."
|
62
|
+
|
63
|
+
else
|
64
|
+
shell.say " - Something is off with this entry!"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def help(*)
|
70
|
+
shell.say "Dropbox Sync command line tool - by Willem van Bergen."
|
71
|
+
shell.say
|
72
|
+
shell.say "This tool will create symlinks for files and directories you provide in your Dropbox folder. "
|
73
|
+
shell.say "This will synchronize it with Dropbox. You can then easily recreate the setup on a different "
|
74
|
+
shell.say "machine by running 'dropbox-sync setup'."
|
75
|
+
shell.say
|
76
|
+
shell.say "Wait until all files are synced, and then quit Dropbox before using this tool."
|
77
|
+
shell.say
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def setup_infrastructure!
|
84
|
+
if File.directory?(File.expand_path(options['dropbox-dir']))
|
85
|
+
DropboxSync::Entry.sync_folder = File.join(File.expand_path(options['dropbox-dir']), 'Sync')
|
86
|
+
else
|
87
|
+
raise "The dropbox folder was not found on #{options['dropbox-dir']}."
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
class DropboxSync::Entry
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_accessor :sync_folder
|
8
|
+
|
9
|
+
def sync_foler=(folder)
|
10
|
+
@sync_folder = folder
|
11
|
+
@entries = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def settings_file
|
15
|
+
File.join(sync_folder, 'sync-settings.yml')
|
16
|
+
end
|
17
|
+
|
18
|
+
def each(&block)
|
19
|
+
entries.each(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_entry(entry)
|
23
|
+
entries << entry
|
24
|
+
save_entries!
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_entry(entry)
|
28
|
+
entries.delete(self[entry])
|
29
|
+
save_entries!
|
30
|
+
end
|
31
|
+
|
32
|
+
def entries
|
33
|
+
@entries ||= begin
|
34
|
+
hash = YAML.load(File.read(settings_file)) || {}
|
35
|
+
hash.map { |name, options| DropboxSync::Entry.from_hash(name, options) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def [](name_or_path)
|
40
|
+
return name_or_path if name_or_path.kind_of?(DropboxSync::Entry)
|
41
|
+
entries.detect { |entry| entry.name == name_or_path || File.expand_path(name_or_path) == entry.target_path }
|
42
|
+
end
|
43
|
+
|
44
|
+
def save_entries!
|
45
|
+
hash = {}
|
46
|
+
each { |entry| hash[entry.name] = entry.to_hash }
|
47
|
+
File.open(settings_file, 'w') { |io| io.write(YAML.dump(hash)) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def from_hash(name, options)
|
51
|
+
self.new(name, options['path'])
|
52
|
+
end
|
53
|
+
|
54
|
+
def create(name, path)
|
55
|
+
|
56
|
+
raise "#{path.inspect} not found!" unless File.exist?(path)
|
57
|
+
raise "#{path.inspect} is already being synced!" if entries.any? { |e| e.target_path == File.expand_path(path) }
|
58
|
+
raise "Entry #{name.inspect} already exists, choose another name!" if entries.any? { |e| e.name == name }
|
59
|
+
|
60
|
+
entry = self.new(name, path)
|
61
|
+
entry.create!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_reader :name, :path
|
66
|
+
|
67
|
+
def initialize(name, path)
|
68
|
+
@name, @path = name, self.class.normalized_path(path)
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.normalized_path(path)
|
72
|
+
File.expand_path(path).sub(Regexp.new('^' + Regexp.quote(File.expand_path('~'))), '~')
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_hash
|
76
|
+
{ 'path' => @path }
|
77
|
+
end
|
78
|
+
|
79
|
+
def sync_path
|
80
|
+
File.join(self.class.sync_folder, name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def create!
|
84
|
+
FileUtils.ln_s(target_path, sync_path)
|
85
|
+
self.class.add_entry(self)
|
86
|
+
end
|
87
|
+
|
88
|
+
def applied?
|
89
|
+
File.symlink?(sync_path) && File.readlink(sync_path) == target_path && File.exist?(target_path)
|
90
|
+
end
|
91
|
+
|
92
|
+
def applyable?
|
93
|
+
File.exist?(sync_path) && !File.symlink?(sync_path) && File.exist?(target_path)
|
94
|
+
end
|
95
|
+
|
96
|
+
def target_path
|
97
|
+
File.expand_path(path)
|
98
|
+
end
|
99
|
+
|
100
|
+
def backup_path
|
101
|
+
target_path + '.local_backup'
|
102
|
+
end
|
103
|
+
|
104
|
+
def target_exist?
|
105
|
+
File.exist?(target_path)
|
106
|
+
end
|
107
|
+
|
108
|
+
def backup_target!
|
109
|
+
FileUtils.mv(target_path, backup_path)
|
110
|
+
end
|
111
|
+
|
112
|
+
def apply!
|
113
|
+
raise "Traget already exists" if target_exist?
|
114
|
+
FileUtils.mv(sync_path, target_path)
|
115
|
+
FileUtils.ln_s(target_path, sync_path)
|
116
|
+
end
|
117
|
+
|
118
|
+
def unapply!
|
119
|
+
raise "Cannot unapply entries that have not been applied!" unless applied?
|
120
|
+
FileUtils.rm(sync_path)
|
121
|
+
FileUtils.cp_r(target_path, sync_path)
|
122
|
+
self.class.remove_entry(self)
|
123
|
+
end
|
124
|
+
|
125
|
+
def destroy!
|
126
|
+
FileUtils.rm(sync_path) if File.exist?(sync_path)
|
127
|
+
self.class.remove_entry(self)
|
128
|
+
end
|
129
|
+
|
130
|
+
def status
|
131
|
+
if applied?
|
132
|
+
:applied
|
133
|
+
elsif applyable?
|
134
|
+
:applyable
|
135
|
+
else
|
136
|
+
:invalid
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_s
|
141
|
+
"#{name} -> #{path} [#{status}]"
|
142
|
+
end
|
143
|
+
end
|
data/test
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dropbox-sync
|
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
|
+
- Willem van Bergen
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-05 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: thor
|
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
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: bundler
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 23
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 0
|
47
|
+
- 0
|
48
|
+
version: 1.0.0
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
description: " This tool will create symbolic links in the Dropbox folder to synchronize paths outside of it. This\n will cause Dropbox to synchronize the content with your Dropbox account. This tool can then be used\n on a different machine (with the same Dropbox account) to recreate the symbolic links and setup\n synchronization between your machines.\n"
|
52
|
+
email:
|
53
|
+
- willem@railsdoctors.com
|
54
|
+
executables:
|
55
|
+
- dropbox-sync
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- .gitignore
|
62
|
+
- Gemfile
|
63
|
+
- README.rdoc
|
64
|
+
- Rakefile
|
65
|
+
- bin/dropbox-sync
|
66
|
+
- dropbox-sync.gemspec
|
67
|
+
- lib/dropbox_sync.rb
|
68
|
+
- lib/dropbox_sync/cli.rb
|
69
|
+
- lib/dropbox_sync/entry.rb
|
70
|
+
- lib/dropbox_sync/version.rb
|
71
|
+
- test
|
72
|
+
has_rdoc: true
|
73
|
+
homepage: http://github.com/wvanbergen/dropbox-sync
|
74
|
+
licenses: []
|
75
|
+
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 23
|
96
|
+
segments:
|
97
|
+
- 1
|
98
|
+
- 3
|
99
|
+
- 6
|
100
|
+
version: 1.3.6
|
101
|
+
requirements: []
|
102
|
+
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.3.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Tool to synchronize folders between machiens using Dropbox and symbolic links.
|
108
|
+
test_files: []
|
109
|
+
|