lib/lita/handlers/task_scheduler.rb in lita-task-scheduler-1.0.0 vs lib/lita/handlers/task_scheduler.rb in lita-task-scheduler-1.1.0
- old
+ new
@@ -1,31 +1,43 @@
-require 'pry'
-require 'json'
+require 'lita/scheduler'
module Lita
module Handlers
class TaskScheduler < Handler
+ # START:routes
route(/^schedule\s+"(.+)"\s+in\s+(.+)$/i, :schedule_command, command: true)
route(/^show schedule$/i, :show_schedule, command: true)
route(/^empty schedule$/i, :empty_schedule, command: true)
+ # END:routes
- REDIS_TASKS_KEY = name.to_s
-
+ # START:handlers
def show_schedule(payload)
- schedule = redis.hgetall(REDIS_TASKS_KEY)
-
- payload.reply schedule_report(schedule)
+ payload.reply schedule_report(scheduler.get_all)
end
def empty_schedule(payload)
- redis.del(REDIS_TASKS_KEY)
+ scheduler.clear
show_schedule payload
end
+ # START:schedule_command
+ def schedule_command(payload)
+ task, timing = payload.matches.last
+ run_at = parse_timing(timing)
+ serialized = command_to_hash(payload.message, new_body: task)
+
+ defer_task(serialized, run_at)
+ show_schedule payload
+ end
+ # END:schedule_command
+
+ def scheduler
+ @_schedule ||= Scheduler.new(redis: redis, logger: Lita.logger)
+ end
+
def schedule_report(schedule)
- reply = 'Scheduled tasks: '
descriptions = []
schedule.keys.each do |timestamp|
play_time = Time.at(timestamp.to_i)
tasks_json = schedule[timestamp]
@@ -34,79 +46,20 @@
tasks.each do |task|
descriptions << "\n - \"#{task.fetch('body')}\" at #{play_time}"
end
end
- reply + (descriptions.empty? ? 'None.' : descriptions.join)
+ 'Scheduled tasks: ' + (descriptions.empty? ? 'None.' : descriptions.join)
end
- def schedule_command(payload)
- task, timing = payload.matches.last
- run_at = parse_timing(timing)
- serialized = serialize_message(payload.message, new_body: task)
-
- defer_task(serialized, run_at)
- show_schedule(payload)
- end
-
+ # START:defer_task
def defer_task(serialized_task, run_at)
- key_time = run_at.to_i.to_s
-
- redis.watch(REDIS_TASKS_KEY)
-
- tasks = redis.hget(REDIS_TASKS_KEY, key_time) || []
-
- tasks = JSON.parse(tasks) unless tasks.empty?
- tasks << serialized_task
-
- redis.hset(REDIS_TASKS_KEY, key_time, tasks.to_json)
-
- redis.unwatch
-
- tasks
+ scheduler.add(serialized_task, run_at)
end
+ # END:defer_task
- def execute_tasks(serialized_tasks)
- serialized_tasks.each do |serialized_task|
- Lita.logger.debug "Resending task #{serialized_task}"
- resend serialized_task
- end
- end
-
- def run_loop
- Thread.new do
- loop do
- tick
- sleep 1
- end
- end
- end
-
- def tick
- tasks = find_tasks_due
- tasks.each { |t| resend t }
- Lita.logger.debug "Task loop done for #{Time.now}"
- end
-
- def find_tasks_due
- results = []
- timestamps = redis.hkeys(REDIS_TASKS_KEY)
-
- timestamps.each do |t|
- key_time = Time.at(t.to_i)
- next unless key_time <= Time.now
-
- tasks_raw = redis.hget(REDIS_TASKS_KEY, t)
- tasks = JSON.parse(tasks_raw)
-
- results += tasks
- redis.hdel(REDIS_TASKS_KEY, t)
- end
-
- results
- end
-
+ # START:parse_timing
def parse_timing(timing)
count, unit = timing.split
count = count.to_i
unit = unit.downcase.strip.gsub(/s$/, '')
@@ -123,47 +76,61 @@
raise ArgumentError, "I don't recognize #{unit}"
end
Time.now.utc + seconds
end
+ # END:parse_timing
- def rebroadcast(payload)
- serialized = serialize_message(payload.message)
-
- key = "delay_#{rand(100..10_000)}"
- redis.set(key, serialized.to_json)
- reloaded = JSON.parse redis.get(key), symbolize_names: true
-
- resend(reloaded)
- end
-
- def resend(serialized)
- user = Lita::User.new(serialized.fetch('user_name'))
- room = Lita::Room.new(serialized.fetch('room_name'))
+ # START:resend_command
+ def resend_command(command_hash)
+ user = Lita::User.new(command_hash.fetch('user_name'))
+ room = Lita::Room.new(command_hash.fetch('room_name'))
source = Lita::Source.new(user: user, room: room)
- body = "#{robot.name} #{serialized.fetch('body')}"
+ body = "#{robot.name} #{command_hash.fetch('body')}"
newmsg = Lita::Message.new(
robot,
body,
source
)
robot.receive newmsg
end
+ # END:resend_command
- def serialize_message(message, new_body: nil)
+ # START:serialize_message
+ def command_to_hash(command, new_body: nil)
{
- user_name: message.user.name,
- room_name: message.source.room,
- body: new_body || message.body
+ user_name: command.user.name,
+ room_name: command.source.room,
+ body: new_body || command.body
}
end
+ # END:serialize_message
- Lita.register_handler(self)
+ def find_tasks_due
+ scheduler.find_tasks_due
+ end
- on :loaded do
- run_loop
+ # START:loop_ticks
+ def run_loop
+ Thread.new do
+ loop do
+ tick
+ sleep 1
+ end
+ end
end
+
+ def tick
+ tasks = find_tasks_due
+ tasks.each { |t| resend_command t }
+ Lita.logger.debug "Task loop done for #{Time.now}"
+ end
+
+ on(:loaded) { run_loop }
+ # END:loop_ticks
+
+ Lita.register_handler(self)
end
end
end