rhail 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +77 -0
- data/bin/rhail +78 -0
- data/generator_folders/.DS_Store +0 -0
- data/generator_folders/json/.DS_Store +0 -0
- data/generator_folders/json/.ruby-version +1 -0
- data/generator_folders/json/Gemfile +6 -0
- data/generator_folders/json/Gemfile.lock +17 -0
- data/generator_folders/json/config.ru +61 -0
- data/generator_folders/json/db/database.sqlite3 +0 -0
- data/generator_folders/json/db/seed.rb +31 -0
- data/generator_folders/json/public/.DS_Store +0 -0
- data/generator_folders/json/public/img/.DS_Store +0 -0
- data/generator_folders/json/public/img/favicon.png +0 -0
- data/generator_folders/json/settings.yml +1 -0
- data/generator_folders/plain/.DS_Store +0 -0
- data/generator_folders/plain/.ruby-version +1 -0
- data/generator_folders/plain/Gemfile +6 -0
- data/generator_folders/plain/Gemfile.lock +17 -0
- data/generator_folders/plain/config.ru +59 -0
- data/generator_folders/plain/db/database.sqlite3 +0 -0
- data/generator_folders/plain/db/seed.rb +31 -0
- data/generator_folders/plain/public/.DS_Store +0 -0
- data/generator_folders/plain/public/css/styles.css +123 -0
- data/generator_folders/plain/public/html/example_one.html +35 -0
- data/generator_folders/plain/public/html/example_three.html +75 -0
- data/generator_folders/plain/public/html/example_two.html +50 -0
- data/generator_folders/plain/public/html/foot.html +22 -0
- data/generator_folders/plain/public/html/head.html +51 -0
- data/generator_folders/plain/public/html/home.html +29 -0
- data/generator_folders/plain/public/img/favicon.png +0 -0
- data/generator_folders/plain/public/img/jumbotron.jpg +0 -0
- data/generator_folders/spa/.DS_Store +0 -0
- data/generator_folders/spa/.ruby-version +1 -0
- data/generator_folders/spa/Gemfile +6 -0
- data/generator_folders/spa/Gemfile.lock +17 -0
- data/generator_folders/spa/config.ru +49 -0
- data/generator_folders/spa/db/database.sqlite3 +0 -0
- data/generator_folders/spa/db/seed.rb +31 -0
- data/generator_folders/spa/public/.DS_Store +0 -0
- data/generator_folders/spa/public/css/styles.css +123 -0
- data/generator_folders/spa/public/html/index.html +186 -0
- data/generator_folders/spa/public/img/favicon.png +0 -0
- data/generator_folders/spa/public/img/jumbotron.jpg +0 -0
- data/generator_folders/spa/public/js/another-component.js +72 -0
- data/generator_folders/spa/public/js/app.js +16 -0
- data/lib/rhail.rb +13 -0
- data/lib/rhail/generator.rb +46 -0
- data/lib/rhail/helper.rb +117 -0
- data/lib/rhail/main.rb +8 -0
- data/rhail.gemspec +46 -0
- metadata +123 -0
Binary file
|
@@ -0,0 +1,123 @@
|
|
1
|
+
body {
|
2
|
+
min-height: 1000px;
|
3
|
+
}
|
4
|
+
|
5
|
+
.navbar {
|
6
|
+
margin-bottom: 0px;
|
7
|
+
}
|
8
|
+
|
9
|
+
/* Sticky footer styles
|
10
|
+
-------------------------------------------------- */
|
11
|
+
|
12
|
+
html {
|
13
|
+
position: relative;
|
14
|
+
min-height: 100%;
|
15
|
+
}
|
16
|
+
|
17
|
+
body {
|
18
|
+
margin-bottom: 100px; /* Margin bottom by footer height */
|
19
|
+
}
|
20
|
+
|
21
|
+
.footer {
|
22
|
+
position: absolute;
|
23
|
+
bottom: 0;
|
24
|
+
width: 100%;
|
25
|
+
height: 100px; /* Set the fixed height of the footer here */
|
26
|
+
background-color: #f5f5f5;
|
27
|
+
}
|
28
|
+
|
29
|
+
/* Navbar Colors
|
30
|
+
-------------------------------------------------- */
|
31
|
+
|
32
|
+
.navbar-default .navbar-brand {
|
33
|
+
color: #fff;
|
34
|
+
}
|
35
|
+
|
36
|
+
.navbar-default {
|
37
|
+
background-color: #2da3f3;
|
38
|
+
border-color: #14264d;
|
39
|
+
}
|
40
|
+
|
41
|
+
.navbar-default .navbar-nav>li>a {
|
42
|
+
color: #fff;
|
43
|
+
}
|
44
|
+
|
45
|
+
.navbar-default .navbar-nav>.active>a, .navbar-default .navbar-nav>.active>a:focus, .navbar-default .navbar-nav>.active>a:hover {
|
46
|
+
color: #9acdef;
|
47
|
+
background-color: #263b66;
|
48
|
+
}
|
49
|
+
|
50
|
+
.navbar-default .navbar-nav>li>a:focus, .navbar-default .navbar-nav>li>a:hover {
|
51
|
+
color: #263b66;
|
52
|
+
background-color: transparent;
|
53
|
+
}
|
54
|
+
|
55
|
+
|
56
|
+
.navbar-default .navbar-brand:focus, .navbar-default .navbar-brand:hover {
|
57
|
+
color: #263b66;
|
58
|
+
background-color: transparent;
|
59
|
+
}
|
60
|
+
|
61
|
+
.navbar-default .navbar-nav>.open>a, .navbar-default .navbar-nav>.open>a:focus, .navbar-default .navbar-nav>.open>a:hover {
|
62
|
+
color: #9acdef;
|
63
|
+
background-color: #263b66;
|
64
|
+
}
|
65
|
+
|
66
|
+
.dropdown-menu {
|
67
|
+
background-color: #263b66;
|
68
|
+
}
|
69
|
+
|
70
|
+
.dropdown-menu>li>a {
|
71
|
+
color: #9acdef;
|
72
|
+
}
|
73
|
+
|
74
|
+
.dropdown-header {
|
75
|
+
color: #ddd;
|
76
|
+
}
|
77
|
+
|
78
|
+
/* Navbar (mobile stacked) colors
|
79
|
+
-------------------------------------------------- */
|
80
|
+
.navbar-default .navbar-toggle .icon-bar {
|
81
|
+
background-color: #eee;
|
82
|
+
}
|
83
|
+
|
84
|
+
.navbar-default .navbar-toggle:focus, .navbar-default .navbar-toggle:hover {
|
85
|
+
background-color: #263b66;
|
86
|
+
}
|
87
|
+
|
88
|
+
/* Jumbotron
|
89
|
+
-------------------------------------------------- */
|
90
|
+
|
91
|
+
.jumbotron {
|
92
|
+
background-color: #ddd;
|
93
|
+
background: url('/img/jumbotron.jpg') no-repeat; /* LICENSE: I (Maksim Sundukov) do own rights for this picture, I made it, feel free to use it fo free. */
|
94
|
+
background-position: 0% 30%;
|
95
|
+
background-size: auto;
|
96
|
+
}
|
97
|
+
|
98
|
+
.jumbotron .h1, .jumbotron h1 {
|
99
|
+
color: #444;
|
100
|
+
}
|
101
|
+
|
102
|
+
.jumbotron p {
|
103
|
+
color: #fff;
|
104
|
+
text-shadow: 1px 1px 4px #000;
|
105
|
+
}
|
106
|
+
|
107
|
+
/* Footer
|
108
|
+
-------------------------------------------------- */
|
109
|
+
|
110
|
+
.footer-links {
|
111
|
+
margin-top: 20px;
|
112
|
+
}
|
113
|
+
|
114
|
+
.footer-links a {
|
115
|
+
margin-right: 20px;
|
116
|
+
}
|
117
|
+
|
118
|
+
/* IDs
|
119
|
+
-------------------------------------------------- */
|
120
|
+
|
121
|
+
#features-form {
|
122
|
+
margin-top: 50px;
|
123
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<div class="container">
|
2
|
+
|
3
|
+
<div class="row">
|
4
|
+
<h2>Heading Zero</h2>
|
5
|
+
<p>Reload the page and see contents changes below</p>
|
6
|
+
<p>
|
7
|
+
#{
|
8
|
+
random_words = %w(Fusce dapibus tellus ac cursus commodo tortor mauris condimentum nibh ut fermentum massa)
|
9
|
+
s = ''
|
10
|
+
(1..3).each do |i|
|
11
|
+
s += "#{i}. #{random_words.sample(3).join(' ')}<br>"
|
12
|
+
end
|
13
|
+
s
|
14
|
+
}
|
15
|
+
</p>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="row">
|
19
|
+
<h2>Heading One</h2>
|
20
|
+
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
|
21
|
+
<p><a href="#">View details »</a></p>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="row">
|
25
|
+
<h2>Heading Two</h2>
|
26
|
+
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
|
27
|
+
<p><a href="#">View details »</a></p>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class="row">
|
31
|
+
<h2>Heading Three</h2>
|
32
|
+
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
|
33
|
+
<p><a href="#">View details »</a></p>
|
34
|
+
</div>
|
35
|
+
</div> <!-- /container -->
|
@@ -0,0 +1,75 @@
|
|
1
|
+
<div class="container">
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-md-4">
|
4
|
+
<form id="features-form" action="example_three" method="POST">
|
5
|
+
|
6
|
+
<input type="hidden" name="csrf_token" value="#{local_vars[:csrf_token]}" />
|
7
|
+
|
8
|
+
<div class="form-group">
|
9
|
+
<label for="name">Name</label>
|
10
|
+
<input class="form-control" placeholder='John Doe' id="name" name="name">
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div class="form-group">
|
14
|
+
<label for="city">City</label>
|
15
|
+
<input class="form-control" placeholder='Atlanta' id="city" name="city">
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="form-group">
|
19
|
+
<label for="state">State</label>
|
20
|
+
<input class="form-control" placeholder='GA' id="state" name="state">
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div class="form-group">
|
24
|
+
<label for="zipcode">Zip</label>
|
25
|
+
<input class="form-control" placeholder='30303' id="zipcode" name="zipcode">
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="form-group">
|
29
|
+
<button type="submit" class="btn btn-primary">Add</button>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
</form>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="row">
|
37
|
+
<div class="col-md-4">
|
38
|
+
<h4>Results:</h4>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<div class="row">
|
43
|
+
<div class="col-md-8">
|
44
|
+
<table class="table table-hover table-condensed ">
|
45
|
+
<thead>
|
46
|
+
<tr>
|
47
|
+
<th>Name</th>
|
48
|
+
<th>City</th>
|
49
|
+
<th>State</th>
|
50
|
+
<th>Zip</th>
|
51
|
+
</tr>
|
52
|
+
</thead>
|
53
|
+
<tbody>
|
54
|
+
#{
|
55
|
+
s = ''
|
56
|
+
if local_vars[:results]
|
57
|
+
|
58
|
+
local_vars[:results].each do |p|
|
59
|
+
s += '<tr>'
|
60
|
+
p.each do |_, v|
|
61
|
+
s += '<td>' + v.to_s + '</td>'
|
62
|
+
end
|
63
|
+
s += '</tr>'
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
s
|
69
|
+
}
|
70
|
+
</tbody>
|
71
|
+
</table>
|
72
|
+
</div>
|
73
|
+
</div>
|
74
|
+
|
75
|
+
</div>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<div class="container">
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-md-4">
|
4
|
+
<form id="features-form" action="example_two" method="POST">
|
5
|
+
<div class="form-group">
|
6
|
+
|
7
|
+
<label for="one">Filed One</label>
|
8
|
+
<input class="form-control" placeholder='Something here' id="one" name="one">
|
9
|
+
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="form-group">
|
13
|
+
|
14
|
+
<label for="one">Filed Two</label>
|
15
|
+
<input class="form-control" placeholder='Something here too' id="two" name="two">
|
16
|
+
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="form-group">
|
20
|
+
|
21
|
+
<button type="submit" class="btn btn-primary">Go!</button>
|
22
|
+
|
23
|
+
</div>
|
24
|
+
</form>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="row">
|
29
|
+
<div class="col-md-4">
|
30
|
+
<h4>Results:</h4>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
#{
|
35
|
+
s = ''
|
36
|
+
if local_vars[:results]
|
37
|
+
s += '<div class="row"><div class="col-md-4">'
|
38
|
+
|
39
|
+
local_vars[:results].each do |k, v|
|
40
|
+
s += '<p>' + k + ': ' + v + '</p>'
|
41
|
+
end
|
42
|
+
|
43
|
+
s += '</div></div>'
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
s
|
48
|
+
}
|
49
|
+
|
50
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
<footer class="footer">
|
3
|
+
<div class="container">
|
4
|
+
<div class="row">
|
5
|
+
<div class="col-md-offset-2 col-md-8">
|
6
|
+
<p class="footer-links">
|
7
|
+
<a href="#">Donec id elit</a>
|
8
|
+
<a href="#">Non mi porta</a>
|
9
|
+
<a href="#">Gravida at eget</a>
|
10
|
+
<a href="#">Metus</a>
|
11
|
+
<a href="#">Fusce dapibus</a>
|
12
|
+
</p>
|
13
|
+
<p>© 2016 Company, Inc.</p>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
</footer>
|
18
|
+
|
19
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
20
|
+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
21
|
+
</body>
|
22
|
+
</html>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Ruby Hail. Plain.</title>
|
4
|
+
|
5
|
+
<link rel="icon" type="image/png" href="/img/favicon.png" />
|
6
|
+
|
7
|
+
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
|
8
|
+
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
9
|
+
<link rel="stylesheet" type="text/css" href="/css/styles.css">
|
10
|
+
|
11
|
+
</head>
|
12
|
+
|
13
|
+
<body>
|
14
|
+
|
15
|
+
<nav class="navbar navbar-default navbar-static-top">
|
16
|
+
<div class="container">
|
17
|
+
<div class="navbar-header">
|
18
|
+
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
|
19
|
+
<span class="icon-bar"></span>
|
20
|
+
<span class="icon-bar"></span>
|
21
|
+
<span class="icon-bar"></span>
|
22
|
+
</button>
|
23
|
+
<a class="navbar-brand" href="/">Ruby Hail Plain</a>
|
24
|
+
</div>
|
25
|
+
<div id="navbar" class="navbar-collapse collapse">
|
26
|
+
<ul class="nav navbar-nav">
|
27
|
+
<li class="#{local_vars[:page] == 'home' ? 'active' : 'inactive'}"><a href="/">Home</a></li>
|
28
|
+
<li class="#{local_vars[:page] == 'example_one' ? 'active' : 'inactive'}"><a href="/example_one">Example One</a></li>
|
29
|
+
<li class="#{local_vars[:page] == 'example_two' ? 'active' : 'inactive'}"><a href="/example_two">Example Two</a></li>
|
30
|
+
<li class="#{local_vars[:page] == 'example_three' ? 'active' : 'inactive'}"><a href="/example_three">Example Three</a></li>
|
31
|
+
<li class="dropdown">
|
32
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Drop-down Menu <span class="caret"></span></a>
|
33
|
+
<ul class="dropdown-menu">
|
34
|
+
<li><a href="#">One</a></li>
|
35
|
+
<li><a href="#">Two</a></li>
|
36
|
+
<li><a href="#">Three</a></li>
|
37
|
+
<li role="separator" class="divider"></li>
|
38
|
+
<li class="dropdown-header">Text</li>
|
39
|
+
<li><a href="#">Four</a></li>
|
40
|
+
<li><a href="#">Five</a></li>
|
41
|
+
</ul>
|
42
|
+
</li>
|
43
|
+
</ul>
|
44
|
+
<ul class="nav navbar-nav navbar-right">
|
45
|
+
<li><a href="#">Contact</a></li>
|
46
|
+
<li><a href="#">Visit</a></li>
|
47
|
+
<li><a href="#">Jobs</a></li>
|
48
|
+
</ul>
|
49
|
+
</div><!--/.nav-collapse -->
|
50
|
+
</div>
|
51
|
+
</nav>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<div class="jumbotron">
|
2
|
+
<div class="container">
|
3
|
+
<h1>Ruby Hail. Plain Example.</h1>
|
4
|
+
<p>Ea qui laoreet repudiandae neglegentur, cu detraxit euripidis vim, sit ex odio choro dicam. Cu eos lucilius postulant maiestatis, no alii commodo placerat per. Mei an dicta atomorum urbanitas, mei impetus noluisse in. Vim at solet viderer gloriatur, quo ut duis facete melius.</p>
|
5
|
+
<p>
|
6
|
+
<a class="btn btn-lg btn-primary" href="#">More info »</a>
|
7
|
+
</p>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="container">
|
12
|
+
<div class="row">
|
13
|
+
<div class="col-md-4">
|
14
|
+
<h2>Heading</h2>
|
15
|
+
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
|
16
|
+
<p><a class="btn btn-primary" href="#">View details »</a></p>
|
17
|
+
</div>
|
18
|
+
<div class="col-md-4">
|
19
|
+
<h2>Heading</h2>
|
20
|
+
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
|
21
|
+
<p><a class="btn btn-primary" href="#">View details »</a></p>
|
22
|
+
</div>
|
23
|
+
<div class="col-md-4">
|
24
|
+
<h2>Heading</h2>
|
25
|
+
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.</p>
|
26
|
+
<p><a class="btn btn-primary" href="#">View details »</a></p>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div> <!-- /container -->
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.3.0@rhail_spa
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rhail/helper'
|
2
|
+
require 'yaml'
|
3
|
+
require 'sequel'
|
4
|
+
|
5
|
+
use Rack::Static, :urls => ['/img', '/css', '/js', '/html'], :root => 'public'
|
6
|
+
DB = Sequel.sqlite('db/database.sqlite3')
|
7
|
+
use Rack::Session::Pool
|
8
|
+
|
9
|
+
class Spa
|
10
|
+
|
11
|
+
def self.call(env)
|
12
|
+
req = Rack::Request.new(env)
|
13
|
+
|
14
|
+
case
|
15
|
+
when req.get? && req.path_info == '/'
|
16
|
+
|
17
|
+
Rhail::Helper.render_html(files: ['index'])
|
18
|
+
|
19
|
+
when req.get? && req.path_info == '/api/example_one'
|
20
|
+
|
21
|
+
people_with_addresses = DB[:people].left_join(:addresses, id: :address_id).select(:name, :city, :state, :zipcode).all
|
22
|
+
req.session['csrf.token'] = SecureRandom.urlsafe_base64(32)
|
23
|
+
Rhail::Helper.render_json(response_structure: people_with_addresses, headers: {'csrf_token' => env['rack.session']['csrf.token']})
|
24
|
+
|
25
|
+
when req.post? && req.path_info == '/api/example_two'
|
26
|
+
|
27
|
+
params = Rhail::Helper.params_from_json_request(req)
|
28
|
+
|
29
|
+
if env['HTTP_CSRF_TOKEN'] == req.session['csrf.token']
|
30
|
+
|
31
|
+
address_id = DB[:addresses].insert(city: params['city'], state: params['state'], zipcode: params['zipcode'])
|
32
|
+
DB[:people].insert(name: params['name'], address_id: address_id)
|
33
|
+
|
34
|
+
Rhail::Helper.render_json(response_structure: {result: 'OK'})
|
35
|
+
|
36
|
+
else
|
37
|
+
Rhail::Helper.render_json(response_structure: {error: 'CSRF mismatch!'}, status: 400)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
rescue => e
|
42
|
+
puts e.message
|
43
|
+
puts e.backtrace
|
44
|
+
Rhail::Helper.render_json(response_structure: {status: '500', error: 'Internal Server Error'}, status: 500)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
run Spa
|