This repository has been archived on 2021-04-24. You can view files and clone it, but cannot push or open issues or pull requests.
Mikubot/plugins/isup.lua

225 lines
5.5 KiB
Lua

do
local function prot_url(url)
local url, h = string.gsub(url, "http://", "")
local url, hs = string.gsub(url, "https://", "")
local protocol = "http"
if hs == 1 then
protocol = "https"
end
return url, protocol
end
local function get_base_redis(id, option, extra)
local ex = ''
if option ~= nil then
ex = ex .. ':' .. option
if extra ~= nil then
ex = ex .. ':' .. extra
end
end
return 'isup:' .. id .. ex
end
local function print_cron(id)
local uhash = get_base_redis(id)
local subs = redis:smembers(uhash)
local text = id .. ' prüft folgende Webseiten:\n---------\n'
for k,v in pairs(subs) do
text = text .. k .. ") " .. v .. '\n'
end
return text
end
local function save_cron(id, url)
local url = string.lower(url)
local baseurl, protocol = prot_url(url)
local prothash = get_base_redis(baseurl, "protocol")
local checkhash = get_base_redis(baseurl, "check")
local uhash = get_base_redis(id)
if redis:sismember(uhash, baseurl) then
return url..' wird bereits geprüft.'
end
print('Saving...')
redis:set(prothash, protocol)
redis:sadd(checkhash, id)
redis:sadd(uhash, baseurl)
return url.." wird jetzt alle fünf Minuten geprüft!"
end
local function delete_cron(id, n)
n = tonumber(n)
local uhash = get_base_redis(id)
local subs = redis:smembers(uhash)
if n < 1 or n > #subs then
return "ID zu hoch!"
end
local sub = subs[n]
local lhash = get_base_redis(sub, "check")
redis:srem(uhash, sub)
redis:srem(lhash, id)
local left = redis:smembers(lhash)
if #left < 1 then -- no one subscribed, remove it
local prothash = get_base_redis(sub, "protocol")
local downhash = get_base_redis(sub, "down")
redis:del(prothash)
redis:del(downhash)
end
return sub.." wird nicht mehr geprüft."
end
local function is_up_socket(ip, port)
print('Connect to', ip, port)
local c = socket.try(socket.tcp())
c:settimeout(3)
local conn = c:connect(ip, port)
if not conn then
return false
else
c:close()
return true
end
end
local function is_up_http(url)
-- Parse URL from input, default to http
local parsed_url = URL.parse(url, { scheme = 'http', authority = '' })
-- Fix URLs without subdomain not parsed properly
if not parsed_url.host and parsed_url.path then
parsed_url.host = parsed_url.path
parsed_url.path = ""
end
-- Re-build URL
local url = URL.build(parsed_url)
local protocols = {
["https"] = https,
["http"] = http
}
local options = {
url = url,
redirect = false,
method = "GET"
}
local response = { protocols[parsed_url.scheme].request(options) }
local code = tonumber(response[2])
if code == nil or code >= 400 then
return false
end
return true
end
local function isup(url)
local pattern = '^(%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?):?(%d?%d?%d?%d?%d?)$'
local ip,port = string.match(url, pattern)
local result = nil
-- !isup 8.8.8.8:53
if ip then
port = port or '80'
result = is_up_socket(ip, port)
else
result = is_up_http(url)
end
return result
end
local function cron()
local keys = redis:keys(get_base_redis("*", "check"))
for k,v in pairs(keys) do
local base = string.match(v, "isup:(.+):check") -- Get the URL base
print('ISUP: '..base)
local prot = redis:get(get_base_redis(base, "protocol"))
local url = prot .. "://" .. base
local hash = 'isup:'..base..':down'
local isdown = redis:get(hash)
if not isup(url) then
if isdown ~= 'true' then
redis:set(hash, 'true')
local text = url..' ist DOWN! ❌'
for e, receiver in pairs(redis:smembers(v)) do
send_msg(receiver, text, ok_cb, false)
end
else
print(base..' ist immer noch down')
end
else
if isdown == 'true' then
redis:set(hash, 'false')
local text = url..' ist wieder UP! ✅'
for e, receiver in pairs(redis:smembers(v)) do
send_msg(receiver, text, ok_cb, false)
end
end
end
end
end
local function run(msg, matches)
local id = "user#id" .. msg.from.id
if is_chat_msg(msg) then
id = "chat#id" .. msg.to.id
end
if matches[1] == 'cron show' then
if not is_sudo(msg) then
return 'Du darfst diesen Befehl nicht benutzen!'
end
return print_cron(id)
elseif matches[1] == 'cron check' then
if not is_sudo(msg) then
return 'Du darfst diesen Befehl nicht benutzen!'
end
return cron()
elseif matches[1] == 'cron delete' then
if not is_sudo(msg) then
return 'Du darfst diesen Befehl nicht benutzen!'
end
return delete_cron(id, matches[2])
elseif matches[1] == 'cron' then
if not is_sudo(msg) then
return 'Du darfst diesen Befehl nicht benutzen!'
end
return save_cron(id, matches[2])
elseif isup(matches[1]) then
return matches[1]..' ist UP! ✅'
else
return matches[1]..' ist DOWN! ❌'
end
end
return {
description = "Checkt, ob eine Webseite up ist.",
usage = {
"#isup [Host]: Checkt, ob die Seite up ist",
"#isup cron [Host]: Checkt diese Seite alle 5 Minuten (nur Superuser)",
"#isup cron check: Prüfe alle Seiten jetzt",
"#isup cron show: Listet alle zu prüfenden Seiten auf",
"#isup cron delete [ID]: Checkt diese Seite nicht mehr"
},
patterns = {
"^#isup (cron check)$",
"^#isup (cron show)$",
"^#isup (cron delete) (%d+)$",
"^#isup (cron) (.*)$",
"^#isup (.*)$",
"^#ping (.*)$"
},
run = run,
cron = cron
}
end