From ec9aea94c5de868ed8605d42baefa8fe931612ac Mon Sep 17 00:00:00 2001 From: Aleksei Date: Fri, 31 Aug 2018 16:03:17 +0300 Subject: [PATCH 1/7] Config --- Gemfile | 1 + Gemfile.lock | 6 ++++++ app/controllers/application_controller.rb | 2 +- app/views/calendar/new.html.slim | 9 ++++++--- app/workers/birthday_notification_worker.rb | 2 +- dump.rdb | Bin 869 -> 1452 bytes 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 3c13d5d..8c1bc0f 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 c9e96d3..6eb33e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -264,7 +264,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) @@ -420,6 +425,7 @@ DEPENDENCIES puma (~> 3.11) pundit rails (~> 5.2.0) + rails_12factor rails_layout rspec-rails sass-rails (~> 5.0) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0852d53..ccf7574 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base def set_locale logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" locale = extract_locale_from_accept_language_header - I18n.locale = locale == 'ru' ? :ru : I18n.default_locale + I18n.locale = (locale == 'ru' || locale == 'ru-RU') ? :ru : I18n.default_locale logger.debug "* Locale set to '#{I18n.locale}'" end diff --git a/app/views/calendar/new.html.slim b/app/views/calendar/new.html.slim index 4896c6f..185ec06 100644 --- a/app/views/calendar/new.html.slim +++ b/app/views/calendar/new.html.slim @@ -1,3 +1,6 @@ -h3 - | #{t('calendar.new.title')} -= render 'form' \ No newline at end of file +.main.ui.container + .ui.raised.very.padded.text.container.segment + .ui.top.attached.label + h3 + | #{t('calendar.new.title')} + = render 'form' \ No newline at end of file diff --git a/app/workers/birthday_notification_worker.rb b/app/workers/birthday_notification_worker.rb index fbbb5ff..e32f720 100644 --- a/app/workers/birthday_notification_worker.rb +++ b/app/workers/birthday_notification_worker.rb @@ -3,6 +3,6 @@ class BirthdayNotificationWorker def perform User.all.each { |user| user.birthday_seen = false; user.save! } - BirthdayNotificationWorker.perform_at(DateTime.today + 1.day).to_f + BirthdayNotificationWorker.perform_at(Date.today + 1.day).to_f end end diff --git a/dump.rdb b/dump.rdb index 55fb60f9114e6df9dfcb0fc88c291804445b3b06..5599947bf561fbb2e92e7e73443e22de8ff00d4a 100644 GIT binary patch literal 1452 zcmchX&2QX97{^S;0LdET2h z=3iNY5PHK&ier+i8<QK3E=BiyX&l5BKi=7M~Y} zr%{%ueTq>p?BX5af$&F7k|c^59h7&Q*P8FmZpu*?<+&Wl*9c{+F&eZoMiLSsMzZwH zY?7{FDl0Og9q`-}%kL=i__iD{T3|(9FK~gul}d~gRCF15vHUKH!PzGx--*M>G!fGE z*baT@BV@$33BYW`%V9WfBPIvBZQ8B@q2X%2sk^%AC~^s>D{t(Hpk}(dW_h;h7&ZVk zN;BH-;XFs3#%8HV!PYEEaSVExt!6P;VOcx543dn3CBzf}b+A;$ePBS{3+BOQ_3dmHeAasH*PoiZ%|>(MzryMGPUPaq3z1=Y82J$j9Te#t z=efsl0&&VPG|#nl+p!dROtTD58yvF5Dcg<#z5ko%#O>{`D!v8zfZazl!FSCUIL(Q< z&+kb#G@-Qxe)wi)1hZTj8!IoJIy9DWCTEBReVRqw0yy5O?O!)v`UsZDV!TGy zgVB*94^Dywp&$sC_$LZNz39i>h3!#troO+)qf@CIT(4Hg1}ACf;Xb*e94~Q_y-$|- z@^}fMKJIH|x^YwYgQx~rXhUxoyphMTemYsOM z?TgZSK`@gN)XlLN@`Rl~%$8;HZ0Wk^8J0-WB-?F#-S~z3bT!Laih7tQ{}`#+BP||% zULk!fuur*~R!N02)uj!>z%0 z&a!+sUYYNeE(&qCaS_xje4HsG3}|~7KHX;E_4=benGUiz1;_CLP( t{=$dcIl{~s{?S8mFj^KW^i)&l{`%|G^xsDGk0TGKpa1>NkGE!?{Sz^M#&G}u delta 490 zcmZ3({giEjq45j(&gfqprNyZ!y1A*jhZO1s7=H02=BMcv6s0ESCgr3aVED)Io1goS za>vsCR7M5{7TrlKGVYe<7UovwX-R3OrYR}Lsg@}$EJ>+}B|?U##-`?m#zv+ldKRVz z29{<xsl?NDD3rjOoOIXtqbBa@0GV{{%4?FB}xIQ_S#ZD5a%7n#S&(g?Hfm6U# zN2wq)Mac?e!Q?G0!Qu(Ud?*$v)&BAQC227^o>kW0$l?I!A1$Fun=YWk7{rQ85=*So z5;JpBQ>=^(3@vmGEOd=54>0_B{C27nZY9PBKqY4~{~3bJG&3?k!1(82rIZ^U4Tc98 z7`TyaJHRmcFOw3R5ZEH1DRRCbBSFr@Z3xiq5L@vmF$XFEI%RSkt0Ef%*rOmP3IhGa g!Ngfml%JehT%20W2#OIYj2QX<<%`R8$(AT107rqINdN!< From 7b31e93ce956020af60b385e045e6118210caf2a Mon Sep 17 00:00:00 2001 From: Aleksei Date: Fri, 31 Aug 2018 16:14:50 +0300 Subject: [PATCH 2/7] Config add --- Procfile | 1 + app/workers/birthday_notification_worker.rb | 5 +++-- config.ru | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..f4cbe68 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: foreman start -f Procfile.for \ No newline at end of file diff --git a/app/workers/birthday_notification_worker.rb b/app/workers/birthday_notification_worker.rb index e32f720..f9e2bc3 100644 --- a/app/workers/birthday_notification_worker.rb +++ b/app/workers/birthday_notification_worker.rb @@ -1,8 +1,9 @@ class BirthdayNotificationWorker include Sidekiq::Worker + include Sidekiq::Status::Worker - def perform + def perform(*args) User.all.each { |user| user.birthday_seen = false; user.save! } - BirthdayNotificationWorker.perform_at(Date.today + 1.day).to_f + BirthdayNotificationWorker.perform_at(DateTime.now.tomorrow) end end diff --git a/config.ru b/config.ru index c843332..4781323 100644 --- a/config.ru +++ b/config.ru @@ -3,4 +3,4 @@ require_relative 'config/environment' run Rails.application -BirthdayNotificationWorker.perform_at(DateTime.now).to_f +BirthdayNotificationWorker.perform_async From 5d9fa263a497546977659679852d879e89a21b81 Mon Sep 17 00:00:00 2001 From: Aleksei Date: Fri, 31 Aug 2018 19:09:28 +0300 Subject: [PATCH 3/7] Fix calendar --- app/assets/javascripts/errors.coffee | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 app/assets/javascripts/errors.coffee diff --git a/app/assets/javascripts/errors.coffee b/app/assets/javascripts/errors.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/errors.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://coffeescript.org/ From a8e494a3c108a4a47b4a7be795666fc4358728b5 Mon Sep 17 00:00:00 2001 From: Aleksei Date: Fri, 31 Aug 2018 19:10:42 +0300 Subject: [PATCH 4/7] Fix application.rb --- Procfile.for | 2 +- app/controllers/calendar_controller.rb | 16 +++++++-------- app/controllers/trainings_controller.rb | 25 ++++++++++++------------ config/application.rb | 2 +- config/locales/activerecord.en.yml | 6 +++++- config/locales/activerecord.ru.yml | 4 ++++ dump.rdb | Bin 1452 -> 1053 bytes 7 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Procfile.for b/Procfile.for index 8878cc0..52ce224 100644 --- a/Procfile.for +++ b/Procfile.for @@ -1,3 +1,3 @@ -web: bundle exec rails server -p 3000 redis: redis-server sidekiq: sidekiq +rails: bundle exec rails server -p 3000 \ No newline at end of file diff --git a/app/controllers/calendar_controller.rb b/app/controllers/calendar_controller.rb index 9632d60..f69dca3 100644 --- a/app/controllers/calendar_controller.rb +++ b/app/controllers/calendar_controller.rb @@ -9,6 +9,10 @@ def index begin client = Signet::OAuth2::Client.new(client_options) client.update!(session[:authorization]) + if client.refresh_token == nil + refresh_token = Calendar.find_by(user_id: current_user.id).code + client.refresh_token = refresh_token + end service = Google::Apis::CalendarV3::CalendarService.new service.authorization = client @calendar = Calendar.find_by(user_id: current_user.id) @@ -16,10 +20,6 @@ def index @calendar_summary = service.get_calendar(@calendar.calendar_id).summary end rescue Google::Apis::AuthorizationError - if client.refresh_token == nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end response = client.refresh! session[:authorization] = session[:authorization].merge(response) retry @@ -33,6 +33,10 @@ def new begin client = Signet::OAuth2::Client.new(client_options) client.update!(session[:authorization]) + if client.refresh_token == nil + refresh_token = Calendar.find_by(user_id: current_user.id).code + client.refresh_token = refresh_token + end service = Google::Apis::CalendarV3::CalendarService.new service.authorization = client @calendar = Calendar.new @@ -44,10 +48,6 @@ def new @calendars << calendar end rescue Google::Apis::AuthorizationError - if client.refresh_token == nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end response = client.refresh! session[:authorization] = session[:authorization].merge(response) retry diff --git a/app/controllers/trainings_controller.rb b/app/controllers/trainings_controller.rb index 14f8c33..3f0406b 100644 --- a/app/controllers/trainings_controller.rb +++ b/app/controllers/trainings_controller.rb @@ -52,6 +52,10 @@ def create if calendar_id @client = Signet::OAuth2::Client.new(client_options) @client.update!(session[:authorization]) + if client.refresh_token == nil + refresh_token = Calendar.find_by(user_id: current_user.id).code + client.refresh_token = refresh_token + end service = Google::Apis::CalendarV3::CalendarService.new service.authorization = @client start_time = @training.time @@ -67,10 +71,6 @@ def create service.insert_event(calendar_id, event) end rescue Google::Apis::AuthorizationError - if client.refresh_token == nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end response = client.refresh! session[:authorization] = session[:authorization].merge(response) retry @@ -98,7 +98,10 @@ def update if calendar_id @client = Signet::OAuth2::Client.new(client_options) @client.update!(session[:authorization]) - + if client.refresh_token == nil + refresh_token = Calendar.find_by(user_id: current_user.id).code + client.refresh_token = refresh_token + end service = Google::Apis::CalendarV3::CalendarService.new service.authorization = @client start_time = @training.time @@ -115,10 +118,6 @@ def update end end rescue Google::Apis::AuthorizationError - if client.refresh_token == nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end response = client.refresh! session[:authorization] = session[:authorization].merge(response) retry @@ -147,6 +146,10 @@ def destroy if calendar_id @client = Signet::OAuth2::Client.new(client_options) @client.update!(session[:authorization]) + if client.refresh_token == nil + refresh_token = Calendar.find_by(user_id: current_user.id).code + client.refresh_token = refresh_token + end service = Google::Apis::CalendarV3::CalendarService.new service.authorization = @client if service.get_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom').status != 'cancelled' @@ -154,10 +157,6 @@ def destroy end end rescue Google::Apis::AuthorizationError - if client.refresh_token == nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end response = client.refresh! session[:authorization] = session[:authorization].merge(response) retry diff --git a/config/application.rb b/config/application.rb index c2ab447..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? ? :sidekq : :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/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 6cedd58..b483604 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -26,4 +26,8 @@ en: name: blank: "can't be blank" units: - blank: "can't be blank" \ No newline at end of file + blank: "can't be blank" + user: + attributes: + email: + taken: " already taken, select another" \ No newline at end of file diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml index d0ebc3b..0d450b4 100644 --- a/config/locales/activerecord.ru.yml +++ b/config/locales/activerecord.ru.yml @@ -27,3 +27,7 @@ ru: blank: "не может быть пустым" units: blank: "не может быть пустым" + user: + attributes: + email: + taken: " уже занят, выберите другой" diff --git a/dump.rdb b/dump.rdb index 5599947bf561fbb2e92e7e73443e22de8ff00d4a..4de93ee4ca87d9c9455d21a12a3527d29c5b1428 100644 GIT binary patch literal 1053 zcmcIjJx>%t7+&BGk3$GiVl*+~vXzOqo1LB6&&Kl$wGpC;6sR~m`|dHacMG$#Bo}gt ztyc8@1OJ2Zf{nF>(byO&D}TUA&^ZJJBZUR!ym{Wd&paRZZr-?a-?A*fKPDjNxv>sn zl$e%@tbX;^B;qpfHTq>Hc?-67o6i^fl_H1OXhCc19huVlr)icLs{&{%N};FiYTqj( zJ0HvB){7xc(=Oza%5YU=405#=+7|K+%QrCUO_VD+TZXtuVWhFSp|h0cxgP4*xRA>+ z?cB{IPdKBJXYGYdtbow#Iu%WYS$tI21xV4+Ln#WV>uUuRpmt+OXpu?_JN=v z#vZo8BM}N5n=ocOL;;whEFoT^QV)@X9nbbK!X_ceaV^}%R~}Bk+Wv6$q?oyoC`trD zKq>MA;@S}-Byx^thCLGauG?+xESxAaW@DQKPJ-PSVZxLiL`B3uMl(AIOxyPc(ssW- zem^zPY$uq0vkA)nl6iaHn5XMJRUR7gx@#y?A+bKO!@Y;_W1R+j!mhG_#>EXSrD375nxvZIA&c1vmCy#ts?+%Y0lp`PdPqno1y>ca# rrx5q5!=rmG$cIktx8P3;&m96Du3%N0JlfCR#E&Oi+n2w6o?H3}KoV8y literal 1452 zcmchX&2QX97{^S;0LdET2h z=3iNY5PHK&ier+i8<QK3E=BiyX&l5BKi=7M~Y} zr%{%ueTq>p?BX5af$&F7k|c^59h7&Q*P8FmZpu*?<+&Wl*9c{+F&eZoMiLSsMzZwH zY?7{FDl0Og9q`-}%kL=i__iD{T3|(9FK~gul}d~gRCF15vHUKH!PzGx--*M>G!fGE z*baT@BV@$33BYW`%V9WfBPIvBZQ8B@q2X%2sk^%AC~^s>D{t(Hpk}(dW_h;h7&ZVk zN;BH-;XFs3#%8HV!PYEEaSVExt!6P;VOcx543dn3CBzf}b+A;$ePBS{3+BOQ_3dmHeAasH*PoiZ%|>(MzryMGPUPaq3z1=Y82J$j9Te#t z=efsl0&&VPG|#nl+p!dROtTD58yvF5Dcg<#z5ko%#O>{`D!v8zfZazl!FSCUIL(Q< z&+kb#G@-Qxe)wi)1hZTj8!IoJIy9DWCTEBReVRqw0yy5O?O!)v`UsZDV!TGy zgVB*94^Dywp&$sC_$LZNz39i>h3!#troO+)qf@CIT(4Hg1}ACf;Xb*e94~Q_y-$|- z@^}fMKJIH|x^YwYgQx~rXhUxoyphMTemYsOM z?TgZSK`@gN)XlLN@`Rl~%$8;HZ0Wk^8J0-WB-?F#-S~z3bT!Laih7tQ{}`#+BP||% zULk!fuur*~R!N02)uj!>z%0 z&a!+sUYYNeE(&qCaS_xje4HsG3}|~7KHX;E_4=benGUiz1;_CLP( t{=$dcIl{~s{?S8mFj^KW^i)&l{`%|G^xsDGk0TGKpa1>NkGE!?{Sz^M#&G}u From 2e4c342ee46ccb79f45a409eaca10bf3a3830bbf Mon Sep 17 00:00:00 2001 From: Aleksei Date: Fri, 31 Aug 2018 21:01:46 +0300 Subject: [PATCH 5/7] Fix calendar error --- app/controllers/calendar_controller.rb | 4 ++-- app/controllers/trainings_controller.rb | 18 +++++++++--------- app/views/payments/create.html.slim | 17 ++++++++--------- dump.rdb | Bin 1053 -> 2206 bytes 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/app/controllers/calendar_controller.rb b/app/controllers/calendar_controller.rb index f69dca3..96e9755 100644 --- a/app/controllers/calendar_controller.rb +++ b/app/controllers/calendar_controller.rb @@ -9,7 +9,7 @@ def index begin client = Signet::OAuth2::Client.new(client_options) client.update!(session[:authorization]) - if client.refresh_token == nil + if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil refresh_token = Calendar.find_by(user_id: current_user.id).code client.refresh_token = refresh_token end @@ -33,7 +33,7 @@ def new begin client = Signet::OAuth2::Client.new(client_options) client.update!(session[:authorization]) - if client.refresh_token == nil + if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil refresh_token = Calendar.find_by(user_id: current_user.id).code client.refresh_token = refresh_token end diff --git a/app/controllers/trainings_controller.rb b/app/controllers/trainings_controller.rb index 3f0406b..8ca0190 100644 --- a/app/controllers/trainings_controller.rb +++ b/app/controllers/trainings_controller.rb @@ -50,9 +50,9 @@ def create calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id begin if calendar_id - @client = Signet::OAuth2::Client.new(client_options) - @client.update!(session[:authorization]) - if client.refresh_token == nil + client = Signet::OAuth2::Client.new(client_options) + client.update!(session[:authorization]) + if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil refresh_token = Calendar.find_by(user_id: current_user.id).code client.refresh_token = refresh_token end @@ -96,9 +96,9 @@ def update calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id begin if calendar_id - @client = Signet::OAuth2::Client.new(client_options) - @client.update!(session[:authorization]) - if client.refresh_token == nil + client = Signet::OAuth2::Client.new(client_options) + client.update!(session[:authorization]) + if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil refresh_token = Calendar.find_by(user_id: current_user.id).code client.refresh_token = refresh_token end @@ -144,9 +144,9 @@ def destroy calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id begin if calendar_id - @client = Signet::OAuth2::Client.new(client_options) - @client.update!(session[:authorization]) - if client.refresh_token == nil + client = Signet::OAuth2::Client.new(client_options) + client.update!(session[:authorization]) + if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil refresh_token = Calendar.find_by(user_id: current_user.id).code client.refresh_token = refresh_token end diff --git a/app/views/payments/create.html.slim b/app/views/payments/create.html.slim index ae27552..808b9aa 100644 --- a/app/views/payments/create.html.slim +++ b/app/views/payments/create.html.slim @@ -2,15 +2,14 @@ .ui.raised.very.padded.text.container.segment .ui.top.attached.label h4 #{t('.title')} -= form_tag('new', method: :post) - .ui.form.mb-3 - .field - label #{t('.date')} - #training_date.ui.calendar - .ui.input.left.icon - i.calendar.icon - input placeholder=t('.date') type="text" name="date" / - + =form_tag('new', method: :post) + .ui.form.mb-3 + .field + label #{t('.date')} + #training_date.ui.calendar + .ui.input.left.icon + i.calendar.icon + input placeholder=t('.date') type="text" name="date" / .ui.form.input.mb-3 .field label Price diff --git a/dump.rdb b/dump.rdb index 4de93ee4ca87d9c9455d21a12a3527d29c5b1428..e49e7fd4e13c3671c583f534a22048881ecfe671 100644 GIT binary patch literal 2206 zcmcJRzi%8x6vx-$d^w+;$btw$6p_;w(A+Kab9eR%a{LORAhG}@g@G_T^VVK`cWdv? z8cxBZGG7ote?bfGHqQvAoo!wbwk{;YJA8#-3)`}c-s|URs zVtdiqU65(qTF*fCqAu(>e>ry+jvuRT6i`4ub6i6#i>?`+T)FnjCo_)YJeeD5+Ur@W zAh&ti1YyxaqDAq};^@PtywAa|I`K@NXjn@&+T+zl-lintj0qkqOn}Eoa2d)t=AFU7 z=G?Sb-EroNbuA5C9iyK3`Py)Mx%$X^iJm=O7Ja5VO<$Yh>RR>vG+TqLcIJg7Gpkw- zE~O@k6D3WO_ODFdovp}hC9gVnM<12JN<|=)LL!i1Of9v~bSwha+1j$8AN&h!S@b?^ zO{Kl{E*Pjk6mGwGdZKNmb#bY+BsY_;JyT0>`Yn4%h|+Yewe(_}6CAevFvJ0u3I~!` zDp8RScAVLbA^|fS%We*p2&8!wbIJoMn7|$*gmO+QNk2}%?_BTPJh$bprn%|M9=L7y zkPXl6?dUdLTZGJjzABB|o+b?ldxCmYP>%ejyPjxw0@iemTxq;Ee<3j!GJwWq;-SWK zb(Qv2k!8?VgU0!@sOe74=eC#Kd-ikRZn|9=LAP_NF<-UT>YKzgyx$)C^4n~%IL8K z9b>FXsC`Ze8&{f;(0@P+9iT6Z-lzXBEp%*dZw}-$59dnft_8ZMmu|^W3_#yw|Na$IWhyWc`zY$p&uQWCh%Fn2p`@SJSnF#@?4r z8ksmHiaLPUlO=+_^rR zMn(dPZ7~_js084Xw{e1F&*T{%)RMeJw^ sc}#tcDN|MtX8$iliDo1WJtBg!w8P)u`DJme+1;-%Kl{b4H@`alH+uQRw*UYD delta 341 zcmbOyIG1CBq0Ybb&gfqprNyZ!y1A*jhfbIXF#O_4%umxTC`wJtP0C3}W1^Ave_SviW6Gg4DZb5fZnC$dLumS-U6H_xQ zGZS+&%e2%a~**~If}{7 z&dA)zlGjqtz`)SJ#ME3zsUR~&L4pHhoQ_gSV!DDqw_9e3TTyDNLYR@Bfr0~9a(-TN zX;D#XUUH>^#^ftZdJ3}}O88LhR;p#9(tdZ_KOO+OS#F{L From d17ca9fa439f31f7c1d5efe753c2462b974a7539 Mon Sep 17 00:00:00 2001 From: Aleksei Date: Wed, 12 Sep 2018 15:28:58 +0300 Subject: [PATCH 6/7] Docker --- .dockerignore | 5 ++ Dockerfile | 18 ++++ app/assets/javascripts/application.js | 2 - app/assets/stylesheets/application.css.scss | 9 +- app/controllers/trainings_controller.rb | 95 +++++++++----------- app/views/layouts/application.html.erb | 4 +- app/views/payments/index.html.slim | 25 ++++-- config/application.rb | 2 +- config/initializers/sidekiq.rb | 6 ++ config/secrets.yml | 2 +- db/schema.rb | 64 ++++++------- db/seeds.rb | 85 +++++++++--------- docker-compose.yml | 45 ++++++++++ dump.rdb | Bin 3472 -> 3266 bytes 14 files changed, 211 insertions(+), 151 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml 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/Dockerfile b/Dockerfile new file mode 100644 index 0000000..260588e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM ruby:2.5.1 + +RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ + && apt-get install -y nodejs + +RUN apt-get update -qq && apt-get install -y build-essential libpq-dev && rm -rf /var/lib/apt/lists + +RUN curl -o- -L https://yarnpkg.com/install.sh | bash + +RUN mkdir /app +WORKDIR /app + +COPY Gemfile Gemfile.lock ./ +RUN bundle install + +COPY . . + +LABEL maintainer="Aleksei Lazarenko " \ No newline at end of file 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..50f69f9 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,48 +65,37 @@ 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 if calendar_id - client = Signet::OAuth2::Client.new(client_options) - client.update!(session[:authorization]) - if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end + @client = Signet::OAuth2::Client.new(client_options) + @client.update!(session[:authorization]) service = Google::Apis::CalendarV3::CalendarService.new service.authorization = @client start_time = @training.time 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! + response = @client.refresh! session[:authorization] = session[:authorization].merge(response) retry end @@ -105,7 +107,6 @@ def create end def edit - authorize @training @list = client_list @name = name(@training) @sets = sets(@training, current_user) @@ -113,34 +114,30 @@ 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 if calendar_id - client = Signet::OAuth2::Client.new(client_options) - client.update!(session[:authorization]) - if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end + @client = Signet::OAuth2::Client.new(client_options) + @client.update!(session[:authorization]) + service = Google::Apis::CalendarV3::CalendarService.new service.authorization = @client start_time = @training.time 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 end rescue Google::Apis::AuthorizationError - response = client.refresh! + response = @client.refresh! session[:authorization] = session[:authorization].merge(response) retry end @@ -157,35 +154,29 @@ 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 - client = Signet::OAuth2::Client.new(client_options) - client.update!(session[:authorization]) - if client.refresh_token == nil && Calendar.find_by(user_id: current_user.id) != nil - refresh_token = Calendar.find_by(user_id: current_user.id).code - client.refresh_token = refresh_token - end + @client = Signet::OAuth2::Client.new(client_options) + @client.update!(session[:authorization]) service = Google::Apis::CalendarV3::CalendarService.new service.authorization = @client if service.get_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom').status != 'cancelled' 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! + 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 +207,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..f04a65f 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://redis:6379' + } Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes end Sidekiq.configure_server do |config| # accepts :expiration (optional) + config.redis = { + url: 'redis://redis:6379' + } 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..3d1854a 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-12 11:09:19", 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: "d86dfff5-2070-4078-a743-13ab474f5562" 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: "e5205e08-2779-445a-a9f6-cc4bd0a6b9de", 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: "ac7e45ee-967b-43d3-9753-870f9a6634c2", 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.yml b/docker-compose.yml new file mode 100644 index 0000000..24caef0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +version: '2' + +services: + postgres: + image: 'postgres:10.5' + restart: always + volumes: + - 'postgres:/var/lib/postgresql/data' + env_file: + - '.env' + + redis: + image: 'redis:5.0-rc4' + restart: always + command: redis-server + ports: + - "6379:6379" + volumes: + - 'redis:/data' + + website: + depends_on: + - 'postgres' + build: . + command: puma -C config/puma.rb + ports: + - '3000:3000' + volumes: + - '.:/app' + env_file: + - '.env' + + sidekiq: + depends_on: + - 'redis' + build: . + command: bundle exec sidekiq + volumes: + - '.:/app' + env_file: + - '.env' + +volumes: + redis: + postgres: diff --git a/dump.rdb b/dump.rdb index 2643490cb80a9399eed1469c300fa1198fffc567..dfecc67059fba34717a48f4ccbb684e0a6bf7122 100644 GIT binary patch literal 3266 zcmcJR%WGU!9LFamiFrs;d_lmPa2GCgW;pN1=wf_QMQXGa7eVAaey6#1GLznWClKR> zE?kH%6c^$u-TMzHxEbQwow_ax;z|lal{8dOl8J30UT|@@hu{6(&-wly=lkYMFTQdS zA*A+aGw^BN+JbDFwNV?R{kh{4n-=+~yFcZMbOZJ_|N3%me`c72Z*9QF-puvI#{Pq5 z5L%lVm<`*5QR7bI_QLGJ)`d^LhlxgGvVDHFwQ9D~UOMQv{FZ247!+U!gDb7o7diwB zPCHsLM730s3o{Z#E$5B&VcYKFOIhle{ol z0sdW6BpuADkQ@uWq}rTtE+}s%o2gHZ|J_Uqb9v?U>5vv716X-x&JFr*m}Ss++bhpL zj+)8UAq*i;I%|oCV1~USd8e85jD=qJk(K%B)I+~Wi3UwRi2~C{tr8LKmIQY~Ub|>UIdis)ck5Lo+iDym}FQskLnUSmZK395oD3MVir>Fx)$YG%3g z8aXC8cUn;%9OoJ#QbiVnr7XYA$7FT2nMF2u$sN-{N(qdBGLGXaGK`5T-%|BT#t=r- zNsFArS~%|o32`mj3b5Ffg0gb)tDRbl39*I*St5<5;I+XdPN;w<1@|hD;IU(hV^c+jHDjWD`p)~cY9_J5vBRiQ5^Jo3u#8h~pn?oDj43T|mSeJ- z20&Y9IaOLaAw5VJ7!^L)s-+QknH1#{m+F^}GNdR)vRq!S zm&_s_cdU1uC?981V`PD95~|1;kB?V*`^I*yZ5HRBYZ?M`6toEr8wi~9iao0|N1D^} zwU_H9ix}1z9UP+Iu#68Uj;x|$&ng|elCg4`)l0?{xFCWT)-hn$_IN`%9fQX7n~m;e=@d_;Kp`{FTKWB$m*1(Wu`kLC_`zy9U?k-2;9 zp7XJ@Q!R=|b7y8x9A7^1KaKLiqus`b)z*>RYcNk?IC7VbgD2IWuT~~PcreNIr xq;Z$%)DV1#^RFbQ``sf|mKqE9o8i$@XQq!`_{0NazcIx`y$ zVMKe<_Mp{z6Ge)bB6{dSdy!bNg$g1bJP3kX1SuXA1R;&q-)`Dkaf0+P1AEw=dGo$} zf8XExefEh*9)9#mgpgX^kUE=Wjd_>WSbzeImd96r36nfqYAugMdD3y`PaZseV0o;U zIos&C&iVRpcY4bcrW-frQfE40+bwy2c~>V!S5AHT(kVCOd7JLf66yp6p%YjSs}zvrf}PEQ{{P+R|OVn^;g&hGqHbrd?Q%C>d#;<#xO8mW?j+5RShKLVne`5;1Lz3z3bZn8%?c4#NWxc$YhS$mD(#bIPTri0eSWMOpE}dsn8e{P@kT)@#)W zqsR%#5kXW@gRP<=w!(5+CX7oVWPpekO0nYH51)Q~u|j3qXvPSUJf>K}jxv^I17#HzGmI<=rRFLYks{VfMUFWQp`nm@Eu|$?5rJ{UU3o19Q!3zE zVn&Pi+0NGo!YYbC6c9z&I3jff83W%CXE9f$rR30?fyRC$qc=MijFP^VZ8AFJ3ZIyHp<`JQ>RE)8Rlq;i%1e|HO zWRX5_da+7n%7l(U&Xi#yrVQ)8V>BvnOsp`0BZCMfS@Fv?I#i`HNqI{*!=G!rC@7z;~dwyKOureQ`Dot5cI zmBBedn1)#{ET$|1Kj0Vvj3|p4kwoi&DA~8R`1#=1oBN)58~c#gj7`#Zc4>TFZNOUD z(CBs6TDM^??M5!kTs9O;?Q85a^GO?EuVLp!1L)6%-R?|d-$PBv646Z-!%VjQ!5os6 zw?Dc(bsTuryZ4qongn6hK&nCU()h|w^~YmtJ)#>3FL^6(tVO+R(O+v}0rs5#AL?Ce z^-bzsb;6F_4)dOWo+PjDNu8_j2WYA98jrfO zQ7=v1Y_w3{y&YXA?>>^>WN%>eHVlMzYfF7&4gQAA=J1Z-`@7$Iu{V07{Pp4WA@Pgh z5E%TfRr+R%q5#^00i+Cvy=(z0dov$f2l==WG<$1Awt9E``{vTNe?n8fZjhUyYbTnc LPyPAInVo+FkqvKU From b670211f481938867595a8dcfcfaf9df3ea2ab83 Mon Sep 17 00:00:00 2001 From: Aleksei Date: Mon, 17 Sep 2018 15:27:45 +0300 Subject: [PATCH 7/7] First configuration of nginx without https --- .gitignore | 1 + Dockerfile | 18 ------------ config/initializers/sidekiq.rb | 4 +-- db/schema.rb | 8 +++--- docker-compose.override.yml | 9 ++++++ docker-compose.yml | 50 ++++++++++++++++++++-------------- docker/app/Dockerfile | 30 ++++++++++++++++++++ docker/nginx/Dockerfile | 23 ++++++++++++++++ docker/nginx/index.html | 18 ++++++++++++ docker/nginx/nginx.conf | 37 +++++++++++++++++++++++++ localhost.crt | 18 ++++++++++++ localhost.key | 28 +++++++++++++++++++ 12 files changed, 200 insertions(+), 44 deletions(-) delete mode 100644 Dockerfile create mode 100644 docker-compose.override.yml create mode 100644 docker/app/Dockerfile create mode 100644 docker/nginx/Dockerfile create mode 100644 docker/nginx/index.html create mode 100644 docker/nginx/nginx.conf create mode 100644 localhost.crt create mode 100644 localhost.key 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/Dockerfile b/Dockerfile deleted file mode 100644 index 260588e..0000000 --- a/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM ruby:2.5.1 - -RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ - && apt-get install -y nodejs - -RUN apt-get update -qq && apt-get install -y build-essential libpq-dev && rm -rf /var/lib/apt/lists - -RUN curl -o- -L https://yarnpkg.com/install.sh | bash - -RUN mkdir /app -WORKDIR /app - -COPY Gemfile Gemfile.lock ./ -RUN bundle install - -COPY . . - -LABEL maintainer="Aleksei Lazarenko " \ No newline at end of file diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index f04a65f..9bef71d 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -4,7 +4,7 @@ Sidekiq.configure_client do |config| # accepts :expiration (optional) config.redis = { - url: 'redis://redis:6379' + url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}" } Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes end @@ -12,7 +12,7 @@ Sidekiq.configure_server do |config| # accepts :expiration (optional) config.redis = { - url: 'redis://redis:6379' + url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}" } Sidekiq::Status.configure_server_middleware config, expiration: 30.minutes diff --git a/db/schema.rb b/db/schema.rb index 3d1854a..bdbbdc4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -57,7 +57,7 @@ t.string "second_name", default: "", null: false t.string "phone_number", default: "", null: false t.integer "user_id" - t.datetime "birth", default: "2018-09-12 11:09:19", null: false + 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 @@ -65,7 +65,7 @@ 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: "d86dfff5-2070-4078-a743-13ab474f5562" + 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 @@ -188,7 +188,7 @@ t.bigint "user_id" t.string "name" t.string "token" - t.string "telegram_webhook_id", default: "e5205e08-2779-445a-a9f6-cc4bd0a6b9de", null: false + 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" @@ -219,7 +219,7 @@ t.string "encrypted_password", default: "", null: false t.string "bot_token" t.string "bot_name" - t.string "telegram_webhook_id", default: "ac7e45ee-967b-43d3-9753-870f9a6634c2", 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" 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 index 24caef0..f5a7e8e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,44 +1,54 @@ version: '2' services: + # todo: ngnix, https:// postgres: - image: 'postgres:10.5' + image: postgres:10.5 restart: always volumes: - - 'postgres:/var/lib/postgresql/data' + - /data:/var/lib/postgresql/data env_file: - - '.env' + - .env redis: - image: 'redis:5.0-rc4' + image: redis:5.0-rc4 restart: always command: redis-server ports: - - "6379:6379" + - $REDIS_PORT:$REDIS_PORT volumes: - - 'redis:/data' + - /data:/var/data/redis + env_file: + - .env - website: + app: depends_on: - - 'postgres' - build: . - command: puma -C config/puma.rb - ports: - - '3000:3000' + - postgres + build: + context: . + dockerfile: ./docker/app/Dockerfile volumes: - - '.:/app' - env_file: - - '.env' + - .:/app + + web: + build: + context: . + dockerfile: ./docker/nginx/Dockerfile + depends_on: + - app + ports: + - 90:90 + - 443:443 sidekiq: depends_on: - - 'redis' - build: . + - redis + build: + context: . + dockerfile: ./docker/app/Dockerfile command: bundle exec sidekiq volumes: - - '.:/app' - env_file: - - '.env' + - .:/app volumes: redis: 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/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-----