jekyll_remote_assets 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/jekyll_remote_assets.rb +171 -0
  3. metadata +65 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8f68758084318ca0826f198ad193561eaadc6ed0
4
+ data.tar.gz: 3509c3789e3ba1336da8493fd0826b577ff06813
5
+ SHA512:
6
+ metadata.gz: 5fce80ddeb49d69f0533c406d9ae78607c810af9fd9be45c0eb7bd27c92d1bc2f61982498299e5a17c7d3812babf7d39afbf7da76d5a358e2040719538522679
7
+ data.tar.gz: d7bbff9c56a4e6b8bc926f508b57fb8ed3e8846583b36659d01ce4db8a00707554f6e137c9dc1335fd88fe7a4b153fa1d68c1ca493e6339b4924860a2f25f94c
@@ -0,0 +1,171 @@
1
+ require 'uri'
2
+ require 'unirest'
3
+ require 'set'
4
+
5
+ module Jekyll
6
+ module RemoteAsset
7
+
8
+ module SitePatch
9
+ def remote_assets
10
+ @remote_assets ||= {}
11
+ end
12
+ end
13
+
14
+ Jekyll::Site.send :include, Jekyll::RemoteAsset::SitePatch
15
+
16
+ class RemoteAssetTag < Liquid::Tag
17
+ def initialize(tag_name, asset_name, tokens)
18
+ super
19
+ @asset_name = asset_name.strip
20
+ end
21
+
22
+ def render(context)
23
+ "#{ context.registers[:site].remote_assets[@asset_name] }"
24
+ end
25
+ end
26
+
27
+ Liquid::Template.register_tag('asset', Jekyll::RemoteAsset::RemoteAssetTag)
28
+
29
+ class Generator < Jekyll::Generator
30
+ REQUEST_TOKEN_URL = "https://api.dropbox.com/1/oauth/request_token"
31
+ ACCESS_TOKEN_URL = "https://api.dropbox.com/1/oauth/access_token"
32
+ FILES_PUT_URL = "https://api-content.dropbox.com/1/files_put/auto"
33
+ FILE_METADATA_URL = "https://api.dropbox.com/1/metadata/auto"
34
+ SHARES_URL = "https://api.dropbox.com/1/shares/auto"
35
+
36
+ def config_oauth(plugin_config)
37
+ @oauth_config = {}
38
+ config_file = plugin_config["config"] || __dir__ + "/.remote_assets_config"
39
+ if not File.exist?(config_file)
40
+ puts "1. Create a new application on the Dropbox App Console, if you haven't already: https://www.dropbox.com/developers/apps"
41
+ $stdin.gets
42
+
43
+ puts "2. Please enter your app key. "
44
+ @oauth_config[:app_key] = $stdin.gets.strip
45
+
46
+ puts "3. Please enter your app secret. "
47
+ @oauth_config[:app_secret] = $stdin.gets.strip
48
+
49
+ response = Unirest.post REQUEST_TOKEN_URL,
50
+ headers: { "Authorization" => build_oauth1_header(@oauth_config[:app_key], @oauth_config[:app_secret]) }
51
+
52
+ request_tokens = CGI::parse(response.body)
53
+
54
+ puts "4. Visit https://www.dropbox.com/1/oauth/authorize?oauth_token=#{ request_tokens['oauth_token'][0] } and approve this app. Press enter when finished."
55
+ $stdin.gets
56
+
57
+ response = Unirest.post ACCESS_TOKEN_URL,
58
+ headers: {"Authorization" => build_oauth1_header(@oauth_config[:app_key], @oauth_config[:app_secret], request_tokens['oauth_token'][0], request_tokens['oauth_token_secret'][0]) }
59
+
60
+ access_tokens = CGI::parse(response.body)
61
+
62
+ @oauth_config[:access_token] = access_tokens['oauth_token'][0]
63
+ @oauth_config[:access_token_secret] = access_tokens['oauth_token_secret'][0]
64
+
65
+ File.open(config_file, 'w+') do |f|
66
+ YAML.dump(@oauth_config, f)
67
+ end
68
+ else
69
+ File.open(config_file) do |f|
70
+ @oauth_config = YAML.load_file(f)
71
+ end
72
+ end
73
+ end
74
+
75
+ def init_cache(plugin_config)
76
+ @cache = {}
77
+ cache_file = plugin_config["cache"] || __dir__ + "/.remote_assets_cache"
78
+
79
+ # TODO: fix first-time set up of cache
80
+ if not File.exist?(cache_file)
81
+ File.open(cache_file, 'w+') do |f|
82
+ YAML.dump(@cache, f)
83
+ end
84
+ end
85
+
86
+ File.open(cache_file) do |f|
87
+ @cache = YAML.load_file(f)
88
+ end
89
+ end
90
+
91
+ def nonce(size = 7)
92
+ Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/, '')
93
+ end
94
+
95
+ def build_oauth1_header(app_key, app_secret, token=nil, token_secret=nil)
96
+ header_params = {
97
+ oauth_version: "1.0",
98
+ oauth_consumer_key: app_key,
99
+ oauth_signature_method: "PLAINTEXT",
100
+ oauth_token: token,
101
+ oauth_signature: "#{ app_secret }&#{ token_secret }"
102
+ }
103
+
104
+ result = header_params.map do |k, v|
105
+ "#{ k }=\"#{ v }\"" if v
106
+ end
107
+
108
+ return "OAuth #{ result.compact.join ', ' }"
109
+ end
110
+
111
+ def generate(site)
112
+ plugin_config = site.config["remote_assets"] || {}
113
+ config_oauth(plugin_config)
114
+ init_cache(plugin_config)
115
+
116
+ file_set = Set.new
117
+
118
+ Dir.glob("_assets/**/*") do |filename|
119
+ begin
120
+ next if File.directory?(filename)
121
+
122
+ name = filename[filename.index('/')..-1]
123
+ overwrite = plugin_config['overwrite'] || true
124
+
125
+ File.open(filename) do |f|
126
+ file_set.add filename
127
+
128
+ md5 = Digest::MD5.file(filename).hexdigest
129
+ if @cache[filename] and @cache[filename][:md5] == md5
130
+ # if it's cached, make sure the file is still in the Dropbox drive
131
+ response = Unirest.get FILE_METADATA_URL + name,
132
+ headers: {"Authorization" => build_oauth1_header(@oauth_config[:app_key], @oauth_config[:app_secret], @oauth_config[:access_token], @oauth_config[:access_token_secret])}
133
+
134
+ if response.body["error"] == nil && !response.body["is_deleted"]
135
+ site.remote_assets[name[1..name.length]] = @cache[filename][:url]
136
+ next
137
+ end
138
+ end
139
+
140
+ # upload the file
141
+ response = Unirest.put FILES_PUT_URL + name + "?overwrite=#{ overwrite }",
142
+ headers: {"Authorization" => build_oauth1_header(@oauth_config[:app_key], @oauth_config[:app_secret], @oauth_config[:access_token], @oauth_config[:access_token_secret]),
143
+ "Content-Length" => File::size(f),
144
+ "Content-Type" => "text/plain"},
145
+ parameters: f
146
+
147
+ # retrieve the url
148
+ response = Unirest.post SHARES_URL + name,
149
+ headers: {"Authorization" => build_oauth1_header(@oauth_config[:app_key], @oauth_config[:app_secret], @oauth_config[:access_token], @oauth_config[:access_token_secret])},
150
+ parameters: {short_url: false}
151
+
152
+ uri = URI(response.body["url"])
153
+ site.remote_assets[name[1..-1]] = "http://dl.dropboxusercontent.com#{ uri.path }"
154
+
155
+ @cache[filename] = { md5: md5, url: "http://dl.dropboxusercontent.com#{ uri.path }"}
156
+ end
157
+ rescue
158
+ puts "Error uploading #{ filename }"
159
+ end
160
+ end
161
+ @cache.delete_if { |key, value| not file_set.include? key }
162
+
163
+ # TODO: clean up file saving
164
+ File.open(plugin_config["cache"] || __dir__ + "/.remote_assets_cache", 'w+') do |f|
165
+ YAML.dump(@cache, f)
166
+ end
167
+ end
168
+ end
169
+
170
+ end
171
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll_remote_assets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Broder
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: unirest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ - - '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.1'
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.2
33
+ description:
34
+ email: aaronbroder@gmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - lib/jekyll_remote_assets.rb
40
+ homepage: https://github.com/abroder/jekyll-remote-assets
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.4.5
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: Automatically upload static assets to Dropbox on site generation to save
64
+ on server costs
65
+ test_files: []