From a954fa55b1f1594fc66d682b71a4613b1aab9a20 Mon Sep 17 00:00:00 2001 From: Raekye Date: Fri, 6 Nov 2015 16:03:44 -0500 Subject: [PATCH] scheduled task model changes, UI for schedule --- app/models/scheduled_task.rb | 20 ++++++++----- app/models/server.rb | 5 ++++ app/models/server_log.rb | 2 +- app/views/servers/_schedule.html.erb | 30 +++++++++++++++++++ app/views/servers/show.html.erb | 9 ++++-- config/application.rb | 2 ++ .../20151106024157_create_scheduled_tasks.rb | 1 + db/schema.rb | 1 + test/models/server_test.rb | 1 + 9 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 app/views/servers/_schedule.html.erb diff --git a/app/models/scheduled_task.rb b/app/models/scheduled_task.rb index a6ecf39..cbde051 100644 --- a/app/models/scheduled_task.rb +++ b/app/models/scheduled_task.rb @@ -41,7 +41,7 @@ class ScheduledTask < ActiveRecord::Base def to_user_string m = self.partition % 100 - hours = self.partition / 100 + hours = (self.partition / 100) + self.server.timezone_delta h_24 = hours % 24 h_12 = h_24 % 12 ampm = h_24 < 12 ? 'am' : 'pm' @@ -49,17 +49,17 @@ def to_user_string return "#{DAYS_OF_WEEK_INVERSE[d]} #{h_12}:#{m} #{ampm} #{action}" end - def self.parse(str) + def self.parse(str, server) xs = [] str.each_line do |l| - x = self.parse_line(l.clean) + x = self.parse_line(l.clean, server) if !x.nil? xs.push(x) end end end - def self.parse_line(line) + def self.parse_line(line, server) if line =~ /([a-z]+)\s+(\d+):(\d+)\s*([a-z]+)\s+([a-z]+)/ day = DAYS_OF_WEEK[$1] hour = $2.to_i % 12 @@ -87,13 +87,19 @@ def self.parse_line(line) return nil end return ScheduledTask.new({ - partition: self.calculate_partition(day, hour, minute, ampm), + server: server, + partition: self.calculate_partition(day, hour, minute, ampm, server.timezone_delta), action: action, }) end end - def self.calculate_partition(day, hour, minute, ampm) - return (day * 24 + hour + ampm * 12) * 100 + minute + def self.calculate_partition(day, hour, minute, ampm, delta) + x = ((day * 24) + (hour) + (ampm * 12) - (delta)) % (7 * 24) + return x * 100 + minute + end + + def self.server_time + return DateTime.now.in_time_zone(Gamocosm::TIMEZONE).strftime('%-I:%M %P (%H:%M) %Z') end end diff --git a/app/models/server.rb b/app/models/server.rb index f1f48f4..4db2160 100644 --- a/app/models/server.rb +++ b/app/models/server.rb @@ -16,6 +16,7 @@ # remote_region_slug :string not null # remote_size_slug :string not null # remote_snapshot_id :integer +# timezone_delta :integer default(0), not null # class Server < ActiveRecord::Base @@ -55,6 +56,10 @@ def before_validate_callback self.ssh_keys = self.ssh_keys.try(:gsub, /\s/, '').clean end + def schedule_text + return self.scheduled_tasks.map { |x| x.to_user_string }.join("\n") + end + def host_name return "#{name}.minecraft.gamocosm" end diff --git a/app/models/server_log.rb b/app/models/server_log.rb index 0928bbd..af3e8d5 100644 --- a/app/models/server_log.rb +++ b/app/models/server_log.rb @@ -14,6 +14,6 @@ class ServerLog < ActiveRecord::Base belongs_to :server def when - return created_at.in_time_zone(ActiveSupport::TimeZone[-8]).strftime('%Y %b %e (%H:%M:%S %Z)') + return created_at.in_time_zone(Gamocosm::TIMEZONE).strftime('%Y %b %-d (%H:%M:%S %Z)') end end diff --git a/app/views/servers/_schedule.html.erb b/app/views/servers/_schedule.html.erb new file mode 100644 index 0000000..a1e3932 --- /dev/null +++ b/app/views/servers/_schedule.html.erb @@ -0,0 +1,30 @@ +
+<%= panel_with_heading 'Schedule' do %> + <%= simple_form_for @server, (@demo.nil? ? { url: server_path(@server), method: :put } : { html: { onsubmit: 'return false;' } }) do |f| %> +

+ You can setup a schedule to start/stop a server at different days of the week. + Autoshutdown also works with the schedule, but note that autoshutdown goes off after ~8 minutes of inactivity. +

+
+ <%= f.input :timezone_delta %> +

+ The current server time is <%= ScheduledTask.server_time %> (Pacific Time). + Suppose your time is 3 hours ahead of the server: your "timezone delta" is 3. + If your time is behind the server, you can enter a negative number. + This way, your schedule will be based on your times. +

+
+ <%= f.input :schedule_text, as: :text, label: 'Schedule', input_html: { rows: 4 } %> +

+ Enter a rule on each line, in the format [day of week] [hour]:[minute] [am or pm] [start or stop]: +

+

+
+ <%= f.button :submit, 'Save', class: 'btn btn-success' %> + <%end %> +<% end %> diff --git a/app/views/servers/show.html.erb b/app/views/servers/show.html.erb index 9720561..f2ae3cb 100644 --- a/app/views/servers/show.html.erb +++ b/app/views/servers/show.html.erb @@ -19,20 +19,22 @@
-
+

<%= render partial: 'servers/profile' %>
@@ -42,6 +44,9 @@
<%= render partial: 'servers/ftp_ssh' %>
+
+ <%= render partial: 'servers/schedule' %> +
<%= render partial: 'servers/advanced' %>
diff --git a/config/application.rb b/config/application.rb index 7fde615..e0dc23a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,6 +37,8 @@ module Gamocosm DIGITAL_OCEAN_SSH_PUBLIC_KEY_FINGERPRINT = Digest::MD5.hexdigest(Base64.decode64(DIGITAL_OCEAN_SSH_PUBLIC_KEY.split(/\s+/m)[1])).scan(/../).join(':') GIT_HEAD = `git rev-parse HEAD`.strip GIT_HEAD_DATE = Time.at(`git show -s --format=%ct HEAD`.to_i).strftime('%Y %b %-d %H:%M %Z') + # see ActiveSupport::TimeZone + TIMEZONE = 'Pacific Time (US & Canada)' @digital_ocean = nil def self.digital_ocean diff --git a/db/migrate/20151106024157_create_scheduled_tasks.rb b/db/migrate/20151106024157_create_scheduled_tasks.rb index 5850575..2c97432 100644 --- a/db/migrate/20151106024157_create_scheduled_tasks.rb +++ b/db/migrate/20151106024157_create_scheduled_tasks.rb @@ -7,5 +7,6 @@ def change end add_foreign_key :scheduled_tasks, :servers, { on_delete: :cascade } add_index :scheduled_tasks, :partition + add_column :servers, :timezone_delta, :integer, { null: false, default: 0 } end end diff --git a/db/schema.rb b/db/schema.rb index 0da5b94..82b421d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -62,6 +62,7 @@ t.string "remote_region_slug", null: false t.string "remote_size_slug", null: false t.integer "remote_snapshot_id" + t.integer "timezone_delta", default: 0, null: false end add_index "servers", ["domain"], name: "index_servers_on_domain", unique: true, using: :btree diff --git a/test/models/server_test.rb b/test/models/server_test.rb index eca8ce4..6218c38 100644 --- a/test/models/server_test.rb +++ b/test/models/server_test.rb @@ -16,6 +16,7 @@ # remote_region_slug :string not null # remote_size_slug :string not null # remote_snapshot_id :integer +# timezone_delta :integer default(0), not null # require 'test_helper'