123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- #!/usr/bin/ruby
-
- require 'rubygems'
- require 'stomp'
- require 'digest/md5'
- #users = [ "mihawksrv", "qwnu", "qwnuposter", "pauldevqw", "paulkibito" ]
- # WRITE COMMANDS as ROLE everyone:
- # PING - reply from central: PONG
- # WHO - reply from everyone: WHO_RE
- # C - reply from central: C
- # PART - reply from central: SYS Goodbye
- # WRITE COMMANDS as ROLE broadcast:
- # REQ_BC - reply from central: BC_ID
- # BC_RE
- # WRITE COMMANDS as ROLE adminspecbots:
- # REQ_ASSIGN - reply from specbot: assign_re..
- # REQ_UNASSIGN - reply from specbot: unassign_re..
- # REQ_PING - reply from specbots: ping_re..
- # REQ_ASSIGNMENTS - reply from specbot: assignments_re..
- # WRITE COMMANDS as ROLE specbot:
- # ASSIGN_RE
- # UNASSIGN_RE
- # PING_RE
- # ASSIGNMENTS_RE
- # USERS: ROLE
- # paulkibito: broadcast
- # qwnu: broadcast
- # mihawk: broadcast specbot
- # pauldevqw: broadcast specbot
- # qwsbalance: adminspecbots
- #
- # .. allowed commands .. ROLES = CAPABILITIES
- # normal users have ROLE broadcast. Roles are defined on a per-user basis .. in a config.
- STDOUT.sync = true
-
- raise "ARGV[0] must be a userstring - no numbers!" unless ARGV[0] =~ /^[a-zA-Z]+$/
- $user = "%s" % [ARGV[0]]
- $broadcasts = Hash.new
- $debug = 0
- def put_debug(msg)
-
- if $debug == 1
- puts msg
- end
- end
- def put_log(msg)
- puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S %z")}: #{msg}"
- end
- # consuming process with a loop
- def consuming(user)
- put_log "SYS Starting consuming/reading thread\n"
- client = Stomp::Connection.new("", "", "localhost", 61613, true)
- client.subscribe("/topic/messages")
- client.subscribe("/topic/#{user}-replies")
- loop do
- begin
- msg = client.receive
- if not msg.body =~ /^[\d]+ #{user}:/
- put_debug "DEBUG: #{msg.body}"
- message = msg.body
- regex = Regexp.new('^(\d+) ([a-zA-Z]+):[ ,](([a-zA-Z_]+)[ ,](.*))$')
- msg_array = message.scan(regex)
- put_debug "msg.headers #{msg.headers["reply-to"]}"
- put_debug "msg_array #{msg_array}"
- m_time = msg_array[0][0]
- m_user = msg_array[0][1]
- m_msg = msg_array[0][2]
- m_cmd = msg_array[0][3]
- m_pload= msg_array[0][4]
- if m_cmd =~ /^JOIN/
- put_log "JOINED User '#{m_user}' just joined the party."
- elsif m_cmd =~ /^C/
- put_log "C #{m_user}: #{m_pload}"
- elsif m_cmd =~ /^BC_RE/
- put_log "BC_RE #{m_pload}"
- elsif m_cmd =~ /^BC/
- # we received a broadcast from #{m_user} with a hash. save it for later.
- m_pload =~ /^(.+?) /
- bcid = $1
- #put_log "bcid #{bcid}"
- $broadcasts[bcid] = m_user
- # give sth to the client to process.
- put_log "BC #{m_pload}"
- #sending a fake reply.
- if $user == "paulfakereply"
- put_log "debug: sending fake reply to #{m_user}"
- send("/topic/#{m_user}-replies", "BC_RE #{bcid} Squirrels=2,Nuts=5")
- end
- elsif m_cmd =~ /^WHO_RE/
- put_log "WHO_RE '#{m_user}' with ROLES: xyz,xyz in the house."
- elsif m_cmd =~ /^WHO/
- reply_to_msg(msg, "WHO_RE #{user} is online.")
- elsif m_cmd =~ /^PART/
- put_log "PARTED User '#{m_user}' just left the party."
- else
- put_log "dbg: #{m_cmd}"
- end
- else
- put_debug "RECEIVED from myself. Ignoring."
- end
- rescue
- put_debug "hum?"
- retry
-
- end
- end
- end
- def reply_to_msg(msg, payload)
- if msg.headers["reply-to"]
- send(msg.headers["reply-to"], payload)
- end
- end
- def send(path, inputmsg, *header)
- begin
- finalmessage = ""
- Timeout::timeout(2) do
- stomp = Stomp::Client.new("", "", "localhost", 61613)
- finalmessage = "%d %s: %s" % [Time.now.utc.to_i, $user, inputmsg]
- if header != ""
- stomp.publish(path, finalmessage, *header)
- else
- stomp.publish(path, finalmessage)
- end
- stomp.close
- end
- rescue Timeout::Error
- put_debug "Failed to send within the 2 second timeout"
- exit 1
- else
- put_debug "SENT: #{finalmessage}"
- end
- end
- put_log "HELLO Hi user '#{$user}'! How are you?"
- send("/topic/messages", "JOIN Hi guys, I'm user '#{$user}'.")
- thread_consuming = Thread.new {consuming $user}
- #put_log "SYS Going into input loop"
- inputmessage = ""
- while inputmessage != "PART"
- inputmessage = ""
- inputmessage = STDIN.gets.chomp
- if inputmessage =~ /^(PING)$/
- put_log "PONG"
- elsif inputmessage =~ /^(REQ_BC)/
- inputmessage =~ /^(REQ_BC)[ ,](.+),(.+),(.+),'(.+)','(.+)'$/
- # n f s ni txt
- error = 0
- # $&
- # The string matched by the last successful pattern match in this scope, or nil if the last pattern match failed. (Mnemonic: like & in some editors.) This variable is read-only.
- if $& == nil
- put_log "SYS Command format is REQ_BC <network>,<frequency>,<source/channel>,'<nickname>','<message>'"
- error = 1
- else
- command = "BC"
- network = $2
- freqname = $3
- source = $4
- nickname = $5
- text = $6
- if network =~ /^(QWalt)|(QDEV)/
- else
- put_log "SYS Network name #{network} is unknown: QWalt or QDEV allowed."
- error = 1
- end
- if freqname =~ /^(-qw-)|(-spam-)|(-dev-)/
- else
- put_log "SYS Frequency name is unknown #{freqname}"
- error = 1
- end
- if source =~ /^(#.+)|(qw:\/\/)|(http:\/\/)/
- else
- put_log "SYS Source string is not in the form ^(#.+)|(qw:\/\/)|(http:\/\/) was: #{source}"
- error = 1
- end
- if nickname =~ /^.+/
- else
- put_log "SYS Nickname string is not in the form ^.+ #{nickname}"
- error = 1
- end
- if text =~ /^.+/
- else
- put_log "SYS Message string is not in the form ^.+ #{text}"
- error = 1
- end
- end
- if error == 0
- finalmessage = "%s network:%s frequency:%s source:%s nickname:%s message:%s" % [command, network, freqname, source, nickname, text]
- # building hash here (bcid)
- bcid = Digest::MD5.hexdigest("%d %s %s %s %s %s" % [Time.now.utc.to_i, network, freqname, source, nickname, text])
- #bcid = OpenSSL::Digest::MD5.hexdigest("%d %s %s %s %s %s" % [Time.now.utc.to_i, network, freqname, source, nickname, text])
- finalmessage = "%s %s %s,%s,%s,'%s','%s'" % [command, bcid, network, freqname, source, nickname, text]
- #finalmessage = "%s" % [inputmessage]
- send("/topic/messages", finalmessage)
- put_log "BC_ID #{bcid} for: #{network},#{freqname},#{source}"
- end
-
-
- elsif inputmessage =~ /^(BC_RE)/
- inputmessage =~ /^(BC_RE) (.+) (.+)=(\d+),(.+)=(\d+)$/
- if $& == nil
- put_log "SYS Format is BC_RE <bcid> <userstring>=<usercount>,<itemstring>=<itemcount>"
- else
- command = $1
- bcid = $2
- user_string = $3
- user_count = $4
- item_string = $5
- item_count = $6
- finalmessage = "%s %s %s=%d,%s=%d" % [command, bcid, user_string, user_count, item_string, item_count]
- # according bcid it is possible to get the originating user.. so send only to his topic!
- if $broadcasts[bcid]
- to_user = $broadcasts[bcid]
- put_log "SYS Broadcast reply bcid: #{bcid} underway. To: '#{to_user}'."
- send("/topic/#{to_user}-replies", finalmessage)
- else
- put_log "SYS Broadcast reply bcid: #{bcid} underway."
- send("/topic/messages", finalmessage)
- end
- end
-
- elsif inputmessage =~ /^(C)/
- inputmessage =~ /^(C) (.+)$/
- error = 0
- if $& == nil
- put_log "SYS Format is C <chattext>"
- error = 1
- else
- put_log "C #{$user}: #{$2}"
- send("/topic/messages", "C #{$2}")
- end
- elsif inputmessage =~ /^(PART)$/
- put_log "SYS Goodbye '#{$user}'."
- send("/topic/messages", "PART The party was fun.")
- elsif inputmessage =~ /^(WHO)/
- put_log "SYS Asking who's here."
- send("/topic/messages", "WHO is here?", "reply-to" => "/topic/#{$user}-replies")
- else
- put_log "SYS Not a known command, #{inputmessage}, possible commands are:"
- put_log "SYS 'C' 'REQ_BC' 'BC_RE' 'WHO' 'PING' or 'PART'"
- end
- # puts "%d: " % [Time.now.utc.to_i]
- #frequency = "-qw-" #inputmessage
- #channel = "#qwnet" #inputmessage
- #nickname = user
- #message = inputmessage
- #find type of message?
- #validate message against that type ..
- #then send in a format.
- #client sending message and awaiting replies
- #stomp.subscribe("/temp-queue/random_replies")
- #stomp.publish("/queue/random_generator", "random", {"reply-to" => "/temp-queue/random_replies"})
- #Timeout::timeout(2) do
- # msg = stomp.receive
- # puts "Got the response: #{msg.body}"
- #end
- #
- #stomp.publish(msg.headers["reply-to"], number)
- #
- #
- end
|