Agh ok do a bunch of stuff
This commit is contained in:
		
							parent
							
								
									f72eeb3528
								
							
						
					
					
						commit
						661d0f3f9a
					
				
							
								
								
									
										7
									
								
								ika.rb
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								ika.rb
									
									
									
									
									
								
							| @ -1,8 +1,13 @@ | |||||||
| require 'discordrb' | require 'discordrb' | ||||||
| require_relative './lib/ika' | require_relative './lib/ika' | ||||||
|  | require_relative './lib/discord_handler' | ||||||
|  | require_relative './lib/console_handler' | ||||||
| 
 | 
 | ||||||
| token = File.read("./token") | token = File.read("./token") | ||||||
| 
 | 
 | ||||||
| ika = Ika.new Discordrb::Bot.new(token:) | bot = Discordrb::Bot.new(token:) | ||||||
|  | 
 | ||||||
|  | # ika = Ika.for(type: DiscordHandler, bot:) | ||||||
|  | ika = Ika.for(type: ConsoleHandler) | ||||||
| 
 | 
 | ||||||
| ika.start! | ika.start! | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ module Commands | |||||||
| 
 | 
 | ||||||
|     def self.for(ika, message) |     def self.for(ika, message) | ||||||
|       Commands.registered_commands.find do |command_class| |       Commands.registered_commands.find do |command_class| | ||||||
|         command_class.matches? message.message.content |         command_class.matches? message.content | ||||||
|       end&.new(ika, message) |       end&.new(ika, message) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -12,6 +12,7 @@ module Commands | |||||||
|       return message.respond("There's already a lesson running!") if ika.current_lesson_running? |       return message.respond("There's already a lesson running!") if ika.current_lesson_running? | ||||||
| 
 | 
 | ||||||
|       message.respond("Starting a lesson now!") |       message.respond("Starting a lesson now!") | ||||||
|  | 
 | ||||||
|       ika.start_lesson! message |       ika.start_lesson! message | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								lib/console_handler.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/console_handler.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | require_relative './ika' | ||||||
|  | 
 | ||||||
|  | class ConsoleHandler < Ika | ||||||
|  |   def start! | ||||||
|  |     @handling_messages = true | ||||||
|  | 
 | ||||||
|  |     while @handling_messages | ||||||
|  |       handle_message Message::Console.new(responder(nil), gets.chomp) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def stop! | ||||||
|  |     @handling_messages = false | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def responder(_) | ||||||
|  |     lambda { |response| puts "<Ika> #{response}" } | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										28
									
								
								lib/discord_handler.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/discord_handler.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | require_relative './ika' | ||||||
|  | 
 | ||||||
|  | class DiscordHandler < Ika | ||||||
|  |   attr_reader :bot | ||||||
|  | 
 | ||||||
|  |   def initialize(bot:) | ||||||
|  |     super() | ||||||
|  |     @bot = bot | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def start! | ||||||
|  |     bot.remove_handler @message_handler if @message_handler | ||||||
|  | 
 | ||||||
|  |     @message_handler = bot.message do |message_event| | ||||||
|  |       handle_message Message::Discord.new(responder(message_event.channel), message_event.message) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     bot.run # you can run this in the background, idk | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def stop! | ||||||
|  |     bot.remove_handler @message_handler if @message_handler | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def responder(channel) | ||||||
|  |     lambda { |response| channel.send_message(response) } | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										42
									
								
								lib/drill.rb
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								lib/drill.rb
									
									
									
									
									
								
							| @ -1,32 +1,48 @@ | |||||||
| class Drill | class Drill | ||||||
|  |   COMMANDS = %w[ | ||||||
|  |     init | ||||||
|  |     start | ||||||
|  |     end | ||||||
|  |   ] | ||||||
|  | 
 | ||||||
|   attr_reader :channel |   attr_reader :channel | ||||||
| 
 | 
 | ||||||
|   def initialize(channel) |   def initialize(channel) | ||||||
|     @channel = channel |     @channel = channel | ||||||
|  |     @exists = false | ||||||
|     @started = false |     @started = false | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def init! | ||||||
|  |     @exists = true | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   def start! |   def start! | ||||||
|     @started = true |     @started = true | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def end! | ||||||
|  |     @started = false | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def handle_message(message) | ||||||
|  |     message.command_message ? handle_command(message) : handle_normal_message(message) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def handle_command(message) | ||||||
|  |     command = message.command | ||||||
|  |     if COMMANDS.includes?(command) | ||||||
|  |       send("handle_#{command}", message) | ||||||
|  |     else | ||||||
|  |       puts "[Drill] Unknown command #{command}" | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   def started? |   def started? | ||||||
|     @started |     @started | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def exists? |   def exists? | ||||||
|     true |     @exists | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   class Empty < Drill |  | ||||||
|     def initialize |  | ||||||
|       super(nil) |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     def start!; end |  | ||||||
| 
 |  | ||||||
|     def exists? |  | ||||||
|       false |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  | |||||||
| @ -2,16 +2,14 @@ require_relative "drill" | |||||||
| 
 | 
 | ||||||
| class DrillPlugin | class DrillPlugin | ||||||
|   COMMANDS = %w[ |   COMMANDS = %w[ | ||||||
|     init |     help | ||||||
|     start |  | ||||||
|     end |  | ||||||
|   ] |   ] | ||||||
| 
 | 
 | ||||||
|   attr_reader :bot, :drills |   attr_reader :bot, :drills | ||||||
| 
 | 
 | ||||||
|   def initialize(bot) |   def initialize(bot) | ||||||
|     @bot = bot |     @bot = bot | ||||||
|     @drills = Hash.new { Drill::Empty.new }  |     @drills = Hash.new { Drill.new }  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def handle_message(message) |   def handle_message(message) | ||||||
| @ -24,7 +22,8 @@ class DrillPlugin | |||||||
|       drill = drills[message.channel.id] |       drill = drills[message.channel.id] | ||||||
|       send("handle_#{command}", message, drill) |       send("handle_#{command}", message, drill) | ||||||
|     else |     else | ||||||
|       message.respond "Unknown command #{command}" |       drill = drills[message.channel.id] | ||||||
|  |       drill.handle_message(message) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								lib/ika.rb
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								lib/ika.rb
									
									
									
									
									
								
							| @ -1,42 +1,33 @@ | |||||||
| require_relative './session' | require_relative './session' | ||||||
| require_relative './lesson' | require_relative './lesson' | ||||||
| require_relative './commands' | require_relative './commands' | ||||||
|  | require_relative './message' | ||||||
| require_relative './drill_plugin' | require_relative './drill_plugin' | ||||||
| 
 | 
 | ||||||
| class Ika | class Ika | ||||||
|   attr_reader :bot |   attr_reader :handler | ||||||
|   attr_reader :lessons, :sessions |   attr_reader :lessons, :sessions | ||||||
|   attr_accessor :current_lesson, :current_session |   attr_accessor :current_lesson, :current_session | ||||||
|   attr_reader :drill_plugin |   attr_reader :drill_plugin | ||||||
| 
 | 
 | ||||||
|   def initialize(bot) |   def self.for(type:, **kwargs) | ||||||
|     @bot = bot |     type.new **kwargs | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def initialize | ||||||
|     @lessons = {} |     @lessons = {} | ||||||
|     @sessions = {} |     @sessions = {} | ||||||
|     @current_session = nil |     @current_session = nil | ||||||
|     @current_lesson = Lesson.new |     @current_lesson = Lesson.new(responder: responder(nil)) | ||||||
|     @drill_plugin = DrillPlugin.new(self) |     @drill_plugin = DrillPlugin.new(self) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def start! |  | ||||||
|     bot.remove_handler @message_handler if @message_handler |  | ||||||
| 
 |  | ||||||
|     @message_handler = bot.message do |message| |  | ||||||
|       handle_message message |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     bot.run # you can run this in the background, idk |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def stop! |  | ||||||
|     bot.remove_handler @message_handler if @message_handler |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def current_lesson_running? |   def current_lesson_running? | ||||||
|     current_lesson.running? |     current_lesson.running? | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def start_lesson!(message) |   def start_lesson!(message) | ||||||
|  |     current_lesson.responder = responder(message.channel) | ||||||
|     current_lesson.start!(message.channel) |     current_lesson.start!(message.channel) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
| @ -49,10 +40,6 @@ class Ika | |||||||
|       command.execute |       command.execute | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     if message.content.start_with? "!drill" |     # drill_plugin.handle_message message | ||||||
|       drill_plugin.handle_message message |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     return current_session&.respond_to message |  | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  | |||||||
| @ -8,12 +8,14 @@ DEFAULT_LESSON_PLAN = [ | |||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| class Lesson | class Lesson | ||||||
|   attr_reader :lesson_plan, :channel, :thread, :running, :scheduler |   attr_reader :lesson_plan, :channel, :running, :scheduler | ||||||
|  |   attr_accessor :responder | ||||||
| 
 | 
 | ||||||
|   def initialize(lesson_plan=DEFAULT_LESSON_PLAN, scheduler: Rufus::Scheduler.new) |   def initialize(lesson_plan=DEFAULT_LESSON_PLAN, scheduler: Rufus::Scheduler.new, responder: nil) | ||||||
|     @lesson_plan = lesson_plan |     @lesson_plan = lesson_plan | ||||||
|     @running = false |     @running = false | ||||||
|     @scheduler = scheduler |     @scheduler = scheduler | ||||||
|  |     @responder = responder | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def stop! |   def stop! | ||||||
| @ -25,13 +27,13 @@ class Lesson | |||||||
|       offset = lesson_plan.map(&:first)[0..index - 1].sum(0) |       offset = lesson_plan.map(&:first)[0..index - 1].sum(0) | ||||||
|       offset = 0 if index == 0 |       offset = 0 if index == 0 | ||||||
|       scheduler.in "#{offset}m" do |       scheduler.in "#{offset}m" do | ||||||
|         channel.send_message "#{time} minutes to #{message}" |         responder.call "#{time} minutes to #{message}" | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     end_offset = lesson_plan.map(&:first).sum(0) |     end_offset = lesson_plan.map(&:first).sum(0) | ||||||
|     scheduler.in "#{end_offset}m" do |     scheduler.in "#{end_offset}m" do | ||||||
|       channel.send_message "Lesson over!" |       responder.call "Lesson over!" | ||||||
|       @running = false |       @running = false | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										109
									
								
								lib/message.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								lib/message.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | class Message | ||||||
|  |   attr_reader :responder | ||||||
|  | 
 | ||||||
|  |   def initialize(responder) | ||||||
|  |     @responder = responder | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def content | ||||||
|  |     # TODO: figure out how to delegate | ||||||
|  |     discord_message.content | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def author | ||||||
|  |     # TODO: figure out how to delegate | ||||||
|  |     discord_message.author | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def channel | ||||||
|  |     # TODO: figure out how to delegate | ||||||
|  |     discord_message.channel | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def respond(response) | ||||||
|  |     # TODO: figure out how to delegate | ||||||
|  |     discord_message.respond response | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def message | ||||||
|  |     discord_message | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def words | ||||||
|  |     content.split(" ") | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def first_word | ||||||
|  |     words.first | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def command_message? | ||||||
|  |     first_word.start_with? "!" | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def command | ||||||
|  |     command_message? ? first_word[1..] : nil | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def subcommand | ||||||
|  |     command_message? ? words[1] : nil | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def params | ||||||
|  |     command_message? ? words[2..] : [] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   class Console < Message | ||||||
|  |     attr_reader :content | ||||||
|  | 
 | ||||||
|  |     def initialize(responder, content) | ||||||
|  |       super(responder) | ||||||
|  |       @content = content | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def author | ||||||
|  |       OpenStruct.new(display_name: "CHANGE ME") | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def channel | ||||||
|  |       OpenStruct.new(id: nil) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def respond(response) | ||||||
|  |       responder.call response | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   class Discord < Message | ||||||
|  |     attr_reader :discord_message | ||||||
|  | 
 | ||||||
|  |     def initialize(responder, discord_message) | ||||||
|  |       super(responder) | ||||||
|  |       @discord_message = discord_message | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def content | ||||||
|  |       # TODO: figure out how to delegate | ||||||
|  |       discord_message.content | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def author | ||||||
|  |       # TODO: figure out how to delegate | ||||||
|  |       discord_message.author | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def channel | ||||||
|  |       # TODO: figure out how to delegate | ||||||
|  |       discord_message.channel | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def respond(response) | ||||||
|  |       # TODO: figure out how to delegate | ||||||
|  |       discord_message.respond response | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def message | ||||||
|  |       discord_message | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										15
									
								
								test/test_discord_handler.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/test_discord_handler.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | require_relative "../lib/discord_handler" | ||||||
|  | require "minitest/autorun" | ||||||
|  | 
 | ||||||
|  | class TestDiscordHandler < Minitest::Test | ||||||
|  |   def setup | ||||||
|  |     @bot = Minitest::Mock.new | ||||||
|  |     @ika = DiscordHandler.new bot: @bot | ||||||
|  |   end | ||||||
|  |   | ||||||
|  |   def test_start! | ||||||
|  |     @bot.expect(:message, nil) | ||||||
|  |     @bot.expect(:run, nil) | ||||||
|  |     @ika.start! | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -1,16 +1,21 @@ | |||||||
| require_relative "../lib/ika" | require_relative "../lib/ika" | ||||||
| require "minitest/autorun" | require "minitest/autorun" | ||||||
| 
 | 
 | ||||||
| class TestIka < Minitest::Test | class TestHandler < Ika | ||||||
|   def setup |   attr_reader :responses | ||||||
|     @bot = Minitest::Mock.new | 
 | ||||||
|     @ika = Ika.new @bot |   def initialize | ||||||
|  |     @responses = [] | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_start |   def responder | ||||||
|     @bot.expect(:message, nil) |     lambda { |response| @responses << response } | ||||||
|     @bot.expect(:run, nil) |   end | ||||||
|     @ika.start! | end | ||||||
|  | 
 | ||||||
|  | class TestIka < Minitest::Test | ||||||
|  |   def setup | ||||||
|  |     @ika = TestHandler.new | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_handle_command_message |   def test_handle_command_message | ||||||
| @ -19,6 +24,7 @@ class TestIka < Minitest::Test | |||||||
|     Commands::Command.stub(:for, @command) do |x| |     Commands::Command.stub(:for, @command) do |x| | ||||||
|       @ika.handle_message("msg") |       @ika.handle_message("msg") | ||||||
|     end |     end | ||||||
|  |     assert_equal [], @ika.responses | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_handle_normal_message |   def test_handle_normal_message | ||||||
| @ -30,5 +36,6 @@ class TestIka < Minitest::Test | |||||||
|         @ika.handle_message("msg") |         @ika.handle_message("msg") | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |     assert_equal [], @ika.responses | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  | |||||||
| @ -4,10 +4,12 @@ require "minitest/autorun" | |||||||
| class TestLesson < Minitest::Test | class TestLesson < Minitest::Test | ||||||
|   def setup |   def setup | ||||||
|     @scheduler = Minitest::Mock.new |     @scheduler = Minitest::Mock.new | ||||||
|  |     @responses = [] | ||||||
|  |     @responder = lambda { |rsp| @responses << rsp } | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_start |   def test_start | ||||||
|     @lesson = Lesson.new [[1, "test the thing"], [3, "finish testing"]], scheduler: @scheduler |     @lesson = Lesson.new [[1, "test the thing"], [3, "finish testing"]], scheduler: @scheduler, responder: @responder | ||||||
|     @scheduler.expect(:in, nil) { |time| time == "0m" } |     @scheduler.expect(:in, nil) { |time| time == "0m" } | ||||||
|     @scheduler.expect(:in, nil) { |time| time == "1m" } |     @scheduler.expect(:in, nil) { |time| time == "1m" } | ||||||
|     @scheduler.expect(:in, nil) { |time| time == "4m" } |     @scheduler.expect(:in, nil) { |time| time == "4m" } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user