skypager 0.1.2 → 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.
- checksums.yaml +4 -4
- data/Rakefile +0 -11
- data/bin/skypager +16 -10
- data/lib/skypager.rb +1 -69
- data/lib/skypager/cli.rb +14 -0
- data/lib/skypager/cli/01_extensions.rb +25 -0
- data/lib/skypager/cli/config.rb +41 -0
- data/lib/skypager/proxy.rb +0 -10
- data/lib/skypager/version.rb +1 -1
- data/skypager.gemspec +1 -15
- metadata +9 -216
- data/ARCHITECTURE.md +0 -34
- data/CONTRIBUTING.md +0 -7
- data/LICENSE.txt +0 -22
- data/bin/bootstrap.sh +0 -29
- data/examples/.gitignore +0 -4
- data/examples/blog-site/.gitignore +0 -18
- data/examples/blog-site/.pryrc +0 -4
- data/examples/blog-site/Gemfile +0 -8
- data/examples/blog-site/config.rb +0 -17
- data/examples/blog-site/data/dropbox.json +0 -1
- 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 +0 -10
- data/examples/blog-site/source/javascripts/all.js +0 -1
- data/examples/blog-site/source/layouts/layout.erb +0 -19
- data/examples/blog-site/source/posts/introduction-to-skypager.html.md +0 -23
- data/examples/blog-site/source/posts/skypager-and-dnsimple-and-amazon-web-services-combo.html.md +0 -9
- data/examples/blog-site/source/stylesheets/all.css +0 -55
- data/examples/blog-site/source/stylesheets/normalize.css +0 -375
- data/examples/gallery-site/.gitignore +0 -18
- data/examples/gallery-site/.pryrc +0 -4
- data/examples/gallery-site/Gemfile +0 -11
- data/examples/gallery-site/config.rb +0 -38
- data/examples/gallery-site/data/dropbox.json +0 -1
- data/examples/gallery-site/data/galleries.json +0 -1
- data/examples/gallery-site/source/gallery.html.erb +0 -7
- 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 +0 -10
- data/examples/gallery-site/source/javascripts/all.js +0 -1
- data/examples/gallery-site/source/layouts/layout.erb +0 -20
- data/examples/gallery-site/source/stylesheets/all.css +0 -0
- data/examples/gallery-site/source/stylesheets/normalize.css +0 -375
- data/examples/gallery-site/source/tutorial.md +0 -151
- data/lib/skypager/builder.rb +0 -158
- data/lib/skypager/cli/commands/build.rb +0 -64
- data/lib/skypager/cli/commands/config.rb +0 -58
- data/lib/skypager/cli/commands/create.rb +0 -98
- data/lib/skypager/cli/commands/deploy.rb +0 -62
- data/lib/skypager/cli/commands/edit.rb +0 -32
- data/lib/skypager/cli/commands/list.rb +0 -12
- data/lib/skypager/cli/commands/setup.rb +0 -153
- data/lib/skypager/cli/commands/site.rb +0 -22
- data/lib/skypager/cli/commands/sync.rb +0 -20
- data/lib/skypager/data.rb +0 -8
- data/lib/skypager/data/excel_spreadsheet.rb +0 -8
- data/lib/skypager/data/google_spreadsheet.rb +0 -227
- data/lib/skypager/data/request.rb +0 -12
- data/lib/skypager/data/source.rb +0 -194
- data/lib/skypager/data/source_routes_proxy.rb +0 -30
- data/lib/skypager/dns.rb +0 -69
- data/lib/skypager/extension.rb +0 -271
- 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/sync.rb +0 -23
- data/lib/skypager/sync/amazon.rb +0 -181
- data/lib/skypager/sync/dropbox.rb +0 -173
- data/lib/skypager/sync/dropbox/delta.rb +0 -67
- data/lib/skypager/sync/folder.rb +0 -266
- data/lib/skypager/sync/github.rb +0 -55
- data/lib/skypager/sync/google.rb +0 -143
- data/spec/dummy/site-one/.gitignore +0 -18
- data/spec/dummy/site-one/Gemfile +0 -14
- data/spec/dummy/site-one/config.rb +0 -13
- data/spec/dummy/site-one/source/images/background.png +0 -0
- data/spec/dummy/site-one/source/images/middleman.png +0 -0
- data/spec/dummy/site-one/source/index.html.erb +0 -10
- data/spec/dummy/site-one/source/javascripts/all.js +0 -1
- data/spec/dummy/site-one/source/layouts/layout.erb +0 -19
- data/spec/dummy/site-one/source/stylesheets/all.css +0 -55
- data/spec/dummy/site-one/source/stylesheets/normalize.css +0 -375
- data/spec/lib/skypager/builder/server_spec.rb +0 -5
- data/spec/lib/skypager/configuration_spec.rb +0 -12
- data/spec/lib/skypager/data_spec.rb +0 -5
- data/spec/lib/skypager/site_spec.rb +0 -44
- data/spec/lib/skypager_spec.rb +0 -9
- data/spec/skypager-test-config.rb.example +0 -22
- data/spec/spec_helper.rb +0 -49
- data/spec/support/fixtures/cwd_config.json +0 -3
- data/spec/support/fixtures/home_config.json +0 -1
- data/spec/support/json_helper.rb +0 -7
data/lib/skypager/data/source.rb
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
module Skypager
|
|
2
|
-
module Data
|
|
3
|
-
class Source
|
|
4
|
-
attr_reader :options, :name
|
|
5
|
-
attr_accessor :raw, :processed, :format, :scopes, :slug_column, :refreshed_at, :path
|
|
6
|
-
|
|
7
|
-
class << self
|
|
8
|
-
attr_accessor :required_options
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.requires *args
|
|
12
|
-
self.required_options = args
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def initialize(name, options={})
|
|
16
|
-
@name ||= name
|
|
17
|
-
@options ||= options
|
|
18
|
-
@format ||= options.fetch(:format, :json)
|
|
19
|
-
@path ||= options.fetch(:path) { Pathname(Dir.pwd()) }
|
|
20
|
-
|
|
21
|
-
@slug_column = options.fetch(:slug_column, :_id)
|
|
22
|
-
|
|
23
|
-
ensure_valid_options!
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def to_s
|
|
27
|
-
data.to_json
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# defines a scope for the records in this data source
|
|
31
|
-
# a scope is a named filter, implemented in the form of a block
|
|
32
|
-
# which is passed each record. if the block returns true, it returns
|
|
33
|
-
# the record:
|
|
34
|
-
#
|
|
35
|
-
# Example:
|
|
36
|
-
#
|
|
37
|
-
# data_source(:galleries) do
|
|
38
|
-
# scope :active, -> {|record| record.state == "active" }
|
|
39
|
-
# end
|
|
40
|
-
def scope(*args, block)
|
|
41
|
-
name = args.first
|
|
42
|
-
(self.scopes ||= {})[name.to_sym] = block
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def has_scope?(scope_name)
|
|
46
|
-
scope_name && (self.scopes ||= {}).key?(scope_name.to_sym)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# compute properties takes the raw data of each record
|
|
50
|
-
# and sets additional properties on the records which may
|
|
51
|
-
# not be persited in the data source
|
|
52
|
-
def compute_properties
|
|
53
|
-
self.processed && self.processed.map! do |row|
|
|
54
|
-
if slug_column && row.respond_to?(slug_column)
|
|
55
|
-
row.slug = row.send(slug_column).to_s.parameterize
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
row
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
processors.each do |processor|
|
|
62
|
-
original = self.processed.dup
|
|
63
|
-
modified = []
|
|
64
|
-
|
|
65
|
-
original.each_with_index do |record, index|
|
|
66
|
-
previous = original[index - 1]
|
|
67
|
-
modified.push(processor.call(record, index, previous: previous, set: original))
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
self.processed = modified
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def processors &block
|
|
75
|
-
@processors ||= []
|
|
76
|
-
@processors << block if block_given?
|
|
77
|
-
@processors
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# makes sure that the required options for this data source
|
|
81
|
-
# are passed for any instance of the data source
|
|
82
|
-
def ensure_valid_options!
|
|
83
|
-
missing_options = (Array(self.class.required_options) - options.keys.map(&:to_sym))
|
|
84
|
-
|
|
85
|
-
missing_options.reject! do |key|
|
|
86
|
-
respond_to?(key) && send(key).present?
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
if missing_options.length > 0
|
|
90
|
-
raise 'Error: failure to supply the following options:' + missing_options.map(&:to_s).join(",")
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def select(&block)
|
|
95
|
-
data.select(&block)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def refresh
|
|
99
|
-
fetch
|
|
100
|
-
process
|
|
101
|
-
self.refreshed_at = Time.now.to_i
|
|
102
|
-
self
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def refresh_if_stale?
|
|
106
|
-
refresh! if stale?
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# A data source is stale if it has been populated
|
|
110
|
-
# and the age is greater than the max age we allow.
|
|
111
|
-
def stale?
|
|
112
|
-
!need_to_refresh? && (age > max_age)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def fresh_on_server?
|
|
116
|
-
need_to_refresh?
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def max_age
|
|
120
|
-
max = ENV['MAX_DATA_SOURCE_AGE']
|
|
121
|
-
(max && max.to_i) || 120
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# how long since this data source has been refreshed?
|
|
125
|
-
def age
|
|
126
|
-
Time.now.to_i - refreshed_at.to_i
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def data
|
|
130
|
-
refresh if need_to_refresh?
|
|
131
|
-
processed
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def refresh!
|
|
135
|
-
refresh
|
|
136
|
-
save_to_disk
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def need_to_refresh?
|
|
140
|
-
!(@fetched && @_processed)
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def fetch
|
|
144
|
-
@fetched = true
|
|
145
|
-
self.raw = []
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def preprocess
|
|
149
|
-
self.raw.dup
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def process
|
|
153
|
-
@_processed = true
|
|
154
|
-
self.processed = preprocess
|
|
155
|
-
# set_id
|
|
156
|
-
compute_properties
|
|
157
|
-
self.processed
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def refreshed_at
|
|
161
|
-
return @refreshed_at if @refreshed_at.to_i > 0
|
|
162
|
-
|
|
163
|
-
if path_to_file.exist?
|
|
164
|
-
@refreshed_at = File.mtime(path.join(file)).to_i
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def save_to_disk
|
|
169
|
-
unless path_to_file.dirname.exist?
|
|
170
|
-
FileUtils.mkdir(path_to_file.dirname)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
path_to_file.open('w+') {|fh| fh.write(to_s) }
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def persisted?
|
|
177
|
-
path_to_file && path_to_file.exist?
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def file
|
|
181
|
-
@file ||= name.parameterize if name.respond_to?(:parameterize)
|
|
182
|
-
@file.gsub!("-","_")
|
|
183
|
-
@file = "#{@file}.json" unless @file.match(/\.json/i)
|
|
184
|
-
@file
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def path_to_file
|
|
188
|
-
Pathname(path).join("#{ file }")
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
require 'uri_template'
|
|
2
|
-
|
|
3
|
-
module Skypager
|
|
4
|
-
module Data
|
|
5
|
-
class SourceRoutesProxy
|
|
6
|
-
def initialize(app, data_source, options={})
|
|
7
|
-
template = URITemplate.new(:colon, options[:url])
|
|
8
|
-
|
|
9
|
-
data = data_source.data
|
|
10
|
-
|
|
11
|
-
# If we're passed a scope that means we should
|
|
12
|
-
# limit the set of records we are mapping to by the
|
|
13
|
-
# scope defined in this data source
|
|
14
|
-
if options[:scope]
|
|
15
|
-
tester = data_source.scopes[options[:scope]]
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
to = options[:template] || options[:to]
|
|
19
|
-
|
|
20
|
-
as = options.fetch(:as, :current_record)
|
|
21
|
-
|
|
22
|
-
data.each do |row|
|
|
23
|
-
url = template.expand(row.to_hash)
|
|
24
|
-
app.proxy(url, to, :locals => {as => row}, :ignore => true)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
data/lib/skypager/dns.rb
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
module Skypager::DNS
|
|
2
|
-
class Manager
|
|
3
|
-
include Singleton
|
|
4
|
-
|
|
5
|
-
def self.method_missing(meth, *args, &block)
|
|
6
|
-
if client.respond_to?(meth)
|
|
7
|
-
client.send(meth, *args, &block)
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.client
|
|
12
|
-
instance.tap {|i| i.authorize }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def setup(options={})
|
|
16
|
-
unless Skypager.config.dnsimple_api_token
|
|
17
|
-
if dnsimple_api_token = options.fetch(:dnsimple_api_token) { ask("What is the DNSimple API Token?", String) }
|
|
18
|
-
Skypager.config.set 'dnsimple_api_token', dnsimple_api_token
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
unless Skypager.config.dnsimple_username
|
|
23
|
-
if dnsimple_username = options.fetch(:dnsimple_username) { ask("What is the DNSimple Username or email?", String) }
|
|
24
|
-
Skypager.config.set 'dnsimple_username', dnsimple_username
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def authorize
|
|
30
|
-
@authorized ||= begin
|
|
31
|
-
DNSimple::Client.api_token = Skypager.config.dnsimple_api_token
|
|
32
|
-
DNSimple::Client.username = Skypager.config.dnsimple_username
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def domain
|
|
37
|
-
parent_domain
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def parent_domain
|
|
41
|
-
@parent_domain ||= DNSimple::Domain.find(Skypager.config.domain)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def domain_records
|
|
45
|
-
DNSimple::Record.all(parent_domain)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def cname_records
|
|
49
|
-
domain_records.select do |record|
|
|
50
|
-
record.record_type == "CNAME"
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def deployment_alias_records
|
|
55
|
-
cname_records.select do |record|
|
|
56
|
-
record.content.include? "s3-website-us-east-1.amazonaws.com"
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Used to link up a skypager internal site to an S3 Bucket
|
|
61
|
-
def setup_cname internal_name, external_host
|
|
62
|
-
authorize
|
|
63
|
-
|
|
64
|
-
unless cname_records.find {|r| r.name == internal_name }
|
|
65
|
-
DNSimple::Record.create(parent_domain, internal_name, 'CNAME', external_host)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
data/lib/skypager/extension.rb
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
require 'middleman-core' unless defined?(::Middleman)
|
|
2
|
-
|
|
3
|
-
module Skypager
|
|
4
|
-
class Extension < ::Middleman::Extension
|
|
5
|
-
|
|
6
|
-
option :site_name, nil, 'The name of this site'
|
|
7
|
-
option :synced_folders, {}, 'The settings for dropbox source syncing'
|
|
8
|
-
option :data_sources, [], 'The data source mappings for this site'
|
|
9
|
-
option :deploy_options, {}, 'Deploy options: domain, bucket_name, use_cdn, aliases, auto_deploy'
|
|
10
|
-
option :skypager, {}, 'Options to be passed to Skypager.config'
|
|
11
|
-
|
|
12
|
-
def initialize(app, options_hash={}, &block)
|
|
13
|
-
# if only skypager/extension is required this will be necessary
|
|
14
|
-
require 'skypager' unless defined?(Skypager::Data)
|
|
15
|
-
|
|
16
|
-
super
|
|
17
|
-
|
|
18
|
-
app.include(ClassMethods)
|
|
19
|
-
|
|
20
|
-
options_hash.reverse_merge!(:data_sources => {}.to_mash,
|
|
21
|
-
:synced_folders => {}.to_mash,
|
|
22
|
-
:deploy_options => {}.to_mash,
|
|
23
|
-
:site_name => File.basename(app.root))
|
|
24
|
-
|
|
25
|
-
options_hash.each do |key, value|
|
|
26
|
-
app.set(key, value)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
unless ($skypager_command || ENV['DISABLE_SKYPAGER_SYNC']) && !$enable_skypager_sync_from_command
|
|
30
|
-
app.ready do
|
|
31
|
-
sync_folders()
|
|
32
|
-
load_stores()
|
|
33
|
-
# Load the data source and save it to disk
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# In development, we will try to refresh remote data stores (e.g. google spreadsheets)
|
|
37
|
-
# before every request once every minute or so
|
|
38
|
-
app.before do
|
|
39
|
-
if !Skypager.config.dropbox_setup? && !Skypager.config.google_setup? && !Skypager.config.amazon_setup?
|
|
40
|
-
puts "\n\n== Use Skypager's one time setup script to automate huge parts of your workflow!"
|
|
41
|
-
puts "Run 'skypager setup' now"
|
|
42
|
-
puts "\n\n\n"
|
|
43
|
-
raise 'Run skypager setup first'
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
data_sources.values.each do |data_source|
|
|
47
|
-
data_source.refresh_if_stale?
|
|
48
|
-
end if development?
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
app.before_configuration do
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
app.after_build do
|
|
56
|
-
site.requires_build!(false)
|
|
57
|
-
deploy! if auto_deploy?
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
app.after_configuration do
|
|
61
|
-
save_site_config()
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
helpers do
|
|
67
|
-
def deploy!
|
|
68
|
-
site.deploy(build_path)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def auto_deploy?
|
|
72
|
-
!!deploy_options[:auto_deploy]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def save_site_config
|
|
76
|
-
syncable_config = site.config.syncables ||= {}.to_mash
|
|
77
|
-
|
|
78
|
-
syncables.each do |folder|
|
|
79
|
-
type = folder.type
|
|
80
|
-
cfg = syncable_config[type] ||= {}.to_mash
|
|
81
|
-
cfg.paths ||= []
|
|
82
|
-
cfg.paths.push(syncable.remote_path.to_s)
|
|
83
|
-
cfg.paths.uniq!
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
if Skypager.config.dropbox_setup?
|
|
87
|
-
syncable_config.dropbox ||= {}
|
|
88
|
-
syncable_config.dropbox.uid = Skypager.dropbox.account.uid
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
site.set(:syncables, syncable_config)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def site
|
|
95
|
-
return @site if @site
|
|
96
|
-
|
|
97
|
-
@site = Skypager::Site.new(site_name, deploy_options: deploy_options).tap do |site|
|
|
98
|
-
site.load_config
|
|
99
|
-
site.set(:deploy_options, deploy_options)
|
|
100
|
-
site.set(:root, root) unless site.config.key?(:root)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
module ClassMethods
|
|
106
|
-
def build_path
|
|
107
|
-
Pathname(build_dir)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def data_path
|
|
111
|
-
Pathname(data_dir)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def source_path
|
|
115
|
-
Pathname(source_dir)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def deploy_to(provider, options={})
|
|
119
|
-
self.deploy_options ||= {}
|
|
120
|
-
|
|
121
|
-
self.deploy_options[:auto_deploy] = !!options[:auto_deploy]
|
|
122
|
-
|
|
123
|
-
if provider == :amazon || provider == :aws
|
|
124
|
-
self.deploy_options[:domain] = options[:domain] || Skypager.config.domain
|
|
125
|
-
self.deploy_options[:bucket_name] = options[:bucket_name] || "#{ site_name }.#{ deploy_options[:domain] }"
|
|
126
|
-
self.deploy_options[:custom_domain] = options[:custom_domain]
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def dropbox_sync(*args)
|
|
131
|
-
folder = args.first
|
|
132
|
-
options = args.extract_options!
|
|
133
|
-
|
|
134
|
-
local_path = folder
|
|
135
|
-
remote_path ||= options[:to] || options[:with] || args[1] || local_path
|
|
136
|
-
|
|
137
|
-
dropbox_data[:folders] ||= {}
|
|
138
|
-
|
|
139
|
-
f = dropbox_data[:folders][folder] ||= {
|
|
140
|
-
remote_path: remote_path,
|
|
141
|
-
local_path: local_path,
|
|
142
|
-
type: "dropbox",
|
|
143
|
-
cursor: nil,
|
|
144
|
-
site_name: site_name,
|
|
145
|
-
folder: folder
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
dropbox_data[:folders][folder].merge!(options)
|
|
149
|
-
|
|
150
|
-
self.synced_folders[folder] = Skypager::Sync::Folder.new(f.merge(app: self, root:Pathname(root)))
|
|
151
|
-
|
|
152
|
-
save_dropbox_settings
|
|
153
|
-
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def app
|
|
157
|
-
self
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def stores
|
|
161
|
-
data_sources.values
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def load_stores persist=false
|
|
165
|
-
data_sources.each do |name, source|
|
|
166
|
-
source.refresh
|
|
167
|
-
source.save_to_disk if persist || !source.persisted?
|
|
168
|
-
data.callbacks(name, -> { source.data })
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
after_stores_loaded.each do |callback|
|
|
172
|
-
callback = app.method(callback) if callback.is_a?(Symbol)
|
|
173
|
-
app.instance_eval(&callback) if callback.respond_to?(:call)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# middleman does have an event system, we can piggyback on that instead
|
|
178
|
-
def after_stores_loaded &block
|
|
179
|
-
@after_stores_callbacks ||= []
|
|
180
|
-
@after_stores_callbacks << block if block_given?
|
|
181
|
-
@after_stores_callbacks
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def sync_folders
|
|
185
|
-
syncables.each(&:sync)
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def syncables
|
|
189
|
-
@syncables ||= Array(synced_folders.values)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def syncable
|
|
193
|
-
syncables.first
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def save_dropbox_settings
|
|
197
|
-
json = dropbox_data.to_json
|
|
198
|
-
dropbox_data_file.open('w+') {|fh| fh.write(json) }
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def dropbox_data
|
|
202
|
-
unless Pathname(data_dir).exist?
|
|
203
|
-
FileUtils.mkdir_p Pathname(data_dir)
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
@dropbox_data ||= begin
|
|
207
|
-
JSON.parse(dropbox_data_file.read).to_mash
|
|
208
|
-
rescue
|
|
209
|
-
{}.to_mash
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def dropbox_data_file
|
|
214
|
-
Pathname(data_dir).join('dropbox.json').tap do |path|
|
|
215
|
-
unless path.exist?
|
|
216
|
-
path.open('w+') {|fh| fh.write("{}") }
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def google_spreadsheets
|
|
222
|
-
Skypager::Data::GoogleSpreadsheet
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def map_data_source(name, *args)
|
|
226
|
-
options = args.extract_options!
|
|
227
|
-
options[:data_source] = name
|
|
228
|
-
scope = options[:scope] = args.first
|
|
229
|
-
|
|
230
|
-
_data_source = data_sources[name]
|
|
231
|
-
|
|
232
|
-
if !_data_source
|
|
233
|
-
raise "Could not find a data source named #{ name }"
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
if scope && !_data_source.has_scope?(scope)
|
|
237
|
-
raise "Invalid scope for #{name} data source"
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
Skypager::Data::SourceRoutesProxy.new(self, _data_source, options)
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def data_source(name, options=nil, &block)
|
|
244
|
-
if options.nil? && !block_given? && self.data_sources[name.to_sym]
|
|
245
|
-
return self.data_sources[name.to_sym]
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
source = case
|
|
249
|
-
when options[:type].to_s == "google"
|
|
250
|
-
unless existing = google_spreadsheets[options[:key] || options[:title]]
|
|
251
|
-
raise 'Could not find a spreadsheet. You can use the `skypager list spreadsheets` command to find the right one, or the `skypager create data source` command to create a new one.'
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
existing
|
|
255
|
-
when options[:type].to_s == "excel"
|
|
256
|
-
|
|
257
|
-
when options[:type].to_s == "request"
|
|
258
|
-
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
(self.data_sources[name.to_sym] = source).tap do |ds|
|
|
262
|
-
ds.instance_eval(&block) if block.respond_to?(:call)
|
|
263
|
-
ds.slug_column = (options[:slug] || options[:slug_column]) if (options[:slug] || options[:slug_column])
|
|
264
|
-
ds.path ||= Pathname(root).join(data_dir)
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
::Middleman::Extensions.register(:skypager, Skypager::Extension)
|