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
:.
+ # 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
+ 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: , ...
+ 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 knights to go a-questing.
+
+(from han)
+!avalon propose
+ => wrong number of knights
+=> laughinghan proposes , , and . Knights of the round table, what say ye? (PM the bot with "yea" or "nay")
+
+(wait for all votes)
+=> has voted. Still waiting for [...]
+
+=> The votes are in! The team is [accepted|rejected]
+ jayferd: yea
+ doveStep: nay
+ laughinghan: yea
+ ...
+
+rejected: The team is rejected!
+(next king, go to is King...)
+
+accepted: The team is accepted! [team members], please PM the bot with "success" or "failure"
+
+=> has voted.
+=> has voted.
+=> has voted.
+=> The chalices are in. The mission [failed|succeeded].
+
+
+
+"#csua":
+ players:
+ - : merlin
+ - : morgana
+ - ...
+ features:
+ - lady (#use, #unuse)
+ - mordred
+ - morberon
+ - merlin
+ king:
+ hammer:
+ log:
+ - success:
+ team: , ...
+ chalices: true, true, false
+ - ...
+ mode: voting
+ votes: [nick: bool]
+ chalices: [nick: bool ]
+ team: []