From 6fffe876e84346a4f6f0ccc70bc6adce1ddb308e Mon Sep 17 00:00:00 2001 From: Jinks Date: Thu, 1 Feb 2018 15:44:30 +0100 Subject: [PATCH] lots of changes I never bothered to structure... --- .gitignore | 3 ++ log.lua | 90 ++++++++++++++++++++++++++++++++++++ luameat.lua | 10 ++-- misc.lua | 54 ++++++++++++++++++++-- plugin/twitch.lua | 112 ++++++++++++++++++++++++++++++++++++++++++++- plugin/utils.lua | 83 +++++++++++++++++++++++++++++++++ plugin/youtube.lua | 20 +++++--- 7 files changed, 356 insertions(+), 16 deletions(-) create mode 100644 log.lua diff --git a/.gitignore b/.gitignore index ee5ca03..6c19487 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ luac.out # Config file (contains private data) config.lua + +# Database +bot.db diff --git a/log.lua b/log.lua new file mode 100644 index 0000000..d7bc2d4 --- /dev/null +++ b/log.lua @@ -0,0 +1,90 @@ +-- +-- log.lua +-- +-- Copyright (c) 2016 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- + +local log = { _version = "0.1.0" } + +log.usecolor = true +log.outfile = nil +log.level = "trace" + + +local modes = { + { name = "trace", color = "\27[34m", }, + { name = "debug", color = "\27[36m", }, + { name = "info", color = "\27[32m", }, + { name = "warn", color = "\27[33m", }, + { name = "error", color = "\27[31m", }, + { name = "fatal", color = "\27[35m", }, +} + + +local levels = {} +for i, v in ipairs(modes) do + levels[v.name] = i +end + + +local round = function(x, increment) + increment = increment or 1 + x = x / increment + return (x > 0 and math.floor(x + .5) or math.ceil(x - .5)) * increment +end + + +local _tostring = tostring + +local tostring = function(...) + local t = {} + for i = 1, select('#', ...) do + local x = select(i, ...) + if type(x) == "number" then + x = round(x, .01) + end + t[#t + 1] = _tostring(x) + end + return table.concat(t, " ") +end + + +for i, x in ipairs(modes) do + local nameupper = x.name:upper() + log[x.name] = function(...) + + -- Return early if we're below the log level + if i < levels[log.level] then + return + end + + local msg = tostring(...) + local info = debug.getinfo(2, "Sl") + local lineinfo = info.short_src .. ":" .. info.currentline + + -- Output to console + print(string.format("%s[%-6s%s]%s %s: %s", + log.usecolor and x.color or "", + nameupper, + os.date("%H:%M:%S"), + log.usecolor and "\27[0m" or "", + lineinfo, + msg)) + + -- Output to log file + if log.outfile then + local fp = io.open(log.outfile, "a") + local str = string.format("[%-6s%s] %s: %s\n", + nameupper, os.date(), lineinfo, msg) + fp:write(str) + fp:close() + end + + end +end + + +return log diff --git a/luameat.lua b/luameat.lua index 35b84e5..5ac0837 100644 --- a/luameat.lua +++ b/luameat.lua @@ -16,13 +16,14 @@ irc.DEBUG = true irc.register_callback("connect", function() irc.send("CAP REQ :twitch.tv/membership") -- request twitch to send join/paty notices... + --irc.send("CAP REQ :twitch.tv/tags") -- request twitch to send userinfo... for i,v in ipairs(defaulChannels) do irc.join(v) end end) irc.register_callback("channel_msg", function(channel, from, message) - local is_cmd, cmd, arg = message:match("^(@)(%w+)%s*(.*)$") + local is_cmd, cmd, arg = message:match("^([@!])(%w+)%s*(.*)$") if is_cmd and plugin[cmd] then plugin[cmd](channel.name, from, arg) end @@ -65,6 +66,9 @@ end) irc.register_callback("nick_change", function(from, old_nick) end) --]] - -irc.connect{network = network, port = port, nick = nick, username = username, realname = realname, pass = password} +while true do + irc.connect{network = network, port = port, nick = nick, username = username, realname = realname, pass = password} + print("Disconnected...") + os.execute("sleep 10") +end diff --git a/misc.lua b/misc.lua index b3e92fc..9088264 100644 --- a/misc.lua +++ b/misc.lua @@ -13,12 +13,24 @@ function elapsed (datestring) local start = os.time({year = year, month = month, day = day, hour = hour, min = min, sec = sec, isdst = false }) local utcnow = os.time(os.date("!*t")) local diff = utcnow-start - local days = math.floor(diff/86400) - local hours = math.floor(diff/3600 - days*24) - local mins = math.floor(diff/60 - hours*60 - days*24) + local years = math.floor(diff / 31557600) + local remainder = diff % 31557600 + local months = math.floor(remainder / 2629800) + local remainder = diff % 2629800 + local days = math.floor(remainder / 86400) + local remainder = diff % 86400 + local hours = math.floor(remainder / 3600) + local remainder = diff % 3600 + local mins = math.floor(remainder / 60) local rval = "" + if years > 0 then + rval = rval..pluralize(years, "year").." " + end + if months > 0 then + rval = rval..pluralize(months, "month").." " + end if days > 0 then - rval = pluralize(days, "day").." " + rval = rval..pluralize(days, "day").." " end if hours > 0 then rval = rval..pluralize(hours,"hour").." and "..pluralize(mins,"minute") @@ -27,3 +39,37 @@ function elapsed (datestring) end return rval end + +function print_r ( t ) + local print_r_cache={} + local function sub_print_r(t,indent) + if (print_r_cache[tostring(t)]) then + print(indent.."*"..tostring(t)) + else + print_r_cache[tostring(t)]=true + if (type(t)=="table") then + for pos,val in pairs(t) do + if (type(val)=="table") then + print(indent.."["..pos.."] => "..tostring(t).." {") + sub_print_r(val,indent..string.rep(" ",string.len(pos)+8)) + print(indent..string.rep(" ",string.len(pos)+6).."}") + elseif (type(val)=="string") then + print(indent.."["..pos..'] => "'..val..'"') + else + print(indent.."["..pos.."] => "..tostring(val)) + end + end + else + print(indent..tostring(t)) + end + end + end + if (type(t)=="table") then + print(tostring(t).." {") + sub_print_r(t," ") + print("}") + else + sub_print_r(t," ") + end + print() +end diff --git a/plugin/twitch.lua b/plugin/twitch.lua index 1da6fb2..2d5c193 100644 --- a/plugin/twitch.lua +++ b/plugin/twitch.lua @@ -4,21 +4,76 @@ local json = require("json") local https = require("ssl.https") local ltn12 = require("ltn12") local msc = require("misc") +--local curl = require("cURL") -local function fetch_data (endpoint) +local function fetch_data(endpoint) local response = {} + hdrs = { Accept = "application/vnd.twitchtv.v3+json", ["Client-ID"] = cid } local r,c,h = https.request{url = "https://api.twitch.tv/kraken/"..endpoint, - headers = { accept = "application/vnd.twitchtv.v3+json"}, + headers = hdrs, sink = ltn12.sink.table(response)} return json.decode(table.concat(response)) end +--[[ +local function fetch_data_curl (url) + t = {} + curl.easy() + :setopt_url("https://api.twitch.tv/kraken/"..url) + :setopt_httpheader{ + "Accept: application/vnd.twitchtv.v3+json", + "Client-ID:".. cid + } + :setopt_writefunction(function(buf) + table.insert(t,buf) + return #buf + end) + :perform() + return json.decode(table.concat(t)) +end +]] + +local COLOR = true + +local ON = true +local outfile = io.output() + +local function _message(msg_type, msg, color) + if ON then + local endcolor = "" + if COLOR and outfile == io.stdout then + color = color or "\027[1;30m" + endcolor = "\027[0m" + else + color = "" + endcolor = "" + end + outfile:write(color .. msg_type .. ": " .. msg .. endcolor .. "\n") + end +end +-- }}} +function red(msg) + _message("ERR", msg, "\027[0;31m") +end + +function yellow(msg) + _message("WARN", msg, "\027[0;33m") +end + +local function match_any( str, pattern_list ) + for _, pattern in ipairs( pattern_list ) do + local w = string.match( str, pattern ) + if w then return w end + end +end + plugin.uptime = function (target, from, arg) local channel = string.sub(target, 2) if arg and arg ~= "" then channel = arg end local j = fetch_data("streams/"..channel) + --print_r(j) if j.stream then if j.stream ~= json.decode("null") then irc.say(target, j.stream.channel.display_name.." is streaming ["..j.stream.game.."] for "..elapsed(j.stream.created_at)..".") @@ -29,3 +84,56 @@ plugin.uptime = function (target, from, arg) irc.say(target, "Stream "..channel.." not found.") end end + +plugin.followage = function (target, from, arg) + local channel = string.sub(target, 2) + if arg and arg ~= "" then + user = arg + else + user = from + end + local j = fetch_data("users/"..user.."/follows/channels/"..channel) + --print_r(j) + if j.channel and j.created_at then + if j.created_at ~= json.decode("null") then + irc.say(target, user.." is following "..j.channel.display_name.." for "..elapsed(j.created_at)..".") + end + elseif j.message then + irc.say(target, "Error: " .. j.message) + else + irc.say(target, "Error: Could not find any data.") + end + +end + +plugin.dilfa = function (target, from, arg) + irc.say(target, "!img https://i.imgur.com/2rUOXMT.png") +end + +plugin.owl = function (target, from, arg) + irc.say(target, "!img https://i.imgur.com/C5Uz6Pv.gif") +end + +plugin.bus = function (target, from, arg) + irc.say(target, "!img https://memeguy.com/photos/images/short-bus-243553.jpg") +end + +--[[ +callback.fospam = function (target, from, message) + local patterns = { + ".*son%s.*%svillain.*", + ".*son%s.*%sbadguy.*", + ".*son%s.*%sbad%sguy.*", + "have.*to.*bomb%s.*boston.*", + "have.*to.*nuke%s.*boston.*", + "have.*to.*bomb%s.*commonwealth.*", + "have.*to.*nuke%s.*commonwealth.*", + } + + local spam = match_any(message:lower(), patterns) + if spam then + irc.say(target, ".ban "..from) + yellow("Banned "..from.." for spoliers ["..spam.."]!") + end +end +]] diff --git a/plugin/utils.lua b/plugin/utils.lua index 2dabbcf..49ba500 100644 --- a/plugin/utils.lua +++ b/plugin/utils.lua @@ -1,7 +1,90 @@ -- Small utilty commands that return static text and don't fit anywhere else. +booms = 0 +last_boom = os.time() +last_unboom = os.time() -- Bot's code repository plugin.code = function (target, from, arg) irc.say(target, "My source code can be found at https://github.com/jinks/LuaMeat") end plugin.source = plugin.code + +plugin.ping = function (target, from, arg) + irc.say(target, "PONG") +end + +plugin.say = function(target, from, arg) + if from == "jinks___" then + local sp = arg:find("%s") or 1 + local ch = arg:sub(1,sp-1) + for channel in irc.channels() do + if (channel.name == ch) then + print(arg) + target = channel + arg = arg:sub(sp+1) + print(arg) + break + end + end + irc.say(target, arg) + end +end + +plugin.join = function (target, from, arg) + if (from == "jinks___") then + irc.join(arg) + end +end + +plugin.part = function (target, from, arg) + if (from == "jinks___") then + if arg:len() > 0 then + irc.part(arg) + else + irc.part(target) + end + end +end + +plugin.hail = function (target, from, arg) + irc.say(target, "HAIL HYDRATION! And our lord and savior Crop Rotation. But really: http://bit.ly/1ipyhGd") +end + +plugin.score = function (target, from, arg) + irc.say(target, "BOOM counter is " .. booms) +end + +plugin.unboom = function (target, from, arg) + now = os.time() + if now-last_unboom > 20 then + last_unboom = now + booms = booms - 1 + irc.say(target, "BOOM counter is now " .. booms) + end +end + +plugin.boom = function (target, from, arg) + now = os.time() + if now-last_boom > 20 then + last_boom = now + booms = booms + 1 + irc.say(target, "BOOM counter is now " .. booms) + end +end + +plugin.resetboom = function (target, from, arg) + if (from == "jinks___" or from == "4kbshort") then + booms = 0 + irc.say(target, "BOOM counter reset.") + end +end + +plugin.setboom = function (target, from, arg) + if (from == "jinks___" or from == "4kbshort") then + num = tonumber(arg) + if num ~= nil then + booms = num + end + irc.say(target, "BOOM counter is " .. booms) + end +end diff --git a/plugin/youtube.lua b/plugin/youtube.lua index 03ea28a..23c45aa 100644 --- a/plugin/youtube.lua +++ b/plugin/youtube.lua @@ -6,17 +6,23 @@ local function fetch_title (videoid) --local response = {} local r,c,h = https.request("https://www.googleapis.com/youtube/v3/videos?id="..videoid.."&key="..yt_api_key.."&part=snippet&fields=items(snippet(title))") local j = json.decode(r) - if j and next(j.items) then + if j and j.items and next(j.items) then return j.items[1].snippet.title end end callback.youtube = function (target, from, message) - local ytid = message:match(".*https?://w?w?w?%.?youtube.com/watch%?v=(%g*)%s*.*") - if ytid then - local t = fetch_title(ytid) - if t then - irc.say(target, "Youtube video title: "..t) - end + local ytid = message:match(".*https?://w?w?w?%.?youtube.com/watch%?v=(%g*)(#?.*)%s*.*") + local ybid = message:match(".*https?://w?w?w?%.?youtu.be/(%g*)%s*.*") + if ybid then + ytid = ybid + end + if not ytid then return end + if ytid:find("#") then + ytid = ytid:match("(.*)#") + end + local t = fetch_title(ytid) + if t then + irc.say(target, "Youtube video title: "..t) end end