lib/lita/handlers/coffee.rb in lita-coffee-0.0.2 vs lib/lita/handlers/coffee.rb in lita-coffee-0.1.0

- old
+ new

@@ -9,194 +9,313 @@ # Configuration # default_group - the name of the default group in which users will order a coffee # default_coffee - the coffee we will order if users don't specify what they would like config :default_group, type: String, default: 'coffee-lovers' config :default_coffee, type: String, default: 'Single origin espresso' + config :default_timeout, type: Integer, default: 28800 on :loaded, :set_constants def set_constants(payload) @@DEFAULT_GROUP = config.default_group @@DEFAULT_COFFEE = config.default_coffee + @@DEFAULT_GROUP_TIMEOUT = config.default_timeout end + # --------------- + # Nice new routes + # --------------- + + # Welcome new users route( - /^\(?coffee\)?(\s+\-[bcdgist]?|\s+\+)?(.*)/i, - :coffee, + /coffee/i, + :init_user, + ) + + # Order a coffee + route( + /^\s*\(?coffee\)?\s+\+\s*(\S.*)?$/i, + :get_me_a_coffee, help: { + 'coffee +' => "Order a coffee", + } + ) + + # Cancel your order + route( + /^\s*\(?coffee\)?\s+\-c\s*$/i, + :cancel_order, + help: { + 'coffee -c' => "Cancel your order", + } + ) + + # List orders + route( + /^\s*\(?coffee\)?\s*$/i, + :list_orders, + help: { 'coffee' => "List the orders for your group", + } + ) + + # Display profile informatino + route( + /^\s*\(?coffee\)?\s+\-i\s*$/i, + :display_profile, + help: { 'coffee -i' => "Display your profile", + } + ) + + # Set preferences + route( + /^\s*\(?coffee\)?\s+\-s\s+(.*)$/i, + :set_prefs, + help: { 'coffee -s Colombian Filter' => "Set your coffee preference", - 'coffee -g Cool Kids' => "Change your group", - 'coffee +' => "Order a coffee", - 'coffee -c' => "Cancel your order", + } + ) + + # Set group + route( + /^\s*\(?coffee\)?\s+\-g\s+(.*)$/i, + :set_group, + help: { + 'coffee -g Cool Kids' => "Change your group", + } + ) + + # Buy coffees + route( + /^\s*\(?coffee\)?\s+\-b\s*(.*)$/i, + :buy_coffees, + help: { 'coffee -b You owe me one!' => "Buy coffee for your group, clear the orders and send a message to each coffee drinker", + } + ) + + # Display system settings + route( + /^\s*\(?coffee\)?\s+\-t\s*$/i, + :system_settings, + help: { 'coffee -t' => "Display system settings", + } + ) + + # Delete me + route( + /^\s*\(?coffee\)?\s+\-d\s*$/i, + :delete_me, + help: { 'coffee -d' => "Delete you from the coffee system", } ) - def coffee(response) - get_settings = response.matches[0][0].strip == "-i" rescue false - set_coffee = response.matches[0][0].strip == "-s" rescue false - change_group = response.matches[0][0].strip == "-g" rescue false - order = response.matches[0][0].strip == "+" rescue false - cancel = response.matches[0][0].strip == "-c" rescue false - buy_coffee = response.matches[0][0].strip == "-b" rescue false - system_settings = response.matches[0][0].strip == "-t" rescue false - delete_me = response.matches[0][0].strip == "-d" rescue false + # List all groups + route( + /^\s*\(?coffee\)?\s+\-l\s*$/i, + :list_groups, + help: { + 'coffee -l' => "List the available coffee groups", + } + ) - preference = response.matches[0][1].strip rescue nil + # Coffee stats a.k.a. who owes whom? + route( + /^\s*\(?coffee\)?\s+\-w\s*(.*)$/i, + :show_stats, + help: { + 'coffee -w' => "Show stats for a group", + } + ) - my_user = response.user.name - group = get_group(my_user) + # Setup new users + def init_user(response) + response.reply("Welcome to coffee! You have been added to the #{@@DEFAULT_GROUP} group with an order of #{@@DEFAULT_COFFEE}. Type help coffee for help.") if initialize_user_redis(response.user.name) == :new_user + end - # Setup new users - response.reply("Welcome to coffee! You have been added to the #{@@DEFAULT_GROUP} group with an order of #{@@DEFAULT_COFFEE}. Type help coffee for help.") if initialize_user_redis(my_user) == :new_user + # Order coffee + def get_me_a_coffee(response) + group = response.matches[0][0].strip rescue get_group(response.user.name) + orders = (get_orders(group) + [response.user.name]).uniq + result = redis.set("orders:#{group}",orders.to_json) + set_timeout(group) + if result == "OK" + response.reply("Ordered you a coffee from #{group}") + else + response.reply("(sadpanda) Failed to order your coffee for some reason: #{result.inspect}") + end + end - # Retrieve my preference - if get_settings - settings = get_settings(my_user) - response.reply("Your current coffee is #{settings['coffee']}. You are in the #{settings['group']} group.") - # Set my coffee - elsif set_coffee - result = set_coffee(my_user,preference) - if result == "OK" - response.reply("Coffee set to #{preference}") - else - response.reply("(sadpanda) Failed to set your coffee for some reason: #{result.inspect}") - end - # Delete me altogether - elsif delete_me - result = delete_user(my_user) - if result == 1 - response.reply("You have been deleted from coffee") - else - response.reply("(sadpanda) Failed to delete you from coffee for some reason: #{result.inspect}") - end - # Change my coffee group - elsif change_group - result = set_coffee_group(my_user,preference) - if result == "OK" - response.reply("Group set to #{preference}") - else - response.reply("(sadpanda) Failed to set your coffee group for some reason: #{result.inspect}") - end - # Order a coffee - elsif order - result = order_coffee(my_user) - if result == "OK" - response.reply("Ordered you a coffee") - else - response.reply("(sadpanda) Failed to order your coffee for some reason: #{result.inspect}") - end - # Cancel a coffee - elsif cancel - result = cancel_coffee(my_user) - if result == "OK" - response.reply("Cancelled your coffee") - else - response.reply("(sadpanda) Failed to cancel your coffee for some reason: #{result.inspect}") - end - # Buy the coffees and clear the orders - elsif buy_coffee - response.reply("Thanks for ordering the coffee for #{group}!\n--") - get_orders(group).each do |order| - response.reply("#{order}: #{get_coffee(order)}") - send_coffee_message(order,my_user,preference) unless order == my_user - end - result = clear_orders(group) - if result == "OK" - response.reply("Cleared all orders for #{group}") - else - response.reply("(sadpanda) Failed to clear the orders for some reason: #{result.inspect}") - end - # tests - elsif system_settings - response.reply("Default coffee: #{@@DEFAULT_COFFEE}, Default group: #{@@DEFAULT_GROUP}") - # List the orders + # Cancel coffee order + def cancel_order(response) + group = get_group(response.user.name) + orders = get_orders(group) + orders.delete(response.user.name) + result = redis.set("orders:#{group}",orders.to_json) + set_timeout(group) + if result == "OK" + response.reply("Cancelled your coffee") else - response.reply("Current orders for #{group}:-\n--") - get_orders(group).each do |order| - response.reply("#{order}: #{get_coffee(order)}") - end + response.reply("(sadpanda) Failed to cancel your coffee for some reason: #{result.inspect}") end + end + # List the coffee orders for your group + def list_orders(response) + group = get_group(response.user.name) + response.reply("Current orders for #{group}:-\n--") + get_orders(group).each do |order| + response.reply("#{order}: #{get_coffee(order)}") + end end + # Display profile + def display_profile(response) + settings = get_settings(response.user.name) + response.reply("Your current coffee is #{settings['coffee']}. You are in the #{settings['group']} group.") + end + + # Set coffee preference + # TODO: a single method to update user info + def set_prefs(response) + preference = response.matches[0][0].strip rescue nil + result = update_user_coffee(response.user.name,preference) + if result == "OK" + response.reply("Coffee set to #{preference}") + else + response.reply("(sadpanda) Failed to set your coffee for some reason: #{result.inspect}") + end + end + + # Set coffee group + # TODO: merge with coffee preference + def set_group(response) + preference = response.matches[0][0].strip rescue nil + result = set_coffee_group(response.user.name,preference) + if result == "OK" + response.reply("Group set to #{preference}") + else + response.reply("(sadpanda) Failed to set your coffee group for some reason: #{result.inspect}") + end + end + + # Buy all the coffee for your group + def buy_coffees(response) + group = get_group(response.user.name) + message = response.matches[0][0].strip rescue nil + response.reply("Thanks for ordering the coffee for #{group}!\n--") + stats = get_coffee_stats(group) + get_orders(group).each do |order| + response.reply("#{order}: #{get_coffee(order)}") + send_coffee_message(order,response.user.name,message) unless order == response.user.name + stats[order] -= 1 rescue stats[order] = -1 + stats[response.user.name] += 1 rescue stats[response.user.name] = 1 + end + set_coffee_stats(group,stats) + result = clear_orders(group) + if result == 1 + response.reply("Cleared all orders for #{group}") + else + response.reply("(sadpanda) Failed to clear the orders for some reason: #{result.inspect}") + end + end + + # Display the system settings + def system_settings(response) + response.reply("Default coffee: #{@@DEFAULT_COFFEE}, Default group: #{@@DEFAULT_GROUP}") + end + + # Delete a user + def delete_me(response) + result = redis.del("settings:#{response.user.name}") + if result == 1 + response.reply("You have been deleted from coffee") + else + response.reply("(sadpanda) Failed to delete you from coffee for some reason: #{result.inspect}") + end + end + + # List groups + def list_groups(response) + groups = redis.keys('stats:*') + response.reply("The following groups are active:-\n--\n#{groups.map{|g| g.split(':')[1]}.join("\n")}") + end + + # Display the stats + def show_stats(response) + group = response.matches[0][0].strip rescue get_group(response.user.name) + stats = get_coffee_stats(group) + response.reply("Who owes whom?\n--\n#{stats.map{|s| "#{s[0]}: #{s[1]}"}.join("\n")}") + end + ####### private ####### + def get_coffee_stats(group) + JSON.parse(redis.get("stats:#{group}")) rescue {} + end + + def set_coffee_stats(group,stats) + redis.set("stats:#{group}",stats.to_json) + end + def initialize_user_redis(user) - if redis.get("settings-#{user}").nil? - redis.set("settings-#{user}",{group: @@DEFAULT_GROUP, coffee: @@DEFAULT_COFFEE}.to_json) + if redis.get("settings:#{user}").nil? + redis.set("settings:#{user}",{group: @@DEFAULT_GROUP, coffee: @@DEFAULT_COFFEE}.to_json) return :new_user else return :existing_user end end - def delete_user(user) - redis.del("settings-#{user}") - end - def get_settings(user) - JSON.parse(redis.get("settings-#{user}")) rescue {group: @@DEFAULT_GROUP, coffee: @@DEFAULT_COFFEE} + JSON.parse(redis.get("settings:#{user}")) rescue {group: @@DEFAULT_GROUP, coffee: @@DEFAULT_COFFEE} end def get_orders(group) - JSON.parse(redis.get("#{group}-orders")) rescue [] + set_timeout(group) + JSON.parse(redis.get("orders:#{group}")) rescue [] end def get_coffee(user) - JSON.parse(redis.get("settings-#{user}"))['coffee'] rescue @@DEFAULT_COFFEE + JSON.parse(redis.get("settings:#{user}"))['coffee'] rescue @@DEFAULT_COFFEE end def get_group(user) - JSON.parse(redis.get("settings-#{user}"))['group'] rescue @@DEFAULT_GROUP + JSON.parse(redis.get("settings:#{user}"))['group'] rescue @@DEFAULT_GROUP end - def set_coffee(user,coffee) + def update_user_coffee(user,coffee) my_settings = get_settings(user) my_settings[:coffee] = coffee - redis.set("settings-#{user}",my_settings.to_json) + redis.set("settings:#{user}",my_settings.to_json) end def set_coffee_group(user,group) my_settings = get_settings(user) my_settings[:group] = group - redis.set("settings-#{user}",my_settings.to_json) + redis.set("settings:#{user}",my_settings.to_json) end - def order_coffee(user) - group = get_group(user) - Lita.logger.debug("Group: #{group}") - orders = get_orders(group) - Lita.logger.debug("Orders: #{orders}") - orders << user - orders.uniq! - Lita.logger.debug("New orders: #{orders}") - redis.set("#{group}-orders",orders.to_json) - end - - def cancel_coffee(user) - group = get_group(user) - orders = get_orders(group) - orders.delete(user) - redis.set("#{group}-orders",orders.to_json) - end - def clear_orders(group) - redis.set("#{group}-orders",[]) + set_timeout(group) + redis.del("orders:#{group}") end def send_coffee_message(user,purchaser,message) myuser = Lita::User.find_by_name(user) msg = Lita::Message.new(robot,'',Lita::Source.new(user: myuser)) msg.reply("#{purchaser} has bought you a coffee!") msg.reply(message) # what happens if message is nil? rescue => e Lita.logger.error("Coffee#send_coffee_message raised #{e.class}: #{e.message}\n#{e.backtrace}") + end + + def set_timeout(group) + redis.expire("orders:#{group}",@@DEFAULT_GROUP_TIMEOUT) end end