diff --git a/images/is_this_a_pidgeon.png b/images/is_this_a_pidgeon.png new file mode 100644 index 0000000..34d221d Binary files /dev/null and b/images/is_this_a_pidgeon.png differ diff --git a/internet.lua b/internet.lua index c946b3b..c707c22 100644 --- a/internet.lua +++ b/internet.lua @@ -1,4 +1,5 @@ +local http = require 'socket.http' local https = require 'ssl.https' local md5 = require 'md5' local json = require 'json' @@ -44,6 +45,14 @@ local function safe_access (base, path) return base end +local function generic_request (...) + local output, code, headers, status = https.request(...) + if status == nil and code ~= 'connection refused' then + return output, code, headers, status + end + return http.request(...) +end + -------------------------------------------------------------------------------- -- Searching Clearbit for logoes -- Contains logoes @@ -255,7 +264,7 @@ end function internet.download_file (url, filename) -- retrieve the content of a URL local body, code = https.request(url) - if not body then error(code) end + if not body then error(('Https connection to "%s" failed, with error "%s"'):format(url, code)) end -- save the content to a file local f = assert(io.open(filename, 'wb')) -- open in "binary" mode @@ -271,6 +280,18 @@ function internet.download_video (url) return video_filename..'.mkv' end +function internet.download_headers (url) + assert(type(url) == 'string') + -- + local _, code, headers, status = generic_request { + url = url, + method = 'HEAD' + } + -- + return headers +end + + -------------------------------------------------------------------------------- return internet diff --git a/memes.lua b/memes.lua index 10e6d5c..240c7b2 100644 --- a/memes.lua +++ b/memes.lua @@ -75,11 +75,13 @@ local function flatten_onto(target_img, other_img, x0, y0) return end +local MAX_FONT_SIZE = 1000 + local function fit_font_to_line_height (font_name, height) assert(type(font_name) == 'string') assert(type(height) == 'number') -- - local size_min, size_max = 1, 50 + local size_min, size_max = 1, MAX_FONT_SIZE while true do local size_guess = math.floor((size_max + size_min)/2) assert(size_min <= size_guess and size_guess <= size_max) @@ -103,7 +105,7 @@ local function determine_required_font_size (font_name, text, width) assert(type(text) == 'string') assert(type(width) == 'number') -- - local size_min, size_max = 1, 50 + local size_min, size_max = 1, MAX_FONT_SIZE while true do local size_guess = math.floor((size_max + size_min)/2) assert(size_min <= size_guess and size_guess <= size_max) @@ -143,13 +145,18 @@ end local COLOR_WHITE = imlib.color.new(255, 255, 255) local COLOR_BLACK = imlib.color.new( 0, 0, 0) -local function draw_centered_lines (draw_onto, lines, x0, y0, width, font, font_color) + +local function draw_centered_lines (draw_onto, lines, x0, y0, width, font, font_colors) assert(type(lines) == 'table') local y = y0 for i, line in ipairs(lines) do local text_w, text_h = font:get_size(line) + local SHADOW_OFFSET = select(2, font:get_size(line)) / -20 local x = x0 + (width - text_w) / 2 - draw_onto:draw_text(font, line, x, y, font_color or COLOR_BLACK) + for i, color in ipairs(type(font_colors) == 'table' and font_colors or {font_colors}) do + local offset = (i-1) * SHADOW_OFFSET + draw_onto:draw_text(font, line, x + offset, y + offset, color) + end -- y = y + text_h end @@ -193,14 +200,14 @@ local function determine_font_and_lines_for_box (font_name, text, width, height) return actual_font, actual_lines end -local function draw_centered_text_in_box (font_name, draw_onto, text, x0, y0, width, height, bg_color, font_color) +local function draw_centered_text_in_box (font_name, draw_onto, text, x0, y0, width, height, bg_color, font_colors) assert(type(font_name) == 'string') local font, lines = determine_font_and_lines_for_box(font_name, text, width, height) -- local y = y0 + (height - #lines * select(2, font:get_size(text))) / 2 -- if bg_color then draw_onto:fill_rectangle(x0, y0, width, height, bg_color) end - draw_centered_lines(draw_onto, lines, x0, y, width, font, font_color) + draw_centered_lines(draw_onto, lines, x0, y, width, font, font_colors) end local function choose_random_font () @@ -223,7 +230,7 @@ local function paste_topic_onto_image (target, topic, x, y, w, h, bg_color, font -- Download and paste found image if topic.type == 'image' then local file_extension = topic.url:match '%.(%a+)$' - local url, filename = topic.url, CONFIG.IMGGEN_PATH_OUTPUT..'topic_'..topic.topic..'.'..file_extension + local url, filename = topic.url, os.tmpname() --CONFIG.IMGGEN_PATH_OUTPUT..'topic_'..topic.topic..'.'..file_extension assert(type(url) == 'string' and #url > 0) assert(type(filename) == 'string' and #filename > 0) internet.download_file(url, filename) @@ -350,7 +357,13 @@ local function generate_comparison_meme_generator (positions) -- Paste topic onto head for index, pos in ipairs(rand_positions) do - paste_topic_onto_image(base_img, topics[index], pos.x, pos.y, pos.w, pos.h, nil, font_name, pos.font_color) + local font_colors = {} + if pos.font_color == COLOR_WHITE then font_colors[1] = COLOR_BLACK + elseif pos.font_color == COLOR_BLACK then font_colors[1] = COLOR_WHITE + end + + table.insert(font_colors, pos.font_color) + paste_topic_onto_image(base_img, topics[index], pos.x, pos.y, pos.w, pos.h, nil, font_name, font_colors) end -- Droste @@ -394,6 +407,13 @@ local generate_into_the_trash = generate_comparison_meme_generator { { x = 377, xr = 20, y = 261, yr = 20, w = 400, h = 400, font_color = COLOR_BLACK }, } +local generate_is_this_a_pidgeon = generate_comparison_meme_generator { + base_img_path = './images/is_this_a_pidgeon.png', + + { x = 1100, xr = 20, y = 100, yr = 20, w = 450, h = 450, font_color = COLOR_WHITE }, + { x = 15, xr = 0, y = 1200, yr = 0, w = 1587 - 15, h = 1443-1200-15, font_color = COLOR_WHITE }, +} + local GENERATE_COMPARISON_MEME_OF_2 = { generate_distracted_boyfriend, generate_distracted_boyfriend_oldy_times, @@ -507,6 +527,13 @@ local curb = require 'curb_your_enthusiasm' -------------------------------------------------------------------------------- +local function is_image_link (str) + print(str) + if type(str) ~= 'string' then return false end + if not str:match '^%a+://.+$' then return false end + local headers = internet.download_headers(str) + return headers['content-type']:match '^image/%a+$' +end function memes.generate_for_message (user, message) @@ -520,6 +547,18 @@ function memes.generate_for_message (user, message) return 'https://www.youtube.com/watch?v=wl-LeTFM8zo', 'MACHINE' end + -- Is this a rich picture? + if is_image_link(message) then + local url = message + local img_link = generate_is_this_a_pidgeon { + { type = 'image', url = url }, + { type = 'text', text = 'Is this a rich picture?' } + } + return img_link, 'KYNG' + end + + + do -- Curb your enthusiasm local url = message:match '^[Cc]urb%s+[Yy]our%s+(.+)$' local url2, timestamp = message:match '^(..-)%s+at%s+(-?[%d.]+)$'