staticd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/bin/staticd +7 -0
  3. data/lib/rack/auth/hmac.rb +81 -0
  4. data/lib/rack/request_time.rb +19 -0
  5. data/lib/staticd.rb +7 -0
  6. data/lib/staticd/api.rb +356 -0
  7. data/lib/staticd/app.rb +130 -0
  8. data/lib/staticd/cache_engine.rb +45 -0
  9. data/lib/staticd/cli.rb +70 -0
  10. data/lib/staticd/config.rb +115 -0
  11. data/lib/staticd/database.rb +41 -0
  12. data/lib/staticd/datastore.rb +64 -0
  13. data/lib/staticd/datastores/local.rb +48 -0
  14. data/lib/staticd/datastores/s3.rb +63 -0
  15. data/lib/staticd/domain_generator.rb +42 -0
  16. data/lib/staticd/http_cache.rb +65 -0
  17. data/lib/staticd/http_server.rb +197 -0
  18. data/lib/staticd/json_request.rb +15 -0
  19. data/lib/staticd/json_response.rb +29 -0
  20. data/lib/staticd/models/base.rb +43 -0
  21. data/lib/staticd/models/domain_name.rb +17 -0
  22. data/lib/staticd/models/release.rb +20 -0
  23. data/lib/staticd/models/resource.rb +19 -0
  24. data/lib/staticd/models/route.rb +19 -0
  25. data/lib/staticd/models/site.rb +36 -0
  26. data/lib/staticd/models/staticd_config.rb +71 -0
  27. data/lib/staticd/public/jquery-1.11.1.min.js +4 -0
  28. data/lib/staticd/public/main.css +61 -0
  29. data/lib/staticd/public/main.js +15 -0
  30. data/lib/staticd/version.rb +3 -0
  31. data/lib/staticd/views/main.haml +9 -0
  32. data/lib/staticd/views/setup.haml +47 -0
  33. data/lib/staticd/views/welcome.haml +92 -0
  34. data/lib/staticd_utils/archive.rb +80 -0
  35. data/lib/staticd_utils/file_size.rb +26 -0
  36. data/lib/staticd_utils/gli_object.rb +14 -0
  37. data/lib/staticd_utils/memory_file.rb +36 -0
  38. data/lib/staticd_utils/sitemap.rb +100 -0
  39. data/lib/staticd_utils/tar.rb +43 -0
  40. metadata +300 -0
@@ -0,0 +1,80 @@
1
+ require "zlib"
2
+ require "base64"
3
+ require "open-uri"
4
+ require "staticd_utils/memory_file"
5
+ require "staticd_utils/tar"
6
+
7
+ module StaticdUtils
8
+
9
+ # Manage Staticd archives.
10
+ #
11
+ # This class can manage the archives used as transport package to transfer
12
+ # files beetween Staticd client and Staticd API.
13
+ class Archive
14
+ attr_reader :stream
15
+
16
+ def self.open_file(url)
17
+ new(open(url))
18
+ end
19
+
20
+ # Create an archive from a folder.
21
+ #
22
+ # Can include a manifest as an array of files full path (from directory path
23
+ # as root).
24
+ #
25
+ # Example:
26
+ # StaticdUtils::Archive.create("/tmp/my_site", ["/index.html"])
27
+ # # Only the /tmp/my_site/index.html file will be included into
28
+ # the archive.
29
+ def self.create(directory_path, manifest=nil)
30
+ files =
31
+ if manifest
32
+ manifest.map { |entry| directory_path + entry }
33
+ else
34
+ Dir["#{directory_path}/**/*"].select { |f| File.file?(f) }
35
+ end
36
+ new(Tar.tar(files))
37
+ end
38
+
39
+ def initialize(stream)
40
+ @stream = stream
41
+ end
42
+
43
+ def open
44
+ Dir.mktmpdir do |tmp|
45
+ Dir.chdir(tmp) do
46
+ extract(tmp)
47
+ yield tmp
48
+ end
49
+ end
50
+ end
51
+
52
+ def close
53
+ @stream.close unless @stream.closed?
54
+ end
55
+
56
+ def extract(path)
57
+ return false if @stream.closed?
58
+
59
+ Tar.untar(@stream, path)
60
+ close
61
+ path
62
+ end
63
+
64
+ def size
65
+ @stream.size
66
+ end
67
+
68
+ def to_file(path)
69
+ return false if @stream.closed?
70
+
71
+ File.open(path, 'w') { |file| file.write(@stream.read) }
72
+ self.close
73
+ path
74
+ end
75
+
76
+ def to_memory_file
77
+ StaticdUtils::MemoryFile.new(@stream)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,26 @@
1
+ module StaticdUtils
2
+
3
+ # Class to convert file size in octect to human readable size.
4
+ #
5
+ # Example:
6
+ # Staticd::FileSize.new(1000).to_s
7
+ # # => "1KB"
8
+ class FileSize
9
+
10
+ def initialize(size)
11
+ @size = size
12
+ end
13
+
14
+ def to_s
15
+ units = %w(B KB MB GB TB)
16
+ base = 1000
17
+ return "#{@size}#{units[0]}" if @size < base
18
+
19
+ exponent = (Math.log(@size) / Math.log(base)).to_i
20
+ exponent = units.size - 1 if exponent > units.size - 1
21
+
22
+ human_size = @size / base**exponent
23
+ "#{human_size}#{units[exponent]}"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ require "gli"
2
+
3
+ # Move the GLI::App module into its own class.
4
+ #
5
+ # It's usefull to build a GLI::App like object.
6
+ #
7
+ # Example:
8
+ # gli = GLIObject.new
9
+ # gli.program_desc("My Ultimate CLI")
10
+ # gli.version("1.0")
11
+ # gli.run(*args)
12
+ class GLIObject
13
+ include GLI::App
14
+ end
@@ -0,0 +1,36 @@
1
+ module StaticdUtils
2
+
3
+ # Make an IO object behave like File objects.
4
+ #
5
+ # Example:
6
+ # io = StringIO.new("Content")
7
+ # file = MemoryFile.new(io)
8
+ # file.read
9
+ # # => "Content"
10
+ # file.path
11
+ # # => "memory_file"
12
+ # file.content_type
13
+ # # => "application/octet-stream"
14
+ class MemoryFile
15
+
16
+ def initialize(stream)
17
+ @stream = stream
18
+ end
19
+
20
+ def read(*args)
21
+ @stream.read(*args)
22
+ end
23
+
24
+ def path
25
+ original_filename
26
+ end
27
+
28
+ def original_filename
29
+ "memory_file"
30
+ end
31
+
32
+ def content_type
33
+ "application/octet-stream"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,100 @@
1
+ require "digest/sha1"
2
+ require "yaml"
3
+ require "staticd_utils/memory_file"
4
+
5
+ module StaticdUtils
6
+
7
+ # Manifest for Staticd releases.
8
+ #
9
+ # A Sitemap consist of an associative array representing each resources of a
10
+ # site release. Each entry consist of the sha1 digest of the resource content
11
+ # and the complete HTTP path this resource must be available to.
12
+ #
13
+ # Example:
14
+ # sitemap = StaticdUtils::Sitemap.create("/tmp/my_website")
15
+ # sitemap.to_h
16
+ # # => {
17
+ # "058ec3fa8aab4c0ccac27d80fd24f30a8730d3f6"=>"/index.html",
18
+ # "92136ff551f50188f46486ab80db269eda4dfd4e"=>"/hello/world.html"
19
+ # }
20
+ class Sitemap
21
+
22
+ # Create a sitemap from a directory content.
23
+ #
24
+ # It register each files digest and path inside the sitemap.
25
+ def self.create(path)
26
+ map = {}
27
+ if File.directory?(path)
28
+ Dir.chdir(path) do
29
+ Dir["**/*"].each do |object|
30
+ if File.file?(object)
31
+ sha1 = Digest::SHA1.hexdigest(File.read(object))
32
+ map[sha1] = "/#{object}"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ new(map)
38
+ end
39
+
40
+ # Create a sitemap from a YAML string.
41
+ #
42
+ # The YAML string must reflect the sitemap associative array structure.
43
+ #
44
+ # Example:
45
+ # yaml = "---\n058ec3fa8aab4c0ccac27d80fd24f30a8730d3f6: \"/hi.html\"\n"
46
+ # sitemap = StaticdUtils::Sitemap.open(yaml)
47
+ def self.open(yaml)
48
+ new(YAML.load(yaml))
49
+ end
50
+
51
+ # Create a sitemap from a YAML file.
52
+ #
53
+ # The YAML file must reflect the sitemap associative array structure.
54
+ def self.open_file(path)
55
+ open(File.read(path))
56
+ end
57
+
58
+ # Create a sitemap from an associative array.
59
+ #
60
+ # The associative array must have the folowing structure:
61
+ # * Key: the sha1 of the ressource
62
+ # * Value: the HTTP path of the resource
63
+ #
64
+ # Example:
65
+ # sitemap = Sitemap.new({
66
+ # 058ec3fa8aab4c0ccac27d80fd24f30a8730d3f6: "hi.html"
67
+ # })
68
+ def initialize(map)
69
+ @map = map
70
+ end
71
+
72
+ # View all HTTP path of the sitemap.
73
+ def routes
74
+ @map.map { |sha1, path| path }
75
+ end
76
+
77
+ # View all sha1 digest of the sitemap.
78
+ def digests
79
+ @map.map { |sha1, path| sha1 }
80
+ end
81
+
82
+ # Iterate over each resources of the sitemap.
83
+ def each_resources
84
+ @map.each { |sha1, path| yield sha1, path }
85
+ end
86
+
87
+ def to_h
88
+ @map
89
+ end
90
+
91
+ def to_yaml
92
+ @map.to_yaml
93
+ end
94
+
95
+ # Export the sitemap to a YAML file stored into memory.
96
+ def to_memory_file
97
+ StaticdUtils::MemoryFile.new(StringIO.new(to_yaml))
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,43 @@
1
+ require "rubygems/package"
2
+ require "digest/sha1"
3
+
4
+ module StaticdUtils
5
+
6
+ # Creation and Extraction of Tarball Stream.
7
+ #
8
+ # Example:
9
+ # tar = Tar.tar(["/tmp/hello"])
10
+ # Tar.untar(tar, "/tmp")
11
+ class Tar
12
+
13
+ def self.tar(files)
14
+ io = StringIO.new
15
+ tar = Gem::Package::TarWriter.new(io)
16
+
17
+ # Gem::Package::TarReader raise an exeption extracting an empty tarball,
18
+ # this add at least one useless file to extract.
19
+ tar.add_file("about", 0644) { |file| file.write("Hello.") }
20
+
21
+ files.each do |file|
22
+ content = File.read(file)
23
+ sha1 = Digest::SHA1.hexdigest(content)
24
+ tar.add_file(sha1, 0644) { |entry| entry.write(content) }
25
+ end
26
+
27
+ io.rewind
28
+ io
29
+ end
30
+
31
+ def self.untar(io, path)
32
+ FileUtils.mkdir_p("#{path}")
33
+ tar = Gem::Package::TarReader.new(io)
34
+ tar.rewind
35
+ tar.each do |entry|
36
+ File.open("#{path}/#{entry.full_name}", "w+") do |file|
37
+ file.write(entry.read)
38
+ end
39
+ end
40
+ tar.close
41
+ end
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,300 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: staticd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Etienne Garnier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: puma
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.9.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.9.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ - - <
35
+ - !ruby/object:Gem::Version
36
+ version: '2.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '1.1'
44
+ - - <
45
+ - !ruby/object:Gem::Version
46
+ version: '2.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: sinatra
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 1.4.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '='
59
+ - !ruby/object:Gem::Version
60
+ version: 1.4.5
61
+ - !ruby/object:Gem::Dependency
62
+ name: rack-test
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '='
66
+ - !ruby/object:Gem::Version
67
+ version: 0.6.2
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '='
73
+ - !ruby/object:Gem::Version
74
+ version: 0.6.2
75
+ - !ruby/object:Gem::Dependency
76
+ name: data_mapper
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '='
80
+ - !ruby/object:Gem::Version
81
+ version: 1.2.0
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '='
87
+ - !ruby/object:Gem::Version
88
+ version: 1.2.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: dm-postgres-adapter
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '='
94
+ - !ruby/object:Gem::Version
95
+ version: 1.2.0
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '='
101
+ - !ruby/object:Gem::Version
102
+ version: 1.2.0
103
+ - !ruby/object:Gem::Dependency
104
+ name: gli
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 2.12.2
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '='
115
+ - !ruby/object:Gem::Version
116
+ version: 2.12.2
117
+ - !ruby/object:Gem::Dependency
118
+ name: api-auth
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '='
122
+ - !ruby/object:Gem::Version
123
+ version: 1.2.6
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - '='
129
+ - !ruby/object:Gem::Version
130
+ version: 1.2.6
131
+ - !ruby/object:Gem::Dependency
132
+ name: aws-sdk
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '='
136
+ - !ruby/object:Gem::Version
137
+ version: 1.57.0
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '='
143
+ - !ruby/object:Gem::Version
144
+ version: 1.57.0
145
+ - !ruby/object:Gem::Dependency
146
+ name: sendfile
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - '='
150
+ - !ruby/object:Gem::Version
151
+ version: 1.2.2
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - '='
157
+ - !ruby/object:Gem::Version
158
+ version: 1.2.2
159
+ - !ruby/object:Gem::Dependency
160
+ name: haml
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - '='
164
+ - !ruby/object:Gem::Version
165
+ version: 4.0.6
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - '='
171
+ - !ruby/object:Gem::Version
172
+ version: 4.0.6
173
+ - !ruby/object:Gem::Dependency
174
+ name: dm-sqlite-adapter
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '='
178
+ - !ruby/object:Gem::Version
179
+ version: 1.2.0
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - '='
185
+ - !ruby/object:Gem::Version
186
+ version: 1.2.0
187
+ - !ruby/object:Gem::Dependency
188
+ name: rake
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - '='
192
+ - !ruby/object:Gem::Version
193
+ version: 10.3.2
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - '='
199
+ - !ruby/object:Gem::Version
200
+ version: 10.3.2
201
+ - !ruby/object:Gem::Dependency
202
+ name: byebug
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - '='
206
+ - !ruby/object:Gem::Version
207
+ version: 3.5.1
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - '='
213
+ - !ruby/object:Gem::Version
214
+ version: 3.5.1
215
+ - !ruby/object:Gem::Dependency
216
+ name: foreman
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - '='
220
+ - !ruby/object:Gem::Version
221
+ version: 0.75.0
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - '='
227
+ - !ruby/object:Gem::Version
228
+ version: 0.75.0
229
+ description: Staticd API and HTTP service to manage and serve staticd content over
230
+ HTTP
231
+ email: garnier.etienne@gmail.com
232
+ executables:
233
+ - staticd
234
+ extensions: []
235
+ extra_rdoc_files: []
236
+ files:
237
+ - lib/staticd/json_response.rb
238
+ - lib/staticd/cli.rb
239
+ - lib/staticd/http_cache.rb
240
+ - lib/staticd/json_request.rb
241
+ - lib/staticd/public/main.css
242
+ - lib/staticd/public/jquery-1.11.1.min.js
243
+ - lib/staticd/public/main.js
244
+ - lib/staticd/http_server.rb
245
+ - lib/staticd/config.rb
246
+ - lib/staticd/domain_generator.rb
247
+ - lib/staticd/app.rb
248
+ - lib/staticd/models/staticd_config.rb
249
+ - lib/staticd/models/resource.rb
250
+ - lib/staticd/models/domain_name.rb
251
+ - lib/staticd/models/route.rb
252
+ - lib/staticd/models/release.rb
253
+ - lib/staticd/models/site.rb
254
+ - lib/staticd/models/base.rb
255
+ - lib/staticd/database.rb
256
+ - lib/staticd/datastore.rb
257
+ - lib/staticd/views/setup.haml
258
+ - lib/staticd/views/welcome.haml
259
+ - lib/staticd/views/main.haml
260
+ - lib/staticd/version.rb
261
+ - lib/staticd/datastores/s3.rb
262
+ - lib/staticd/datastores/local.rb
263
+ - lib/staticd/api.rb
264
+ - lib/staticd/cache_engine.rb
265
+ - lib/staticd_utils/memory_file.rb
266
+ - lib/staticd_utils/file_size.rb
267
+ - lib/staticd_utils/sitemap.rb
268
+ - lib/staticd_utils/gli_object.rb
269
+ - lib/staticd_utils/archive.rb
270
+ - lib/staticd_utils/tar.rb
271
+ - lib/rack/auth/hmac.rb
272
+ - lib/rack/request_time.rb
273
+ - lib/staticd.rb
274
+ - bin/staticd
275
+ homepage: http://staticd.eggnet.io
276
+ licenses:
277
+ - MIT
278
+ metadata: {}
279
+ post_install_message:
280
+ rdoc_options: []
281
+ require_paths:
282
+ - lib
283
+ - lib
284
+ required_ruby_version: !ruby/object:Gem::Requirement
285
+ requirements:
286
+ - - '>='
287
+ - !ruby/object:Gem::Version
288
+ version: '0'
289
+ required_rubygems_version: !ruby/object:Gem::Requirement
290
+ requirements:
291
+ - - '>='
292
+ - !ruby/object:Gem::Version
293
+ version: '0'
294
+ requirements: []
295
+ rubyforge_project:
296
+ rubygems_version: 2.0.14
297
+ signing_key:
298
+ specification_version: 4
299
+ summary: Staticd API and HTTP service
300
+ test_files: []