require "http/client" require "json" require "pretty_print" require "xml" require "inotify" home = Path["~/"].expand.to_s access_token = File.read( home + ".config/twitch/access_token" ).chomp client_id = File.read( home + ".config/twitch/client_id" ).chomp channel = File.read( home + ".config/twitch/channel" ).chomp channel_id = File.read( home + ".config/twitch/channel_id" ).chomp voices = Hash(String, String).new File.each_line( home + "voicelist" ) do |line| voices[ line.downcase ] = line end #FIXME: cache twitch results def twitch_name_to_uid( client_id, name ) twitchclient = HTTP::Client.new( "api.twitch.tv", port = 443, tls = true ) response = twitchclient.exec( "GET", "/helix/users?login=" + name, headers: HTTP::Headers{ "Client-ID" => client_id } ) puts response.status_code json = JSON.parse( response.body ) uid = json["data"][0]["id"].to_s.match(/[0-9]+/).not_nil![0] twitchclient.close return uid end def twitch_uid_to_name( client_id, uid ) client = HTTP::Client.new( "api.twitch.tv", port = 443, tls = true ) response = client.exec( "GET", "/helix/users?id=" + uid, headers: HTTP::Headers{ "Client-ID" => client_id } ) puts response.status_code json = JSON.parse( response.body ) name = json["data"][0]["login"].to_s.match(/[a-z0-9_]+/).not_nil![0] client.close return name end def twitch_v5_channel( client_id, uid ) client = HTTP::Client.new( "api.twitch.tv", port = 443, tls = true ) response = client.exec( "GET", "/kraken/channels?id=" + uid, headers: HTTP::Headers{ "Client-ID" => client_id, "Accept" => "application/vnd.twitchtv.v5+json" } ) puts response.status_code json = JSON.parse( response.body ) client.close ctime = json["channels"][0]["created_at"].to_s.match( /\d{4}-\d{2}-\d{2}/ ).not_nil![0] return ctime end def commanderroot_changelog( uid ) client = HTTP::Client.new( "twitch-tools.rootonline.de", port = 443, tls = true ) response = client.exec( "GET", "/username_changelogs_search.php?q=" + uid ) client.close puts response.status_code document = XML.parse_html( response.body ) rows = document.xpath_nodes( "/html/body/div/table/tbody/tr" ) text = Array(String).new rows.each do |row| text.push( row.first_element_child.not_nil!.next_element.not_nil!.inner_text.chomp(" ").match(/[0-9a-z_]+/).not_nil![0] + " " + row.first_element_child.not_nil!.next_element.not_nil!.next_element.not_nil!.next_element.not_nil!.inner_text.chomp(" ").match(/\d{4}-\d{2}-\d{2}/).not_nil![0] ) end text.reverse! return text end log = File.open(home + "irclogs/twitch/#" + channel + ".log".to_s) log.seek(log.size) watcher = Inotify.watch(home + "irclogs/twitch/#" + channel + ".log".to_s) do | event | if event.type.to_s == "MODIFY" log.read_string( log.size - log.pos ).each_line do | string | # FIXME: support old names? might get confusing with e.g. reverse5612 match = string.match(/^[0-9][0-9]:[0-9][0-9] <.([a-z0-9_]+)> !([a-z]+) ([a-zA-Z0-9_-]+)/) || next if match[2] == "name" begin puts match[3] arg = match[3] if arg =~ /^[0-9]+$/ user_id = arg name = twitch_uid_to_name( client_id, user_id ).to_s else name = arg user_id = twitch_name_to_uid( client_id, name ).to_s end # FIXME: more specific exception handling pp user_id pp name user_ctime = twitch_v5_channel( client_id, user_id ) history = commanderroot_changelog( user_id ) history.unshift( user_ctime ) history.unshift( user_id ) history.push( name ) puts history.join(" ") sock = Socket.unix sock.connect Socket::UNIXAddress.new( home + ".irssi/twitch-socket".to_s ) sock.puts( "#bungmonkey | " + history.join( " " ) ) sock.close rescue sock = Socket.unix sock.connect Socket::UNIXAddress.new( home + ".irssi/twitch-socket".to_s ) sock.puts( "#bungmonkey | An error occurred" ) sock.close end end if match[2] == "voice" chatuser = match[1] voice = match[3].downcase if voices.has_key?( voice ) csvoice = voices[voice] dir = home + ".cache/twitchtools/users/" + chatuser File.directory?( dir ) || Dir.mkdir( dir ) File.write( dir + "/voice", csvoice ) pp dir pp File.read( dir + "/voice" ) # TODO: make separate script to print streamelements URLs to client machine end end end end end sleep 300.seconds watcher.close log.close