staticd 0.0.1

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.
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: []