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]
:
+
+ - A day of the week is [<%= ScheduledTask::DAYS_OF_WEEK_INVERSE.map { |k, v| k }.join(', ') %>], or just the first 3 letters
+ - The hour is in 12-hour format (1-12)
+ - The minute is either "00" or "30" (only half-hour intervals supported)
+ - Everything is case-insensitive ("am" is the same as "AM")
+
+
+
+ <%= 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 @@
<% if @demo.nil? %>
- - <%= link_to 'Profile', server_path(@server, anchor: 'profile'), 'data-toggle' => 'tab' %>
+ - <%= link_to 'Profile', server_path(@server, anchor: 'profile'), 'data-toggle' => 'tab' %>
- <%= link_to 'Minecraft Settings', server_path(@server, anchor: 'settings'), 'data-toggle' => 'tab' %>
- <%= link_to 'FTP and SSH', server_path(@server, anchor: 'ftp_ssh'), 'data-toggle' => 'tab' %>
+ - <%= link_to 'Schedule', server_path(@server, anchor: 'schedule'), 'data-toggle' => 'tab' %>
- <%= link_to 'Advanced', server_path(@server, anchor: 'advanced'), 'data-toggle' => 'tab' %>
<% else %>
- Profile
- Minecraft Settings
- FTP and SSH
+ - Schedule
- Advanced
<% end %>
-
+
<%= 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'