diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..d817069
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,5 @@
+.git
+.dockerignore
+.byebug_history
+log/*
+tmp/*
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 0254eab..e550422 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
/vendor/bundle/
/vendor/ruby/
/node_modules
+/docker/ssl_keys
# minimal Rails specific artifacts
diff --git a/Gemfile b/Gemfile
index 08cfd34..334fe4a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,6 +7,7 @@ gem 'bootstrap', '~> 4.0.0'
gem 'jquery-rails'
gem 'bourbon'
gem 'foreman'
+gem 'rails_12factor', group: :production
gem 'dotenv'
gem 'coffee-rails', '~> 4.2'
gem 'devise'
diff --git a/Gemfile.lock b/Gemfile.lock
index 6247f42..b1b76ac 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -270,7 +270,12 @@ GEM
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
+ rails_12factor (0.0.3)
+ rails_serve_static_assets
+ rails_stdout_logging
rails_layout (1.0.42)
+ rails_serve_static_assets (0.0.5)
+ rails_stdout_logging (0.0.5)
railties (5.2.1)
actionpack (= 5.2.1)
activesupport (= 5.2.1)
@@ -429,6 +434,7 @@ DEPENDENCIES
puma (~> 3.11)
pundit
rails (~> 5.2.0)
+ rails_12factor
rails_layout
rspec-rails
sass-rails (~> 5.0)
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 6274a2b..fcda9cc 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -15,8 +15,6 @@
//= require popper
//= require bootstrap-sprockets
//= require moment
-////= require select2/dist/js/select2.full.js
-//= require chart.js/dist/Chart.js
//= require cable
//= require moment
//= require jquery
diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss
index ae55bc4..10d3c59 100644
--- a/app/assets/stylesheets/application.css.scss
+++ b/app/assets/stylesheets/application.css.scss
@@ -11,7 +11,6 @@
* It is generally better to create a new file per style scope.
*
*= require fullcalendar
- //*= require select2/dist/css/select2.css
*= require_tree .
*= require_self
@@ -32,14 +31,14 @@
}
.main.ui.container {
-//#main-container {
+ //#main-container {
display: flex;
flex-flow: row nowrap;
justify-content: center;
}
.ui.raised.container.segment {
-//#container-segment {
+ //#container-segment {
margin-top: 23px;
margin-right: auto !important;
margin-left: auto !important;
@@ -52,7 +51,7 @@
margin-left: 210px;
}
-@media only screen and (max-width: 1520px) {
+@media only screen and (max-width: 1144px) {
#fixed-sidebar {
display: none;
}
@@ -77,7 +76,7 @@
}
}
-@media only screen and (min-width: 1521px) {
+@media only screen and (min-width: 1145px) {
#fixed-sidebar {
display: flex;
}
diff --git a/app/controllers/trainings_controller.rb b/app/controllers/trainings_controller.rb
index ecca016..f39a8f2 100644
--- a/app/controllers/trainings_controller.rb
+++ b/app/controllers/trainings_controller.rb
@@ -8,13 +8,26 @@ class TrainingsController < ApplicationController
# protect_from_forgery with: :null_session
skip_before_action :verify_authenticity_token, only: %i[join_clients exercises]
+ def index
+ @training = Training.where(user_id: current_user.id).map do |training|
+ {
+ name: Client.find_by(id: training.client_id).full_name,
+ training: training
+ }
+ end
+ end
+
+ def show
+ @name = Client.find_by(id: @training.client_id).full_name
+ @sets = kit_constructor
+ end
+
def new
@clients = current_user.clients
(current_user.trainings.find_by(status: 0))&.delete
+ @date = params[:date]
training = current_user.trainings.build
redirect_url calendar_path, alert: "Couldn't create training" unless training.save
- @date = params[:date]
- @training = current_user.trainings.build
end
def join_clients
@@ -52,22 +65,15 @@ def exercises
render layout: false
end
- def show
- authorize @training
- @name = Client.find_by(id: @training.client_id).full_name
- @sets = kit_constructor
- end
-
def client_list
current_user.clients.map do |client|
- # Client.where(user_id: user).map do |client|
+ # Client.where(user_id: user).map do |client|
[client.first_name + ' ' + client.second_name, client.id]
end
end
def create
@training = current_user.trainings.build(training_params)
- authorize @training
if @training.save
calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id
begin
@@ -84,13 +90,13 @@ def create
end_time = start_time + 2.hours
summary = Client.find_by(id: @training.client_id).full_name
event = Google::Apis::CalendarV3::Event.new(
- id: 'training' + @training.id.to_s + 'fitfree1asslcom',
- start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339),
- end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339),
- summary: summary,
- description: @training.description
- )
- service.insert_event(calendar_id, event)
+ id: 'training' + @training.id.to_s + 'fitfree1asslcom',
+ start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339),
+ end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339),
+ summary: summary,
+ description: @training.description
+ )
+ service.insert_event(calendar_id, event)
end
rescue Google::Apis::AuthorizationError
response = client.refresh!
@@ -105,7 +111,6 @@ def create
end
def edit
- authorize @training
@list = client_list
@name = name(@training)
@sets = sets(@training, current_user)
@@ -113,7 +118,6 @@ def edit
def update
@training.update(status: :planned)
- authorize @training
if @training.update(training_params)
calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id
begin
@@ -130,11 +134,11 @@ def update
end_time = start_time + 2.hours
summary = Client.find_by(id: @training.client_id).full_name
event = Google::Apis::CalendarV3::Event.new(
- start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339),
- end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339),
- summary: summary,
- description: @training.description
- )
+ start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339),
+ end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339),
+ summary: summary,
+ description: @training.description
+ )
if service.get_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom')
service.patch_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom', event)
end
@@ -157,12 +161,10 @@ def update
end
def cancel
- authorize @training
@training.update(status: :canceled)
end
def destroy
- authorize @training
calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id
begin
if calendar_id
@@ -178,14 +180,14 @@ def destroy
service.delete_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom')
end
end
+ TrainingsHelper::BackgroundProccess.delete_background_proc(@training.id) if @training.status == :planned
+ @training.destroy
+ redirect_to calendar_index_path
rescue Google::Apis::AuthorizationError
response = client.refresh!
session[:authorization] = session[:authorization].merge(response)
retry
end
- TrainingsHelper::BackgroundProccess.delete_background_proc(@training.id) if @training.status == :planned
- @training.destroy
- redirect_to calendar_index_path
end
private
@@ -216,8 +218,8 @@ def create_background_proc(training_id)
def kit_constructor
sets = Kit.where(training_id: @training.id, user_id: current_user.id).map do |kit|
{
- exercises: Exercise.where(kit_id: kit.id, user_id: current_user.id),
- kit: kit
+ exercises: Exercise.where(kit_id: kit.id, user_id: current_user.id),
+ kit: kit
}
end
sets.each do |kit|
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index de67dd2..c44ca30 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -28,7 +28,7 @@
<%= t('navigation.clients') %>
-
+
<%= t('navigation.settings') %>
@@ -55,7 +55,7 @@
<%= t('navigation.clients') %>
-
+
<%= t('navigation.settings') %>
diff --git a/app/views/payments/index.html.slim b/app/views/payments/index.html.slim
index 17d1297..569d4e0 100644
--- a/app/views/payments/index.html.slim
+++ b/app/views/payments/index.html.slim
@@ -1,6 +1,6 @@
= render 'clients/navbar', active_section: :payments
-.ui.container
+.main.ui.container
/todo: change depends screen size => .html.ui.top.attached.segment
.ui.raised.container.segment
.ui.top.attached.label
@@ -21,11 +21,22 @@
td.Date = payment.datetime.strftime("%B %d, %Y")
td.Price = payment.price
td.right.aligned.Cancel: button.negative.ui.button [onclick="document.location.replace('#{'payments/' + payment.id.to_s + '/delete'}')"] Ⓧ
- center
- .pagniation-wrapper align="center"
- = paginate @payments_list
- button.positive.ui.button [onclick="window.location='payments/create';"] #{t('.add')}
-
+ tfoot
+ tr
+ th colspan="3"
+ button.positive.ui.button [onclick="window.location='payments/create';"] Add
+ .ui.right.floated.pagination.menu
+ a.icon.item
+ i.left.chevron.icon
+ a.item 1
+ a.item 2
+ a.item 3
+ a.item 4
+ a.icon.item
+ i.right.chevron.icon
- else
h4 #{t('payments.index.no_payments')}
- button.positive.ui.button [type="submit" onclick="window.location='payments/create';"] #{t('.add')}
\ No newline at end of file
+ button.positive.ui.button [type="submit" onclick="window.location='payments/create';"] #{t('payments.index.add')}
+ /todo: make pagination
+ = paginate @payments_list,
+ previous_label: 'Previous', next_label: 'Next', inner_window: 1, outer_window: 0
\ No newline at end of file
diff --git a/config/application.rb b/config/application.rb
index 7ba4599..8d4a4a4 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -29,7 +29,7 @@ class Application < Rails::Application
config.i18n.default_locale = :en
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
- config.active_job.queue_adapter = Rails.env.production? ? :sidekiq : :async
+ config.active_job.queue_adapter = :sidekiq
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index 57930f9..9bef71d 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -3,11 +3,17 @@
Sidekiq.configure_client do |config|
# accepts :expiration (optional)
+ config.redis = {
+ url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}"
+ }
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes
end
Sidekiq.configure_server do |config|
# accepts :expiration (optional)
+ config.redis = {
+ url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}"
+ }
Sidekiq::Status.configure_server_middleware config, expiration: 30.minutes
# accepts :expiration (optional)
diff --git a/config/secrets.yml b/config/secrets.yml
index 8945aaf..efe5aff 100644
--- a/config/secrets.yml
+++ b/config/secrets.yml
@@ -38,7 +38,7 @@ test:
production:
admin_name: <%= ENV["ADMIN_NAME"] %>
admin_email: <%= ENV["ADMIN_EMAIL"] %>
- admin_password: <%= ENV["ADMIN_PASSWORD"] %>
+ admin_password: 123456789
email_provider_username: <%= ENV["SENDGRID_USERNAME"] %>
email_provider_password: <%= ENV["SENDGRID_PASSWORD"] %>
domain_name: <%= ENV["DOMAIN_NAME"] %>
diff --git a/db/schema.rb b/db/schema.rb
index bda4585..bdbbdc4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -34,13 +34,12 @@
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.index ["confirmation_token"], name: "index_administrators_on_confirmation_token", unique: true
- t.index ["email"], name: "index_administrators_on_email", unique: true
- t.index ["reset_password_token"], name: "index_administrators_on_reset_password_token", unique: true
end
create_table "attachments", force: :cascade do |t|
t.integer "message_id"
- t.text "path"
+ t.text "name"
+ t.integer "status"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
@@ -58,18 +57,18 @@
t.string "second_name", default: "", null: false
t.string "phone_number", default: "", null: false
t.integer "user_id"
- t.integer "price"
- t.datetime "birth"
- t.string "email"
- t.string "instagram_link"
- t.string "facebook_link"
- t.string "vk_link"
- t.integer "status"
+ t.datetime "birth", default: "2018-09-14 07:48:24", null: false
+ t.string "email", default: "", null: false
+ t.string "instagram_link", default: "", null: false
+ t.string "facebook_link", default: "", null: false
+ t.string "vk_link", default: "", null: false
+ t.integer "status", default: 0, null: false
+ t.integer "price", default: 0, null: false
+ t.string "telegram_chat_id"
+ t.string "telegram_bind_id", default: "73e911d9-da46-4354-9a08-086271698cc1"
t.integer "gender"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.string "telegram_chat_id"
- t.string "telegram_bind_id", default: "13a4cefa-016e-434b-a25d-1ae406d74abb"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.bigint "avatar_file_size"
@@ -111,21 +110,13 @@
end
create_table "exercises", force: :cascade do |t|
- t.integer "exercise_type_id"
+ t.bigint "exercise_type_id"
t.integer "kit_id"
- t.integer "user_id"
t.integer "repeats"
- t.integer "approach"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
- create_table "images", force: :cascade do |t|
- t.integer "message_id"
- t.integer "status"
- t.string "name"
+ t.integer "approaches"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.index ["exercise_type_id"], name: "index_exercises_on_exercise_type_id"
end
create_table "jobs", force: :cascade do |t|
@@ -180,9 +171,9 @@
create_table "metrics", force: :cascade do |t|
t.string "name", null: false
t.string "units", null: false
+ t.integer "kind_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.integer "kind_id"
end
create_table "snapshots", force: :cascade do |t|
@@ -193,30 +184,25 @@
t.index ["client_id"], name: "index_snapshots_on_client_id"
end
- create_table "statuses", force: :cascade do |t|
- t.string "name"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
create_table "telegram_bots", force: :cascade do |t|
t.bigint "user_id"
- t.string "token", default: "", null: false
- t.string "telegram_webhook_id", default: "11d6d037-15d1-4394-9485-5c3bb7b470d3", null: false
+ t.string "name"
+ t.string "token"
+ t.string "telegram_webhook_id", default: "f442b4a9-9882-4d20-9265-c20452cddfd4", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_telegram_bots_on_user_id"
end
create_table "trainings", force: :cascade do |t|
+ t.bigint "user_id"
t.datetime "time"
t.integer "price"
t.text "description"
- t.integer "user_id"
- t.integer "client_id"
- t.integer "status", default: 0, null: false
+ t.integer "status", default: 0
t.datetime "created_at", null: false
- t.datetime "updated_at", null: fals
+ t.datetime "updated_at", null: false
+ t.index ["user_id"], name: "index_trainings_on_user_id"
end
create_table "transactions", force: :cascade do |t|
@@ -233,7 +219,7 @@
t.string "encrypted_password", default: "", null: false
t.string "bot_token"
t.string "bot_name"
- t.string "bot_webhook_id", default: "b7c5bf6b-a8ea-4cba-ab0d-9216b8a876de", null: false
+ t.string "telegram_webhook_id", default: "eb4ddba1-640c-4ac1-8070-9be5c7f36b2c", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
@@ -249,11 +235,11 @@
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.datetime "blocked_at"
- t.integer "role"
- t.boolean "birthday_seen"
+ t.boolean "birthday_seen", default: false, null: false
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
+ add_foreign_key "jobs", "trainings"
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 422c1e7..173c4e0 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -14,49 +14,50 @@
%w[Приседания Подтягивания].each do |name|
Metric.find_or_create_by(name: name, units: 'повторы', kind_id: 1)
end
-Metric.create(name: 'Жим штанги лёжа', units: 'повторы', kind_id: 1)
-Metric.create(name: 'Становая тяга', units: 'повторы', kind_id: 1)
+Metric.find_or_create_by(name: 'Жим штанги лёжа', units: 'повторы', kind_id: 1)
+Metric.find_or_create_by(name: 'Становая тяга', units: 'повторы', kind_id: 1)
puts 'Created strength metrics'
-ExerciseType.create(name: 'Bench press with chest standing', description: '')
-ExerciseType.create(name: 'Press of dumbbells', description: '')
-ExerciseType.create(name: 'Mahi dumbbells in the sides', description: '')
-ExerciseType.create(name: 'Pulling the head with a wide grip', description: '')
-ExerciseType.create(name: 'Push-ups from the floor with a wide grip', description: '')
-ExerciseType.create(name: 'Pressing dumbbells at an angle of 30-40 °', description: '')
-ExerciseType.create(name: 'Press the rod at an angle of 30-40 °', description: '')
-ExerciseType.create(name: 'Hyperextension', description: '')
-ExerciseType.create(name: 'Deadlift on straight legs', description: '')
-ExerciseType.create(name: 'Static draft with dumbbells', description: '')
-ExerciseType.create(name: 'Pulling up to the chest with a wide grip', description: '')
-ExerciseType.create(name: 'Thrust of horizontal block', description: '')
-ExerciseType.create(name: 'Thrust T-neck in slope', description: '')
-ExerciseType.create(name: 'Pulling in a Smith machine', description: '')
-ExerciseType.create(name: 'Thrust from the upper block with a narrow handle', description: '')
-ExerciseType.create(name: 'Pull-ups', description: '')
-ExerciseType.create(name: 'Bending of arms with a standing post', description: '')
-ExerciseType.create(name: 'Bending of hands with dumbbells', description: '')
-ExerciseType.create(name: 'Push-ups from the beams on the triceps', description: '')
-ExerciseType.create(name: 'Push-ups with a narrow grip from the floor', description: '')
-ExerciseType.create(name: 'Press bar with a narrow grip', description: '')
-ExerciseType.create(name: 'Flexion of the wrists with the bar sitting', description: '')
-ExerciseType.create(name: 'Extension of hands with a bar sitting', description: '')
-ExerciseType.create(name: 'Lifting the legs in the vise', description: '')
-ExerciseType.create(name: 'Lifting the legs on an incline bench', description: '')
-ExerciseType.create(name: 'Twisting on an incline bench', description: '')
-ExerciseType.create(name: 'Twisting in a Roman chair', description: '')
-ExerciseType.create(name: 'Squats', description: '')
-ExerciseType.create(name: 'Impacts with a barbell', description: '')
-ExerciseType.create(name: 'Dumbbells with dumbbells', description: '')
-ExerciseType.create(name: 'Standing rod standing on a stand', description: '')
-ExerciseType.create(name: 'Squats', description: '')
-ExerciseType.create(name: 'Squats with a barbell on the chest', description: '')
-ExerciseType.create(name: 'Pressing your feet in the machine', description: '')
-ExerciseType.create(name: 'Deadlift on straight legs', description: '')
-ExerciseType.create(name: 'Leg bending in the machine', description: '')
-ExerciseType.create(name: 'Side Effects', description: '')
-ExerciseType.create(name: 'Bringing the hip in a crossover', description: '')
-ExerciseType.create(name: 'Ascent to the socks in a standing machine', description: '')
-ExerciseType.create(name: 'Ascent to the socks in a sitting simulator', description: '')
+ExerciseType.find_or_create_by(name: 'Bench press with chest standing', description: '')
+ExerciseType.find_or_create_by(name: 'Press of dumbbells', description: '')
+ExerciseType.find_or_create_by(name: 'Mahi dumbbells in the sides', description: '')
+ExerciseType.find_or_create_by(name: 'Pulling the head with a wide grip', description: '')
+ExerciseType.find_or_create_by(name: 'Push-ups from the floor with a wide grip', description: '')
+ExerciseType.find_or_create_by(name: 'Pressing dumbbells at an angle of 30-40 °', description: '')
+ExerciseType.find_or_create_by(name: 'Press the rod at an angle of 30-40 °', description: '')
+ExerciseType.find_or_create_by(name: 'Hyperextension', description: '')
+ExerciseType.find_or_create_by(name: 'Deadlift on straight legs', description: '')
+ExerciseType.find_or_create_by(name: 'Static draft with dumbbells', description: '')
+ExerciseType.find_or_create_by(name: 'Pulling up to the chest with a wide grip', description: '')
+ExerciseType.find_or_create_by(name: 'Thrust of horizontal block', description: '')
+ExerciseType.find_or_create_by(name: 'Thrust T-neck in slope', description: '')
+ExerciseType.find_or_create_by(name: 'Pulling in a Smith machine', description: '')
+ExerciseType.find_or_create_by(name: 'Thrust from the upper block with a narrow handle', description: '')
+ExerciseType.find_or_create_by(name: 'Pull-ups', description: '')
+ExerciseType.find_or_create_by(name: 'Bending of arms with a standing post', description: '')
+ExerciseType.find_or_create_by(name: 'Bending of hands with dumbbells', description: '')
+ExerciseType.find_or_create_by(name: 'Push-ups from the beams on the triceps', description: '')
+ExerciseType.find_or_create_by(name: 'Push-ups with a narrow grip from the floor', description: '')
+ExerciseType.find_or_create_by(name: 'Press bar with a narrow grip', description: '')
+ExerciseType.find_or_create_by(name: 'Flexion of the wrists with the bar sitting', description: '')
+ExerciseType.find_or_create_by(name: 'Extension of hands with a bar sitting', description: '')
+ExerciseType.find_or_create_by(name: 'Lifting the legs in the vise', description: '')
+ExerciseType.find_or_create_by(name: 'Lifting the legs on an incline bench', description: '')
+ExerciseType.find_or_create_by(name: 'Twisting on an incline bench', description: '')
+ExerciseType.find_or_create_by(name: 'Twisting in a Roman chair', description: '')
+ExerciseType.find_or_create_by(name: 'Squats', description: '')
+ExerciseType.find_or_create_by(name: 'Impacts with a barbell', description: '')
+ExerciseType.find_or_create_by(name: 'Dumbbells with dumbbells', description: '')
+ExerciseType.find_or_create_by(name: 'Standing rod standing on a stand', description: '')
+ExerciseType.find_or_create_by(name: 'Squats', description: '')
+ExerciseType.find_or_create_by(name: 'Squats with a barbell on the chest', description: '')
+ExerciseType.find_or_create_by(name: 'Pressing your feet in the machine', description: '')
+ExerciseType.find_or_create_by(name: 'Deadlift on straight legs', description: '')
+ExerciseType.find_or_create_by(name: 'Leg bending in the machine', description: '')
+ExerciseType.find_or_create_by(name: 'Side Effects', description: '')
+ExerciseType.find_or_create_by(name: 'Bringing the hip in a crossover', description: '')
+ExerciseType.find_or_create_by(name: 'Ascent to the socks in a standing machine', description: '')
+ExerciseType.find_or_create_by(name: 'Ascent to the socks in a sitting simulator', description: '')
+puts 'Created default exercise types'
superadmin = Administrator.create(email: 'superadmin@gmail.com',
password: admin_password,
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
new file mode 100644
index 0000000..6441ed4
--- /dev/null
+++ b/docker-compose.override.yml
@@ -0,0 +1,9 @@
+version: '2'
+
+services:
+ app:
+ build:
+ args:
+ BRANCH: Alex
+ REPOSITORY: git@github.com:rubizza-survival-camp/fitfree.git
+ PROJECT_NAME: fitfree
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..f5a7e8e
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,55 @@
+version: '2'
+
+services:
+ # todo: ngnix, https://
+ postgres:
+ image: postgres:10.5
+ restart: always
+ volumes:
+ - /data:/var/lib/postgresql/data
+ env_file:
+ - .env
+
+ redis:
+ image: redis:5.0-rc4
+ restart: always
+ command: redis-server
+ ports:
+ - $REDIS_PORT:$REDIS_PORT
+ volumes:
+ - /data:/var/data/redis
+ env_file:
+ - .env
+
+ app:
+ depends_on:
+ - postgres
+ build:
+ context: .
+ dockerfile: ./docker/app/Dockerfile
+ volumes:
+ - .:/app
+
+ web:
+ build:
+ context: .
+ dockerfile: ./docker/nginx/Dockerfile
+ depends_on:
+ - app
+ ports:
+ - 90:90
+ - 443:443
+
+ sidekiq:
+ depends_on:
+ - redis
+ build:
+ context: .
+ dockerfile: ./docker/app/Dockerfile
+ command: bundle exec sidekiq
+ volumes:
+ - .:/app
+
+volumes:
+ redis:
+ postgres:
diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile
new file mode 100644
index 0000000..0838e5e
--- /dev/null
+++ b/docker/app/Dockerfile
@@ -0,0 +1,30 @@
+# todo: +-git cloning
+
+FROM rubyroidlabs/ruby:2-5-1-node-stretch
+
+ARG BRANCH
+ARG REPOSITORY
+ARG PROJECT_NAME
+
+LABEL maintainer="Aleksei Lazarenko "
+
+ENV RAILS_ROOT /var/www/fitfree
+RUN mkdir -p $RAILS_ROOT
+
+# Set working directory
+WORKDIR $RAILS_ROOT
+
+# Adding gems
+COPY Gemfile Gemfile
+COPY Gemfile.lock Gemfile.lock
+
+RUN bundle install
+
+# Adding project files
+COPY . .
+
+#RUN rails assets:precompile
+
+EXPOSE 3000
+
+CMD [ "bundle", "exec", "puma", "-C", "config/puma.rb" ]
diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile
new file mode 100644
index 0000000..d99cebe
--- /dev/null
+++ b/docker/nginx/Dockerfile
@@ -0,0 +1,23 @@
+FROM valian/docker-nginx-auto-ssl
+
+# establish where Nginx should look for files
+ENV RAILS_ROOT /var/www/fitfree
+
+# Set our working directory inside the image
+WORKDIR $RAILS_ROOT
+
+# create log directory
+RUN mkdir log
+
+# copy over static assets
+COPY public public/
+
+# Copy Nginx config template
+COPY docker/nginx/nginx.conf /usr/local/openresty/nginx/conf/
+COPY docker/ssl_keys/localhost.crt /usr/local/openresty/nginx/conf/localhost.crt
+COPY docker/ssl_keys/localhost.key /usr/local/openresty/nginx/conf/localhost.key
+
+EXPOSE 90 443
+
+# Use the "exec" form of CMD so Nginx shuts down gracefully on SIGTERM (i.e. `docker stop`)
+CMD [ "nginx", "-g", "daemon off;" ]
\ No newline at end of file
diff --git a/docker/nginx/index.html b/docker/nginx/index.html
new file mode 100644
index 0000000..9de2253
--- /dev/null
+++ b/docker/nginx/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+ Document
+
+
+
+
Here I am
+
+
+ Some other text
+
+
+
\ No newline at end of file
diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf
new file mode 100644
index 0000000..3e54e23
--- /dev/null
+++ b/docker/nginx/nginx.conf
@@ -0,0 +1,37 @@
+events {
+ worker_connections 1024;
+}
+
+http {
+ upstream puma_rails_app {
+ server app:3000;
+ }
+
+ include resty-http.conf;
+
+ server {
+ listen 443 ssl;
+ server_name my_app.com;
+ include resty-server-https.conf;
+ location / {
+ try_files $uri $uri/@rails_app;
+ }
+ location @rails_app {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $http_host;
+ proxy_redirect off;
+ proxy_pass https://puma_rails_app;
+ # limit_req zone=one;
+ access_log /var/www/fitfree/log/nginx.access.log;
+ error_log /var/www/fitfree/log/nginx.error.log;
+ }
+ ssl_certificate /usr/local/openresty/nginx/conf/localhost.crt;
+ ssl_certificate_key /usr/local/openresty/nginx/conf/localhost.key;
+ }
+
+ server {
+ listen 90 default_server;
+ server_name my_app.com;
+ include resty-server-http.conf;
+ }
+}
\ No newline at end of file
diff --git a/dump.rdb b/dump.rdb
deleted file mode 100644
index 2643490..0000000
Binary files a/dump.rdb and /dev/null differ
diff --git a/localhost.crt b/localhost.crt
new file mode 100644
index 0000000..be06efd
--- /dev/null
+++ b/localhost.crt
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC5TCCAc2gAwIBAgIJAMqTj9uW0y7FMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
+BAMMCWxvY2FsaG9zdDAeFw0xODA5MTcwNjQ2MTJaFw0xODEwMTcwNjQ2MTJaMBQx
+EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALZHXpQy12W1+hTRhRckSqjyT9xkHXo7XDc08dJgo2SFp4uB6ltKdZbNiJvn
+wv9JVWok3BcKLgENkpPhyPwfOqw6H8TH1JdKoZ/tMISpgNoz1YhAKKjgrs/RBWmR
+xRK/Kbyn2buNuKOtutfPrfemXUEk18/Jfj2HdNmrY3IkOvrsUmu4dfxzjIBgTBIt
+laxdxHoznp1YB12aknNZDmZwN6eaZRtnA+2AdSLXTTPsbNR81vGIv4pR5KXXJkoZ
+2/NDNDsXTVvx1ZzY/7p3vEafeYfpsGExAimJevxcQ/AYV07BxiuNgKCLndXCyXK9
+5IYNYXfu51CvgWjCcq6ZmQS1vCUCAwEAAaM6MDgwFAYDVR0RBA0wC4IJbG9jYWxo
+b3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B
+AQsFAAOCAQEAEq+2Bi0v7iKH+8d7MF79iEi+Q9xG9iMlPPAKro6yw+0mJX4EGKsa
+xE9tn4lbmCn/cOVKSHiLMIVng3iTGQdLmq1z9O4OWeszhemQ3BaP3lgPTuk7OmPL
+NbEw7H4JQA651vf5tdtd3IR/LM36U36TOnPdB2FJkrj3Ga7l9ZX61RRQBkhjzpmo
+9BN45gtdS8gBD3pHyWgVdlAciX+y84g4uXX/XWeOys4BhYmGdNNPAqYAphR936ys
+rv4RaPcyNFzzcPeoOM8Cx6X6lapw0bEeZVA8ETF510Sz8I6sE88qrEaZmeljC94V
+/JX2bE1aljgmVHUELkHSjrM8lWIcG81rbw==
+-----END CERTIFICATE-----
diff --git a/localhost.key b/localhost.key
new file mode 100644
index 0000000..172f7fd
--- /dev/null
+++ b/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2R16UMtdltfoU
+0YUXJEqo8k/cZB16O1w3NPHSYKNkhaeLgepbSnWWzYib58L/SVVqJNwXCi4BDZKT
+4cj8HzqsOh/Ex9SXSqGf7TCEqYDaM9WIQCio4K7P0QVpkcUSvym8p9m7jbijrbrX
+z633pl1BJNfPyX49h3TZq2NyJDr67FJruHX8c4yAYEwSLZWsXcR6M56dWAddmpJz
+WQ5mcDenmmUbZwPtgHUi100z7GzUfNbxiL+KUeSl1yZKGdvzQzQ7F01b8dWc2P+6
+d7xGn3mH6bBhMQIpiXr8XEPwGFdOwcYrjYCgi53VwslyveSGDWF37udQr4FownKu
+mZkEtbwlAgMBAAECggEAbIsfZPzJi4XL/+2sZVV1KBnzOHhdnVYP2cgrYG2vnsKA
+PPEGD4rNbxnBiaV/VunidSyx6v5i2rmsWWeQeaJXHAwYsuOUUutcR5HE3JrbYhSP
+yWz7SWVSc+oyYOUvB7TSM8d4Ptlr4/wmUTEYlWp6CbrY0KFaDWXGTYBj3ap5fMWP
+etODZI9zXCxkc3M8veW2UMFiLnU1qcLnGkCfyR6tEUGLU6YQ3GvobdhWD6v2uJc8
+PpdOkp+yAyUEJm6aUw6o6KT0ANOuOnhY7rimnZIpujkZ3fDpjczMUYgju9svCrLM
+C1zy0vhQEnAXe4dsfcd3d9egrCVxvEMOoWCy9XUBwQKBgQDn8V2JItT4r8LIxrDp
+2P2Hy2dpRixkyBLx0tMnD0VqHGejH0hcg/TXJPSKtZQ3w+wcOUdxLndDH5xz21ZE
+u7rwGRh8+vRq1cEA3D9KeVLTPK/OUmK9lRU9Yn8EcVyjABltX90gSoRxSIJeG+7Z
+ZLpKJw+jxa47KNB+hk+vc5ZfiQKBgQDJL04r8OoAbvFKJcVF5Ka5+9LyE/1cqgTI
+Cx7WQrlbk1CxSgA2pbgjlrxOpg6XZ4+OZ0Itbe5OVA3BHfF25+q9s8eaYXAjzOo9
+I5yuel2/tCZtIWC16gsI7/bZUhugvzXjSJsfHqgNFhzdt48PS1VW5bfjk1x+qla3
+7E+aoEaUvQKBgE91zQmSOUwJSr3l8+3pPNIsyPyz4bmVIYhfJZ+YB7vWh1rG+M9Z
+FaQvMOfkVSbVpCn3JZaMyKbiSYMXfXKGrgBbWJxYjSucl0ZoLfahodJkVAZnCxTP
+4jrpZ4JqI8Zj3lIuKV9KqBz3LlJ3V1h6vadxwlXk/0+dJ/BwqxP8kWOhAoGBAJU5
+vG8FZFxr7hfEil38atq6+k3LG/v2tFM5RGdC2MAfNhQ6wovGQh5LuWNQ8rPFAgtr
+df/Ccaex2v3qWueKwGhziFNvgMFdRkWRO6+DXjRKyNHblyN39TVs4JlzuMBz8+Gh
+QkZD8/y48TJX7Ao5I5SwEcUA0fO2H1qPMsCLr661AoGAImj3kx1SSNEsLJHnPy7y
+28V+ieNLo0Q9iDNJzH+dxx155sMzN3NWKvpWKzYSR1Bop8VslGd1XSt2fz9JkKcF
+gNDSMW2CR7wwe+IVJjxiCsBk4e+t7/axi4NnS6jbkNxZdFXmCG4RU1KpLDMcXKUE
+bsw8Iyi7La45Y5xVVg7O5s4=
+-----END PRIVATE KEY-----