impression 0.1 → 0.2
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 +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/test.yml +32 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +59 -27
- data/Rakefile +10 -0
- data/examples/markdown/_assets/style.css +98 -0
- data/examples/markdown/app.rb +11 -5
- data/examples/markdown/docs/tutorial.md +15 -0
- data/impression.gemspec +7 -3
- data/lib/impression/app.rb +9 -0
- data/lib/impression/file_tree.rb +89 -0
- data/lib/impression/file_watcher.rb +50 -0
- data/lib/impression/pages.rb +178 -59
- data/lib/impression/request_extensions.rb +6 -2
- data/lib/impression/request_routing.rb +50 -0
- data/lib/impression/resource.rb +141 -0
- data/lib/impression/version.rb +1 -1
- data/lib/impression.rb +7 -0
- data/test/helper.rb +94 -0
- data/test/run.rb +5 -0
- data/test/static/bar/index.html +1 -0
- data/test/static/foo.html +1 -0
- data/test/static/index.html +1 -0
- data/test/static/js/a.js +1 -0
- data/test/test_app.rb +52 -0
- data/test/test_file_tree.rb +116 -0
- data/test/test_file_watcher.rb +57 -0
- data/test/test_resource.rb +129 -0
- metadata +55 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aaea11fcf3fcaab1902290a620d9cdb0fa5dfb11ae38c90335f80471629d652f
|
4
|
+
data.tar.gz: 9eaebd5c2a28856a568e583399c3ea6db8332e6c2aae6d570639505788203dc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 145722a3828e039ed1a021c002cc0a551e66f78a300d869203f15d8c3df8c2d532d71d37674a7c11b1d995c39cb138a06040665a785e22581473843d28581a49
|
7
|
+
data.tar.gz: 9d179f895f2d819f1c63762099137dda5511614176c9e25df4aef7d735975fbda25167b5f3c3a94788f96c8b37ece7c2f42acc7b54dcaa38054863976f039ccf
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github: ciconia
|
@@ -0,0 +1,32 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
os: [ubuntu-latest, macos-latest]
|
11
|
+
ruby: ['2.7', '3.0', '3.1', 'head']
|
12
|
+
|
13
|
+
name: >-
|
14
|
+
${{matrix.os}}, ${{matrix.ruby}}
|
15
|
+
|
16
|
+
runs-on: ${{matrix.os}}
|
17
|
+
|
18
|
+
env:
|
19
|
+
POLYPHONY_USE_LIBEV: "1"
|
20
|
+
|
21
|
+
steps:
|
22
|
+
- name: Setup machine
|
23
|
+
uses: actions/checkout@v1
|
24
|
+
- name: Setup Ruby and install deps
|
25
|
+
uses: ruby/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
ruby-version: ${{matrix.ruby}}
|
28
|
+
bundler-cache: true # 'bundle install' and cache
|
29
|
+
cache-version: 1
|
30
|
+
|
31
|
+
- name: Run tests
|
32
|
+
run: bundle exec rake test
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,53 +1,86 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
impression (0.
|
4
|
+
impression (0.2)
|
5
5
|
kramdown (~> 2.3.0)
|
6
6
|
kramdown-parser-gfm (~> 1.1.0)
|
7
|
-
|
7
|
+
papercraft (~> 0.12)
|
8
|
+
polyphony (~> 0.73.1)
|
9
|
+
qeweney (~> 0.15)
|
8
10
|
rouge (~> 3.26.0)
|
9
|
-
tipi (~> 0.
|
11
|
+
tipi (~> 0.45)
|
10
12
|
|
11
13
|
GEM
|
12
14
|
remote: https://rubygems.org/
|
13
15
|
specs:
|
14
|
-
|
15
|
-
|
16
|
-
docile (1.
|
16
|
+
acme-client (2.0.9)
|
17
|
+
faraday (>= 0.17, < 2.0.0)
|
18
|
+
docile (1.4.0)
|
17
19
|
escape_utils (1.2.1)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
ever (0.1)
|
21
|
+
extralite (1.11)
|
22
|
+
faraday (1.9.3)
|
23
|
+
faraday-em_http (~> 1.0)
|
24
|
+
faraday-em_synchrony (~> 1.0)
|
25
|
+
faraday-excon (~> 1.1)
|
26
|
+
faraday-httpclient (~> 1.0)
|
27
|
+
faraday-multipart (~> 1.0)
|
28
|
+
faraday-net_http (~> 1.0)
|
29
|
+
faraday-net_http_persistent (~> 1.0)
|
30
|
+
faraday-patron (~> 1.0)
|
31
|
+
faraday-rack (~> 1.0)
|
32
|
+
faraday-retry (~> 1.0)
|
33
|
+
ruby2_keywords (>= 0.0.4)
|
34
|
+
faraday-em_http (1.0.0)
|
35
|
+
faraday-em_synchrony (1.0.0)
|
36
|
+
faraday-excon (1.1.0)
|
37
|
+
faraday-httpclient (1.0.1)
|
38
|
+
faraday-multipart (1.0.3)
|
39
|
+
multipart-post (>= 1.2, < 3)
|
40
|
+
faraday-net_http (1.0.1)
|
41
|
+
faraday-net_http_persistent (1.2.0)
|
42
|
+
faraday-patron (1.0.0)
|
43
|
+
faraday-rack (1.0.0)
|
44
|
+
faraday-retry (1.0.3)
|
45
|
+
h1p (0.2)
|
46
|
+
http-2 (0.11.0)
|
47
|
+
json (2.6.1)
|
48
|
+
kramdown (2.3.1)
|
22
49
|
rexml
|
23
50
|
kramdown-parser-gfm (1.1.0)
|
24
51
|
kramdown (~> 2.0)
|
52
|
+
localhost (1.1.9)
|
25
53
|
minitest (5.11.3)
|
26
|
-
minitest-reporters (1.4.3)
|
27
|
-
ansi
|
28
|
-
builder
|
29
|
-
minitest (>= 5.0)
|
30
|
-
ruby-progressbar
|
31
54
|
msgpack (1.4.2)
|
32
|
-
|
33
|
-
|
55
|
+
multipart-post (2.1.1)
|
56
|
+
papercraft (0.12)
|
57
|
+
escape_utils (= 1.2.1)
|
58
|
+
kramdown (~> 2.3.0)
|
59
|
+
kramdown-parser-gfm (~> 1.1.0)
|
60
|
+
rouge (~> 3.26.0)
|
61
|
+
polyphony (0.73.1)
|
62
|
+
qeweney (0.15)
|
34
63
|
escape_utils (~> 1.2.1)
|
35
64
|
rack (2.2.3)
|
36
65
|
rake (12.3.3)
|
37
|
-
rexml (3.2.
|
38
|
-
rouge (3.26.
|
39
|
-
|
66
|
+
rexml (3.2.5)
|
67
|
+
rouge (3.26.1)
|
68
|
+
ruby2_keywords (0.0.5)
|
40
69
|
simplecov (0.17.1)
|
41
70
|
docile (~> 1.1)
|
42
71
|
json (>= 1.8, < 3)
|
43
72
|
simplecov-html (~> 0.10.0)
|
44
73
|
simplecov-html (0.10.2)
|
45
|
-
tipi (0.
|
46
|
-
|
47
|
-
|
74
|
+
tipi (0.45)
|
75
|
+
acme-client (~> 2.0.8)
|
76
|
+
ever (~> 0.1)
|
77
|
+
extralite (~> 1.2)
|
78
|
+
h1p (~> 0.2)
|
79
|
+
http-2 (~> 0.11)
|
80
|
+
localhost (~> 1.1.4)
|
48
81
|
msgpack (~> 1.4.2)
|
49
|
-
polyphony (~> 0.
|
50
|
-
qeweney (~> 0.
|
82
|
+
polyphony (~> 0.71)
|
83
|
+
qeweney (~> 0.14)
|
51
84
|
rack (>= 2.0.8, < 2.3.0)
|
52
85
|
websocket (~> 1.2.8)
|
53
86
|
websocket (1.2.9)
|
@@ -58,9 +91,8 @@ PLATFORMS
|
|
58
91
|
DEPENDENCIES
|
59
92
|
impression!
|
60
93
|
minitest (~> 5.11.3)
|
61
|
-
minitest-reporters (~> 1.4.2)
|
62
94
|
rake (~> 12.3.3)
|
63
95
|
simplecov (~> 0.17.1)
|
64
96
|
|
65
97
|
BUNDLED WITH
|
66
|
-
2.
|
98
|
+
2.3.3
|
data/Rakefile
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
* {
|
2
|
+
border: 0;
|
3
|
+
font: inherit;
|
4
|
+
font-size: 100%;
|
5
|
+
vertical-align: baseline;
|
6
|
+
margin: 0;
|
7
|
+
padding: 0;
|
8
|
+
color: black;
|
9
|
+
}
|
10
|
+
|
11
|
+
body {
|
12
|
+
font: normal 14px monospace;
|
13
|
+
}
|
14
|
+
|
15
|
+
h1, h2 {
|
16
|
+
font-weight: bold;
|
17
|
+
}
|
18
|
+
|
19
|
+
header {
|
20
|
+
margin-bottom: 20px;
|
21
|
+
}
|
22
|
+
|
23
|
+
a {
|
24
|
+
color: -webkit-link;
|
25
|
+
}
|
26
|
+
|
27
|
+
li {
|
28
|
+
margin-left: 40px;
|
29
|
+
}
|
30
|
+
|
31
|
+
em {
|
32
|
+
font-style: italic;
|
33
|
+
}
|
34
|
+
|
35
|
+
strong {
|
36
|
+
font-weight: bold;
|
37
|
+
}
|
38
|
+
|
39
|
+
p, ul, ol {
|
40
|
+
margin: 20px;
|
41
|
+
}
|
42
|
+
|
43
|
+
pre {
|
44
|
+
margin-bottom: 20px;
|
45
|
+
padding: 20px 5px;
|
46
|
+
overflow-x: visible;
|
47
|
+
}
|
48
|
+
|
49
|
+
pre code {
|
50
|
+
word-wrap: no;
|
51
|
+
}
|
52
|
+
|
53
|
+
hr {
|
54
|
+
display: block;
|
55
|
+
margin-top: 0.5em;
|
56
|
+
margin-bottom: 0.5em;
|
57
|
+
margin-left: auto;
|
58
|
+
margin-right: auto;
|
59
|
+
border-style: inset;
|
60
|
+
border-width: 1px;
|
61
|
+
}
|
62
|
+
|
63
|
+
#nav {
|
64
|
+
padding: 20px 5px;
|
65
|
+
}
|
66
|
+
|
67
|
+
#nav, #content, footer {
|
68
|
+
margin: 0 20px;
|
69
|
+
max-width: 580px;
|
70
|
+
}
|
71
|
+
|
72
|
+
#nav h1 {
|
73
|
+
margin-bottom: 20px;
|
74
|
+
}
|
75
|
+
|
76
|
+
iframe {
|
77
|
+
margin: 20px;
|
78
|
+
max-width: 530px;
|
79
|
+
}
|
80
|
+
|
81
|
+
#content img {
|
82
|
+
max-width: 100%;
|
83
|
+
}
|
84
|
+
|
85
|
+
#title {
|
86
|
+
margin-top: 40px;
|
87
|
+
font-weight: bold;
|
88
|
+
text-align: center;
|
89
|
+
}
|
90
|
+
|
91
|
+
#date {
|
92
|
+
display: block;
|
93
|
+
text-align: right;
|
94
|
+
}
|
95
|
+
|
96
|
+
#webring {
|
97
|
+
padding-bottom: 10px;
|
98
|
+
}
|
data/examples/markdown/app.rb
CHANGED
@@ -11,13 +11,19 @@ opts = {
|
|
11
11
|
}
|
12
12
|
|
13
13
|
puts "pid: #{Process.pid}"
|
14
|
-
puts 'Listening on port 4411...'
|
15
14
|
|
16
|
-
Tipi.
|
17
|
-
|
15
|
+
Tipi.full_service do |req|
|
16
|
+
req.route do
|
17
|
+
if req.host != 'noteflakes.com'
|
18
|
+
req.respond(nil, ':status' => Qeweney::Status::SERVICE_UNAVAILABLE)
|
19
|
+
stop_routing
|
20
|
+
end
|
21
|
+
req.on('assets') { req.serve_file(req.route_relative_path, base_path: File.join(__dir__, '_assets')) }
|
22
|
+
req.default { app.call(req) }
|
23
|
+
end
|
18
24
|
rescue Exception => e
|
19
|
-
p e
|
20
|
-
puts e.backtrace.join("\n")
|
25
|
+
p [req.path, e]
|
26
|
+
# puts e.backtrace.join("\n")
|
21
27
|
status = e.respond_to?(:http_status) ? e.http_status : 500
|
22
28
|
req.respond(e.inspect, ':status' => status)
|
23
29
|
end
|
data/impression.gemspec
CHANGED
@@ -19,15 +19,19 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
# s.executables = ['impression']
|
21
21
|
|
22
|
-
s.add_runtime_dependency 'polyphony', '~>0.
|
23
|
-
s.add_runtime_dependency 'tipi', '~>0.
|
22
|
+
s.add_runtime_dependency 'polyphony', '~>0.73.1'
|
23
|
+
s.add_runtime_dependency 'tipi', '~>0.45'
|
24
|
+
s.add_runtime_dependency 'qeweney', '~>0.15'
|
25
|
+
|
24
26
|
s.add_runtime_dependency 'kramdown', '~>2.3.0'
|
25
27
|
s.add_runtime_dependency 'rouge', '~>3.26.0'
|
26
28
|
s.add_runtime_dependency 'kramdown-parser-gfm', '~>1.1.0'
|
27
29
|
|
30
|
+
# s.add_runtime_dependency 'rb-inotify', '~>0.10.1'
|
31
|
+
s.add_runtime_dependency 'papercraft', '~>0.12'
|
32
|
+
|
28
33
|
|
29
34
|
s.add_development_dependency 'rake', '~>12.3.3'
|
30
35
|
s.add_development_dependency 'minitest', '~>5.11.3'
|
31
|
-
s.add_development_dependency 'minitest-reporters', '~>1.4.2'
|
32
36
|
s.add_development_dependency 'simplecov', '~>0.17.1'
|
33
37
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative './resource'
|
5
|
+
|
6
|
+
module Impression
|
7
|
+
|
8
|
+
# `FileTree` implements a resource that maps to a static file hierarchy.
|
9
|
+
class FileTree < Resource
|
10
|
+
|
11
|
+
# Initializes a `FileTree` resource.
|
12
|
+
#
|
13
|
+
# @param directory [String] static directory path
|
14
|
+
# @return [void]
|
15
|
+
def initialize(directory:, **props)
|
16
|
+
super(**props)
|
17
|
+
@directory = directory
|
18
|
+
@path_info_cache = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Responds to a request.
|
22
|
+
#
|
23
|
+
# @param req [Qeweney::Request] request
|
24
|
+
# @return [void]
|
25
|
+
def respond(req)
|
26
|
+
path_info = get_path_info(req.resource_relative_path)
|
27
|
+
render_from_path_info(req, *path_info)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Renders a response from the given response kind and path.
|
33
|
+
#
|
34
|
+
# @param req [Qeweney::Request] request
|
35
|
+
# @param kind [Symbol] path kind (`:not_found` or `:file`)
|
36
|
+
# @param path [String, nil] file path
|
37
|
+
def render_from_path_info(req, kind, path = nil)
|
38
|
+
case kind
|
39
|
+
when :not_found
|
40
|
+
req.respond(nil, ':status' => Qeweney::Status::NOT_FOUND)
|
41
|
+
when :file
|
42
|
+
req.serve_file(path)
|
43
|
+
else
|
44
|
+
raise "Invalid path info kind #{kind.inspect}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the path info for the given relative path.
|
49
|
+
#
|
50
|
+
# @param path [String] relative path
|
51
|
+
# @return [Array] path info (a tuple comprising kind and file path)
|
52
|
+
def get_path_info(path)
|
53
|
+
@path_info_cache[path] || calculate_path_info(path)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Calculates the path info for the given relative path.
|
57
|
+
#
|
58
|
+
# @param path [String] relative path
|
59
|
+
# @param add_html_ext [bool] whether to add .html extension if not found
|
60
|
+
# @return [Array] path info
|
61
|
+
def calculate_path_info(path, add_html_ext = true)
|
62
|
+
full_path = File.join(@directory, path)
|
63
|
+
|
64
|
+
stat = File.stat(full_path) rescue nil
|
65
|
+
if !stat
|
66
|
+
return add_html_ext ?
|
67
|
+
calculate_path_info("#{path}.html", false) : [:not_found]
|
68
|
+
elsif stat.directory?
|
69
|
+
return calculate_directory_path_info(full_path)
|
70
|
+
else
|
71
|
+
return [:file, full_path]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Calculates the path info for a directory. If an `index.html` file exists,
|
76
|
+
# its path info is returned, otherwise a `:not_found` path info is returned.
|
77
|
+
#
|
78
|
+
# @param path [String] directory path
|
79
|
+
# @return [Array] path info
|
80
|
+
def calculate_directory_path_info(path)
|
81
|
+
index_path = File.join(path, 'index.html')
|
82
|
+
if File.file?(index_path)
|
83
|
+
[:file, index_path]
|
84
|
+
else
|
85
|
+
[:not_found]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rb-inotify'
|
4
|
+
|
5
|
+
module Impression
|
6
|
+
class FileWatcher
|
7
|
+
def initialize(spec)
|
8
|
+
@notifier = INotify::Notifier.new
|
9
|
+
@buffer = []
|
10
|
+
setup(spec)
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup(spec)
|
14
|
+
if File.file?(spec)
|
15
|
+
setup_single_file(spec)
|
16
|
+
elsif File.directory?(spec)
|
17
|
+
setup_directory(spec)
|
18
|
+
else
|
19
|
+
dir = File.dir_name(spec)
|
20
|
+
filename = File.basename(spec)
|
21
|
+
if dir =~ /\/\*\*$/
|
22
|
+
dir = File.dir_name(dir)
|
23
|
+
filename = "**/#{filename}"
|
24
|
+
end
|
25
|
+
setup_directory(dir, filename)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup_directory(dir)
|
30
|
+
@notifier.watch(dir, :moved_to, :create, :move, :attrib, :modify, :delete) do |event|
|
31
|
+
kind = event.flags.first
|
32
|
+
|
33
|
+
@buffer << [kind, event.absolute_name]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def each(&block)
|
38
|
+
@receiver = Fiber.current
|
39
|
+
io = @notifier.to_io
|
40
|
+
loop do
|
41
|
+
io.wait_readable
|
42
|
+
@notifier.process
|
43
|
+
next if @buffer.empty?
|
44
|
+
|
45
|
+
@buffer.each(&block)
|
46
|
+
@buffer.clear
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|