summaryrefslogtreecommitdiff
path: root/crystal/name-command.cr
blob: 26b423ce877b9c59c42c91515a205d99346d03ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
require "http/client"
require "json"
require "pretty_print"
require "xml"
require "inotify"
require "time"
require "twitcr"

settings = Hash(String, String).new

settings["home"]         = Path.home.to_s
["access_token", "channel", "channel_id", "client_id", "client_id_twitch"].each do |key|
  begin
    settings[key] = File.read( settings["home"] + "/.config/twitch/" + key ).chomp
  rescue IO::Error
    STDERR.puts "Warning: Missing " + settings["home"] + "/.config/twitch/" + key
  end
end

client = Twitcr::Client.new( settings )

def ircmsg( home : String, channel : String, msg : String)
  if msg !~ /(\r|\n)/
    sock = Socket.unix
#    sock.connect Socket::UNIXAddress.new( home + "/.irssi/twitch-socket".to_s, type: Socket::Type::DGRAM )
    sock.connect Socket::UNIXAddress.new( home + "/.irssi/twitch-socket".to_s )
    sock.puts( "#" + channel + " | " + msg )
    sock.close
  end
end

voices = Hash(String, String).new
File.each_line( settings["home"] + "/voicelist" ) do |line|
  voices[ line.downcase ] = line
end

#FIXME: cache twitch results

def urbandef( term : String )
  #http://api.urbandictionary.com/v0/define?term=waifu
  client = HTTP::Client.new( "api.urbandictionary.com" )
  response = client.exec( "GET", "/v0/define?term=" + term )
  puts response.status_code
  json = JSON.parse( response.body )
  return json["list"][0]["definition"].to_s.gsub( /[\[\]]/, "" ).gsub( /\n/, "" )
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

logwatcher = logwatch( settings, client, voices, settings["home"] + "/irclogs/twitch/#" + settings["channel"] + "/" + Time.local.to_s("%Y-%m-%d") + ".log".to_s )

dirwatcher = Inotify.watch( settings["home"] + "/irclogs/twitch/#" + settings["channel"] + "/" ) do | event |
  if event.type.to_s == "CREATE" && event.name =~ /\.log$/
    # FIXME: logwatcher is wrong scope, probably should move the function boundary further into it so we still hold the watcher handle
    logwatcher.close
    puts [ event.type, event.path, event.name ].join(" ")
    logwatcher = logwatch( settings, client, voices, event.path.not_nil! + event.name.not_nil! )
  end
end

def logwatch( settings, client, voices, logfile )
  log = File.open( logfile )
  log.seek(log.size)
  logwatcher = Inotify.watch( logfile ) 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
        next unless match = string.match(/^[0-9][0-9]:[0-9][0-9] <.([a-z0-9_]+)> !([A-Za-z]+) (([a-zA-Z0-9' _\:,&.-]|!)+)/) || string.match(/^[0-9][0-9]:[0-9][0-9] <.([a-z0-9_]+)> !([A-Za-z]+)/)
        if match[1] == settings["channel"]
#          if match[2].downcase == "status"
#            begin
#              if match[3]?
#                json = JSON.parse( client.put_channel!( settings["channel_id"].to_u64, status: match[3] ) )
#                ircmsg( settings["home"], settings["channel"], "Status is now \"#{ json["status"] }\"")
#              else
#                json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) )
#                ircmsg( settings["home"], settings["channel"], "Status is currently \"#{ json["status"] }\"")
#              end
#            rescue ex
#              ircmsg( settings["home"], settings["channel"], "An error occurred! " + ex.message.to_s )
#            end
#          end
#          if match[2].downcase == "game"
#            begin
#              if match[3]?
#              json = JSON.parse( client.put_channel!( settings["channel_id"].to_u64, game: match[3] ) )
#              ircmsg( settings["home"], settings["channel"], "Game is now \"#{ json["game"] }\"")
#              else
#              json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) )
#              ircmsg( settings["home"], settings["channel"], "Game is currently \"#{ json["game"] }\"")
#              end
#            rescue ex
#              ircmsg( settings["home"], settings["channel"], "An error occurred! " + ex.message.to_s )
#            end
#          end
        end
        if match[2].downcase == "name"
          begin
            if match[3]? == nil
              puts match[1]
              arg = match[1]
            elsif match[3]? =~ /^([a-zA-Z0-9_]+)$/
              puts match[3]
              arg = match[3]
            else
              ircmsg( settings["home"], settings["channel"], "Argument must be a valid Twitch username or user id." )
              next
            end
            if arg =~ /^[0-9]+$/
              user_id = arg.to_u64
              name = client.user( user_id ).login
            else
              name = arg
              user_id = client.user( name ).id
            end
            # FIXME: more specific exception handling

            pp user_id
            pp name

            user_ctime = JSON.parse( client.get_channel( user_id ) )["created_at"].to_s.match( /\d{4}-\d{2}-\d{2}/ ).not_nil![0]

            history = commanderroot_changelog( user_id.to_s )

            history.unshift( user_ctime )
            history.unshift( user_id.to_s )
            history.push( name )

            puts history.join(" ")

            ircmsg( settings["home"], settings["channel"], history.join( " " ) )
          rescue ex
            ircmsg( settings["home"], settings["channel"], "An error occurred! " + ex.message.to_s )
          end
        end
        if match[2].downcase == "urban"
          begin
            if match[3]?
              arg = match[3]
              if arg =~ /^[a-zA-Z0-9 -]+$/
                definition = urbandef( arg )
                ircmsg( settings["home"], settings["channel"], definition )
              else
                ircmsg( settings["home"], settings["channel"], "Urban Dictionary search term should consist of letters, numbers, spaces, and/or hyphens." )
              end
            else
              ircmsg( settings["home"], settings["channel"], "Requires an Urban Dictionary search term" )
            end
          rescue ex
            ircmsg( settings["home"], settings["channel"], "An error occurred! " + ex.message.to_s )
          end
        end
      end
    end
  end
  return logwatcher
end
loop do
  sleep 300
end

#watcher.close
#log.close