sinatra-hexacta 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sinatra/extensions/antiquity.rb +34 -0
- data/lib/sinatra/extensions/date.rb +49 -0
- data/lib/sinatra/extensions/init.rb +4 -0
- data/lib/sinatra/extensions/notification.rb +41 -0
- data/lib/sinatra/handlers/errors.rb +10 -3
- data/lib/sinatra/handlers/init.rb +3 -1
- data/lib/sinatra/handlers/notifications.rb +17 -28
- data/lib/sinatra/handlers/params.rb +26 -0
- data/lib/sinatra/handlers/reports.rb +28 -1
- data/lib/sinatra/helpers/alerts.rb +27 -0
- data/lib/sinatra/helpers/cas.rb +92 -0
- data/lib/sinatra/helpers/charts.rb +20 -4
- data/lib/sinatra/helpers/init.rb +4 -0
- data/lib/sinatra/helpers/inputs.rb +2 -2
- data/lib/sinatra/helpers/libraries.rb +2 -2
- data/lib/sinatra/helpers/mailer.rb +74 -0
- data/lib/sinatra/helpers/reports.rb +27 -0
- data/lib/sinatra/helpers/schedule.rb +68 -0
- data/lib/sinatra/helpers/subscriptions.rb +1 -1
- data/lib/sinatra/hexacta.rb +13 -5
- data/lib/sinatra/public/css/app.min.1.css +130 -12
- data/lib/sinatra/public/js/app.js +49 -42
- data/lib/sinatra/public/vendors/chartist/chartist-plugin-legend.js +237 -0
- data/lib/sinatra/views/alerts/empty.slim +7 -0
- data/lib/sinatra/views/alerts/error.slim +7 -0
- data/lib/sinatra/views/alerts/info.slim +7 -0
- data/lib/sinatra/views/alerts/warning.slim +7 -0
- data/lib/sinatra/views/charts/bar.slim +56 -0
- data/lib/sinatra/views/charts/gauge.slim +30 -0
- data/lib/sinatra/views/charts/{simple_line.slim → line.slim} +7 -8
- data/lib/sinatra/views/charts/pie.slim +34 -0
- data/lib/sinatra/views/charts/stacked_bar.slim +36 -0
- data/lib/sinatra/views/inputs/multiple_select.slim +4 -0
- data/lib/sinatra/views/inputs/select.slim +3 -0
- data/lib/sinatra/views/libraries/include_js_after.slim +0 -24
- data/lib/sinatra/views/libraries/include_js_before.slim +1 -0
- data/lib/sinatra/views/notifications.slim +37 -31
- data/lib/sinatra/views/notifications/form.slim +4 -4
- data/lib/sinatra/views/notifications/new.slim +4 -4
- data/lib/sinatra/views/notifications/widget.slim +9 -5
- data/lib/sinatra/views/reports/pick_date.slim +14 -0
- data/lib/sinatra/views/reports/pick_dates.slim +16 -0
- data/lib/sinatra/views/reports/pick_month.slim +14 -0
- data/lib/sinatra/views/reports/pick_year.slim +14 -0
- metadata +26 -3
@@ -1,15 +1,31 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Sinatra
|
3
|
-
module
|
3
|
+
module ChartsHelper
|
4
4
|
extend Hexacta
|
5
5
|
|
6
|
-
def
|
7
|
-
slim "#{Hexacta::GEM_FILE_DIR}/charts/
|
6
|
+
def line_chart(option_hash)
|
7
|
+
slim "#{Hexacta::GEM_FILE_DIR}/charts/line".to_sym, locals: option_hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def bar_chart(option_hash)
|
11
|
+
slim "#{Hexacta::GEM_FILE_DIR}/charts/bar".to_sym, locals: option_hash
|
12
|
+
end
|
13
|
+
|
14
|
+
def pie_chart(option_hash)
|
15
|
+
slim "#{Hexacta::GEM_FILE_DIR}/charts/pie".to_sym, locals: option_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def gauge_chart(option_hash)
|
19
|
+
slim "#{Hexacta::GEM_FILE_DIR}/charts/gauge".to_sym, locals: option_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def stacked_bar_chart(option_hash)
|
23
|
+
slim "#{Hexacta::GEM_FILE_DIR}/charts/stacked_bar".to_sym, locals: option_hash
|
8
24
|
end
|
9
25
|
|
10
26
|
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/charts")
|
11
27
|
symlink_all("/lib/sinatra/views/charts","/app/views/#{Hexacta::GEM_FILE_DIR}/charts")
|
12
28
|
end
|
13
29
|
|
14
|
-
helpers
|
30
|
+
helpers ChartsHelper
|
15
31
|
end
|
data/lib/sinatra/helpers/init.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Sinatra
|
3
|
-
module
|
3
|
+
module InputHelper
|
4
4
|
extend Hexacta
|
5
5
|
|
6
6
|
def date_input(option_hash)
|
@@ -43,5 +43,5 @@ module Sinatra
|
|
43
43
|
symlink_all("/lib/sinatra/views/inputs","/app/views/#{Hexacta::GEM_FILE_DIR}/inputs")
|
44
44
|
end
|
45
45
|
|
46
|
-
helpers
|
46
|
+
helpers InputHelper
|
47
47
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Sinatra
|
3
|
-
module
|
3
|
+
module LibrariesHelper
|
4
4
|
extend Hexacta
|
5
5
|
|
6
6
|
def include_css
|
@@ -21,5 +21,5 @@ module Sinatra
|
|
21
21
|
symlink_all("/lib/sinatra/views/libraries","/app/views/#{Hexacta::GEM_FILE_DIR}/libraries")
|
22
22
|
end
|
23
23
|
|
24
|
-
helpers
|
24
|
+
helpers LibrariesHelper
|
25
25
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'sucker_punch'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
module MailHelper
|
6
|
+
|
7
|
+
attr_reader :access_token, :expire, :refresh_token
|
8
|
+
|
9
|
+
def _do_connect(uri, form={},token=nil)
|
10
|
+
url = URI.parse("#{uri}")
|
11
|
+
http = Net::HTTP.new(url.host, url.port)
|
12
|
+
http.read_timeout = 1000
|
13
|
+
http.use_ssl = (url.scheme == 'https')
|
14
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
15
|
+
header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
16
|
+
header["Authorization"] = "Bearer #{token}" unless token.nil?
|
17
|
+
request = Net::HTTP::Post.new(url, header)
|
18
|
+
request.form_data = form
|
19
|
+
http.start {|http| http.request(request) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def _authorize_mail
|
23
|
+
params = [ [ "grant_type", "password" ], [ "client_id", "MailApp" ], [ "client_secret", "MailAppPRD2018!" ] ]
|
24
|
+
response = _do_connect("https://comunicacion.hexacta.com:4443/apptoken",params)
|
25
|
+
if( response.is_a?( Net::HTTPSuccess ) )
|
26
|
+
token = JSON.parse(response.body)
|
27
|
+
@access_token = token["access_token"]
|
28
|
+
@refresh_token = token["refresh_token"]
|
29
|
+
@expire = DateTime.parse(token[".expires"])
|
30
|
+
else
|
31
|
+
p "Didn't succeed :("
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def _build_map_values(mail_values)
|
36
|
+
values = []
|
37
|
+
for key in mail_values.keys
|
38
|
+
index = mail_values.keys.index(key)
|
39
|
+
values << ["MailValues[#{index}].Key", key]
|
40
|
+
values << ["MailValues[#{index}].Value", mail_values[key]]
|
41
|
+
end
|
42
|
+
values
|
43
|
+
end
|
44
|
+
|
45
|
+
def _build_to_map(to_map)
|
46
|
+
values = []
|
47
|
+
for key in to_map.keys
|
48
|
+
index = to_map.keys.index(key)
|
49
|
+
values << ["ResourcesRequest[#{index}].TypeGroup", to_map[key]]
|
50
|
+
values << ["ResourcesRequest[#{index}].Name", key]
|
51
|
+
end
|
52
|
+
values
|
53
|
+
end
|
54
|
+
|
55
|
+
def _expired?
|
56
|
+
expire.nil? || DateTime.now < expire
|
57
|
+
end
|
58
|
+
|
59
|
+
def send_mail(template,subject,mail_values={},to_map)
|
60
|
+
if _expired?
|
61
|
+
_authorize_mail
|
62
|
+
end
|
63
|
+
params = [ [ "ApplicationCode", 1 ], [ "Name", template ], [ "Subject", subject ], [ "EmailAddress", "apps@hexacta.com" ] ]
|
64
|
+
params = params + _build_map_values(mail_values) + _build_to_map(to_map)
|
65
|
+
response = do_connect("https://comunicacion.hexacta.com:4444/api/app/TemplateNotification/SendMail",params,@access_token)
|
66
|
+
if( !response.is_a?( Net::HTTPSuccess ) )
|
67
|
+
p "Didn't succeed :("
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
helpers MailHelper
|
74
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Sinatra
|
3
|
+
module ReportHelper
|
4
|
+
extend Hexacta
|
5
|
+
|
6
|
+
def pick_date_input(option_hash)
|
7
|
+
slim "#{Hexacta::GEM_FILE_DIR}/reports/pick_date".to_sym, locals: option_hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def pick_dates_input(option_hash)
|
11
|
+
slim "#{Hexacta::GEM_FILE_DIR}/reports/pick_dates".to_sym, locals: option_hash
|
12
|
+
end
|
13
|
+
|
14
|
+
def pick_month_input(option_hash)
|
15
|
+
slim "#{Hexacta::GEM_FILE_DIR}/reports/pick_month".to_sym, locals: option_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def pick_year_input(option_hash)
|
19
|
+
slim "#{Hexacta::GEM_FILE_DIR}/reports/pick_year".to_sym, locals: option_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
setup_dir("/app/views/#{Hexacta::GEM_FILE_DIR}/reports")
|
23
|
+
symlink_all("/lib/sinatra/views/reports","/app/views/#{Hexacta::GEM_FILE_DIR}/reports")
|
24
|
+
end
|
25
|
+
|
26
|
+
helpers ReportHelper
|
27
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
# encoding: utf-8
|
3
|
+
module Sinatra
|
4
|
+
module ScheduleHelper
|
5
|
+
|
6
|
+
@@scheduler = Rufus::Scheduler.new
|
7
|
+
|
8
|
+
def schedule_every(time)
|
9
|
+
@@scheduler.every time do
|
10
|
+
begin
|
11
|
+
file_path = "/tmp/schedule.lock";
|
12
|
+
f = File.open(file_path, "w+")
|
13
|
+
# if file was previosly locked then flock throw a exception
|
14
|
+
f.flock(File::LOCK_EX)
|
15
|
+
ten_minutes = 600
|
16
|
+
# if the process overcome ten minutes, the timeout api throw a exception
|
17
|
+
Timeout::timeout(ten_minutes) do
|
18
|
+
|
19
|
+
begin
|
20
|
+
yield
|
21
|
+
rescue StandardError => error
|
22
|
+
title = error.message.split(':')[0].gsub('#<','');
|
23
|
+
message = error.backtrace.join(',');
|
24
|
+
NotificationSender.send_error(nil,title,message)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
ensure
|
29
|
+
unless f.nil?
|
30
|
+
f.flock(File::LOCK_UN)
|
31
|
+
f.close
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def schedule_at(cron_expression)
|
38
|
+
@@scheduler.cron cron_expression do
|
39
|
+
begin
|
40
|
+
file_path = "/tmp/schedule.lock";
|
41
|
+
f = File.open(file_path, "w+")
|
42
|
+
# if file was previosly locked then flock throw a exception
|
43
|
+
f.flock(File::LOCK_EX)
|
44
|
+
ten_minutes = 600
|
45
|
+
# if the process overcome ten minutes, the timeout api throw a exception
|
46
|
+
Timeout::timeout(ten_minutes) do
|
47
|
+
|
48
|
+
begin
|
49
|
+
yield
|
50
|
+
rescue error
|
51
|
+
title = error.message.split(':')[0].gsub('#<','');
|
52
|
+
message = error.backtrace.join(',');
|
53
|
+
NotificationSender.send_error(nil,title,message)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
ensure
|
58
|
+
unless f.nil?
|
59
|
+
f.flock(File::LOCK_UN)
|
60
|
+
f.close
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
register ScheduleHelper
|
68
|
+
end
|
@@ -3,7 +3,6 @@ module Sinatra
|
|
3
3
|
module SubscriptionHelper
|
4
4
|
|
5
5
|
def notify_to(user,creator,title,message,label,link=nil)
|
6
|
-
#return if creator.id == user.id
|
7
6
|
notification = Notification.find_or_create(:user_id => user.id,
|
8
7
|
:creator_id => creator.id,
|
9
8
|
:title => title,
|
@@ -26,6 +25,7 @@ module Sinatra
|
|
26
25
|
|
27
26
|
def notify_error(creator,title,message)
|
28
27
|
Subscription.where(:label => 'error').all.each do |subscription|
|
28
|
+
creator = subscription.user if creator.nil?
|
29
29
|
notification = Notification.find(:user_id => subscription.user_id,
|
30
30
|
:creator_id => creator.id,
|
31
31
|
:title => title,
|
data/lib/sinatra/hexacta.rb
CHANGED
@@ -1,32 +1,40 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'sinatra/base'
|
3
3
|
require 'fileutils'
|
4
|
+
require 'sucker_punch'
|
5
|
+
require 'rufus-scheduler'
|
4
6
|
|
5
7
|
module Sinatra
|
8
|
+
|
6
9
|
module Hexacta
|
7
10
|
GEM_FILE_DIR = "sinatra-hexacta"
|
8
11
|
|
9
12
|
def symlink(original_path, link_path)
|
10
|
-
#p "Symlinking #{original_path} #{link_path}"
|
11
13
|
File.symlink "#{Gem.loaded_specs["sinatra-hexacta"].gem_dir}#{original_path}", "#{link_path}" unless Gem.loaded_specs["sinatra-hexacta"].nil? || File.exist?("#{link_path}")
|
12
14
|
end
|
13
15
|
|
14
16
|
def symlink_all(original_path, link_path)
|
15
17
|
Dir.foreach("#{Gem.loaded_specs["sinatra-hexacta"].gem_dir}#{original_path}") do |child|
|
16
18
|
symlink("#{original_path}/#{child}","#{link_path}/#{child}") unless child == '.' || child == '..'
|
17
|
-
end
|
19
|
+
end unless Gem.loaded_specs["sinatra-hexacta"].nil?
|
18
20
|
end
|
19
21
|
|
20
22
|
def setup_dir(path)
|
21
|
-
|
23
|
+
unless Gem.loaded_specs["sinatra-hexacta"].nil?
|
24
|
+
FileUtils.remove_dir path if Dir.exist? path
|
25
|
+
FileUtils.mkdir_p path
|
26
|
+
end
|
22
27
|
end
|
23
28
|
|
24
29
|
def copy_dir_structure(original_path, destination_path)
|
25
|
-
|
26
|
-
|
30
|
+
unless Gem.loaded_specs["sinatra-hexacta"].nil?
|
31
|
+
FileUtils.remove_dir destination_path if Dir.exist? destination_path
|
32
|
+
FileUtils.copy_entry("#{Gem.loaded_specs["sinatra-hexacta"].gem_dir}#{original_path}", destination_path)
|
33
|
+
end
|
27
34
|
end
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
31
38
|
require_relative 'helpers/init'
|
32
39
|
require_relative 'handlers/init'
|
40
|
+
require_relative 'extensions/init'
|
@@ -10550,10 +10550,6 @@ h6 small,
|
|
10550
10550
|
left: 0;
|
10551
10551
|
top: 0;
|
10552
10552
|
padding: 0 11px;
|
10553
|
-
transition: all .5s ease-out;
|
10554
|
-
-moz-transition: all .5s ease-out;
|
10555
|
-
-o-transition: all .5s ease-out;
|
10556
|
-
-webkit-transition: all .5s ease-out;
|
10557
10553
|
}
|
10558
10554
|
|
10559
10555
|
#header:not(.sidebar-toggled).header-up {
|
@@ -10571,14 +10567,6 @@ h6 small,
|
|
10571
10567
|
left: 0;
|
10572
10568
|
width: 100%;
|
10573
10569
|
height: 70px;
|
10574
|
-
background: #fff;
|
10575
|
-
-webkit-transition: all;
|
10576
|
-
-o-transition: all;
|
10577
|
-
transition: all;
|
10578
|
-
-webkit-transition-duration: 300ms;
|
10579
|
-
transition-duration: 300ms;
|
10580
|
-
opacity: 0;
|
10581
|
-
filter: alpha(opacity=0);
|
10582
10570
|
z-index: 10;
|
10583
10571
|
}
|
10584
10572
|
|
@@ -11925,6 +11913,10 @@ a.lv-footer:hover {
|
|
11925
11913
|
width: 100%;
|
11926
11914
|
}
|
11927
11915
|
|
11916
|
+
.chart-table table {
|
11917
|
+
font-size: 11px;
|
11918
|
+
}
|
11919
|
+
|
11928
11920
|
/*
|
11929
11921
|
* Sparkline Tooltip
|
11930
11922
|
*/
|
@@ -16229,3 +16221,129 @@ body.login-content:before {
|
|
16229
16221
|
.error .chosen-container-active .chosen-single:after {
|
16230
16222
|
background: #f6675d !Important;
|
16231
16223
|
}
|
16224
|
+
|
16225
|
+
svg.ct-chart-bar, svg.ct-chart-line{
|
16226
|
+
overflow: visible;
|
16227
|
+
}
|
16228
|
+
|
16229
|
+
.ct-label.ct-label.ct-horizontal.ct-end {
|
16230
|
+
position: relative;
|
16231
|
+
justify-content: flex-end;
|
16232
|
+
text-align: right;
|
16233
|
+
transform-origin: 100% 0;
|
16234
|
+
transform: translate(-100%) rotate(-45deg);
|
16235
|
+
white-space:nowrap;
|
16236
|
+
}
|
16237
|
+
|
16238
|
+
|
16239
|
+
.ct-legend {
|
16240
|
+
position: relative;
|
16241
|
+
z-index: 10;
|
16242
|
+
list-style: none;
|
16243
|
+
text-align: left;
|
16244
|
+
cursor: pointer;
|
16245
|
+
}
|
16246
|
+
|
16247
|
+
.bar-chart .ct-legend, .line-chart .ct-legend {
|
16248
|
+
text-align: center;
|
16249
|
+
}
|
16250
|
+
|
16251
|
+
.ct-legend li {
|
16252
|
+
position: relative;
|
16253
|
+
padding-left: 23px;
|
16254
|
+
margin-bottom: 3px;
|
16255
|
+
}
|
16256
|
+
|
16257
|
+
.bar-chart .ct-legend li, .line-chart .ct-legend li{
|
16258
|
+
display: inline-block;
|
16259
|
+
margin: 10px;
|
16260
|
+
}
|
16261
|
+
|
16262
|
+
.ct-legend li:before {
|
16263
|
+
width: 12px;
|
16264
|
+
height: 12px;
|
16265
|
+
position: absolute;
|
16266
|
+
left: 0;
|
16267
|
+
content: '';
|
16268
|
+
border: 3px solid transparent;
|
16269
|
+
border-radius: 2px;
|
16270
|
+
}
|
16271
|
+
|
16272
|
+
.ct-legend li.inactive:before {
|
16273
|
+
background: transparent;
|
16274
|
+
}
|
16275
|
+
|
16276
|
+
.ct-legend .ct-series-0:before {
|
16277
|
+
background-color: #d70206;
|
16278
|
+
border-color: #d70206;
|
16279
|
+
}
|
16280
|
+
|
16281
|
+
.ct-legend .ct-series-1:before {
|
16282
|
+
background-color: #f05b4f;
|
16283
|
+
border-color: #f05b4f;
|
16284
|
+
}
|
16285
|
+
|
16286
|
+
.ct-legend .ct-series-2:before {
|
16287
|
+
background-color: #f4c63d;
|
16288
|
+
border-color: #f4c63d;
|
16289
|
+
}
|
16290
|
+
|
16291
|
+
.ct-legend .ct-series-3:before {
|
16292
|
+
background-color: #d17905;
|
16293
|
+
border-color: #d17905;
|
16294
|
+
}
|
16295
|
+
|
16296
|
+
.ct-legend .ct-series-4:before {
|
16297
|
+
background-color: #453d3f;
|
16298
|
+
border-color: #453d3f;
|
16299
|
+
}
|
16300
|
+
|
16301
|
+
.ct-legend .ct-series-5:before {
|
16302
|
+
background-color: #59922b;
|
16303
|
+
border-color: #59922b;
|
16304
|
+
}
|
16305
|
+
|
16306
|
+
.ct-legend .ct-series-6:before {
|
16307
|
+
background-color: #0544d3;
|
16308
|
+
border-color: #0544d3;
|
16309
|
+
}
|
16310
|
+
|
16311
|
+
.ct-legend .ct-series-7:before {
|
16312
|
+
background-color: #6b0392;
|
16313
|
+
border-color: #6b0392;
|
16314
|
+
}
|
16315
|
+
|
16316
|
+
.ct-legend .ct-series-8:before {
|
16317
|
+
background-color: #f05b4f;
|
16318
|
+
border-color: #f05b4f;
|
16319
|
+
}
|
16320
|
+
|
16321
|
+
.ct-legend .ct-series-9:before {
|
16322
|
+
background-color: #dda458;
|
16323
|
+
border-color: #dda458;
|
16324
|
+
}
|
16325
|
+
|
16326
|
+
.ct-legend .ct-series-10:before {
|
16327
|
+
background-color: #eacf7d;
|
16328
|
+
border-color: #eacf7d;
|
16329
|
+
}
|
16330
|
+
|
16331
|
+
.ct-legend .ct-series-11:before {
|
16332
|
+
background-color: #86797d;
|
16333
|
+
border-color: #86797d;
|
16334
|
+
}
|
16335
|
+
|
16336
|
+
.ct-legend .ct-series-12:before {
|
16337
|
+
background-color: #b2c326;
|
16338
|
+
border-color: #b2c326;
|
16339
|
+
}
|
16340
|
+
|
16341
|
+
.ct-legend .ct-series-13:before {
|
16342
|
+
background-color: #6188e2;
|
16343
|
+
border-color: #6188e2;
|
16344
|
+
}
|
16345
|
+
|
16346
|
+
.ct-legend .ct-series-14:before {
|
16347
|
+
background-color: #a748ca;
|
16348
|
+
border-color: #a748ca;
|
16349
|
+
}
|