-
Notifications
You must be signed in to change notification settings - Fork 268
/
core.rb
244 lines (202 loc) · 7.1 KB
/
core.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#require 'em/pure_ruby'
require 'logger'
require 'sinatra'
require 'sinatra/contrib'
require 'yaml'
require 'rest-client'
require 'cgi'
require 'uri'
require 'shellwords' # shell escapin'
# Improved Json memory efficiency
require 'yajl'
require 'yajl/json_gem'
# Sidekiq
require 'sidekiq'
require 'sidekiq/api'
require 'sidekiq/web'
require 'sidekiq-limit_fetch'
# Global vars
$intrigue_basedir = File.dirname(__FILE__)
$intrigue_environment = ENV.fetch("INTRIGUE_ENV","development")
Encoding.default_external="UTF-8"
Encoding.default_internal="UTF-8"
# System-level Monkey patches
require_relative 'lib/initialize/array'
require_relative 'lib/initialize/hash'
require_relative 'lib/initialize/json_export_file'
require_relative 'lib/initialize/queue'
require_relative 'lib/initialize/sidekiq_profiler'
require_relative 'lib/initialize/string'
require_relative 'lib/initialize/typhoeus'
# load up our system config
require_relative 'lib/system/config'
Intrigue::Core::System::Config.load_config
# system database configuration
require_relative 'lib/system/database'
include Intrigue::Core::System::Database
# used in app as well as tasks
require_relative 'lib/system/validations'
include Intrigue::Core::System::Validations
# used in app as well as tasks
require_relative 'lib/system/helpers'
include Intrigue::Core::System::Helpers
# Debug
require 'logger'
# disable annoying redis messages
Redis.exists_returns_integer = false
#
# Simple configuration check to ensure we have configs in place
def sanity_check_system
configuration_files = [
"#{$intrigue_basedir}/config/config.json",
"#{$intrigue_basedir}/config/database.yml",
"#{$intrigue_basedir}/config/sidekiq.yml",
"#{$intrigue_basedir}/config/redis.yml",
"#{$intrigue_basedir}/config/puma.rb"
]
configuration_files.each do |file|
unless File.exist? file
puts "ERROR! Missing configuration file! Cowardly refusing to start."
puts "Missing file: #{file}"
exit -1
end
end
end
def setup_redis
redis_config = YAML.load_file("#{$intrigue_basedir}/config/redis.yml")
$redis_host = ENV["REDIS_HOST"] || redis_config[$intrigue_environment]["host"] || "localhost"
$redis_port = ENV["REDIS_PORT"] || redis_config[$intrigue_environment]["port"] || 6379
$redis_pass = ENV["REDIS_PASS"] || redis_config[$intrigue_environment]["password"] || nil
$redis_connect_string = "redis://#{$redis_host}:#{$redis_port}/"
# Pull sidekiq config from the environment if it's available (see docker config)
Sidekiq.configure_server do |config|
puts "Connecting to Redis Server at: #{$redis_connect_string}"
# if password is present, use it
if $redis_pass
config.redis = { url: $redis_connect_string, password: $redis_pass}
else
config.redis = { url: $redis_connect_string}
end
end
# configure the client
Sidekiq.configure_client do |config|
puts "Configuring Redis Client for: #{$redis_connect_string}"
# if password is present, use it
if $redis_pass
config.redis = { url: $redis_connect_string, password: $redis_pass}
else
config.redis = { url: $redis_connect_string}
end
end
end
sanity_check_system
setup_redis unless ENV["INTRIGUE_ENV"] == "test"
setup_database
class CoreApp < Sinatra::Base
register Sinatra::Namespace
set :allow_origin, "https://localhost:7778"
set :allow_methods, "GET,HEAD,POST"
set :allow_headers, "content-type,if-modified-since,allow"
set :expose_headers, "location,link"
set :allow_credentials, true
set :sessions => true
set :root, "#{$intrigue_basedir}"
set :views, "#{$intrigue_basedir}/app/views"
set :public_folder, 'public'
if Intrigue::Core::System::Config.config["debug"]
set :logging, true
end
###
### Helpers
###
helpers do
def h(text)
CGI::escapeHTML "#{text}"
end
end
###
### (Very) Simple Auth
###
if Intrigue::Core::System::Config.config
if Intrigue::Core::System::Config.config["http_security"]
use Rack::Auth::Basic, "Restricted" do |username, password|
[username, password] == [
Intrigue::Core::System::Config.config["credentials"]["username"],
Intrigue::Core::System::Config.config["credentials"]["password"]
]
end
end
else
puts "FATAL!! unable to access global config, cowardly refusing to start."
end
before do
# TODO - use settings helper going forward
$intrigue_server_uri = "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}"
# Parse out our project
directive = URI.decode_www_form_component(request.path_info.split("/")[1] || "Default")
# set flash message if we have one
if session[:flash]
@flash = session[:flash]
session[:flash] = nil
end
# Allow certain requests without a project string... these are systemwide,
# and do not depend on a specific project
pass if [ "api", "entity_types.json", "engine", "favicon.ico",
"project", "tasks", "tasks.json",
"version.json", "system", nil ].include? directive
pass if request.path_info =~ /\.js$/ # all js
pass if request.path_info =~ /\.css$/ # all css
pass if request.path_info =~ /(.jpg|.png)$/ # all images
# Set the project based on the directive
project = Intrigue::Core::Model::Project.first(:name => directive)
# If we haven't resolved a project, let's handle it
unless project
# Creating a default project since it doesn't appear to exist (it should always exist)
if directive == "Default"
project = Intrigue::Core::Model::Project.create(:name => "Default", :created_at => Time.now.utc )
else
redirect "/"
end
end
# Set it so we can use it going forward
@project_name = project.name
end
not_found do
"Unable to find this content."
end
### ###
### App-Level Constants ###
### ###
FRONT_PAGE = "/"
### ###
### App-Level Informational API Calls ###
### ###
# Return a JSON array of all entity type
get '/entity_types.json' do
content_type 'application/json'
Intrigue::EntityFactory.entity_types.map{ |e| e.metadata }.sort_by{|m| m[:name] }.to_json
end
# Export All Tasks
get '/tasks.json/?' do
content_type 'application/json'
Intrigue::TaskFactory.list.map{ |t| t.metadata }.sort_by{|m| m[:name] }.to_json
end
# Export a single task
get '/tasks/*.json/?' do
content_type 'application/json'
task_name = params[:splat][0..-1].join('/')
Intrigue::TaskFactory.list.select{|t| t.metadata[:name] == task_name }.first.metadata.to_json
end
# Application libraries
require_relative "app/all"
end
# Core libraries
require_relative "lib/all"
#configure sentry.io error reporting (only if a key was provided)
if (Intrigue::Core::System::Config.config && Intrigue::Core::System::Config.config["sentry_dsn"])
require "raven"
puts "!!! Configuring Sentry error reporting to: #{Intrigue::Core::System::Config.config["sentry_dsn"]}"
Raven.configure do |config|
config.dsn = Intrigue::Core::System::Config.config["sentry_dsn"]
end
end