Permalink
Browse files

Fresh, sanitized repo

  • Loading branch information...
0 parents commit 39fb70dc2fb33dcfc0bffe3ce9d82ff487ccd67f @nathanl committed Nov 24, 2012
Showing with 208 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +29 −0 config/people.yml.example
  3. +5 −0 config/smtp.yml.example
  4. +26 −0 email.rb
  5. +33 −0 emailer.rb
  6. +25 −0 person.rb
  7. +9 −0 santa_logger.rb
  8. +80 −0 secret_santa.rb
@@ -0,0 +1 @@
+config/*.yml
@@ -0,0 +1,29 @@
+people:
+ -
+ name: Edward
+ group: New York Smiths
+ email: edward@example.com
+ -
+ name: Kara
+ group: New York Smiths
+ email: kara@example.com
+ -
+ name: Alberto
+ group: Atlanta Smiths
+ email: alberto@example.com
+ -
+ name: Natasha
+ group: Atlanta Smiths
+ email: jeanette@exaple.com
+ -
+ name: Tyler
+ group: Seattle Joneses
+ email: tyler@example.com
+ -
+ name: Linda
+ group: Seattle Jonses
+ email: linda@example.com
+ -
+ name: Fiona
+ group: Seattle Jonses
+ email: fiona@example.com
@@ -0,0 +1,5 @@
+smtp_server: smtp.gmail.com
+domain: gmail.com
+account_address: hikingfan@gmail.com
+account_password: sUch_a_bEeFy_paSswOrd!_iT's_niGh_ImpeNetrable_29$(@*4729!_gOod_Luck_suckErS
+port: 587
@@ -0,0 +1,26 @@
+require 'time'
+
+class Email
+ attr_accessor :from_address, :to_address, :subject, :body
+
+ def initialize(to_address, subject, body)
+ self.to_address = to_address
+ self.subject = subject
+ self.body = body
+ end
+
+ def headers
+ raise "Must set `from_address` before getting headers!" unless from_address
+ <<EOF
+From: #{from_address}
+To: #{to_address}
+Subject: #{subject}
+Date: #{Time.now.rfc2822}
+EOF
+ end
+
+ def message
+ headers + "\n" + body
+ end
+
+end
@@ -0,0 +1,33 @@
+require 'net/smtp'
+
+class Emailer
+
+ attr_accessor :smtp_server, :domain, :account_address, :account_password, :port
+
+ def initialize(smtp_server, domain, account_address, account_password, port = 587)
+ self.smtp_server = smtp_server
+ self.domain = domain
+ self.account_address = account_address
+ self.account_password = account_password
+ self.port = port
+ end
+
+ def send(email)
+ email.from_address = account_address
+
+ if REALLY_SENDING
+ print "Mailing #{email.to_address}..."
+
+ Net::SMTP.enable_tls
+ Net::SMTP.start(smtp_server, port, domain, account_address, password, :login) do |smtp|
+ smtp.send_message(email.message, email.from_address, email.to_address)
+ end
+
+ print "sent!\n"
+ else
+ puts "**Testing; not really mailing anything**\nEmail would be as follows:\n\n"
+ puts email.message
+ puts "======"
+ end
+ end
+end
@@ -0,0 +1,25 @@
+class Person
+ attr_accessor :name, :group, :email, :santa
+
+ def to_s
+ "#{name} (#{group})"
+ end
+
+ def with_santa
+ "#{self} - santa: #{santa}"
+ end
+
+ def initialize(attrs)
+ self.name = attrs["name"]
+ self.group = attrs["group"]
+ self.email = attrs["email"]
+ end
+
+ def can_be_santa_of?(other)
+ group != other.group
+ end
+
+ def can_swap_santas_with?(other)
+ santa.can_be_santa_of?(other) && other.santa.can_be_santa_of?(self)
+ end
+end
@@ -0,0 +1,9 @@
+class SantaLogger
+
+ attr_accessor :sending
+
+ def log(message)
+ puts "#{message}" unless REALLY_SENDING # Sshh! It's a secret!
+ end
+
+end
@@ -0,0 +1,80 @@
+$LOAD_PATH << '.'
+require 'yaml'
+require 'person'
+require 'emailer'
+require 'email'
+require 'santa_logger'
+
+# Do some testing, then set this to true when ready to send
+# Will cause logging output to be shushed and mails to be sent
+REALLY_SENDING = false
+
+Logger = SantaLogger.new
+
+people_config = YAML.load_file('config/people.yml')
+
+people = people_config['people'].map do |attrs|
+ Person.new(attrs)
+end
+
+santas = people.dup
+people.each do |person|
+ person.santa = santas.delete_at(rand(santas.size))
+end
+
+Logger.log "Initial Santa assignments:"
+people.each do |person|
+ Logger.log person.with_santa
+end
+
+Logger.log "Checking assignments for validity"
+people.each do |person|
+ unless person.santa.can_be_santa_of?(person)
+ Logger.log "\n#{person} can't get a gift from #{person.santa}! Let's try to fix that..."
+ swap_candidates = people.select {|p| person.can_swap_santas_with?(p) }
+ raise "Failure! No one can swap santas with #{person}" if swap_candidates.empty?
+ Logger.log "Any of these can swap santas with #{person}: #{swap_candidates}"
+ swapper = swap_candidates.sample
+ Logger.log "Chose #{swapper} to swap santas with #{person}"
+ misplaced_santa = person.santa
+ person.santa = swapper.santa
+ swapper.santa = misplaced_santa
+ end
+end
+
+Logger.log "\n\nFinal Santa assignments:"
+people.each do |person|
+ Logger.log person.with_santa
+end
+
+smtp_config = YAML.load_file('config/smtp.yml')
+emailer = Emailer.new(
+ smtp_config['smtp_server'],
+ smtp_config['domain'],
+ smtp_config['account_address'],
+ smtp_config['account_password']
+)
+
+people.each do |person|
+ message = <<-MESSAGE
+ GREETINGS #{person.santa.name.upcase},
+
+ HATS ARE NOW OBSELETE.
+
+ SANTABOT 5000 HAS BEEN ACTIVATED. YOU HAVE BEEN CHOSEN AS A SECRET SANTA.
+ YOUR TARGET IS AS FOLLOWS:
+
+ #{person.name.upcase}
+
+ THIS INFORMATION HAS BEEN KEPT SECRET FROM ALL HUMANS BUT YOU.
+
+ IF I, SANTABOT, HAD EMOTIONS, I WOULD WISH YOU A MERRY CHRISTMAS,
+ BUT AS IT IS THAT WOULD NOT REALLY MAKE SENSE.
+
+ THAT IS ALL.
+
+ --SANTABOT 5000
+ MESSAGE
+ email = Email.new(person.santa.email, "SANTABOT 5000: #{Time.now.year} TARGETS", message)
+ emailer.send(email)
+end

0 comments on commit 39fb70d

Please sign in to comment.