nationsync 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9c13ca136a215a8c64a08eae32b04004d90938d4
4
+ data.tar.gz: 1b58076f4c5711f82c127505ad14958195584527
5
+ SHA512:
6
+ metadata.gz: 873b683127d8273faa4804929d9f0e31f8abf3fc056229572995e9c032102589da8eb327cd863edcb022240471777ed85a3190d941a6ca90791b1dfb050993ea
7
+ data.tar.gz: dbb78f5a8eae45052789309876558927e5aa9c4e91e4998c483057303e48084056cc4839b016e3e3a0a6bdb1edaea9d8bb13473cd3b82a8e814b5da61aead92e
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nationsync.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Dirk Gadsden
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Nationsync
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'nationsync'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install nationsync
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/nationsync ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ $:.unshift File.dirname(__FILE__) + '/../lib'
5
+ require 'nationsync/commander'
6
+
@@ -0,0 +1,76 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'rack'
4
+
5
+ module NationSync
6
+
7
+ class API
8
+ # include HTTParty
9
+ @@endpoint = "https://.nationbuilder.com"
10
+
11
+ def initialize(domain, access_token, session_cookie)
12
+ @access_token = access_token
13
+ @session_cookie = session_cookie
14
+
15
+ @conn = Faraday.new(:url => "https://#{domain}.nationbuilder.com") do |faraday|
16
+ faraday.adapter(Faraday.default_adapter)
17
+ faraday.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
18
+ end
19
+ @conn.headers['Cookie'] = "_nbuild_session=#{@session_cookie}"
20
+ @conn.params["access_token"] = @access_token
21
+ end
22
+
23
+ def sites
24
+ @conn.get("/admin/theme_tool_api/sites").body["sites"]
25
+ end
26
+
27
+ def themes
28
+ @conn.get("/admin/theme_tool_api/themes").body["themes"]
29
+ end
30
+ def theme_assets(theme_id)
31
+ @conn.get("/admin/theme_tool_api/themes/#{theme_id}/assets.json").body["assets"]
32
+ end
33
+
34
+ def pages
35
+ @conn.get("/admin/theme_tool_api/pages.json").body["pages"]
36
+ end
37
+
38
+ def theme_asset_put(theme_id, fn, value)
39
+ @conn.put do |req|
40
+ req.url "/admin/theme_tool_api/themes/#{theme_id}/assets.json"
41
+ req.params = {}
42
+ # req.body = JSON.dump({
43
+ req.body = Rack::Utils.build_nested_query({
44
+ "access_token" => @access_token,
45
+ "asset" => {
46
+ "key" => fn,
47
+ "value" => value
48
+ }
49
+ })
50
+ end
51
+ # data: {
52
+ # access_token: nation.get("accessToken"),
53
+ # asset: {
54
+ # key: file.filename,
55
+ # value: value,
56
+ # attachment: attachment
57
+ # }
58
+ # },
59
+ end
60
+ def theme_asset_put_attachment(theme_id, fn, value)
61
+ @conn.put do |req|
62
+ req.url "/admin/theme_tool_api/themes/#{theme_id}/assets.json"
63
+ req.params = {}
64
+ req.body = Rack::Utils.build_nested_query({
65
+ "access_token" => @access_token,
66
+ "asset" => {
67
+ "key" => fn,
68
+ "attachment" => Base64.encode64(value)
69
+ }
70
+ })
71
+ end
72
+ end
73
+
74
+
75
+ end#API
76
+ end#NationSync
@@ -0,0 +1,51 @@
1
+ require 'mechanize'
2
+ require 'httparty'
3
+
4
+ module NationSync
5
+ class Auth
6
+ attr_reader :access_token, :session_id
7
+ attr_accessor :domain, :email, :password
8
+
9
+ def initialize(domain, email, password)
10
+ @domain = domain
11
+ @email = email
12
+ @password = password
13
+ end
14
+
15
+ def authenticate!
16
+ agent = Mechanize.new
17
+ # Disallow redirect
18
+ agent.redirect_ok = false
19
+
20
+ page = agent.get("https://#{@domain}.nationbuilder.com/admin/theme_tool_api/auth")
21
+
22
+ signin = page.forms.select {|f| f.action == "/admin/theme_tool_api/auth" }.first
23
+ email = signin.field "user_session[email]"
24
+ password = signin.field "user_session[password]"
25
+
26
+ email.value = @email
27
+ password.value = @password
28
+
29
+ # Submit the form
30
+ resp = signin.submit()
31
+ # Returns a redirect we have to follow to finish up the authorization.
32
+ auth = agent.get resp.header["Location"]
33
+ # Following the auth redirect we get another redirect to:
34
+ # app://com.nationbuildertheme/index.html?code=[blah]"
35
+ redirect = auth.header["Location"]
36
+ # Extract the code from the redirect
37
+ code = redirect.match(/code=([a-f0-9]+)/)[1]
38
+ # And then exchange the code for an access_token.
39
+ resp = HTTParty.get "https://southforward.nationbuilder.com/admin/theme_tool_api/exchange?code=#{code}"
40
+ body = JSON.parse(resp.body)
41
+ @access_token = body["access_token"]
42
+ #puts "access_token: #{access_token}"
43
+ # Also grab the session ID since we need that.
44
+ @session_id = agent.cookie_jar.select {|c| c.name == "_nbuild_session" }.first.value
45
+ #puts "session_id: (_nbuild_session) #{session_id}"
46
+ return true
47
+ end
48
+
49
+
50
+ end#API
51
+ end#NationSync
@@ -0,0 +1,184 @@
1
+ require 'nationsync'
2
+ require 'listen'
3
+ require 'thor'
4
+ require 'highline'
5
+ require 'pp'
6
+
7
+ class NationSyncThor < Thor
8
+ HL = HighLine.new
9
+
10
+ no_commands do
11
+ def load_project_file
12
+
13
+ end
14
+ def cwd
15
+ Dir.pwd
16
+ end
17
+ def setup_config
18
+ return if @config
19
+ @config = YAML.load_file(File.join(cwd, '.nbconfig1'))
20
+ @domain = @config["domain"]
21
+ @access_token = @config["access_token"]
22
+ @session_id = @config["session_id"]
23
+ end
24
+ def setup_api
25
+ return if @api
26
+ @api = NationSync::API.new(@domain, @access_token, @session_id)
27
+ end
28
+ def save_config!
29
+ fn = File.join(cwd, '.nbconfig1')
30
+ File.open(fn, 'w') { |f| YAML.dump(@config, f) }
31
+ end
32
+ end#/no_commands
33
+
34
+ desc "init", "Initialize a theme in this directory"
35
+ def init
36
+ puts "Creating .nbconfig1"
37
+ domain = HL.ask("Domain: ").to_s
38
+ email = HL.ask("Email: ").to_s
39
+ password = HL.ask("Password: ") {|q| q.echo = false }.to_s
40
+
41
+ print "Fetching credentials..."
42
+ auth = NationSync::Auth.new(domain, email, password)
43
+ auth.authenticate!
44
+ puts " Done"
45
+
46
+ @config = {
47
+ "domain" => domain,
48
+ "email" => email,
49
+ "access_token" => auth.access_token,
50
+ "session_id" => auth.session_id
51
+ }
52
+ save_config!
53
+ puts "Created: #{fn}"
54
+ end
55
+
56
+ desc "watch", "Watch current directory for changes"
57
+ def watch
58
+ setup_config
59
+ setup_api
60
+ unless @config["asset_keys"]
61
+ puts "Please run `nationsync fetch` to get an up-to-date asset list."
62
+ return
63
+ end
64
+ listener = Listen.to(Dir.getwd) do |modified, added, removed|
65
+ modified.each do |path|
66
+ fn = File.basename(path)
67
+ if !@config["asset_keys"].include?(fn)
68
+ puts "- Skipping #{fn}"
69
+ end
70
+ type = MIME::Types.type_for(fn).first
71
+ if type.binary?
72
+ resp = @api.theme_asset_put_attachment(@config["theme_id"], fn, File.read(path))
73
+ else
74
+ resp = @api.theme_asset_put(@config["theme_id"], fn, File.read(path))
75
+ end
76
+
77
+ if resp.status == 200
78
+ if resp.body["success"].to_s == "true"
79
+ puts "- Updated #{fn}" + (type.binary? ? " (binary)" : "")
80
+ else
81
+ puts "- #{HL.color("Error", :red) } updating #{fn}:"
82
+ errors = resp.body["errors"]
83
+ if errors.is_a? Array
84
+ errors.each {|e| puts " #{e}"}
85
+ else
86
+ puts " #{errors.to_s}"
87
+ end
88
+ end
89
+ else
90
+ puts "- #{HL.color("Error", :red) } updating #{fn}:"
91
+ puts " #{resp.body.to_s}"
92
+ end
93
+ end
94
+ added.each do |path|
95
+ fn = File.basename(path)
96
+ puts "- #{HL.color("Warning:", :red)} File addition not supported yet (#{fn})"
97
+ end
98
+ removed.each do |path|
99
+ fn = File.basename(path)
100
+ puts "- #{HL.color("Warning:", :red)} File deletion not supported yet (#{fn})"
101
+ end
102
+ end#listener
103
+ listener.start
104
+ puts "Listening for changes in #{Dir.getwd}"
105
+ sleep
106
+ end#watch
107
+
108
+ desc "clear", "Removes asset files according to manifest in .nbconfig1"
109
+ def clear
110
+ setup_config
111
+ setup_api
112
+ unless @config["asset_keys"]
113
+ puts "Please run `nationsync fetch` to get an up-to-date asset list."
114
+ return
115
+ end
116
+ print "Removing #{@config["asset_keys"].length.to_s} files..."
117
+ @config["asset_keys"].each do |fn|
118
+ File.delete(File.join(cwd, fn))
119
+ end
120
+ @config.delete "asset_keys"
121
+ save_config!
122
+ puts " Done"
123
+ end
124
+
125
+ desc "fetch", "Fetch files"
126
+ def fetch
127
+ setup_config
128
+ setup_api
129
+ unless @config["theme_id"]
130
+ self.pick_theme
131
+ end
132
+ print "Fetching assets for theme #{@config["theme_id"]}..."
133
+ assets = @api.theme_assets(@config["theme_id"])
134
+ puts " Done"
135
+ # if (window.is_binary(file_path)) {
136
+ # attachment = Ti.Codec.encodeBase64(content);
137
+ # } else {
138
+ # value = content.toString();
139
+ # }
140
+ print "Writing files..."
141
+ assets.each do |a|
142
+ # puts "#{a["key"]}: #{a.keys.inspect}"
143
+ fn = a["key"]
144
+ data = a["value"]
145
+ if a["attachment"]
146
+ data = Base64.decode64(a["attachment"])
147
+ end
148
+ File.open(File.join(cwd, fn), 'w') {|f| f.write data }
149
+ end
150
+ puts " Done. (#{assets.length.to_s} Assets)"
151
+ @config["asset_keys"] = assets.map {|a| a["key"] }
152
+ save_config!
153
+ end
154
+
155
+ desc "pick_theme", "Pick theme"
156
+ def pick_theme
157
+ setup_config
158
+ setup_api
159
+ print "Fetching themes for selection..."
160
+ themes = @api.themes
161
+ puts " Done"
162
+ # pp themes
163
+
164
+ id = HL.choose do |m|
165
+ m.prompt = "Select a theme: "
166
+
167
+ themes.each do |t|
168
+ # m.choice(t["id"])
169
+ s = t["name"] + HL.color(" (#{t["id"]})", :gray)
170
+ unless t["sites"].to_s.empty?
171
+ s += "\n (Site: " + t["sites"].to_s + ")"
172
+ end
173
+ m.choice(s) { t["id"] }
174
+ end
175
+ end
176
+ @config["theme_id"] = id
177
+ save_config!
178
+ puts "Using theme #{id}"
179
+ end
180
+
181
+
182
+ end#NationSyncThor
183
+
184
+ NationSyncThor.start
data/lib/nationsync.rb ADDED
@@ -0,0 +1,6 @@
1
+ module NationSync
2
+ VERSION = '0.0.1'
3
+ end
4
+
5
+ require 'nationsync/api'
6
+ require 'nationsync/auth'
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ # require 'nationsync/version'
5
+ require 'nationsync'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "nationsync"
9
+ s.version = NationSync::VERSION
10
+ s.authors = ["Dirk Gadsden"]
11
+ s.email = ["dirk@dirk.to"]
12
+ s.description = "Write a gem description"
13
+ s.summary = "Write a gem summary"
14
+ s.homepage = "http://github.com/dirk/nationsync"
15
+ s.license = "MIT"
16
+
17
+ s.bindir = 'bin'
18
+ s.files = `git ls-files`.split($/)
19
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_dependency 'rack', '~> 1.5'
24
+ s.add_dependency 'faraday', '~> 0.8.8'
25
+ s.add_dependency 'faraday_middleware', '~> 0.9.0'
26
+ s.add_dependency 'thor', '~> 0.18.1'
27
+ s.add_dependency 'listen', '~> 2.2.0'
28
+ s.add_dependency 'highline', '~> 1.6.20'
29
+
30
+
31
+ s.add_development_dependency "bundler", "~> 1.3"
32
+ s.add_development_dependency "rake"
33
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nationsync
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dirk Gadsden
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.8
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.8.8
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.18.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.18.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: listen
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: highline
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.6.20
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.6.20
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.3'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Write a gem description
126
+ email:
127
+ - dirk@dirk.to
128
+ executables:
129
+ - nationsync
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - Gemfile
135
+ - LICENSE.txt
136
+ - README.md
137
+ - Rakefile
138
+ - bin/nationsync
139
+ - lib/nationsync.rb
140
+ - lib/nationsync/api.rb
141
+ - lib/nationsync/auth.rb
142
+ - lib/nationsync/commander.rb
143
+ - nationsync.gemspec
144
+ homepage: http://github.com/dirk/nationsync
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.1.10
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Write a gem summary
168
+ test_files: []