adminix 0.1.20 → 0.1.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/adminix.gemspec +1 -2
- data/exe/adminix +15 -5
- data/lib/adminix/config.rb +25 -4
- data/lib/adminix/setup/routes.rb +108 -0
- data/lib/adminix/setup/services.rb +138 -0
- data/lib/adminix/setup/views.rb +183 -0
- data/lib/adminix/setup.rb +3 -0
- data/lib/adminix/version.rb +1 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 298f9880a3d767fef666c2dd901cc9aefe81948b
|
4
|
+
data.tar.gz: 2ad5aebb4b569cbc4f92ecfefaa5a3a69763111b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee3dcaaf7a68736dbcc9c2e9cf8e9b132b0efa9ff639e79b77563b1c91d4e2e981a8e1b5014450249360423c260f00760eb70cb6afd5ada6a925c1bdc44bd3ee
|
7
|
+
data.tar.gz: 515e255bcf71308ea6753445deb2b5c4e8f9e9f0344263ac33ae0fbe14b85948047d2589143f41f8ef65fbda65eff4510af5d17bdfcedd13d22c99a2d8c9d0f2
|
data/adminix.gemspec
CHANGED
@@ -30,10 +30,9 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
|
-
#spec.add_dependency "daemons", "~> 1.2.4"
|
34
|
-
#spec.add_dependency "action_cable_client", "~> 1.3", ">= 1.3.4"
|
35
33
|
spec.add_dependency "eventmachine", "1.2.3"
|
36
34
|
spec.add_dependency "em-websocket-client", "0.1.2"
|
35
|
+
spec.add_dependency "sinatra", "1.4.8"
|
37
36
|
|
38
37
|
spec.add_development_dependency "bundler", "~> 1.14"
|
39
38
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/exe/adminix
CHANGED
@@ -43,16 +43,26 @@ parsers[options[:action].to_sym].parse!(ARGV) rescue nil
|
|
43
43
|
|
44
44
|
unless options[:action] == "help"
|
45
45
|
require'adminix'
|
46
|
-
Adminix::Config.instance
|
47
|
-
|
48
|
-
|
46
|
+
config = Adminix::Config.instance
|
47
|
+
|
48
|
+
config.secret_key = options[:secret_key]
|
49
|
+
config.service_id = options[:service_id]
|
50
|
+
config.daemon = options[:daemonize]
|
51
|
+
if !config.credentials_defined? && config.creds_file_exists?
|
52
|
+
config.read_creds_file
|
53
|
+
end
|
49
54
|
end
|
50
55
|
|
51
56
|
case options[:action]
|
52
|
-
when "env"
|
57
|
+
when "env"
|
53
58
|
puts Adminix::Service.instance.options_to_envs
|
54
59
|
when "watch"
|
55
|
-
|
60
|
+
if config.credentials_defined?
|
61
|
+
puts Adminix::Watcher.run!(options)
|
62
|
+
else
|
63
|
+
puts 'Credentials are not defined, running setup server'
|
64
|
+
require 'adminix/setup'
|
65
|
+
end
|
56
66
|
when "version"
|
57
67
|
puts "adminix version #{Adminix::VERSION}"
|
58
68
|
else
|
data/lib/adminix/config.rb
CHANGED
@@ -1,19 +1,40 @@
|
|
1
1
|
require 'singleton'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
module Adminix
|
4
5
|
class Config
|
5
6
|
include Singleton
|
6
7
|
|
7
8
|
DEFAULT_HOST = 'http://api.adminix.io'.freeze
|
9
|
+
DEFAULT_SETUP_SERVER_PORT = '8080'
|
8
10
|
|
9
|
-
attr_accessor :service_id, :secret_key, :host, :commands, :daemon
|
11
|
+
attr_accessor :service_id, :secret_key, :host, :commands, :daemon, :setup_server_port
|
10
12
|
|
11
13
|
def initialize
|
12
|
-
|
13
|
-
|
14
|
-
self.host = ENV['ADMINIX_HOST'] || DEFAULT_HOST
|
14
|
+
self.host = ENV['ADMINIX_HOST'] || DEFAULT_HOST
|
15
|
+
self.setup_server_port = ENV['ADMINIX_SETUP_SERVER_PORT'] || DEFAULT_SETUP_SERVER_PORT
|
15
16
|
self.commands = []
|
16
17
|
end
|
18
|
+
|
19
|
+
def read_creds_file
|
20
|
+
file_content = IO.read("#{ENV['HOME']}/.adminix")
|
21
|
+
data = JSON.parse(file_content) rescue nil
|
22
|
+
|
23
|
+
unless data.nil?
|
24
|
+
self.service_id ||= data['service_id']
|
25
|
+
self.secret_key ||= data['secret_key']
|
26
|
+
end
|
27
|
+
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def creds_file_exists?
|
32
|
+
File.exists?("#{ENV['HOME']}/.adminix")
|
33
|
+
end
|
34
|
+
|
35
|
+
def credentials_defined?
|
36
|
+
!service_id.nil? && !secret_key.nil?
|
37
|
+
end
|
17
38
|
end
|
18
39
|
end
|
19
40
|
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Adminix::Setup
|
4
|
+
class Routes < Sinatra::Base
|
5
|
+
get '/' do
|
6
|
+
render('root')
|
7
|
+
end
|
8
|
+
|
9
|
+
get '/login' do
|
10
|
+
render('login')
|
11
|
+
end
|
12
|
+
|
13
|
+
post '/login' do
|
14
|
+
result = Services.create_session(params[:session])
|
15
|
+
case result[0]
|
16
|
+
when :ok
|
17
|
+
redirect "/create-service?t=#{result[1]}"
|
18
|
+
when :error
|
19
|
+
errors = result[1]
|
20
|
+
render('login', session: params[:session], errors: errors)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
get '/sign-up' do
|
25
|
+
render('sign_up')
|
26
|
+
end
|
27
|
+
|
28
|
+
post '/sign-up' do
|
29
|
+
result = Services.create_user(params[:user])
|
30
|
+
case result[0]
|
31
|
+
when :ok
|
32
|
+
redirect "/create-service?t=#{result[1]}"
|
33
|
+
when :error
|
34
|
+
errors = result[1]
|
35
|
+
render('sign_up', user: params[:user], errors: errors)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
get '/create-service' do
|
40
|
+
if params[:t]
|
41
|
+
case (result = Services.get_existing_services(params[:t]))[0]
|
42
|
+
when :ok
|
43
|
+
render('create_service', token: params[:t], service_exists: result[1] != 0)
|
44
|
+
when :error
|
45
|
+
render('error')
|
46
|
+
end
|
47
|
+
else
|
48
|
+
redirect '/sign-up'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
post '/create-service' do
|
53
|
+
if params[:t]
|
54
|
+
case (result = Services.create_service(params[:t], params[:service]))[0]
|
55
|
+
when :ok
|
56
|
+
redirect "/complete?t=#{params[:t]}&id=#{result[1]['id']}"
|
57
|
+
when :error
|
58
|
+
render('error')
|
59
|
+
end
|
60
|
+
else
|
61
|
+
redirect '/sign-up'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
get '/connect-service' do
|
66
|
+
if params[:t]
|
67
|
+
case (result = Services.get_existing_services(params[:t]))[0]
|
68
|
+
when :ok
|
69
|
+
render('connect_service', token: params[:t], services: result[1])
|
70
|
+
when :error
|
71
|
+
render('error')
|
72
|
+
end
|
73
|
+
else
|
74
|
+
redirect '/sign-up'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
post '/connect-service' do
|
79
|
+
redirect "/complete?t=#{params[:t]}&id=#{params[:service][:id]}"
|
80
|
+
end
|
81
|
+
|
82
|
+
get '/complete' do
|
83
|
+
if params[:t] && params[:id]
|
84
|
+
id_is_valid = Services.verify_service_id(params[:t], params[:id])
|
85
|
+
secret_key = Services.get_secret_key(params[:t])
|
86
|
+
if id_is_valid && !secret_key.nil?
|
87
|
+
Services.import_settings(secret_key, params[:id])
|
88
|
+
render('complete')
|
89
|
+
else
|
90
|
+
render('error')
|
91
|
+
end
|
92
|
+
else
|
93
|
+
render('error')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def render(view_name, assigns={})
|
100
|
+
Views.send("#{view_name}_view", assigns)
|
101
|
+
end
|
102
|
+
|
103
|
+
set :port, Adminix::Config.instance.setup_server_port
|
104
|
+
|
105
|
+
run!
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Adminix::Setup
|
5
|
+
module Services
|
6
|
+
def self.create_session(payload)
|
7
|
+
uri = URI.parse("#{config.host}/v1/profile/session")
|
8
|
+
request = Net::HTTP::Post.new(uri)
|
9
|
+
request['Content-Type'] = 'application/json'
|
10
|
+
request.body = {
|
11
|
+
session: {
|
12
|
+
connect_type: 'email',
|
13
|
+
connect_data: {
|
14
|
+
email: payload[:email],
|
15
|
+
password: payload[:password]
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}.to_json
|
19
|
+
opts = { use_ssl: uri.scheme == 'https' }
|
20
|
+
|
21
|
+
response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
|
22
|
+
http.request(request)
|
23
|
+
end
|
24
|
+
|
25
|
+
data = JSON.parse(response.body)
|
26
|
+
|
27
|
+
data['success'] == true ? [:ok, data['result']['token']] : [:error, { email: ['Invalid credentials'] }]
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.create_user(payload)
|
31
|
+
uri = URI.parse("#{config.host}/v1/profile")
|
32
|
+
request = Net::HTTP::Post.new(uri)
|
33
|
+
request['Content-Type'] = 'application/json'
|
34
|
+
request.body = {
|
35
|
+
profile: {
|
36
|
+
connect_type: 'email',
|
37
|
+
connect_data: {
|
38
|
+
email: payload[:email],
|
39
|
+
first_name: payload[:first_name],
|
40
|
+
last_name: payload[:last_name],
|
41
|
+
password: payload[:password],
|
42
|
+
locale: 'en'
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}.to_json
|
46
|
+
opts = { use_ssl: uri.scheme == 'https' }
|
47
|
+
|
48
|
+
response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
|
49
|
+
http.request(request)
|
50
|
+
end
|
51
|
+
|
52
|
+
data = JSON.parse(response.body)
|
53
|
+
|
54
|
+
data['success'] == true ? [:ok, data['result']['token']] : [:error, data['result']]
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.create_service(access_token, payload)
|
58
|
+
uri = URI.parse("#{config.host}/v1/services")
|
59
|
+
request = Net::HTTP::Post.new(uri)
|
60
|
+
request['Content-Type'] = 'application/json'
|
61
|
+
request['X-Auth-Token'] = access_token
|
62
|
+
request.body = {
|
63
|
+
service: {
|
64
|
+
name: payload[:name]
|
65
|
+
}
|
66
|
+
}.to_json
|
67
|
+
opts = { use_ssl: uri.scheme == 'https' }
|
68
|
+
|
69
|
+
response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
|
70
|
+
http.request(request)
|
71
|
+
end
|
72
|
+
|
73
|
+
data = JSON.parse(response.body)
|
74
|
+
|
75
|
+
data['success'] == true ? [:ok, data['result']] : [:error, data['result']]
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.get_existing_services(access_token)
|
79
|
+
uri = URI.parse("#{config.host}/v1/services")
|
80
|
+
request = Net::HTTP::Get.new(uri)
|
81
|
+
request["X-Auth-Token"] = access_token
|
82
|
+
opts = { use_ssl: uri.scheme == 'https' }
|
83
|
+
|
84
|
+
response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
|
85
|
+
http.request(request)
|
86
|
+
end
|
87
|
+
|
88
|
+
data = JSON.parse(response.body) rescue {}
|
89
|
+
|
90
|
+
data['success'] == true ? [:ok, data['result']] : [:error, []]
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.get_secret_key(access_token)
|
94
|
+
uri = URI.parse("#{config.host}/v1/profile/session")
|
95
|
+
request = Net::HTTP::Get.new(uri)
|
96
|
+
request["X-Auth-Token"] = access_token
|
97
|
+
opts = { use_ssl: uri.scheme == 'https' }
|
98
|
+
|
99
|
+
response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
|
100
|
+
http.request(request)
|
101
|
+
end
|
102
|
+
|
103
|
+
data = JSON.parse(response.body) rescue {}
|
104
|
+
|
105
|
+
data['result']['user']['secret_key'] rescue nil
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.verify_service_id(access_token, service_id)
|
109
|
+
uri = URI.parse("#{config.host}/v1/services/#{service_id}")
|
110
|
+
request = Net::HTTP::Get.new(uri)
|
111
|
+
request["X-Auth-Token"] = access_token
|
112
|
+
opts = { use_ssl: uri.scheme == 'https' }
|
113
|
+
|
114
|
+
response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
|
115
|
+
http.request(request)
|
116
|
+
end
|
117
|
+
|
118
|
+
data = JSON.parse(response.body) rescue {}
|
119
|
+
|
120
|
+
data['success'] == true
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def self.config
|
126
|
+
Adminix::Config.instance
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.import_settings(secret_key, service_id)
|
130
|
+
open("#{ENV['HOME']}/.adminix", 'w') do |f|
|
131
|
+
f.puts({ secret_key: secret_key, service_id: service_id }.to_json)
|
132
|
+
end
|
133
|
+
|
134
|
+
true
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
@@ -0,0 +1,183 @@
|
|
1
|
+
module Adminix::Setup
|
2
|
+
module Views
|
3
|
+
def self.root_view(_assigns)
|
4
|
+
layout do
|
5
|
+
%{
|
6
|
+
<div class="row">
|
7
|
+
<div class="col-md-6 col-md-offset-3">
|
8
|
+
<br/>
|
9
|
+
<a href="http://adminix.io" title="Adminix website" target="_blank">
|
10
|
+
<img src="http://www.adminix.io/images/logo_square.jpg" alt="Adminix logo" class="img-responsive center-block" style="width: 130px" />
|
11
|
+
</a>
|
12
|
+
<br/>
|
13
|
+
<p>Thank you for using Adminix image!</p>
|
14
|
+
<p>Your application is almost deployed, please click on "Continue" button to finish setup process.</p>
|
15
|
+
<button type="button" class="btn btn-primary" onclick="location.href='/sign-up';">Continue</button>
|
16
|
+
<br/><br/>
|
17
|
+
<a href="http://adminix.io" title="Adminix website" target="_blank">Click to visit our website</a>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.login_view(assigns)
|
25
|
+
session = assigns[:session] || {}
|
26
|
+
errors = assigns[:errors] || []
|
27
|
+
layout do
|
28
|
+
panel(title: 'Login') do
|
29
|
+
%{
|
30
|
+
<form method="POST" action="/login">
|
31
|
+
#{form_group('email', type: 'email', name: 'session[email]', label: 'Email', placeholder: 'Please enter your email', value: session[:email])}
|
32
|
+
#{form_group('password', type: 'password', name: 'session[password]', label: 'Password', placeholder: 'Please enter your password')}
|
33
|
+
#{errors.count != 0 ? render_errors(errors) : ''}
|
34
|
+
<button type="submit" class="btn btn-primary">Login</button>
|
35
|
+
<br/><br/>
|
36
|
+
<a href="/sign-up" title="Sign up">New to Adminix? Create a FREE account</a>
|
37
|
+
</form>
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.sign_up_view(assigns)
|
44
|
+
user = assigns[:user] || {}
|
45
|
+
errors = assigns[:errors] || []
|
46
|
+
layout do
|
47
|
+
panel(title: 'Create a FREE Adminix account') do
|
48
|
+
%{
|
49
|
+
<form method="POST" action="/sign-up">
|
50
|
+
#{form_group('first_name', type: 'text', name: 'user[first_name]', label: 'First name', placeholder: 'Please enter your first name', value: user[:first_name])}
|
51
|
+
#{form_group('last_name', type: 'text', name: 'user[last_name]', label: 'Last name', placeholder: 'Please enter your last name', value: user[:last_name])}
|
52
|
+
#{form_group('email', type: 'email', name: 'user[email]', label: 'Email', placeholder: 'Please enter your email', value: user[:email])}
|
53
|
+
#{form_group('password', type: 'password', name: 'user[password]', label: 'Password', placeholder: 'Please enter your password')}
|
54
|
+
#{errors.count != 0 ? render_errors(errors) : ''}
|
55
|
+
<button type="submit" class="btn btn-primary">Sign up</button>
|
56
|
+
<br/><br/>
|
57
|
+
<a href="/login" title="Login">Already have an account? Login</a>
|
58
|
+
</form>
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.create_service_view(assigns)
|
65
|
+
layout do
|
66
|
+
panel(title: 'Create service') do
|
67
|
+
%{
|
68
|
+
<form method="POST" action="/create-service?t=#{assigns[:token]}">
|
69
|
+
#{form_group('name', type: 'text', name: 'service[name]', label: 'Service name', placeholder: 'Please enter your service name')}
|
70
|
+
<button type="submit" class="btn btn-primary" onclick="location.href='/complete';">Launch your service</button>
|
71
|
+
<br/><br/>
|
72
|
+
#{assigns[:service_exists] ? "<a href=\"/connect-service?t=#{assigns[:token]}\" title=\"Connect service\">Already have an existing service? Choose it</a>" : ''}
|
73
|
+
</form>
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.connect_service_view(assigns)
|
80
|
+
layout do
|
81
|
+
panel(title: 'Connect existing service') do
|
82
|
+
%{
|
83
|
+
<form method="POST" action="/connect-service?t=#{assigns[:token]}">
|
84
|
+
<div class="form-group">
|
85
|
+
<label for="service_id">Please select service to connect</label>
|
86
|
+
<select class="form-control" name="service[id]" id="service_id">
|
87
|
+
#{(assigns[:services].map { |s| "<option value='#{s['id']}'>#{s['name']}</option>" }).join('')}
|
88
|
+
</select>
|
89
|
+
</div>
|
90
|
+
<button type="submit" class="btn btn-primary">Launch your service</button>
|
91
|
+
<br/><br/>
|
92
|
+
<a href="/create-service?t=#{assigns[:token]}" title="Connect service">Want to create a new one? Create service</a>
|
93
|
+
</form>
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.complete_view(_assigns)
|
100
|
+
layout do
|
101
|
+
panel(title: 'Application setup process completed') do
|
102
|
+
%{
|
103
|
+
<p>Your application setup is completed.
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.error_view(_assigns)
|
110
|
+
layout do
|
111
|
+
panel(title: 'Something went wrong') do
|
112
|
+
%{
|
113
|
+
<p>Something went wrong please retry a process.</p>
|
114
|
+
}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def self.layout
|
122
|
+
%{
|
123
|
+
<html>
|
124
|
+
<head>
|
125
|
+
<title>Adminix setup</title>
|
126
|
+
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
127
|
+
</head>
|
128
|
+
<body>
|
129
|
+
<div class="container">
|
130
|
+
#{yield}
|
131
|
+
</div>
|
132
|
+
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
|
133
|
+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
134
|
+
</body>
|
135
|
+
</html>
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.panel(assigns)
|
140
|
+
%{
|
141
|
+
<div class="row">
|
142
|
+
<div class="col-md-offset-2 col-md-8">
|
143
|
+
<div class="panel panel-default">
|
144
|
+
<div class="panel-heading clearfix">
|
145
|
+
<i class="icon-calendar"></i>
|
146
|
+
<h3 class="panel-title">#{assigns[:title]}</h3>
|
147
|
+
</div>
|
148
|
+
<div class="panel-body">
|
149
|
+
<div class="row">
|
150
|
+
<div class="col-md-6 col-md-offset-3">
|
151
|
+
#{yield}
|
152
|
+
</div>
|
153
|
+
</div>
|
154
|
+
</div>
|
155
|
+
</div>
|
156
|
+
</div>
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.render_errors(errors)
|
161
|
+
flash (errors.map { |k,v| "#{v}<br/>" }).join('<br/>')
|
162
|
+
text = errors.map do |attr, errors|
|
163
|
+
(errors.map { |err| "#{attr} #{err}" }).join('<br/>')
|
164
|
+
end.join('<br/>')
|
165
|
+
|
166
|
+
flash(text)
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.flash(text, type='danger')
|
170
|
+
%{<div class="alert alert-#{type}">#{text}</div>}
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.form_group(id, assigns)
|
174
|
+
%{
|
175
|
+
<div class="form-group">
|
176
|
+
<label for="#{id}">#{assigns[:label]}</label>
|
177
|
+
<input type="#{assigns[:type]}" name="#{assigns[:name]}" value="#{assigns[:value]}" class="form-control" id="#{id}" placeholder="#{assigns[:placeholder]}">
|
178
|
+
</div>
|
179
|
+
}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
data/lib/adminix/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adminix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Dyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.1.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sinatra
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.4.8
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.4.8
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,6 +158,10 @@ files:
|
|
144
158
|
- lib/adminix/.service.rb.swn
|
145
159
|
- lib/adminix/config.rb
|
146
160
|
- lib/adminix/service.rb
|
161
|
+
- lib/adminix/setup.rb
|
162
|
+
- lib/adminix/setup/routes.rb
|
163
|
+
- lib/adminix/setup/services.rb
|
164
|
+
- lib/adminix/setup/views.rb
|
147
165
|
- lib/adminix/system.rb
|
148
166
|
- lib/adminix/version.rb
|
149
167
|
- lib/adminix/watcher.rb
|