jekyll_remote_assets 0.1.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 +7 -0
- data/lib/jekyll_remote_assets.rb +171 -0
- 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: []
|