skypager 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/Rakefile +21 -0
- data/bin/skypager +17 -0
- data/examples/.gitignore +4 -0
- data/examples/blog-site/.gitignore +18 -0
- data/examples/blog-site/.pryrc +4 -0
- data/examples/blog-site/Gemfile +8 -0
- data/examples/blog-site/config.rb +17 -0
- data/examples/blog-site/data/dropbox.json +1 -0
- data/examples/blog-site/source/images/background.png +0 -0
- data/examples/blog-site/source/images/middleman.png +0 -0
- data/examples/blog-site/source/index.html.erb +10 -0
- data/examples/blog-site/source/javascripts/all.js +1 -0
- data/examples/blog-site/source/layouts/layout.erb +19 -0
- data/examples/blog-site/source/posts/introduction-to-skypager.html.md +23 -0
- data/examples/blog-site/source/posts/skypager-and-dnsimple-and-amazon-web-services-combo.html.md +9 -0
- data/examples/blog-site/source/stylesheets/all.css +55 -0
- data/examples/blog-site/source/stylesheets/normalize.css +375 -0
- data/examples/gallery-site/.gitignore +18 -0
- data/examples/gallery-site/.pryrc +4 -0
- data/examples/gallery-site/Gemfile +11 -0
- data/examples/gallery-site/config.rb +38 -0
- data/examples/gallery-site/data/dropbox.json +1 -0
- data/examples/gallery-site/data/galleries.json +1 -0
- data/examples/gallery-site/source/gallery.html.erb +7 -0
- data/examples/gallery-site/source/images/background.png +0 -0
- data/examples/gallery-site/source/images/galleries/cristian-gallery-1/001.jpg +0 -0
- data/examples/gallery-site/source/images/galleries/cristian-gallery-1/002.jpg +0 -0
- data/examples/gallery-site/source/images/galleries/cristian-gallery-1/003.jpg +0 -0
- data/examples/gallery-site/source/images/galleries/cristian-gallery-1/004.jpg +0 -0
- data/examples/gallery-site/source/images/galleries/luca-gallery-1/001.jpg +0 -0
- data/examples/gallery-site/source/images/galleries/luca-gallery-1/002.JPG +0 -0
- data/examples/gallery-site/source/images/galleries/luca-gallery-1/003.jpg +0 -0
- data/examples/gallery-site/source/images/galleries/luca-gallery-1/004.JPG +0 -0
- data/examples/gallery-site/source/images/middleman.png +0 -0
- data/examples/gallery-site/source/index.html.erb +10 -0
- data/examples/gallery-site/source/javascripts/all.js +1 -0
- data/examples/gallery-site/source/layouts/layout.erb +20 -0
- data/examples/gallery-site/source/stylesheets/all.css +0 -0
- data/examples/gallery-site/source/stylesheets/normalize.css +375 -0
- data/examples/gallery-site/source/tutorial.md +151 -0
- data/lib/skypager.rb +92 -0
- data/lib/skypager/build_server.rb +17 -0
- data/lib/skypager/cli/commands/config.rb +58 -0
- data/lib/skypager/cli/commands/create.rb +98 -0
- data/lib/skypager/cli/commands/deploy.rb +30 -0
- data/lib/skypager/cli/commands/edit.rb +32 -0
- data/lib/skypager/cli/commands/list.rb +12 -0
- data/lib/skypager/cli/commands/setup.rb +124 -0
- data/lib/skypager/cli/commands/sync.rb +18 -0
- data/lib/skypager/configuration.rb +173 -0
- data/lib/skypager/data.rb +8 -0
- data/lib/skypager/data/excel_spreadsheet.rb +8 -0
- data/lib/skypager/data/google_spreadsheet.rb +225 -0
- data/lib/skypager/data/request.rb +12 -0
- data/lib/skypager/data/source.rb +171 -0
- data/lib/skypager/data/source_routes_proxy.rb +30 -0
- data/lib/skypager/dns.rb +65 -0
- data/lib/skypager/extension.rb +203 -0
- data/lib/skypager/middleman/commands/data.rb +0 -0
- data/lib/skypager/middleman/commands/deploy.rb +0 -0
- data/lib/skypager/middleman/commands/sync.rb +0 -0
- data/lib/skypager/site.rb +208 -0
- data/lib/skypager/sync.rb +23 -0
- data/lib/skypager/sync/amazon.rb +171 -0
- data/lib/skypager/sync/dropbox.rb +173 -0
- data/lib/skypager/sync/dropbox/delta.rb +67 -0
- data/lib/skypager/sync/folder.rb +235 -0
- data/lib/skypager/sync/google.rb +143 -0
- data/lib/skypager/tar.rb +77 -0
- data/lib/skypager/version.rb +3 -0
- data/skypager.gemspec +40 -0
- data/spec/lib/skypager/configuration_spec.rb +5 -0
- data/spec/lib/skypager/data_spec.rb +5 -0
- data/spec/lib/skypager/site_spec.rb +5 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/json_helper.rb +7 -0
- metadata +383 -0
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module Skypager
|
2
|
+
class Site
|
3
|
+
class << self
|
4
|
+
def directory
|
5
|
+
Skypager.config.sites_directory
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :options,
|
10
|
+
:name,
|
11
|
+
:config
|
12
|
+
|
13
|
+
def initialize(name, options = {})
|
14
|
+
@name = name.to_s.downcase
|
15
|
+
@options = options
|
16
|
+
@config = self.class.directory[@name] || {
|
17
|
+
name: @name
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def set attribute, value
|
22
|
+
@config[attribute.to_sym] = value
|
23
|
+
save!
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def get! attribute
|
28
|
+
val = get(attribute)
|
29
|
+
|
30
|
+
if val.nil? || val.to_s.length == 0
|
31
|
+
nil
|
32
|
+
else
|
33
|
+
val
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def get attribute
|
38
|
+
@config[attribute.to_sym]
|
39
|
+
end
|
40
|
+
|
41
|
+
def hostname= value
|
42
|
+
set(:hostname, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def hostname
|
46
|
+
custom_domain || bucket_hostname
|
47
|
+
end
|
48
|
+
|
49
|
+
def bucket_hostname
|
50
|
+
"#{@config[:name] || @name}.#{ Skypager.config.domain }"
|
51
|
+
end
|
52
|
+
|
53
|
+
def bucket(create=false)
|
54
|
+
return @bucket if @bucket
|
55
|
+
|
56
|
+
b = Skypager.amazon.find_bucket_by_name(bucket_hostname) rescue nil
|
57
|
+
|
58
|
+
if create && !b
|
59
|
+
b = Skypager.amazon.create_bucket(bucket_hostname)
|
60
|
+
end
|
61
|
+
|
62
|
+
@bucket = b
|
63
|
+
end
|
64
|
+
|
65
|
+
def deploy(build_dir)
|
66
|
+
target = bucket || Skypager.amazon.s3_bucket
|
67
|
+
|
68
|
+
upload = lambda do |node|
|
69
|
+
next if node.to_s == ".DS_Store"
|
70
|
+
|
71
|
+
if node.directory?
|
72
|
+
Array(node.children).each(&upload)
|
73
|
+
elsif node.file?
|
74
|
+
rel = node.relative_path_from(build_dir).to_s
|
75
|
+
puts "Deploying #{ rel }"
|
76
|
+
target.files.create(key: rel, body: File.open(node), public: true)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
build_dir.children.each(&upload)
|
81
|
+
end
|
82
|
+
|
83
|
+
def use_cdn?
|
84
|
+
get(:use_cdn) == true || get(:use_cdn) == "yes" || get(:use_cdn) == "true"
|
85
|
+
end
|
86
|
+
|
87
|
+
def paths_to_invalidate(app)
|
88
|
+
app.sitemap.resources.map {|r| "/#{r.request_path}" }
|
89
|
+
end
|
90
|
+
|
91
|
+
def after_setup
|
92
|
+
if use_cdn? && !has_cdn?
|
93
|
+
Skypager.amazon.create_cdn_for(self)
|
94
|
+
end
|
95
|
+
|
96
|
+
if Skypager.config.dnsimple_setup?
|
97
|
+
setup_cname() unless custom_domain?
|
98
|
+
else
|
99
|
+
puts "You will need to setup the DNS for this bucket yourself."
|
100
|
+
|
101
|
+
if has_cdn?
|
102
|
+
puts "You will want to configure the DNS for #{ custom_domain }"
|
103
|
+
puts "Create a CNAME and point to #{ cname_value }"
|
104
|
+
else
|
105
|
+
puts "Create a CNAME for #{ cname_value } on #{ Skypager.config.domain } and point to #{ bucket_host }"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def custom_domain?
|
111
|
+
get!(:custom_domain)
|
112
|
+
end
|
113
|
+
|
114
|
+
def deploy_options_config_string
|
115
|
+
custom_domain = get!(:custom_domain)
|
116
|
+
|
117
|
+
cfg = []
|
118
|
+
|
119
|
+
if custom_domain.length > 0
|
120
|
+
cfg.push(":custom_domain => '#{ custom_domain }'")
|
121
|
+
cfg.push(":use_cdn => true")
|
122
|
+
else
|
123
|
+
cfg.push(":domain => '#{ Skypager.config.domain }'")
|
124
|
+
end
|
125
|
+
|
126
|
+
cfg.push(":bucket_name => '#{ bucket_name }'")
|
127
|
+
|
128
|
+
"\ndeploy_to(:amazon, #{cfg.join(", ")})\n"
|
129
|
+
end
|
130
|
+
|
131
|
+
def bucket_key
|
132
|
+
fetch(:bucket_key) { bucket && bucket.key }
|
133
|
+
end
|
134
|
+
|
135
|
+
def bucket_name
|
136
|
+
bucket_key
|
137
|
+
end
|
138
|
+
|
139
|
+
def custom_domain
|
140
|
+
value = get(:custom_domain).to_s
|
141
|
+
value if value.length > 0
|
142
|
+
end
|
143
|
+
|
144
|
+
def fetch(key, &block)
|
145
|
+
@config.fetch(key, &block)
|
146
|
+
end
|
147
|
+
|
148
|
+
def bucket_url
|
149
|
+
@bucket_url ||= fetch(:bucket_url) { Skypager.amazon.website_url_for(bucket) }
|
150
|
+
end
|
151
|
+
|
152
|
+
def bucket_host
|
153
|
+
@bucket_host ||= fetch(:bucket_host) { URI.parse("http://#{ bucket_url }").host }
|
154
|
+
end
|
155
|
+
|
156
|
+
def setup_cname
|
157
|
+
puts "Creating an alias for #{ cname_value } to #{ bucket_host }"
|
158
|
+
Skypager.dns.setup_cname(cname_value, bucket_host)
|
159
|
+
end
|
160
|
+
|
161
|
+
def cname_value
|
162
|
+
if custom_domain && has_cdn?
|
163
|
+
cdn.domain
|
164
|
+
else
|
165
|
+
name
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def description
|
170
|
+
"#{ name }.#{ Skypager.config.domain }"
|
171
|
+
end
|
172
|
+
|
173
|
+
def has_cdn?
|
174
|
+
@cdn_distribution ||= Skypager.amazon.cdn.distributions.find do |cdn|
|
175
|
+
cdn.comment == description
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def cdn
|
180
|
+
@cdn ||= Skypager.amazon.cdn.distributions.find do |cdn|
|
181
|
+
cdn.comment == description
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def aliases
|
186
|
+
if custom_domain
|
187
|
+
[custom_domain, "www.#{ custom_domain }"]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def delete!
|
192
|
+
directory = self.class.directory
|
193
|
+
directory.delete(name)
|
194
|
+
Skypager.config.set :sites_directory, directory
|
195
|
+
end
|
196
|
+
|
197
|
+
def save!
|
198
|
+
directory = self.class.directory
|
199
|
+
directory[name] = to_config
|
200
|
+
Skypager.config.set :sites_directory, directory
|
201
|
+
end
|
202
|
+
|
203
|
+
def to_config
|
204
|
+
@config
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Skypager
|
2
|
+
module Sync
|
3
|
+
def self.sync_dropbox_path(path, options={})
|
4
|
+
dropbox.sync_path(path, options)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.amazon(options={})
|
8
|
+
require 'skypager/sync/amazon'
|
9
|
+
Skypager::Sync::Amazon.client
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.google(options={})
|
13
|
+
require 'skypager/sync/google'
|
14
|
+
Skypager::Sync::Google.client
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.dropbox(options={})
|
18
|
+
require 'skypager/sync/dropbox'
|
19
|
+
Skypager::Sync::Dropbox.client(options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Skypager
|
2
|
+
module Sync
|
3
|
+
class Amazon
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
require 'fog'
|
7
|
+
|
8
|
+
def aws_access_key_id
|
9
|
+
options[:aws_access_key_id] || options[:access_key_id] || Skypager.config.aws_access_key_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def aws_secret_access_key
|
13
|
+
options[:aws_secret_access_key] || options[:secret_access_key] || Skypager.config.aws_secret_access_key
|
14
|
+
end
|
15
|
+
|
16
|
+
def storage
|
17
|
+
@storage ||= Fog::Storage.new({
|
18
|
+
provider: 'AWS',
|
19
|
+
aws_access_key_id: aws_access_key_id,
|
20
|
+
aws_secret_access_key: aws_secret_access_key,
|
21
|
+
path_style: true
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
def cdn
|
26
|
+
@cdn ||= Fog::CDN.new({
|
27
|
+
provider: 'AWS',
|
28
|
+
aws_access_key_id: aws_access_key_id,
|
29
|
+
aws_secret_access_key: aws_secret_access_key
|
30
|
+
})
|
31
|
+
end
|
32
|
+
|
33
|
+
def s3_bucket_website_url
|
34
|
+
if s3_bucket.is_a?(Fog::Storage::AWS::Directory)
|
35
|
+
website_url_for(s3_bucket)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def site_description
|
40
|
+
options[:description] || options[:site_name] || s3_bucket.key
|
41
|
+
end
|
42
|
+
|
43
|
+
# the domain, and the domain with www
|
44
|
+
def site_domain_aliases
|
45
|
+
options[:aliases]
|
46
|
+
end
|
47
|
+
|
48
|
+
def s3_bucket
|
49
|
+
if bucket_name = options[:bucket_name] || Skypager.config.get("bucket_name") || Skypager.app.deploy_options[:bucket_name]
|
50
|
+
if bucket = find_bucket_by_name(bucket_name)
|
51
|
+
return bucket
|
52
|
+
else
|
53
|
+
"There is no bucket named: #{ bucket_name }. You can create one by running 'skypager setup amazon --create-bucket=BUCKET_NAME"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
puts "Can't determine what bucket name to use."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_cdn_for(site)
|
61
|
+
o = cdn_options(website_url: site.bucket_host,
|
62
|
+
comment: site.description,
|
63
|
+
aliases: site.aliases.join(","))
|
64
|
+
|
65
|
+
existing = cdn.distributions.find do |distribution|
|
66
|
+
distribution.comment == site.description
|
67
|
+
end
|
68
|
+
|
69
|
+
return existing if existing
|
70
|
+
|
71
|
+
cdn.distributions.create(o).tap do |distribution|
|
72
|
+
site.set distribution.domain
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def cdn_options(o={})
|
77
|
+
{
|
78
|
+
enabled: true,
|
79
|
+
custom_origin: {
|
80
|
+
'DNSName'=> o.fetch(:website_url) { s3_bucket_website_url },
|
81
|
+
'OriginProtocolPolicy'=>'match-viewer'
|
82
|
+
},
|
83
|
+
comment: o.fetch(:description) { site_description },
|
84
|
+
caller_reference: Time.now.to_i.to_s,
|
85
|
+
cname: o.fetch(:domain_aliases) { site_domain_aliases },
|
86
|
+
default_root_object: 'index.html'
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.client(options={})
|
91
|
+
@client ||= begin
|
92
|
+
instance.with_options(options)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
def self.method_missing(meth, *args, &block)
|
98
|
+
if client.respond_to?(meth)
|
99
|
+
return client.send(meth, *args, &block)
|
100
|
+
end
|
101
|
+
|
102
|
+
super
|
103
|
+
end
|
104
|
+
|
105
|
+
def website_host_for(bucket_or_bucket_name)
|
106
|
+
URI.parse(webite_url_for(bucket_or_bucket_name)).host
|
107
|
+
end
|
108
|
+
|
109
|
+
def website_url_for(bucket_or_bucket_name)
|
110
|
+
bucket = bucket_or_bucket_name
|
111
|
+
|
112
|
+
if bucket_or_bucket_name.is_a?(String)
|
113
|
+
bucket = storage.directories.get(bucket_or_bucket_name)
|
114
|
+
end
|
115
|
+
|
116
|
+
if bucket
|
117
|
+
"http://#{bucket.key}.s3-website-#{ bucket.location }.amazonaws.com"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def find_or_create_bucket(bucket_name)
|
122
|
+
find_bucket_by_name(bucket_name) || create_bucket(bucket_name)
|
123
|
+
end
|
124
|
+
|
125
|
+
def find_bucket_by_name(bucket_name)
|
126
|
+
storage.directories.get(bucket_name) rescue nil
|
127
|
+
end
|
128
|
+
|
129
|
+
def create_bucket(bucket_name)
|
130
|
+
storage.directories.create(key: bucket_name, public: true).tap do |bucket|
|
131
|
+
storage.put_bucket_website(bucket_name, 'index.html', key: 'error.html')
|
132
|
+
storage.put_bucket_cors(bucket_name, {"AllowedOrigin"=>"*","AllowedMethod"=>"GET","AllowedHeader"=>"Authorization"})
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def create_redirect_bucket(bucket_name, redirect_to_bucket_name)
|
137
|
+
create_bucket(redirect_to_bucket_name) unless find_bucket_by_name(redirect_to_bucket_name)
|
138
|
+
create_bucket(bucket_name)
|
139
|
+
end
|
140
|
+
|
141
|
+
def with_options(opts={})
|
142
|
+
options.merge!(opts)
|
143
|
+
self
|
144
|
+
end
|
145
|
+
|
146
|
+
def options
|
147
|
+
@options ||= {}
|
148
|
+
end
|
149
|
+
|
150
|
+
def has_application_keys?
|
151
|
+
(Skypager.config.aws_access_key_id.to_s.length > 0 && Skypager.config.aws_secret_access_key.to_s.length > 0)
|
152
|
+
end
|
153
|
+
|
154
|
+
def setup(options={})
|
155
|
+
return if has_application_keys?
|
156
|
+
|
157
|
+
unless Skypager.config.aws_access_key_id.to_s.length > 0
|
158
|
+
if value = options[:access_key_id] || ask("What is the AWS Access Key ID?", String)
|
159
|
+
Skypager.config.set 'aws_access_key_id', value
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
unless Skypager.config.aws_secret_access_key.to_s.length > 0
|
164
|
+
if value = options[:secret_access_key] || ask("What is the AWS Secret Access Key?", String)
|
165
|
+
Skypager.config.set 'aws_secret_access_key', value
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module Skypager
|
2
|
+
module Sync
|
3
|
+
class Dropbox
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def self.method_missing(meth, *args, &block)
|
7
|
+
if client.respond_to?(meth)
|
8
|
+
return client.send(meth, *args, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.client(options={})
|
15
|
+
@client ||= begin
|
16
|
+
::Dropbox::API::Config.app_key = options.fetch(:dropbox_app_key) { Skypager.config.dropbox_app_key }
|
17
|
+
::Dropbox::API::Config.app_secret = options.fetch(:dropbox_app_secret) { Skypager.config.dropbox_app_secret }
|
18
|
+
::Dropbox::API::Config.mode = options.fetch(:dropbox_app_type) { Skypager.config.dropbox_app_type }
|
19
|
+
instance.with_options(options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def sandboxed_app?
|
24
|
+
entry = api.ls.first
|
25
|
+
entry && entry.root == "app_folder"
|
26
|
+
end
|
27
|
+
|
28
|
+
def api
|
29
|
+
@api ||= begin
|
30
|
+
token = options.fetch(:token) { Skypager.config.dropbox_client_token }
|
31
|
+
secret = options.fetch(:secret) { Skypager.config.dropbox_client_secret }
|
32
|
+
::Dropbox::API::Client.new(token: token , secret: secret)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def find(path)
|
37
|
+
api.find(path)
|
38
|
+
rescue ::Dropbox::API::Error::NotFound
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def push_from(local_path, options={})
|
43
|
+
path_prefix = options.fetch(:prefix)
|
44
|
+
root = options[:root]
|
45
|
+
|
46
|
+
unless find(path_prefix)
|
47
|
+
api.mkdir(path_prefix)
|
48
|
+
end
|
49
|
+
|
50
|
+
uploader = lambda do |node|
|
51
|
+
next if node.to_s == ".DS_Store"
|
52
|
+
|
53
|
+
if node.directory?
|
54
|
+
Array(node.children).each(&uploader)
|
55
|
+
elsif node.file?
|
56
|
+
relative = node.relative_path_from(local_path)
|
57
|
+
target = "#{path_prefix}/#{relative}"
|
58
|
+
target = target.gsub(/^\//,'')
|
59
|
+
api.upload(target, node.read)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Pathname(local_path).children.each(&uploader)
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_site_folder(folder, allow_overwrite=false)
|
67
|
+
found = find(folder)
|
68
|
+
|
69
|
+
unless (!found || (found && !allow_overwrite))
|
70
|
+
api.mkdir("/#{folder}")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def sync(local_path, remote_path, options={})
|
75
|
+
sync_folders(local_path, remote_path, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Instructs Skypager to create a syncable folder
|
79
|
+
# between the local and remote path, and optionally
|
80
|
+
# modifies the middleman config for the site
|
81
|
+
def sync_folders(local_path, remote_path, options={})
|
82
|
+
app = options[:app]
|
83
|
+
|
84
|
+
folder = Skypager::Sync::Folder.new(local_path: local_path,
|
85
|
+
remote_path: remote_path,
|
86
|
+
app: app).synced
|
87
|
+
|
88
|
+
if !!options[:append_config] == true
|
89
|
+
Skypager.append_config(folder.config_line)
|
90
|
+
end
|
91
|
+
|
92
|
+
folder
|
93
|
+
end
|
94
|
+
|
95
|
+
def method_missing meth, *args, &block
|
96
|
+
if api.respond_to?(meth)
|
97
|
+
return api.send(meth, *args, &block)
|
98
|
+
end
|
99
|
+
|
100
|
+
super
|
101
|
+
end
|
102
|
+
|
103
|
+
def authorize(token, secret)
|
104
|
+
@api = nil if @api
|
105
|
+
options[:token] = token
|
106
|
+
options[:secret] = secret
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
def options
|
111
|
+
@options ||= {}
|
112
|
+
end
|
113
|
+
|
114
|
+
def with_options(opts={})
|
115
|
+
options.merge!(opts)
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
def requires_setup?
|
120
|
+
!(dropbox_app_key.length > 0 && dropbox_app_secret.length > 0)
|
121
|
+
end
|
122
|
+
|
123
|
+
def dropbox_app_key
|
124
|
+
Skypager.config.dropbox_app_key.to_s
|
125
|
+
end
|
126
|
+
|
127
|
+
def dropbox_app_secret
|
128
|
+
Skypager.config.dropbox_app_secret.to_s
|
129
|
+
end
|
130
|
+
|
131
|
+
def setup(options={})
|
132
|
+
if requires_setup?
|
133
|
+
if dropbox_app_key.length == 0
|
134
|
+
if answer = options[:dropbox_app_key] || ask("What is the dropbox app key?", String)
|
135
|
+
Skypager.config.set("dropbox_app_key", answer)
|
136
|
+
end
|
137
|
+
if answer = options[:dropbox_app_secret] || ask("What is the dropbox app secret?", String)
|
138
|
+
Skypager.config.set("dropbox_app_secret", answer)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
raise 'Missing dropbox application values' if requires_setup?
|
144
|
+
|
145
|
+
::Dropbox::API::Config.app_key = Skypager.config.dropbox_app_key
|
146
|
+
::Dropbox::API::Config.app_secret = Skypager.config.dropbox_app_secret
|
147
|
+
|
148
|
+
consumer = ::Dropbox::API::OAuth.consumer(:authorize)
|
149
|
+
request_token = consumer.get_request_token
|
150
|
+
puts "\nGo to this url and click 'Authorize' to get the token:"
|
151
|
+
puts request_token.authorize_url
|
152
|
+
Launchy.open(request_token.authorize_url)
|
153
|
+
|
154
|
+
query = request_token.authorize_url.split('?').last
|
155
|
+
params = CGI.parse(query)
|
156
|
+
token = params['oauth_token'].first
|
157
|
+
print "\nOnce you authorize the app on Dropbox, press enter... "
|
158
|
+
STDIN.gets.chomp
|
159
|
+
|
160
|
+
access_token = request_token.get_access_token(:oauth_verifier => token)
|
161
|
+
|
162
|
+
Skypager.config.set 'dropbox_client_token', access_token.token
|
163
|
+
Skypager.config.set 'dropbox_client_secret', access_token.secret
|
164
|
+
|
165
|
+
puts "\nAuthorization complete!:\n\n"
|
166
|
+
puts " Dropbox::API::Config.app_key = '#{consumer.key}'"
|
167
|
+
puts " Dropbox::API::Config.app_secret = '#{consumer.secret}'"
|
168
|
+
puts " client = Dropbox::API::Client.new(:token => '#{access_token.token}', :secret => '#{access_token.secret}')"
|
169
|
+
puts "\n"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|