skypager 0.0.2
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 +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
@@ -0,0 +1,32 @@
|
|
1
|
+
edit_spreadsheet_command = lambda do |c|
|
2
|
+
c.syntax = "skypager edit datasource NAME"
|
3
|
+
c.description = "Open up the data source editor"
|
4
|
+
|
5
|
+
c.action do |args, options|
|
6
|
+
require 'launchy'
|
7
|
+
require 'middleman-core'
|
8
|
+
|
9
|
+
name = args.first
|
10
|
+
|
11
|
+
if defined?(::Middleman)
|
12
|
+
app = ::Middleman::Application.server.inst do
|
13
|
+
set :environment, 'development'
|
14
|
+
end
|
15
|
+
|
16
|
+
if !name
|
17
|
+
names = app.data_sources.keys.map(&:to_s)
|
18
|
+
name = choose("Which data source?", *names)
|
19
|
+
end
|
20
|
+
|
21
|
+
source = app.data_sources[name.to_sym]
|
22
|
+
|
23
|
+
if source
|
24
|
+
Launchy.open(source.edit_url)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
command "edit data source" do |c|
|
31
|
+
edit_spreadsheet_command.call(c)
|
32
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
command 'list spreadsheets' do |c|
|
2
|
+
c.syntax = 'skypager list:spreadsheets [options]'
|
3
|
+
c.description = 'list available spreadsheets to use with skypager '
|
4
|
+
|
5
|
+
c.action do |_args, _options|
|
6
|
+
|
7
|
+
Skypager::Sync::Google.setup
|
8
|
+
Skypager::Sync.google.spreadsheets.map {|s| puts [s.key,s.title].join("\t\t") }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
command 'setup' do |c|
|
2
|
+
c.syntax = 'skypager setup [options]'
|
3
|
+
c.description = 'setup the integrations for skypager to work'
|
4
|
+
|
5
|
+
c.option '--skip-dropbox', nil, 'Skip dropbox setup'
|
6
|
+
c.option '--skip-google', nil, 'Skip google setup'
|
7
|
+
c.option '--skip-amazon', nil, 'Skip amazon setup'
|
8
|
+
c.option '--skip-dns', nil, 'Skip dns setup'
|
9
|
+
|
10
|
+
c.action do |args, options|
|
11
|
+
Skypager::Sync::Dropbox.setup unless options.skip_dropbox || Skypager.config.dropbox_setup?
|
12
|
+
Skypager::Sync::Google.setup unless options.skip_google || Skypager.config.google_setup?
|
13
|
+
Skypager::Sync::Amazon.setup unless options.skip_amazon || Skypager.config.amazon_setup?
|
14
|
+
|
15
|
+
require 'dnsimple'
|
16
|
+
Skypager.dns.setup unless options.skip_dns || Skypager.config.dnsimple_setup?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
command 'setup amazon' do |c|
|
21
|
+
c.syntax = 'skypager setup amazon [options]'
|
22
|
+
c.description = 'Setup amazon integration'
|
23
|
+
|
24
|
+
c.option '--access-key-id STRING', String, 'What is the AWS access key id?'
|
25
|
+
c.option '--secret-access-key STRING', String, 'What is the AWS secret access key?'
|
26
|
+
c.option '--create-bucket STRING', String, 'What is the bucket name?'
|
27
|
+
|
28
|
+
c.action do |args, options|
|
29
|
+
Skypager::Sync::Amazon.setup(access_key_id: options.access_key_id,
|
30
|
+
secret_access_key: options.secret_access_key)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
command 'setup deployment' do |c|
|
36
|
+
c.syntax = 'skypager setup deployment [options]'
|
37
|
+
c.description = 'Setup AWS deployment / hosting'
|
38
|
+
|
39
|
+
c.option '--access-key-id STRING', String, 'What is the AWS access key id?'
|
40
|
+
c.option '--secret-access-key STRING', String, 'What is the AWS secret access key?'
|
41
|
+
c.option '--create-bucket STRING', String, 'What is the bucket name?'
|
42
|
+
|
43
|
+
c.action do |args, options|
|
44
|
+
Skypager::Sync::Amazon.setup(access_key_id: options.access_key_id,
|
45
|
+
secret_access_key: options.secret_access_key)
|
46
|
+
|
47
|
+
|
48
|
+
app = Skypager.app
|
49
|
+
|
50
|
+
if !Skypager.config.dnsimple_setup?
|
51
|
+
if agree("Do you want to setup DNSimple integration?")
|
52
|
+
Skypager.dns.setup()
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
custom_domain = app.deploy_options[:custom_domain] || options.custom_domain || ask("Enter a custom domain name to deploy to. Leave blank if you don't want to use this.")
|
57
|
+
|
58
|
+
if custom_domain.to_s.length > 0
|
59
|
+
app.site.set :custom_domain, custom_domain
|
60
|
+
app.site.set :use_cdn, true
|
61
|
+
@custom_domain = custom_domain
|
62
|
+
end
|
63
|
+
|
64
|
+
unless @custom_domain || app.deploy_options[:use_cdn] == true
|
65
|
+
if agree("Do you want to use a CDN? Answer yes if you want to use a custom domain, or SSL for this site")
|
66
|
+
app.site.set :use_cdn, true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
bucket_name = app.deploy_options[:bucket_name] || options.create_bucket || ask("Enter a name for this bucket. Leave blank to use #{ app.site.name }.#{ Skypager.config.domain}")
|
71
|
+
bucket_name = app.site_name + "." + Skypager.config.domain if bucket_name.to_s.length == 0
|
72
|
+
|
73
|
+
if bucket_name
|
74
|
+
if bucket = Skypager.amazon.find_or_create_bucket(bucket_name)
|
75
|
+
app.site.set :bucket_key, bucket.key
|
76
|
+
app.site.set :bucket_name, bucket.key
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
config_path = Pathname(app.root).join("config.rb")
|
81
|
+
config_text = config_path.read rescue ""
|
82
|
+
|
83
|
+
app.site.after_setup
|
84
|
+
|
85
|
+
unless config_text.match(/deploy_to\(\:amazon/)
|
86
|
+
puts "Adding the following to your config.rb:\n\n\t#{ line = app.site.deploy_options_config_string }"
|
87
|
+
config_path.open("a+") {|fh| fh.write(line) }
|
88
|
+
end
|
89
|
+
|
90
|
+
site = app.site
|
91
|
+
|
92
|
+
puts "Site Info:"
|
93
|
+
puts "Bucket Name: #{ site.bucket_name }"
|
94
|
+
puts "Bucket URL: #{ site.bucket_url }"
|
95
|
+
puts "CDN URL: #{ site.cname_value }" if site.has_cdn?
|
96
|
+
puts "Custom Domain: #{ site.custom_domain }" if site.custom_domain?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
command 'setup dropbox' do |c|
|
101
|
+
c.syntax = 'skypager setup dropbox [options]'
|
102
|
+
c.description = 'Setup dropbox sync'
|
103
|
+
|
104
|
+
c.option '--app-key STRING', String, 'What is the dropbox app key?'
|
105
|
+
c.option '--app-secret STRING', String, 'What is the dropbox app secret?'
|
106
|
+
|
107
|
+
c.action do |args, options|
|
108
|
+
Skypager::Sync::Dropbox.setup(dropbox_app_key: options.app_key,
|
109
|
+
dropbox_app_secret: options.app_secret)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
command 'setup google' do |c|
|
114
|
+
c.syntax = 'skypager setup google [options]'
|
115
|
+
c.description = 'Setup google sync'
|
116
|
+
|
117
|
+
c.option '--client-id STRING', String, 'What is the google app client id?'
|
118
|
+
c.option '--client-secret STRING', String, 'What is the google app client secret?'
|
119
|
+
|
120
|
+
c.action do |args, options|
|
121
|
+
Skypager::Sync::Google.setup(client_id: options.client_id,
|
122
|
+
client_secret: options.client_secret)
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
command 'sync' do |c|
|
2
|
+
c.action do |args, options|
|
3
|
+
app = ::Middleman::Application.server.inst do
|
4
|
+
set :environment, 'development'
|
5
|
+
end
|
6
|
+
|
7
|
+
app.synced_folders.each do |name, folder|
|
8
|
+
puts "Syncing #{ name }"
|
9
|
+
folder.sync()
|
10
|
+
end
|
11
|
+
|
12
|
+
app.data_sources.each do |name, source|
|
13
|
+
source.refresh
|
14
|
+
source.save_to_disk unless source.persisted?
|
15
|
+
data.callbacks(name, -> { source.data })
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Skypager
|
5
|
+
class Configuration
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
DefaultSettings = {
|
9
|
+
github_username: '',
|
10
|
+
github_api_token: '',
|
11
|
+
|
12
|
+
dnsimple_api_token: '',
|
13
|
+
dnsimple_username: '',
|
14
|
+
|
15
|
+
dropbox_app_key: '',
|
16
|
+
dropbox_app_secret: '',
|
17
|
+
dropbox_app_type: 'sandbox',
|
18
|
+
dropbox_client_token: '',
|
19
|
+
dropbox_client_secret: '',
|
20
|
+
|
21
|
+
aws_access_key_id: '',
|
22
|
+
aws_secret_access_key: '',
|
23
|
+
|
24
|
+
google_client_id: '',
|
25
|
+
google_client_secret: '',
|
26
|
+
google_refresh_token: '',
|
27
|
+
google_access_token: '',
|
28
|
+
|
29
|
+
domain: "skypager.io",
|
30
|
+
|
31
|
+
sites_directory: { }
|
32
|
+
}
|
33
|
+
|
34
|
+
def self.method_missing(meth, *args, &block)
|
35
|
+
if instance.respond_to?(meth)
|
36
|
+
return instance.send meth, *args, &block
|
37
|
+
end
|
38
|
+
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def method_missing(meth, *args, &block)
|
43
|
+
if current.key?(meth.to_s)
|
44
|
+
return current.fetch(meth)
|
45
|
+
end
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def initialize!
|
51
|
+
FileUtils.mkdir_p home_config_path.dirname
|
52
|
+
end
|
53
|
+
|
54
|
+
def dnsimple_setup?
|
55
|
+
dnsimple_api_token.to_s.length > 0 && dnsimple_username.to_s.length > 0
|
56
|
+
end
|
57
|
+
|
58
|
+
def dropbox_setup?
|
59
|
+
dropbox_app_key.to_s.length > 0 && dropbox_app_secret.to_s.length > 0
|
60
|
+
end
|
61
|
+
|
62
|
+
def google_setup?
|
63
|
+
google_client_secret.to_s.length > 0 && google_client_id.to_s.length > 0
|
64
|
+
end
|
65
|
+
|
66
|
+
def amazon_setup?
|
67
|
+
aws_access_key_id.to_s.length > 0 && aws_secret_access_key.to_s.length > 0
|
68
|
+
end
|
69
|
+
|
70
|
+
def show
|
71
|
+
current.each do |p|
|
72
|
+
key, value = p
|
73
|
+
|
74
|
+
unless key == 'sites_directory'
|
75
|
+
puts "#{key}: #{ value.inspect }"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def current
|
81
|
+
@current ||= begin
|
82
|
+
home_config.merge(cwd_config)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def current_config
|
87
|
+
cwd_config_path.exist? ? cwd_config : home_config
|
88
|
+
end
|
89
|
+
|
90
|
+
def get(setting)
|
91
|
+
setting = setting.to_s.downcase
|
92
|
+
current_config[setting]
|
93
|
+
end
|
94
|
+
|
95
|
+
def set(setting, value, persist = true, options={})
|
96
|
+
setting = setting.to_s.downcase
|
97
|
+
cfg = options[:global] ? home_config : current_config
|
98
|
+
cfg[setting] = value
|
99
|
+
save! if persist == true
|
100
|
+
value
|
101
|
+
end
|
102
|
+
|
103
|
+
def unset(setting, persist = true)
|
104
|
+
current_config.delete(setting)
|
105
|
+
save! if persist == true
|
106
|
+
end
|
107
|
+
|
108
|
+
def current
|
109
|
+
defaults = DefaultSettings.dup
|
110
|
+
Hashie::Mash.new(defaults.merge(home_config.merge(cwd_config).merge(applied_config)))
|
111
|
+
end
|
112
|
+
|
113
|
+
def apply_config_from_path(path)
|
114
|
+
path = Pathname(path)
|
115
|
+
parsed = JSON.parse(path.read) rescue {}
|
116
|
+
applied_config.merge!(parsed)
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
120
|
+
def save!
|
121
|
+
save_home_config
|
122
|
+
save_cwd_config
|
123
|
+
end
|
124
|
+
|
125
|
+
def save_cwd_config
|
126
|
+
return nil unless cwd_config_path.exist?
|
127
|
+
|
128
|
+
File.open(cwd_config_path, 'w+') do |fh|
|
129
|
+
fh.write JSON.generate(cwd_config.to_hash)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def save_home_config
|
134
|
+
File.open(home_config_path, 'w+') do |fh|
|
135
|
+
fh.write JSON.generate(home_config.to_hash)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Applied config is configuration values passed in context
|
140
|
+
# usually from the cli, but also in the unit tests
|
141
|
+
def applied_config
|
142
|
+
@applied_config ||= {}
|
143
|
+
end
|
144
|
+
|
145
|
+
def cwd_config
|
146
|
+
@cwd_config ||= begin
|
147
|
+
(cwd_config_path.exist? rescue false) ? JSON.parse(cwd_config_path.read) : {}
|
148
|
+
rescue
|
149
|
+
{}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def home_config
|
154
|
+
@home_config ||= begin
|
155
|
+
(home_config_path.exist? rescue false) ? JSON.parse(home_config_path.read) : {}
|
156
|
+
rescue
|
157
|
+
{}
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def home_folder
|
162
|
+
Pathname(ENV['HOME']).join('.skypager')
|
163
|
+
end
|
164
|
+
|
165
|
+
def home_config_path
|
166
|
+
home_folder.join('config.json')
|
167
|
+
end
|
168
|
+
|
169
|
+
def cwd_config_path
|
170
|
+
Pathname(Dir.pwd).join('skypager.json')
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
module Skypager
|
2
|
+
module Data
|
3
|
+
class GoogleSpreadsheet < Source
|
4
|
+
|
5
|
+
requires :key
|
6
|
+
|
7
|
+
attr_accessor :key,
|
8
|
+
:session,
|
9
|
+
:name
|
10
|
+
|
11
|
+
def initialize name, options={}
|
12
|
+
@options = options
|
13
|
+
|
14
|
+
if name.is_a?(GoogleDrive::Spreadsheet)
|
15
|
+
@spreadsheet = name
|
16
|
+
@name = @spreadsheet.title
|
17
|
+
@key = @spreadsheet.key
|
18
|
+
end
|
19
|
+
|
20
|
+
@key ||= options[:key]
|
21
|
+
@session ||= options.fetch(:session) { Skypager::Sync.google.api }
|
22
|
+
|
23
|
+
ensure_valid_options!
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.create_from_file(path, title)
|
27
|
+
if find_by_title(title)
|
28
|
+
raise 'Spreadsheet with this title already exists'
|
29
|
+
end
|
30
|
+
|
31
|
+
session.upload_from_file(path, title, :content_type => "text/csv")
|
32
|
+
|
33
|
+
find_by_title(title)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.[](key_or_title)
|
37
|
+
find_by_key(key_or_title) || find_by_title(key_or_title)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.find_by_key(key)
|
41
|
+
sheet = session_spreadsheets.detect do |spreadsheet|
|
42
|
+
spreadsheet.key == key
|
43
|
+
end
|
44
|
+
|
45
|
+
sheet && new(sheet, session: Skypager.google.session)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.find_by_title title
|
49
|
+
sheet = session_spreadsheets.detect do |spreadsheet|
|
50
|
+
spreadsheet.title.match(title)
|
51
|
+
end
|
52
|
+
|
53
|
+
sheet && new(sheet, session: Skypager.google.session)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.session_spreadsheets
|
57
|
+
@session_spreadsheets ||= Skypager.google.api.spreadsheets
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.create_from_data(data, options={})
|
61
|
+
require 'csv'
|
62
|
+
|
63
|
+
headers = Array(options[:headers]).map(&:to_s)
|
64
|
+
|
65
|
+
tmpfile = "tmp-csv.csv"
|
66
|
+
|
67
|
+
CSV.open(tmpfile, "wb") do |csv|
|
68
|
+
csv << headers
|
69
|
+
|
70
|
+
data.each do |row|
|
71
|
+
csv << headers.map do |header|
|
72
|
+
row = row.stringify_keys
|
73
|
+
row[header.to_s]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
spreadsheet = Skypager::Sync.google.api.upload_from_file(tmpfile, options[:title], :content_type => "text/csv")
|
79
|
+
|
80
|
+
if options[:skypager_config_info]
|
81
|
+
config_line = "data_source :#{ spreadsheet.title.to_s.downcase.underscore }, :type => 'google', :key => '#{ spreadsheet.key }'\n"
|
82
|
+
|
83
|
+
puts "Adding the following line to your config.rb: \n #{config_line}"
|
84
|
+
|
85
|
+
File.open("config.rb", "a+") do |fh|
|
86
|
+
fh.write("\n")
|
87
|
+
fh.write(config_line)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
new(spreadsheet.title, key: spreadsheet.key)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def title
|
96
|
+
@name ||= spreadsheet.try(:title)
|
97
|
+
end
|
98
|
+
|
99
|
+
def edit_url
|
100
|
+
spreadsheet.human_url
|
101
|
+
end
|
102
|
+
|
103
|
+
def share_write_access_with *emails
|
104
|
+
acl = spreadsheet.acl
|
105
|
+
|
106
|
+
Array(emails).flatten.each do |email|
|
107
|
+
acl.push scope_type: "user",
|
108
|
+
with_key: false,
|
109
|
+
role: "writer",
|
110
|
+
scope: email
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def share_read_access_with *emails
|
115
|
+
acl = spreadsheet.acl
|
116
|
+
|
117
|
+
Array(emails).flatten.each do |email|
|
118
|
+
acl.push scope_type: "user",
|
119
|
+
with_key: false,
|
120
|
+
role: "reader",
|
121
|
+
scope: email
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def add_to_collection collection_title
|
126
|
+
collection = if collection_title.is_a?(GoogleDrive::Collection)
|
127
|
+
collection_title
|
128
|
+
else
|
129
|
+
session.collections.find do |c|
|
130
|
+
c.title == collection_title
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
if !collection
|
135
|
+
collection_names = session.collections.map(&:title)
|
136
|
+
raise 'Could not find collection in Google drive. Maybe you mean: ' + collection_names.join(', ')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def spreadsheet_key
|
141
|
+
key
|
142
|
+
end
|
143
|
+
|
144
|
+
def stale?
|
145
|
+
(!need_to_refresh? && (age > max_age)) || fresh_on_server?
|
146
|
+
end
|
147
|
+
|
148
|
+
def fresh_on_server?
|
149
|
+
refreshed_at.to_i > 0 && (last_updated_at > refreshed_at)
|
150
|
+
end
|
151
|
+
|
152
|
+
def last_updated_at
|
153
|
+
if value = spreadsheet.document_feed_entry.css('updated').try(:text) rescue nil
|
154
|
+
DateTime.parse(value).to_i
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def fetch
|
159
|
+
self.raw = process_worksheets
|
160
|
+
end
|
161
|
+
|
162
|
+
def preprocess
|
163
|
+
single? ? raw.values.flatten : raw
|
164
|
+
end
|
165
|
+
|
166
|
+
protected
|
167
|
+
|
168
|
+
def process_worksheets
|
169
|
+
worksheets.inject(Hashie::Mash.new) do |memo, parts|
|
170
|
+
k, ws = parts
|
171
|
+
header_row = Array(ws.rows[0])
|
172
|
+
column_names = header_row.map {|cell| "#{ cell }".parameterize.underscore }
|
173
|
+
rows = ws.rows.slice(1, ws.rows.length)
|
174
|
+
|
175
|
+
row_index = 1
|
176
|
+
memo[k] = rows.map do |row|
|
177
|
+
col_index = 0
|
178
|
+
|
179
|
+
_record = column_names.inject({}) do |record, field|
|
180
|
+
record[field] = "#{ row[col_index] }".strip
|
181
|
+
record["_id"] = row_index
|
182
|
+
col_index += 1
|
183
|
+
record
|
184
|
+
end
|
185
|
+
|
186
|
+
row_index += 1
|
187
|
+
|
188
|
+
_record
|
189
|
+
end
|
190
|
+
|
191
|
+
memo
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def single?
|
196
|
+
worksheets.length == 1
|
197
|
+
end
|
198
|
+
|
199
|
+
def header_rows_for_worksheet key
|
200
|
+
if key.is_a?(Fixnum)
|
201
|
+
_worksheets[key]
|
202
|
+
else
|
203
|
+
worksheets.fetch(key)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def worksheets
|
208
|
+
@worksheets ||= _worksheets.inject(Hashie::Mash.new) do |memo,ws|
|
209
|
+
key = ws.title.strip.downcase.underscore.gsub(/\s+/,'_')
|
210
|
+
memo[key] = ws
|
211
|
+
memo
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def _worksheets
|
216
|
+
@_worksheets ||= spreadsheet.worksheets
|
217
|
+
end
|
218
|
+
|
219
|
+
def spreadsheet
|
220
|
+
@spreadsheet ||= session.spreadsheet_by_key(spreadsheet_key)
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|