Skip to content

Instantly share code, notes, and snippets.

@andsve
Created December 20, 2010 01:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andsve/747918 to your computer and use it in GitHub Desktop.
Save andsve/747918 to your computer and use it in GitHub Desktop.
module("modules/imgcache2/imgcache2")
function parse_message(bot, msg)
local i,j,chan,s = string.find(msg, ":.-!.- PRIVMSG (.-) :(.+)")
if not (i == nil) then
function db_connect()
local luasql = require("luasql.sqlite3")
local env = luasql.sqlite3()
local conn = env:connect("imgcache2.sqlite")
-- create table if needed
assert(conn:execute([[CREATE TABLE IF NOT EXISTS cachedimages (
orgurl VARCHAR(256) PRIMARY KEY,
cachedfile VARCHAR(256)
)
]]))
return env, conn
end
function db_close(env, conn)
conn:close()
env:close()
end
function get_image(url, block_hosts)
local socket = require("socket")
-- get host and path
local socketurl = require("socket.url")
local parsedurl = socketurl.parse(url)
local host = parsedurl.host
local path = parsedurl.path
-- check if host is blocked
for k,v in pairs(block_hosts) do
local i,j,t = string.find(host, v)
if (i) then
return nil
end
end
-- connect somewhere
local c = socket.try(socket.connect(host, 80))
c:settimeout(10)
local try = socket.newtry(function() print("connection failed"); c:close() end)
try(c:send("GET " .. tostring(path) .. " HTTP/1.1\r\nHost: " .. tostring(host) .. "\r\nReferer: " .. tostring(url) .. "\r\n\r\n"))
local content = ""
local answer = ""
local get_mode = "*l"
local recv_type = "header"
local content_length = nil
local content_type = "png"
repeat
answer = try(c:receive(get_mode))
if (not answer) then
break
end
--print(recv_type .. ": " .. tostring(answer))
-- recieving content
if (recv_type == "content") then
content = answer
if (get_mode ~= "*l") then
break
end
else
-- recieving header
-- Redirected?
local i,j,l = string.find(answer, "Location: (.*)")
if (i) then
--print("Redirected to: " .. tostring(l))
content = get_image(l, block_hosts)
break
end
-- Is this an image?
local i,j,t = string.find(answer, "Content%-Type: (.*)")
if (i) then
local i,j,t = string.find(t, "image/(.*)")
if (not i) then
print("Not an image!")
return nil
else
print("Image type: " .. tostring(t))
if (t == "jpeg") then
content_type = "jpg"
else
content_type = t
end
end
end
end
-- see if the header has ended
if (answer == "") then
if (content_length) then
get_mode = content_length
end
recv_type = "content"
end
-- find content length
local i,j,l = string.find(answer, "Content%-Length: (.*)")
if (i) then
content_length = tonumber(l)
if (content_length) <= 0 then
print("get_content Error: Invalid content length.")
return nil
end
end
until (not answer)
c:close()
return content, content_type
end
-- settings aoeu
local output_dir = "/home/sweetfish/www.md5/cache"
local output_url = "http://cache.md5.se/"
local block_hosts = {"md5%.se"}
-- see if we have a url in this message
local i,j,url = string.find(s, "([%S]+://[%S]+)")
if not (i == nil) then
-- see if this is an image
-- connect db
local env, conn = db_connect()
-- see if url allready has been cached
local cursor = assert(conn:execute("SELECT * FROM cachedimages WHERE orgurl = '" .. tostring(url) .. "'"))
row = {}
if not cursor:fetch(row) then
-- a 'new' url, check if image / get content
local content, content_type = get_image(url, block_hosts)
if (content) then
-- image found, save to disk
local new_filename = tostring(os.time()) .. "-" .. tostring(math.random(1000,9999)) .. "." .. tostring(content_type)
local tmpfile = io.open(tostring(output_dir) .. "/" .. tostring(new_filename), "w+")
tmpfile:write(content)
tmpfile:close()
-- and store in database
assert(conn:execute("INSERT INTO cachedimages VALUES('" .. url .. "', '" .. tostring(new_filename) .. "')"))
end
end
cursor:close()
-- close db
db_close(env, conn)
end
-- see if last message was a title-trigger
local i,j,sender,chan,url = string.find(msg, ":(.-)!.- PRIVMSG (.-) :" .. tostring(bot.config.triggerprefix) .. "cache (.+)")
if not (i == nil) then
if not (string.sub(chan, 1, 1) == "#") then
chan = sender
end
-- connect db
local env, conn = db_connect()
-- get cache filename
local cursor = assert(conn:execute("SELECT * FROM cachedimages WHERE orgurl = '" .. tostring(url) .. "'"))
row = {}
if cursor:fetch(row) then
--print("cache: " .. tostring(row[2]))
bot:say(chan, output_url .. tostring(row[2]))
else
bot:say(chan, "No cache for that url.")
end
cursor:close()
-- close db
db_close(env, conn)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment