diff --git a/images/banner_ifunny.png b/images/banner_ifunny.png new file mode 100644 index 0000000..d917a2b Binary files /dev/null and b/images/banner_ifunny.png differ diff --git a/internet.lua b/internet.lua index faf46a4..e2bf8e9 100644 --- a/internet.lua +++ b/internet.lua @@ -85,7 +85,7 @@ local function search_splashbase_for_stock_photoes (topic) return nil, 'Splashbase does not like æøå: '..tostring(topic) end - local search_url = string.format('http://www.splashbase.co/api/v1/images/search?query=%s', topic:gsub('%s', '%%20')) + local search_url = escape_url('http://www.splashbase.co/api/v1/images/search?query='..topic) local body, code, headers, status = https.request(search_url) if not body then error(code) end local data = json.decode(body) @@ -262,6 +262,37 @@ function internet.search_images (topics) return topic_to_image_url end +-------------------------------------------------------------------------------- +-- Find images on reddit + +function internet.find_reddit_memes (subreddit, filter) + + -- Error check + assert(type(subreddit) == 'string') + filter = filter or function() return true end + assert(type(filter) == 'function') + + -- + local search_url = escape_url('https://www.reddit.com/r/'..subreddit..'/new.json') + local body, code, headers, status = https.request(search_url) + if not body then error(code) end + + local data = json.decode(body) + print(require'pretty'(data)) + + local memes = {} + for _, meme_data in pairs(data.data.children) do + meme_data = meme_data.data + local success = filter(meme_data) + print(meme_data.title, meme_data.score, meme_data.created, success) + if success then + memes[#memes+1] = meme_data + end + end + + return memes +end + -------------------------------------------------------------------------------- -- Download file diff --git a/main.lua b/main.lua index fbfbdd5..1281e5c 100644 --- a/main.lua +++ b/main.lua @@ -23,6 +23,8 @@ if CONFIG.LUA_EXTRA_CPATH then package.cpath = package.cpath .. CONFIG.LUA_EXTR local FARVEL_INTERVAL = 120 local MEME_INTERVAL = 30 local MEME_CHANCE = 0.3 +local MEME_DELAY, MEME_CHECKING_INTERVAL = 4*60*60, 30*60 + -------------------------------------------------------------------------------- -- Make sure all required modules can be loaded @@ -351,38 +353,50 @@ local function init_memebot () shutdown_memebot() os.exit(128 + signum) end) - --- - local RELOADABLE_LIBS = { 'config', 'internet', 'memes', 'curb_your_enthusiasm' } - local ORIG_TABLES = {} - for _, module_name in ipairs(RELOADABLE_LIBS) do + --- + local RELOADABLE_LIBS = { 'config', 'internet', 'memes', 'curb_your_enthusiasm' } + local ORIG_TABLES = {} + for _, module_name in ipairs(RELOADABLE_LIBS) do ORIG_TABLES[module_name] = require(module_name) - end - -- + end + -- signal.signal(signal.SIGUSR1, function (signum) io.write ' !! Received SIGUSR1, will reload modules...\n' for _, module_name in ipairs(RELOADABLE_LIBS) do - io.write(' - '..module_name) + io.write(' - '..module_name) package.loaded[module_name] = nil local new_module = require(module_name) - if type(new_module) == 'table' then - local old_module = ORIG_TABLES[module_name] - for k, v in pairs(new_module) do - old_module[k] = v - end - else + if type(new_module) == 'table' then + local old_module = ORIG_TABLES[module_name] + for k, v in pairs(new_module) do + old_module[k] = v + end + else io.write(' SKIP: Got '..tostring(new_module)..' but expected table.') - end + end io.write '\n' end io.write ' Done\n' end) else - io.write ' !! Module "posix.signal" was missing, so CTRL+C will hard-crash.\n' + io.write ' !! Module "posix.signal" was missing; CTRL+C will hard-crash.\n' end + local NEXT_TIME_TO_CHECK_FOR_MEMES = 0 + -- Think loop while BOT_SHOULD_CONTINUE_RUNNING do + -- Bot thinking bot:think() + + -- Attempt to post memes + if NEXT_TIME_TO_CHECK_FOR_MEMES < os.time() then + NEXT_TIME_TO_CHECK_FOR_MEMES = os.time() + MEME_CHECKING_INTERVAL + local meme_msg = memes.generate_meme_report({'dankmark'}, { os.time() - MEME_DELAY - MEME_CHECKING_INTERVAL, os.time() - MEME_DELAY }) + if meme_msg then send_to_all(meme_msg) end + end + + -- Sleeping sleep(0.5) end end diff --git a/memes.lua b/memes.lua index 27b8467..4559270 100644 --- a/memes.lua +++ b/memes.lua @@ -317,11 +317,41 @@ local function add_compression_artifacts_to_image (image_filename, quality) return output_filename end +local function add_banner_to_image (image_filename, banner_filename, x_offset, background_color) + assert(type(image_filename) == 'string') + assert(type(banner_filename) == 'string') + assert(type(x_offset) == 'number') + -- + local image_img = assert(imlib.image.load(image_filename)) + local banner_img = assert(imlib.image.load(banner_filename)) + + local combi_img = imlib.image.new( image_img:get_width(), image_img:get_height() + banner_img:get_height() ) + local xpos = (0 <= x_offset) and x_offset or (combi_img:get_width() - banner_img:get_width() + x_offset) + + -- Draw + if background_color then + combi_img:draw_rectangle(0, 0, combi_img:get_width(), combi_img:get_height(), background_color) + end + flatten_onto(combi_img, image_img, 0, 0) + flatten_onto(combi_img, banner_img, xpos, image_img:get_height()) + + -- Save and free + image_img:free() + banner_img:free() + local output_filename = os.tmpname()..'.jpg' + combi_img:save(output_filename) + combi_img:free() + + return output_filename +end + local CHANCE_OF_MODIFIER = 0.3 local modifiers = { -- Compression artifacts function (image_filename) return add_compression_artifacts_to_image(image_filename, math.random(1, 20)) end, + -- iFunny banner + function (image_filename) return add_banner_to_image(image_filename, 'images/banner_ifunny.png', -7, imlib.color.new(27, 27, 27)) end, } -------------------------------------------------------------------------------- @@ -350,21 +380,22 @@ local DROSTE_EFFECT_TRIGGERS = { } local function download_and_standardize_image (image_url) - local file_extension = image_url:match '%.(%a+)$' - local url, filename = image_url, os.tmpname() - assert(type(url) == 'string' and #url > 0) - assert(type(filename) == 'string' and #filename > 0) - local success, errmsg = internet.download_file(url, filename) + local file_extension = image_url:match '%.(%a+)$' + local url, filename = image_url, os.tmpname() + assert(type(url) == 'string' and #url > 0) + assert(type(filename) == 'string' and #filename > 0) + local success, errmsg = internet.download_file(url, filename) - -- Convert svg to png - if success and url:match '%.svg$' then - local filename_2 = CONFIG.IMGGEN_PATH_OUTPUT..'topic_'..topic.topic..'.'..'png' - os.execute('convert -density "1200" -resize 400x400 "'..filename..'" "'..filename_2..'" &> /dev/null') - filename = filename_2 - end - -- + -- Convert svg to png + if success and url:match '%.svg$' then + local filename_2 = filename..'.svg' + os.execute('convert -density "1200" -resize 400x400 "'..filename..'" "'..filename_2..'" &> /dev/null') + filename = filename_2 + assert(check_file_exists(filename_2)) + end + -- - return success and filename, errmsg + return success and filename, errmsg end local function fill_in_topics_information (topics) @@ -448,7 +479,7 @@ local function generate_comparison_meme_generator (positions) local image_filename = save_img(base_img) -- Use modifiers - if math.random() < CHANCE_OF_MODIFIER then + while math.random() < CHANCE_OF_MODIFIER do image_filename = choose(modifiers)(image_filename) end @@ -729,6 +760,27 @@ function memes.generate_for_message (user, message) return img_link, 'COMPAR' end +-------------------------------------------------------------------------------- +-- Find memes from dankmark + +function memes.generate_meme_report (subreddits, time_interval) + assert(type(subreddits) == 'table' and #subreddits == 1) + assert(type(time_interval) == 'table' and #time_interval == 2) + + local current_check_time = os.time() + local new_memes = internet.find_reddit_memes(subreddits[1], function(t) return 35 <= t.score and time_interval[1] < t.created and t.created <= time_interval[2] end) + if #new_memes == 0 then return end + + -- Find best meme + local best_meme = new_memes[1] + for i = 2, #new_memes do + if best_meme.score < new_memes[i].score then best_meme = new_memes[i] end + end + + -- Return message to IRC + return string.format('Fugtig migmig fra %s: %s: %s', subreddits[1], best_meme.title, best_meme.url) +end + -------------------------------------------------------------------------------- return memes