intranet-core 1.0.2 → 1.1.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.
- checksums.yaml +4 -4
- data/lib/intranet/abstract_responder.rb +12 -0
- data/lib/intranet/core/builder.rb +32 -7
- data/lib/intranet/core/version.rb +11 -2
- data/lib/intranet/resources/haml/skeleton.haml +8 -5
- data/lib/intranet/resources/www/style.css +19 -5
- data/spec/intranet/core_spec.rb +12 -23
- data/spec/test_responder/responder.rb +13 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf5a56e43b31aff50e2987cb337fdca3308f5444
|
4
|
+
data.tar.gz: c319c8fa7398563f469bb403edb7fff1923c126c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cd16c07120e3a5f3996a9b186d69c40a5816ad58b3852b988d334a82a18637bf2f130dc098ce7d465976a4148b412cbb1955e001cad546ccf5c77d2d23b7599
|
7
|
+
data.tar.gz: a280390146e29d0fa3be5c44faebdc6f72b54d4c7e4599dd81ae94bde5c15e4481ece613c236d777522433beae0c9cb16dd92842488318a109b712f7ef2b9a8d
|
@@ -3,6 +3,18 @@
|
|
3
3
|
module Intranet
|
4
4
|
# The default implementation and interface of an Intranet module.
|
5
5
|
class AbstractResponder
|
6
|
+
# Returns the name of the module.
|
7
|
+
# @return [String] The name of the module
|
8
|
+
def self.module_name; end
|
9
|
+
|
10
|
+
# The version of the module, according to semantic versionning.
|
11
|
+
# @return [String] The version of the module
|
12
|
+
def self.module_version; end
|
13
|
+
|
14
|
+
# The homepage of the module, if any.
|
15
|
+
# @return [String/Nil] The homepage URL of the module, or nil if no homepage is available.
|
16
|
+
def self.module_homepage; end
|
17
|
+
|
6
18
|
# Destroys the responder instance.
|
7
19
|
# This method gets called when server is shut down.
|
8
20
|
def finalize
|
@@ -16,11 +16,16 @@ module Intranet
|
|
16
16
|
# @return [CoreExtensions::Tree]
|
17
17
|
attr_reader :responders
|
18
18
|
|
19
|
+
# The metadata concerning all registered modules (for Haml)
|
20
|
+
# @return [Hash]
|
21
|
+
attr_reader :modules
|
22
|
+
|
19
23
|
# Initializes a new builder.
|
20
24
|
# @param logger [Object] The logger.
|
21
25
|
def initialize(logger)
|
22
26
|
@logger = logger
|
23
27
|
@responders = CoreExtensions::Tree.new
|
28
|
+
@modules = { NAME => { version: VERSION, homepage: HOMEPAGE_URL } }
|
24
29
|
end
|
25
30
|
|
26
31
|
# Finalizes the builder. Each registered responder is called for +finalize+.
|
@@ -63,17 +68,14 @@ module Intranet
|
|
63
68
|
# directory. If empty, the responder will be registered as Home responder
|
64
69
|
# (to serve /index.html in particular). Subdirectories are allowed using
|
65
70
|
# an array element for each directory level.
|
71
|
+
# @raise [ArgumentError] If the +responder+ is not a valid responder instance.
|
66
72
|
# @raise [ArgumentError] If one of the element of the +path+ contains invalid characters.
|
67
73
|
def register(responder, path = [])
|
74
|
+
raise ArgumentError unless responder.class.superclass.to_s == 'Intranet::AbstractResponder'
|
68
75
|
raise ArgumentError unless path.all?(&:urlized?)
|
69
76
|
|
70
|
-
|
71
|
-
|
72
|
-
next if part.empty? || part == '.'
|
73
|
-
|
74
|
-
current_node = current_node.add_child_node(part)
|
75
|
-
end
|
76
|
-
current_node.value = responder
|
77
|
+
insert_responder(responder, path)
|
78
|
+
store_module_metadata(responder)
|
77
79
|
end
|
78
80
|
|
79
81
|
private
|
@@ -93,6 +95,29 @@ module Intranet
|
|
93
95
|
|
94
96
|
[current_treenode.value, '/' + relative_path.join('/')]
|
95
97
|
end
|
98
|
+
|
99
|
+
# Inserts a responder instance in the appropriate Tree node according the given +path+.
|
100
|
+
# Missing Tree nodes are created.
|
101
|
+
# @param responder [Intranet::AbstractResponder] The responder instance of the module.
|
102
|
+
# @param path [Array] See Intranet::Builder::register().
|
103
|
+
def insert_responder(responder, path)
|
104
|
+
current_node = @responders
|
105
|
+
path.each do |part|
|
106
|
+
next if part.empty? || part == '.'
|
107
|
+
|
108
|
+
current_node = current_node.add_child_node(part)
|
109
|
+
end
|
110
|
+
current_node.value = responder
|
111
|
+
end
|
112
|
+
|
113
|
+
# Stores the module name, version and homepage URL. These information are used to display the
|
114
|
+
# 'about' modal window when partial content is returned by a module. The hash structure
|
115
|
+
# ensures that each module metadata are stored once only.
|
116
|
+
# @param responder [Intranet::AbstractResponder] The responder instance of the module.
|
117
|
+
def store_module_metadata(responder)
|
118
|
+
@modules[responder.class.module_name] = { version: responder.class.module_version,
|
119
|
+
homepage: responder.class.module_homepage }
|
120
|
+
end
|
96
121
|
end
|
97
122
|
end
|
98
123
|
end
|
@@ -2,7 +2,16 @@
|
|
2
2
|
|
3
3
|
module Intranet
|
4
4
|
class Core
|
5
|
-
# The
|
6
|
-
|
5
|
+
# The name of the gem.
|
6
|
+
NAME = 'intranet-core'
|
7
|
+
|
8
|
+
# The version of the gem, according to semantic versionning.
|
9
|
+
VERSION = '1.1.1'
|
10
|
+
|
11
|
+
# The URL of the gem homepage.
|
12
|
+
HOMEPAGE_URL = 'https://rubygems.org/gems/intranet-core'
|
13
|
+
|
14
|
+
# The URL of the gem source code.
|
15
|
+
SOURCES_URL = 'https://bitbucket.org/ebling-mis/intranet-core'
|
7
16
|
end
|
8
17
|
end
|
@@ -45,8 +45,11 @@
|
|
45
45
|
%aside#modal
|
46
46
|
%div#modal-content
|
47
47
|
%h2= 'Intranet'
|
48
|
-
%
|
49
|
-
|
50
|
-
%
|
51
|
-
|
52
|
-
|
48
|
+
%dl
|
49
|
+
- modules.each do |name, metadata|
|
50
|
+
%dt
|
51
|
+
- if metadata[:homepage].nil?
|
52
|
+
= name
|
53
|
+
- else
|
54
|
+
%a{href: metadata[:homepage], target: '_blank'}= name
|
55
|
+
%dd= metadata[:version]
|
@@ -3,7 +3,7 @@
|
|
3
3
|
* Design for the IntraNet core.
|
4
4
|
*/
|
5
5
|
|
6
|
-
|
6
|
+
/***************************************** External Fonts *****************************************/
|
7
7
|
|
8
8
|
@font-face {
|
9
9
|
font-family: "Source Sans Pro";
|
@@ -13,7 +13,7 @@
|
|
13
13
|
unicode-range: U+0-FF, U+131, U+152-153, U+2C6, U+2DA, U+2DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
|
14
14
|
}
|
15
15
|
|
16
|
-
|
16
|
+
/***************************************** General design *****************************************/
|
17
17
|
|
18
18
|
body, html {
|
19
19
|
padding: 0px;
|
@@ -21,7 +21,7 @@ body, html {
|
|
21
21
|
height: 100%;
|
22
22
|
}
|
23
23
|
body {
|
24
|
-
background: #1e262b
|
24
|
+
background: #1e262b;
|
25
25
|
font-family: "Source Sans Pro", Cantarell, sans-serif;
|
26
26
|
color: black;
|
27
27
|
}
|
@@ -38,7 +38,7 @@ a {
|
|
38
38
|
cursor: pointer;
|
39
39
|
}
|
40
40
|
|
41
|
-
|
41
|
+
/******************************************* Navigation *******************************************/
|
42
42
|
|
43
43
|
header {
|
44
44
|
position: fixed;
|
@@ -193,6 +193,7 @@ ul.breadcrumb li a, main article a {
|
|
193
193
|
/******************************** Main content *******************************/
|
194
194
|
|
195
195
|
body > aside {
|
196
|
+
background: url('background.jpg') fixed top right no-repeat;
|
196
197
|
height: 45%;
|
197
198
|
min-height: 350px;
|
198
199
|
max-height: 500px; /* less than height of background.jpg */
|
@@ -280,6 +281,19 @@ body > footer aside#modal #modal-content { /* modal box */
|
|
280
281
|
width: 400px;
|
281
282
|
font-size: 125%;
|
282
283
|
}
|
284
|
+
body > footer aside#modal #modal-content dl {
|
285
|
+
display: grid;
|
286
|
+
grid-template-columns: repeat(2, 50%);
|
287
|
+
grid-gap: 5px 25px;
|
288
|
+
}
|
289
|
+
body > footer aside#modal #modal-content dl dt {
|
290
|
+
font-weight: bold;
|
291
|
+
text-align: right;
|
292
|
+
}
|
293
|
+
body > footer aside#modal #modal-content dl dd {
|
294
|
+
text-align: left;
|
295
|
+
margin-left: 0;
|
296
|
+
}
|
283
297
|
/* Mobile devices only */
|
284
298
|
@media only screen and (max-width: 600px), only screen and (max-device-width: 600px) {
|
285
299
|
body > footer {
|
@@ -288,7 +302,7 @@ body > footer aside#modal #modal-content { /* modal box */
|
|
288
302
|
}
|
289
303
|
|
290
304
|
|
291
|
-
|
305
|
+
/******************************************* Error pages ******************************************/
|
292
306
|
|
293
307
|
section#error h2 {
|
294
308
|
color: #ff3333;
|
data/spec/intranet/core_spec.rb
CHANGED
@@ -109,26 +109,9 @@ RSpec.describe Intranet::Core do
|
|
109
109
|
end
|
110
110
|
|
111
111
|
context 'registering an invalid module' do
|
112
|
-
it 'should
|
113
|
-
|
114
|
-
|
115
|
-
@intranet.register_module(nil, [], '')
|
116
|
-
thread = Thread.new do
|
117
|
-
@intranet.start
|
118
|
-
end
|
119
|
-
while @intranet.instance_variable_get(:@server).status != :Running
|
120
|
-
end
|
121
|
-
|
122
|
-
socket = TCPSocket.new('localhost', @intranet.port)
|
123
|
-
socket.puts("GET /index.html HTTP/1.1\r\n" \
|
124
|
-
"Host: localhost:#{@intranet.port}\r\n\r\n")
|
125
|
-
expect(socket.gets).to include('HTTP/1.1 404 Not Found')
|
126
|
-
socket.close
|
127
|
-
ensure
|
128
|
-
socket.close
|
129
|
-
Thread.kill(thread)
|
130
|
-
thread.join
|
131
|
-
end
|
112
|
+
it 'should fail' do
|
113
|
+
@intranet = described_class.new(Intranet::Logger.new(Intranet::Logger::FATAL))
|
114
|
+
expect { @intranet.register_module(nil, [], '') }.to raise_error ArgumentError
|
132
115
|
end
|
133
116
|
end
|
134
117
|
|
@@ -315,9 +298,15 @@ RSpec.describe Intranet::Core do
|
|
315
298
|
expect(html).to match(%r{<script defer='defer' src='module.js'></script>})
|
316
299
|
expect(html).to match(%r{<script defer='defer' src='/js/interactive.js'></script>})
|
317
300
|
|
318
|
-
# Returned HTML document: includes Intranet Core
|
319
|
-
expect(html).to match(
|
320
|
-
|
301
|
+
# Returned HTML document: includes Intranet Core name, version and URL
|
302
|
+
expect(html).to match(
|
303
|
+
%r{<footer>.*<a href='#{Intranet::Core::HOMEPAGE_URL}'.*>#{Intranet::Core::NAME}</a>.*#{Intranet::Core::VERSION}.*</footer>}m # rubocop:disable Metrics/LineLength
|
304
|
+
)
|
305
|
+
|
306
|
+
# Returned HTML document: includes all registered modules version name, version and URL
|
307
|
+
expect(html).to match(
|
308
|
+
%r{<footer>.*<a href='http://nil/'.*>test-responder</a>.*0.0.0.*</footer>}m
|
309
|
+
)
|
321
310
|
ensure
|
322
311
|
socket.close
|
323
312
|
Thread.kill(thread)
|
@@ -15,6 +15,19 @@ module Intranet
|
|
15
15
|
|
16
16
|
def finalize
|
17
17
|
@finalized = true
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.module_name
|
22
|
+
'test-responder'
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.module_version
|
26
|
+
'0.0.0'
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.module_homepage
|
30
|
+
'http://nil/'
|
18
31
|
end
|
19
32
|
|
20
33
|
def resources_dir
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: intranet-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ebling Mis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: haml
|
@@ -191,10 +191,11 @@ files:
|
|
191
191
|
- spec/spec_helper.rb
|
192
192
|
- spec/test_responder/responder.rb
|
193
193
|
- spec/test_responder/www/style.css
|
194
|
-
homepage: https://
|
194
|
+
homepage: https://rubygems.org/gems/intranet-core
|
195
195
|
licenses:
|
196
196
|
- MIT
|
197
|
-
metadata:
|
197
|
+
metadata:
|
198
|
+
source_code_uri: https://bitbucket.org/ebling-mis/intranet-core
|
198
199
|
post_install_message:
|
199
200
|
rdoc_options: []
|
200
201
|
require_paths:
|