diff --git a/.gitignore b/.gitignore index 7a057c8..f790d23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ + #Ignore the yml files used as local storage *.yml diff --git a/db/identities.yml b/db/identities.yml index cf4a514..8b97982 100644 --- a/db/identities.yml +++ b/db/identities.yml @@ -2,214 +2,215 @@ sederam: :name: a follower :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-02-14 01:58:51.598510113 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-13 17:58:51.598510113 -08:00 songe: :name: angie :added_by: czhang stufflebear: :name: mary :added_by: steggy_meeting - :updated_at: !ruby/object:DateTime 2013-02-11 05:48:32.624819340 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-10 21:48:32.624819340 -08:00 john_galt: - :name: '"Randian Hero"' + :name: ! '"Randian Hero"' :added_by: steggy_meeting - :updated_at: !ruby/object:DateTime 2013-02-11 18:24:33.604853946 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-11 10:24:33.604853946 -08:00 bird: - :name: '"The word"' + :name: ! '"The word"' :added_by: steggy - :updated_at: !ruby/object:DateTime 2013-02-11 19:30:42.143053785 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-11 11:30:42.143053785 -08:00 wsong: :name: wayne :added_by: wsong - :updated_at: !ruby/object:DateTime 2013-02-11 19:37:58.404597566 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-11 11:37:58.404597566 -08:00 nfair: :name: a_man_of_mystery :added_by: nfair - :updated_at: !ruby/object:DateTime 2013-02-19 19:16:54.458409521 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-19 11:16:54.458409521 -08:00 skimbrel: - :name: '"corrected"' + :name: ! '"corrected"' :added_by: skimbrel - :updated_at: !ruby/object:DateTime 2013-02-13 00:30:54.424832899 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-12 16:30:54.424832899 -08:00 steggy: :name: the greatest :added_by: steggy - :updated_at: !ruby/object:DateTime 2013-02-11 19:48:54.030991226 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-11 11:48:54.030991226 -08:00 whunt: :name: neckbeard :added_by: jknew - :updated_at: !ruby/object:DateTime 2013-02-14 19:01:39.851819168 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-14 11:01:39.851819168 -08:00 heidi: :name: a dragon boob :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-02-11 19:56:20.760960197 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-11 11:56:20.760960197 -08:00 virulently: - :name: '"Asterisms opinion against the use of drone strikes"' + :name: ! '"Asterisms opinion against the use of drone strikes"' :added_by: steggy_meeting - :updated_at: !ruby/object:DateTime 2013-02-13 00:28:00.678122180 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-12 16:28:00.678122180 -08:00 hail_spacecake: :name: Shuflin every day :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-03-15 20:55:41.653387200 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-15 13:55:41.653387200 -07:00 steggy_meeting: - :name: '"steggy, but at a meeting"' + :name: ! '"steggy, but at a meeting"' :added_by: steggy_meeting - :updated_at: !ruby/object:DateTime 2013-02-13 00:48:33.909658534 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-12 16:48:33.909658534 -08:00 jag: :name: josh silver :added_by: steggy - :updated_at: !ruby/object:DateTime 2013-02-13 21:14:27.392581259 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-13 13:14:27.392581259 -08:00 heidi_sux: :name: she suxx :added_by: heidi_sux - :updated_at: !ruby/object:DateTime 2013-02-14 00:40:51.057327930 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-13 16:40:51.057327930 -08:00 jknew: :name: Jacob :added_by: jknew - :updated_at: !ruby/object:DateTime 2013-02-14 19:04:50.003894840 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-14 11:04:50.003894840 -08:00 asterism: :name: victor :added_by: steggy - :updated_at: !ruby/object:DateTime 2013-02-14 18:57:17.276003440 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-14 10:57:17.276003440 -08:00 czhang: :name: your majesty :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-02-14 19:04:02.404956045 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-14 11:04:02.404956045 -08:00 whunt1: :name: a ghost of the shitty ApartmentList internet :added_by: whunt1 - :updated_at: !ruby/object:DateTime 2013-02-15 00:09:58.558940282 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-14 16:09:58.558940282 -08:00 songe1: :name: the ghost of angies past :added_by: steggy - :updated_at: !ruby/object:DateTime 2013-02-18 20:28:44.120463795 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-18 12:28:44.120463795 -08:00 tag: :name: nfair> tag -> scott the other engineer on the Pigeon team with me :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-02-21 18:20:52.773062929 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-21 10:20:52.773062929 -08:00 steggybot: :name: the guy who throws gang signs out the window, ya bish :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-02-19 19:07:41.047552113 +00:00 + :updated_at: !ruby/object:DateTime 2013-02-19 11:07:41.047552113 -08:00 tullidil: :name: Neil Strauss :added_by: tullidil - :updated_at: !ruby/object:DateTime 2013-03-12 19:26:08.684971632 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-12 12:26:08.684971632 -07:00 sushis: :name: heidi :added_by: wsong - :updated_at: !ruby/object:DateTime 2013-03-01 18:12:02.020550975 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-01 10:12:02.020550975 -08:00 kiwis: :name: heidi :added_by: wsong - :updated_at: !ruby/object:DateTime 2013-03-02 00:04:58.759563332 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-01 16:04:58.759563332 -08:00 angie: :name: actually little chris. Do not be fooled :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-03-02 01:11:31.928665846 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-01 17:11:31.928665846 -08:00 everyone: :name: a feature that has not been implemented yet :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-03-02 01:13:47.443978078 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-01 17:13:47.443978078 -08:00 mimblewhimble: :name: Luke :added_by: angie - :updated_at: !ruby/object:DateTime 2013-03-02 01:51:02.017336670 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-01 17:51:02.017336670 -08:00 mcint: :name: loren :added_by: wsong - :updated_at: !ruby/object:DateTime 2013-03-04 17:29:39.286906971 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-04 09:29:39.286906971 -08:00 acanyon: :name: superwoman :added_by: acanyon - :updated_at: !ruby/object:DateTime 2013-03-07 00:21:40.881123186 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 16:21:40.881123186 -08:00 ians: :name: based god :added_by: ians - :updated_at: !ruby/object:DateTime 2013-03-05 23:50:01.823814647 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-05 15:50:01.823814647 -08:00 goteampeach: :name: angela (ed's gf) :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-03-07 22:00:07.967314786 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-07 14:00:07.967314786 -08:00 jungziege: :name: black ian :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-03-06 19:26:21.536887425 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 11:26:21.536887425 -08:00 blackian: :name: black ian :added_by: blackian - :updated_at: !ruby/object:DateTime 2013-03-06 19:28:30.885750926 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 11:28:30.885750926 -08:00 sarmiento: :name: not magnum :added_by: blackian - :updated_at: !ruby/object:DateTime 2013-03-06 19:49:16.456633901 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 11:49:16.456633901 -08:00 davis: :name: white ian :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-03-06 19:50:36.673238502 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 11:50:36.673238502 -08:00 laughinghan: :name: mordred :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-03-07 00:31:10.486539472 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 16:31:10.486539472 -08:00 laughinhan: :name: mordred :added_by: shijing - :updated_at: !ruby/object:DateTime 2013-03-07 00:31:11.149988951 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 16:31:11.149988951 -08:00 adama: :name: a cylon :added_by: wsong - :updated_at: !ruby/object:DateTime 2013-03-07 00:31:13.907373114 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 16:31:13.907373114 -08:00 bordicon: :name: is prepared to 'go robot' for optimus prime :added_by: sean___ - :updated_at: !ruby/object:DateTime 2013-03-27 22:40:12.558413526 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-27 15:40:12.558413526 -07:00 gaius: :name: fucking a cylon :added_by: czhang - :updated_at: !ruby/object:DateTime 2013-03-07 00:32:46.425318958 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-06 16:32:46.425318958 -08:00 yo_momma: :name: a big bitch :added_by: skimbrel - :updated_at: !ruby/object:DateTime 2013-03-09 00:15:37.610585195 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-08 16:15:37.610585195 -08:00 infair: :name: more than fair :added_by: infair - :updated_at: !ruby/object:DateTime 2013-03-09 00:18:26.969788051 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-08 16:18:26.969788051 -08:00 the_real_slim_shady: :name: whoever is standing :added_by: riderofrohan0 - :updated_at: !ruby/object:DateTime 2013-03-09 00:19:00.245318676 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-08 16:19:00.245318676 -08:00 olivm: :name: loren :added_by: wsong - :updated_at: !ruby/object:DateTime 2013-03-13 19:09:50.623634493 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-13 12:09:50.623634493 -07:00 jocob: :name: biotic kanye :added_by: jlhawn_ - :updated_at: !ruby/object:DateTime 2013-03-15 20:56:29.875151841 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-15 13:56:29.875151841 -07:00 jayferd: :name: jay :added_by: jayferd - :updated_at: !ruby/object:DateTime 2013-03-27 22:39:36.016134004 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-27 15:39:36.016134004 -07:00 angie2: :name: a catalyst for steggybot feature arguments :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-03-18 20:26:00.450223622 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-18 13:26:00.450223622 -07:00 foo: :name: a sad test subject forgotten in the dust of the thousands of "fast-paced" start-ups :added_by: whunt - :updated_at: !ruby/object:DateTime 2013-03-18 20:34:01.968589435 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-18 13:34:01.968589435 -07:00 doves: :name: a wild sam :added_by: heidi - :updated_at: !ruby/object:DateTime 2013-03-22 23:25:05.892580611 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-22 16:25:05.892580611 -07:00 tobefree: :name: hehe :added_by: tobefree - :updated_at: !ruby/object:DateTime 2013-03-27 18:35:08.727808982 +00:00 + :updated_at: !ruby/object:DateTime 2013-03-27 11:35:08.727808982 -07:00 nooblet: :name: WHUNT :added_by: czhang +<<<<<<< HEAD:db/identities.yml :updated_at: !ruby/object:DateTime 2013-03-27 18:34:49.580874666 +00:00 judge_dredd: :name: the law @@ -219,3 +220,10 @@ thundara: :name: Nader (Loren's friend) :added_by: wsong :updated_at: !ruby/object:DateTime 2013-03-29 20:47:05.147218908 +00:00 +======= + :updated_at: !ruby/object:DateTime 2013-03-27 11:34:49.580874666 -07:00 +sugis: + :name: steven + :added_by: dovestep + :updated_at: !ruby/object:DateTime 2013-04-04 15:01:12.371347000 -07:00 +>>>>>>> feature-requests:identities.yml diff --git a/plugins/avalon/spec/avalon_spec.rb b/plugins/avalon/spec/avalon_spec.rb new file mode 100644 index 0000000..88341ee --- /dev/null +++ b/plugins/avalon/spec/avalon_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' +require File.dirname(__FILE__) + "/../avalon.rb" + +describe Avalon do + before(:all) do + @avalon = Avalon.new(new_test_bot) + end + + it 'starts a game' do + @message = mock :user => (mock :nick => 'doveStep'), + :channel => (mock :name => 'csuavalon') + + @message.should_receive :reply do |reply| + reply.should include('Players, join in!') + end + + @avalon.dispatch(@message, 'start') + end +end diff --git a/plugins/feature_request.rb b/plugins/feature_request.rb new file mode 100644 index 0000000..b04f638 --- /dev/null +++ b/plugins/feature_request.rb @@ -0,0 +1,281 @@ +#todo style app that keeps track of features we wish to implement for steggybot + +require 'cinch' +require 'yaml' + +class FeatureRequest + include Cinch::Plugin + + # Adds your input as a feature request to steggybot. + # Works best if you give your feature request a :<description>. + # Example: !add task feature request: a todo style app that lists features + # and their progress + match /(add feature|add request) (.+)/i, method: :add_request + + # Replies with a list of already requested features. + # For a super lengthy list with all of the detail, type !info : + # If you want to use !info in your app, tell me and I'll change it to + # something else. + match /list/i, method: :print_requests + + # Replies with detailed information on each feature whose title or description + # match your query. + match /info (.+)/i, method: :print_info + + # Replies with specific information on each feature whose title/descr matches + # your query. + match /(status|progress) (?![=])(.+)/i, method: :search_tasks + match /(feature|description) (?![=])(.+)/i, method: :search_tasks + match /(who has claimed) (.+)/i, method: :search_tasks + + # Overwrites specific information on each feature whose title/descr matches + # your query. + # Your query should only match one feature request. + # Fix typos, update progress, or stake a claim. + match /(status =|progress =) (.+) for (.+)/i, method: :search_tasks + + match /(complete)( )(.+)/i, method: :search_tasks + match /(start)( )(.+)/i, method: :search_tasks + match /(change claim to) (.+) for (.+)/i, method: :search_tasks + match /(claim)( )(?!(?:to))(.+)/i, method: :search_tasks + + match /(feature =|request =|description =) (.+) for (.+)/i, method: :search_tasks + + # Please only use to remove troll or test feature requests. + # To remove, you must type the *entire* title+description, aka entire "task". + # If you complete a feature request, change its progress to "Completed" and + # it will be moved to the completed_features.yml. + match /remove (.+)/i, method: :remove_request + + + def initialize(*args) + super + @task_list = config[:task_list] + end + + def add_request(m, unused_message, task) + new_task = {:task => task, + :added_by => m.user.nick, + :created_at => Time.now, + :progress => "not started", + :updated_at => Time.now, + :claim => "no one"} + + old_tasks = get_tasks(@task_list) || [] + combined_tasks = old_tasks << new_task + + store combined_tasks + + m.reply "#{m.user.nick}: Request received and rendered ##{new_task}" + end + + + # Replies with a list of already requested features. + def print_requests(m) + tasks = get_tasks @task_list || [] + if tasks == [] + m.reply "No one has requested a feature yet." + else + m.reply "Listing requested features & their statuses below:" + tasks.each do |task| + m.reply "#{task[:task]} -- Progress: #{task[:progress];}" + end + end + end + + + # Replies with all information on each feature whose title or description + # match your query. + # Works best if you have a name for your feature request. + def print_info(m, title) + tasks = get_tasks @task_list + if tasks + tasks.each do |task| + if task[:task].include? title + m.reply "#{m.user.nick}: Info: #{task}" + end + end + end + end + + + # Please only use to remove mistakes. + # To mark a task completed, use !complete <task> + def remove_request(m, task_description) + tasks = get_tasks @task_list + if tasks + nothing_was_deleted = true + tasks.each do |task| + if task[:task] == task_description && task[:added_by] == m.user.nick + tasks.delete task + nothing_was_deleted = false + m.reply "#{m.user.nick}: Removed mistaken feature request " << + "#{task_description}" + end + end + if nothing_was_deleted + m.reply "#{m.user.nick}: Cannot remove '#{task_description}' because "<< + "it is not the full title/description of an added feature request " << + "or you are not the one who added the feature request initially." + end + + end + + store tasks + end + + + #-------------------------------------------------------------------------------- + # Protected + #-------------------------------------------------------------------------------- + + protected + + def store(tasks) + output = File.new(@task_list, 'w') + output.puts YAML.dump(tasks) + output.close + + end + + def get_tasks(file) + output = File.new(file, 'r') + tasks = YAML.load(output.read) + output.close + + tasks + end + + + # Walks through list searching for query matches. + # Replies with success_message for each query matched. + # success_message is a string stored in a proc for lazy evaluation. + # If you change the variable 'task,' you will need to change the strings too. + # Executes code block for each query matched (e.g. claim a task) + # If no matches found, replies with no matches found message. + def search_tasks(m, message, new_data = nil, query) + + tasks = get_tasks @task_list + if tasks + nothing_was_found = true + tasks.each do |task| + if task[:task].include? query + nothing_was_found = false + if new_data # checking if message is a setter + task = try_setting(m, message, task, new_data) + else # message is a getter + get_data(m, message, task) + end + end + end + store tasks + if nothing_was_found + m.reply "#{m.user.nick}: No requests found that match your query #{query}." + end + end + end + + + def try_setting(m, message, task, new_data) + if claimant(m, task) || (message == "claim" && claim_empty?(m, task)) + task = change_data(m, message, task, new_data) + m.reply success_message(m, message, task) + else + m.reply failure_message(m, message, task) + end + task + end + + def get_data(m, message, task) + m.reply success_message(m, message, task) + end + + def success_message(m, message, task) + case message + when /(status =|progress =)/i + "#{m.user.nick}: Progress successfully changed to #{task[:progress]} " << + "for #{task[:task]}." + + when /(status|progress)/i + "#{m.user.nick}: Progress: #{task[:progress]} -- #{task[:task]}" + + when /(feature =|request =|description =)/i + "#{m.user.nick}: Successfully changed task to #{task[:task]}." + + when /(feature|description)/i + "#{m.user.nick}: #{task[:task]}" + + when /(who has claimed)/i + "#{m.user.nick}: #{task[:claim]} has claimed #{task[:task]}" + + when /(change claim to)/i + "#{m.user.nick}: You have successfully given your claim to" << + " #{task[:claim]} for #{task[:task]}" + + when /(claim)/i + "#{m.user.nick}: You have successfully claimed #{task[:task]}" + + when /(start)/i + "#{m.user.nick}: I'm so glad you're starting to work on #{task[:task]}!" + + when /(complete)/i + "#{m.user.nick}: Congratulations on completing #{task[:task]}!!!" + end + end + + def failure_message(m, message, task) + case message + when /(claim)/i + "#{m.user.nick}: #{task[:claim]} has first" << + " dibs on #{task[:task]}. Please sort it with them." + + else + "#{m.user.nick}: Only the claimant #{task[:claim]} may update #{task[:task]}." + end + end + + + def claimant(m, task) + task[:claim] == m.user.nick + end + + def claim_empty?(m, task) + task[:claim] == "no one" + end + + # Check claimant before calling change_data + def change_data(m, message, task, new_data = nil) + case message + when /(status =|progress =)/i + task[:progress] = new_data + task[:updated_at] = Time.now + task + + when /(feature =|request =|description =)/i + task[:task] = new_data + task + + when /(change claim to)/i + task[:claim] = new_data + task + + when /(claim)/i + task[:claim] = m.user.nick + task + + when /(start)/i + task[:progress] = "begun" + task[:updated_at] = Time.now + task + + when /(complete)/i + task[:progress] = "completed" + task[:updated_at] = Time.now + task + + end + end + + + +end \ No newline at end of file diff --git a/plugins/google.rb b/plugins/google.rb index 4093dd1..c759a32 100644 --- a/plugins/google.rb +++ b/plugins/google.rb @@ -7,7 +7,6 @@ class Google include Cinch::Plugin match /google (.+)/, method: :execute match /image (.+)/, method: :image - @help_hash = { :google => "Usage: !google THING Example !google Syria diff --git a/plugins/pazudora.rb b/plugins/pazudora.rb new file mode 100644 index 0000000..484ef0f --- /dev/null +++ b/plugins/pazudora.rb @@ -0,0 +1,219 @@ +require 'cinch' +require 'nokogiri' + +class Pazudora + include Cinch::Plugin + + PUZZLEMON_BASE_URL = "http://www.puzzledragonx.com/en/" + + match /pazudora ([\w-]+) *(.+)*/i, method: :pazudora + match /stupidpuzzledragonbullshit ([\w-]+) *(.+)*/i, method: :pazudora + match /stupiddragonpuzzlebullshit ([\w-]+) *(.+)*/i, method: :pazudora + match /p&d ([\w-]+) *(.+)*/i, method: :pazudora + match /pad ([\w-]+) *(.+)*/i, method: :pazudora + match /puzzlemon ([\w-]+) *(.+)*/i, method: :pazudora + match /puzzledex (.+)*/i, method: :pazudora_lookup + + @help_string = <<-eos + Puzzle and Dragons (on iOS and Android) utility functions. Mostly collects friend codes and tracks the daily dungeon. + Its commands are aliased to pazudora, p&d, pad, and puzzlemon. + eos + @help_hash = { + :add => "Usage: !puzzlemon add NAME CODE +Example: !puzzlemon add steggybot 123,456,789 +Adds user's code to the list of friend codes", + :group => "Usage: !puzzlemon group NAME +Example !puzzlemon group steggybot +Returns the daily dungeon group that the user belongs to.", + :dailies => "Usage: !puzzlemon dailies +Example !puzzlemon dailies +Returns the times (and type) of today's daily dungeons, split by group. If called by +a registered player, also reminds them of their group id.", + :lookup => "Usage: !(puzzlemon lookup|puzzledex) (NAME|ID) +Example !puzzlemon lookup horus, !puzzledex 603 +Returns a description of the puzzlemon. If none is found, returns a pseudorandom (hashed) one.", + :list => "Usage: !puzzlemon list +Example !puzzlemon list +Returns a list of everyone's friends codes." + } + + def initialize(*args) + super + @pddata = config[:pddata] + end + + #Any public method named pazudora_[something] is external and + #can be accessed by the user using the construction "!puzzlemon something [args]". + def pazudora (m, cmd, args) + subr = cmd.downcase.chomp + begin + if args + self.send("pazudora_#{subr}", m, args) + else + self.send("pazudora_#{subr}", m, "") + end + rescue NoMethodError + puts "Pazudora called with invalid command #{subr}." + end + end + + def pazudora_add (m, args) + pargs = args.split + username = pargs[0] + friend_code = pargs[1] + + # add it to the list + friend_codes = load_data || {} + if friend_code =~ /[0-9]{9}/ + friend_code = friend_code.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse + end + if friend_codes[username.downcase] && (friend_codes[username.downcase][:added_by] == username.downcase) + if m.user.nick.downcase == username.downcase + friend_codes[username.downcase] = {:friend_code => friend_code, :added_by => m.user.nick.downcase, :updated_at => DateTime.now} + else + m.reply "#{m.user.nick}: Can't override a user's self-definition." + return + end + else + friend_codes[username.downcase] = {:friend_code => friend_code, :added_by => m.user.nick.downcase, :updated_at => DateTime.now} + end + # write it to the file + output = File.new(@pddata, 'w') + output.puts YAML.dump(friend_codes) + output.close + + m.reply "#{m.user.nick}: #{mangle(username)} successfully added as '#{friend_code}'." + end + + def pazudora_remove(m, args) + pargs = args.split + username = pargs[0] + friend_codes = load_data || {} + + if ! friend_codes[username] + m.reply "#{m.user.nick}: #{mangle(username)} not in friend code list." + return + end + + if (m.user.nick.downcase == username.downcase) || (m.user.nick.downcase == friend_codes[username][:added_by]) + friend_codes.delete(username) + # write it to the file + output = File.new(@pddata, 'w') + output.puts YAML.dump(friend_codes) + output.close + + m.reply "#{m.user.nick}: #{mangle(username)} removed from friend code list." + else + m.reply "#{m.user.nick}: Only the identity creator or subject can remove a friend code from the list." + end + end + + def pazudora_who(m,args) + pargs = args.split + username = pargs[0] + if load_data[username.downcase] + m.reply "#{m.user.nick}: #{mangle(username)}'s friend code is #{load_data[username.downcase][:friend_code]}" + end + end + + def pazudora_list(m,args) + friend_codes = load_data || {} + friend_codes.keys.each_slice(3).with_index { |users, i| + r = i == 0 ? "#{m.user.nick}: " : "" + users.each{ |user| r=r+"#{mangle(user)}:#{friend_codes[user][:friend_code]} " } + m.reply r + } + end + + def pazudora_group(m,args) + pargs = args.split + username = pargs[0] + if load_data[username.downcase] + friend_code = load_data[username.downcase][:friend_code] + group = (Integer(friend_code.split(",")[0][2]) % 5 + 65).chr + m.reply "#{m.user.nick}: #{mangle(username)}'s group is #{group}" + else + m.reply "#{m.user.nick}: #{mangle(username)}'s friend code is not listed. Please use the add command to add it." + end + end + + def pazudora_dailies(m, args) + daily_url = PUZZLEMON_BASE_URL + "option.asp?utc=-8" + + username = args.split[0] || m.user.nick + friend_code = load_data[username.downcase][:friend_code] rescue nil + group_num = friend_code ? group_number_from_friend_code(friend_code) : nil + + unless @daily_timestamp == Time.now.strftime("%m-%d-%y") + @daily_page = nil + @daily_timestamp = Time.now.strftime("%m-%d-%y") + end + + @daily_page ||= Nokogiri::HTML(open(daily_url)) + event_data = @daily_page.css(".event3") + event_rewards = @daily_page.css(".limiteddragon") + + rewards = parse_daily_dungeon_rewards(event_rewards) + m.reply "Dungeons today are: #{rewards.join(', ')}" + + (0..4).each do |i| + m.reply "Group #{(i + 65).chr}: #{event_data[i].text}, #{event_data[i + 5].text}, #{event_data[i + 10].text}" + end + + if group_num + m.reply "User #{username} is in group #{(group_num + 65).chr}" + end + end + + def pazudora_lookup(m, args) + identifier = args + info = get_puzzlemon_info(URI.encode(identifier)) + + #Bypass puzzledragonx's "default to meteor dragon if you can't find the puzzlemon" mechanism to + #get a pseudorandom puzzlemon (up to the max currently released puzzlemon) instead. + meteor_dragon_id = "211" + highest_puzzledex_id = 603 + + if info.css(".name").children.first.text == "Meteor Volcano Dragon" && !(identifier.start_with?("Meteor") || identifier == meteor_dragon_id) + num = (identifier.hash % highest_puzzledex_id) + 1 + info = get_puzzlemon_info(URI.encode(num.to_s)) + end + + desc = info.css("meta [name=description]").first.attributes["content"].text + desc.gsub!(/&/, "&") + m.reply desc + end + + protected + + def mangle(s) + s.chop + "." + s[-1] + end + + def load_data + datafile = File.new(@pddata, 'r') + friend_codes = YAML.load(datafile.read) + datafile.close + return friend_codes + end + + def group_number_from_friend_code(friend_code) + return Integer(friend_code.split(",")[0][2]) % 5 + end + + def parse_daily_dungeon_rewards(rewards) + puzzlemon_numbers = [ + rewards[0].children.first.attributes["src"].value.match(/thumbnail\/(\d+).png/)[1], + rewards[5].children.first.attributes["src"].value.match(/thumbnail\/(\d+).png/)[1], + rewards[10].children.first.attributes["src"].value.match(/thumbnail\/(\d+).png/)[1]] + + puzzlemon_numbers.map{|x| + get_puzzlemon_info(x).css(".name").children.first.text rescue "Unrecognized Name" } + end + + def get_puzzlemon_info(name_or_number) + search_url = PUZZLEMON_BASE_URL + "monster.asp?n=#{name_or_number}" + puzzlemon_info = Nokogiri::HTML(open(search_url)) + end +end + diff --git a/steggybot.rb b/steggybot.rb index 1e64502..114e2bb 100644 --- a/steggybot.rb +++ b/steggybot.rb @@ -5,11 +5,19 @@ bot = Cinch::Bot.new do configure do |c| c.server = "irc.freenode.net" - c.nick = "steggybot" + c.nick = "steppybot" + + c.channels = ["#csuatest", "##csua"] # "#csua", + c.plugins.plugins = [Google, UrbanDictionary, TitleGrabber, Quotes, Pokedex, + Youtube, YaBish, Roll, WhoAreThesePeople, PlusPlus, + Pazudora, FeatureRequest] + c.plugins.plugins << Help + c.channels = ["#csua", "#csuatest"] # c.channels = ["#csuatest"] c.plugins.plugins = [Google, UrbanDictionary, TitleGrabber, Quotes, Pokedex, Youtube, - Roll, WhoAreThesePeople, PlusPlus, Pazudora, Contributors, Countdown, FrenchRevCal, FeatureRequestPlugin] + Roll, WhoAreThesePeople, PlusPlus, Pazudora, Contributors, Countdown, + FrenchRevCal, FeatureRequestPlugin] c.plugins.plugins << Help c.plugins.options[YaBish] = { :db => 'db/ya_bish', diff --git a/tmp/scratch b/tmp/scratch new file mode 100644 index 0000000..32d5924 --- /dev/null +++ b/tmp/scratch @@ -0,0 +1,82 @@ +#### + +!avalon status +=> mode: waiting for votes + .... +!avalon who + Current players: <nick>, <nick>... + Current characters: merlin, assassin, ... +!avalon log + + +#### + + +!avalon start [characters...] +!avalon start +=> starting an avalon game + + +# each person +!avalon in +=> 7 players: using merlin, assasin, ... + +!avalon use merl +!avalon use + +!avalon go +=> Darkness falls over camelot. Check your PM for ... + +(pm to each player) +=> You are Merlin (good). Assassin, Morgana, and Oberon are (in some order) jayferd, doveStep, and laughinghan. + +=> laughinghan is King. The hammer is doveStep. +=> King, please propose a team of <n> knights to go a-questing. + +(from han) +!avalon propose <nick> <nick> <nick> + => wrong number of knights +=> laughinghan proposes <nick>, <nick>, and <nick>. Knights of the round table, what say ye? (PM the bot with "yea" or "nay") + +(wait for all votes) +=> <nick> has voted. Still waiting for [<nick>...] + +=> The votes are in! The team is [accepted|rejected] + jayferd: yea + doveStep: nay + laughinghan: yea + ... + +rejected: The team is rejected! +(next king, go to <nick> is King...) + +accepted: The team is accepted! [team members], please PM the bot with "success" or "failure" + +=> <nick> has voted. +=> <nick> has voted. +=> <nick> has voted. +=> The chalices are in. The mission [failed|succeeded]. + + + +"#csua": + players: + - <nick>: merlin + - <nick>: morgana + - ... + features: + - lady (#use, #unuse) + - mordred + - morberon + - merlin + king: <nick> + hammer: <nick> + log: + - success: <bool> + team: <nick>, <nick>... + chalices: true, true, false + - ... + mode: voting + votes: [nick: bool] + chalices: [nick: bool ] + team: [<nick>]