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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5a7e55ef9ff6c795a485a4b1e50456949932d923425ad447ada836ef2e69b0c
4
- data.tar.gz: 669f0781d30986542fb09aad0af058107a658281136ace716edfdefc18fefabb
3
+ metadata.gz: aaea11fcf3fcaab1902290a620d9cdb0fa5dfb11ae38c90335f80471629d652f
4
+ data.tar.gz: 9eaebd5c2a28856a568e583399c3ea6db8332e6c2aae6d570639505788203dc1
5
5
  SHA512:
6
- metadata.gz: 1cdbfd6167b1e1717e5a3fda6089c84bb0ed7c6d810b1dac9376a1cd81a38a473c097ba6dd6ecbd07c61145b86b5e10f13c8be02ac69c14c556ba6991f87e4f4
7
- data.tar.gz: cf2e071b60b5ed0aa0ab826d2721c55d15cabb7fa0f63e84d068f76eef9a39db68159d6a651ddf5371976c4703a72a910883e50becdd64ff365d4b955cb93192
6
+ metadata.gz: 145722a3828e039ed1a021c002cc0a551e66f78a300d869203f15d8c3df8c2d532d71d37674a7c11b1d995c39cb138a06040665a785e22581473843d28581a49
7
+ data.tar.gz: 9d179f895f2d819f1c63762099137dda5511614176c9e25df4aef7d735975fbda25167b5f3c3a94788f96c8b37ece7c2f42acc7b54dcaa38054863976f039ccf
@@ -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
@@ -0,0 +1,8 @@
1
+ ## 0.2 2022-01-13
2
+
3
+ - Implement `FileTree` (#2)
4
+ - Rename `Resource#render` to `Resource#respond`
5
+ - Rewrite resource routing (#1)
6
+ - Implement `Resource`
7
+
8
+ ## 0.1 2021-02-24
data/Gemfile CHANGED
@@ -1,3 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ # %w{polyphony tipi qeweney rubyoshka}.each do |dep|
6
+ # dir = "../#{dep}"
7
+ # gem(dep, path: dir) if File.directory?(dir)
8
+ # end
data/Gemfile.lock CHANGED
@@ -1,53 +1,86 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- impression (0.1)
4
+ impression (0.2)
5
5
  kramdown (~> 2.3.0)
6
6
  kramdown-parser-gfm (~> 1.1.0)
7
- polyphony (~> 0.51.0)
7
+ papercraft (~> 0.12)
8
+ polyphony (~> 0.73.1)
9
+ qeweney (~> 0.15)
8
10
  rouge (~> 3.26.0)
9
- tipi (~> 0.37)
11
+ tipi (~> 0.45)
10
12
 
11
13
  GEM
12
14
  remote: https://rubygems.org/
13
15
  specs:
14
- ansi (1.5.0)
15
- builder (3.2.4)
16
- docile (1.3.5)
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
- http-2 (0.10.2)
19
- http_parser.rb (0.6.0)
20
- json (2.5.1)
21
- kramdown (2.3.0)
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
- polyphony (0.51.0)
33
- qeweney (0.5)
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.4)
38
- rouge (3.26.0)
39
- ruby-progressbar (1.11.0)
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.37)
46
- http-2 (~> 0.10.0)
47
- http_parser.rb (~> 0.6.0)
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.51.0)
50
- qeweney (~> 0.5)
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.1.4
98
+ 2.3.3
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/clean"
5
+
6
+ task :default => [:test]
7
+
8
+ task :test do
9
+ exec 'ruby test/run.rb'
10
+ end
@@ -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
+ }
@@ -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.serve('0.0.0.0', 4411, opts) do |req|
17
- app.call(req)
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
@@ -0,0 +1,15 @@
1
+ # This is a tutorial
2
+
3
+ ## I'm an h2
4
+
5
+ ```ruby
6
+ "here's some code"
7
+
8
+ class A
9
+ def b
10
+ [:c, 42, /foo/]
11
+ end
12
+ end
13
+
14
+ p A.new.b
15
+ ```
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.51.0'
23
- s.add_runtime_dependency 'tipi', '~>0.37'
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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Impression
4
+ class App < Resource
5
+ def initialize(path: '/', **opts)
6
+ super(path: path, **opts)
7
+ end
8
+ end
9
+ 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