2015-12-05 16:03:43 +01:00
-- You need a Google API key and a Google Custom Search Engine set up to use this, in config.google_api_key and config.google_cse_key, respectively.
2016-04-12 05:55:46 +02:00
-- You must also sign up for the CSE in the Google Developer Console, and enable image results.
2015-12-05 16:03:43 +01:00
2016-04-11 06:04:47 +02:00
local gImages = { }
local HTTPS = require ( ' ssl.https ' )
2016-07-07 00:31:19 +02:00
HTTPS.timeout = 10
2016-04-11 06:04:47 +02:00
local URL = require ( ' socket.url ' )
2016-04-15 21:07:23 +02:00
local JSON = require ( ' dkjson ' )
2016-07-05 15:25:08 +02:00
local redis = ( loadfile " ./otouto/redis.lua " ) ( )
2016-06-07 06:31:34 +02:00
local utilities = require ( ' otouto.utilities ' )
2016-06-11 14:46:41 +02:00
local bindings = require ( ' otouto.bindings ' )
2016-04-11 06:04:47 +02:00
2016-05-27 02:26:30 +02:00
function gImages : init ( config )
2016-06-11 14:46:41 +02:00
if not cred_data.google_apikey then
print ( ' Missing config value: google_apikey. ' )
2016-04-11 06:04:47 +02:00
print ( ' gImages.lua will not be enabled. ' )
return
2016-06-11 14:46:41 +02:00
elseif not cred_data.google_cse_id then
print ( ' Missing config value: google_cse_id. ' )
2016-04-11 06:04:47 +02:00
print ( ' gImages.lua will not be enabled. ' )
return
end
2016-06-19 20:52:59 +02:00
gImages.triggers = utilities.triggers ( self.info . username , config.cmd_pat ) : t ( ' img ' , true ) : t ( ' i ' , true ) . table
2016-06-12 22:16:43 +02:00
gImages.doc = [ [ *
] ] .. config.cmd_pat .. [ [ img * _ < Suchbegriff > _
2016-06-11 14:46:41 +02:00
Sucht Bild mit Google und versendet es ( SafeSearch aktiv )
2016-06-12 22:16:43 +02:00
Alias : * ] ] .. config.cmd_pat .. [[i*]]
2015-12-05 16:03:43 +01:00
end
2016-06-11 14:46:41 +02:00
gImages.command = ' img <Suchbegriff> '
2015-07-03 00:15:52 +02:00
2016-07-05 16:13:57 +02:00
-- Yes, the callback is copied from below, but I can't think of another method :\
2016-07-02 14:58:04 +02:00
function gImages : callback ( callback , msg , self , config , input )
2016-07-04 01:29:51 +02:00
if not msg then return end
utilities.answer_callback_query ( self , callback , ' Suche nochmal nach " ' .. URL.unescape ( input ) .. ' " ' )
2016-07-02 12:35:14 +02:00
utilities.send_typing ( self , msg.chat . id , ' upload_photo ' )
2016-07-05 16:13:57 +02:00
local hash = ' telegram:cache:gImages '
local results = redis : smembers ( hash .. ' : ' .. string.lower ( URL.unescape ( input ) ) )
if not results [ 1 ] then
print ( ' doing web request ' )
results = gImages : get_image ( input )
if results == 403 then
utilities.send_reply ( self , msg , config.errors . quotaexceeded , true )
return
elseif not results then
utilities.send_reply ( self , msg , config.errors . results , true )
return
end
gImages : cache_result ( results , input )
2016-07-02 22:11:37 +02:00
end
2016-07-04 01:29:51 +02:00
2016-07-05 16:13:57 +02:00
-- Random image from table
local i = math.random ( # results )
-- Thanks to Amedeo for this!
local failed = true
local nofTries = 0
while failed and nofTries < # results do
if results [ i ] . image then
img_url = results [ i ] . link
mimetype = results [ i ] . mime
context = results [ i ] . image.contextLink
else -- from cache
img_url = results [ i ]
mimetype = redis : hget ( hash .. ' : ' .. img_url , ' mime ' )
context = redis : hget ( hash .. ' : ' .. img_url , ' contextLink ' )
end
-- It's important to save the image with the right ending!
if mimetype == ' image/gif ' then
file = download_to_file ( img_url , ' img.gif ' )
elseif mimetype == ' image/png ' then
file = download_to_file ( img_url , ' img.png ' )
elseif mimetype == ' image/jpeg ' then
file = download_to_file ( img_url , ' img.jpg ' )
else
file = nil
end
if not file then
nofTries = nofTries + 1
i = i + 1
if i > # results then
i = 1
end
else
failed = false
end
end
if failed then
utilities.send_reply ( self , msg , ' Fehler beim Herunterladen eines Bildes. ' , true , ' {"inline_keyboard":[[{"text":"Nochmal versuchen","callback_data":"gImages: ' .. input .. ' "}]]} ' )
return
end
2016-07-02 12:35:14 +02:00
if mimetype == ' image/gif ' then
2016-07-07 23:23:24 +02:00
result = utilities.send_document ( self , msg.chat . id , file , nil , msg.message_id , ' {"inline_keyboard":[[{"text":"Seite aufrufen","url":" ' .. context .. ' "},{"text":"Bild aufrufen","url":" ' .. img_url .. ' "},{"text":"Nochmal suchen","callback_data":"gImages: ' .. input .. ' "}]]} ' )
2016-07-05 16:13:57 +02:00
else
2016-07-04 01:29:51 +02:00
result = utilities.send_photo ( self , msg.chat . id , file , nil , msg.message_id , ' {"inline_keyboard":[[{"text":"Seite aufrufen","url":" ' .. context .. ' "},{"text":"Bild aufrufen","url":" ' .. img_url .. ' "},{"text":"Nochmal suchen","callback_data":"gImages: ' .. input .. ' "}]]} ' )
2016-07-02 12:35:14 +02:00
end
2016-07-04 01:29:51 +02:00
2016-07-02 12:35:14 +02:00
if not result then
2016-07-02 14:58:04 +02:00
utilities.send_reply ( self , msg , config.errors . connection , true , ' {"inline_keyboard":[[{"text":"Nochmal versuchen","callback_data":"gImages: ' .. input .. ' "}]]} ' )
2016-06-11 14:46:41 +02:00
return
end
2016-07-02 12:35:14 +02:00
end
2016-06-11 14:46:41 +02:00
2016-07-02 12:35:14 +02:00
function gImages : get_image ( input )
2016-07-05 20:32:35 +02:00
local apikey = cred_data.google_apikey -- 100 requests is RIDICULOUS, Google!
local cseid = cred_data.google_cse_id
2016-06-11 14:46:41 +02:00
local BASE_URL = ' https://www.googleapis.com/customsearch/v1 '
2016-07-05 15:25:08 +02:00
local url = BASE_URL .. ' /?searchType=image&alt=json&num=10&key= ' .. apikey .. ' &cx= ' .. cseid .. ' &safe=high ' .. ' &q= ' .. input .. ' &fields=items(link,mime,image(contextLink)) '
2016-06-11 14:46:41 +02:00
local jstr , res = HTTPS.request ( url )
2016-07-05 15:25:08 +02:00
local jdat = JSON.decode ( jstr ) . items
if not jdat then
return ' NORESULTS '
end
2016-07-02 22:11:37 +02:00
if jdat.error then
if jdat.error . code == 403 then
return 403
else
return false
end
2016-06-21 23:06:35 +02:00
end
2016-07-05 16:13:57 +02:00
return jdat
2016-07-05 15:25:08 +02:00
end
2016-06-11 14:46:41 +02:00
2016-07-05 15:25:08 +02:00
function gImages : cache_result ( results , text )
local cache = { }
for v in pairs ( results ) do
table.insert ( cache , results [ v ] . link )
end
for n , link in pairs ( cache ) do
redis : hset ( ' telegram:cache:gImages: ' .. link , ' mime ' , results [ n ] . mime )
redis : hset ( ' telegram:cache:gImages: ' .. link , ' contextLink ' , results [ n ] . image.contextLink )
redis : expire ( ' telegram:cache:gImages: ' .. link , 1209600 )
end
cache_data ( ' gImages ' , string.lower ( text ) , cache , 1209600 , ' set ' )
2016-07-02 12:35:14 +02:00
end
function gImages : action ( msg , config , matches )
local input = utilities.input ( msg.text )
if not input then
if msg.reply_to_message and msg.reply_to_message . text then
input = msg.reply_to_message . text
else
utilities.send_message ( self , msg.chat . id , gImages.doc , true , msg.message_id , true )
return
end
end
print ( ' Checking if search contains blacklisted word: ' .. input )
if is_blacklisted ( input ) then
utilities.send_reply ( self , msg , ' Vergiss es! ._. ' )
return
end
utilities.send_typing ( self , msg.chat . id , ' upload_photo ' )
2016-07-05 16:13:57 +02:00
local hash = ' telegram:cache:gImages '
local results = redis : smembers ( hash .. ' : ' .. string.lower ( input ) )
if not results [ 1 ] then
print ( ' doing web request ' )
results = gImages : get_image ( URL.escape ( input ) )
if results == 403 then
utilities.send_reply ( self , msg , config.errors . quotaexceeded , true )
return
2016-07-05 20:32:35 +02:00
elseif not results or results == ' NORESULTS ' then
2016-07-05 16:13:57 +02:00
utilities.send_reply ( self , msg , config.errors . results , true )
return
end
gImages : cache_result ( results , input )
end
-- Random image from table
local i = math.random ( # results )
-- Thanks to Amedeo for this!
local failed = true
local nofTries = 0
while failed and nofTries < # results do
if results [ i ] . image then
img_url = results [ i ] . link
mimetype = results [ i ] . mime
context = results [ i ] . image.contextLink
else -- from cache
img_url = results [ i ]
mimetype = redis : hget ( hash .. ' : ' .. img_url , ' mime ' )
context = redis : hget ( hash .. ' : ' .. img_url , ' contextLink ' )
end
-- It's important to save the image with the right ending!
if mimetype == ' image/gif ' then
file = download_to_file ( img_url , ' img.gif ' )
elseif mimetype == ' image/png ' then
file = download_to_file ( img_url , ' img.png ' )
elseif mimetype == ' image/jpeg ' then
file = download_to_file ( img_url , ' img.jpg ' )
else
file = nil
end
if not file then
nofTries = nofTries + 1
i = i + 1
if i > # results then
i = 1
end
else
failed = false
end
end
if failed then
utilities.send_reply ( self , msg , ' Fehler beim Herunterladen eines Bildes. ' , true , ' {"inline_keyboard":[[{"text":"Nochmal versuchen","callback_data":"gImages: ' .. URL.escape ( input ) .. ' "}]]} ' )
2016-07-02 22:11:37 +02:00
return
end
2016-07-02 12:35:14 +02:00
if mimetype == ' image/gif ' then
2016-07-07 23:23:24 +02:00
result = utilities.send_document ( self , msg.chat . id , file , nil , msg.message_id , ' {"inline_keyboard":[[{"text":"Seite aufrufen","url":" ' .. context .. ' "},{"text":"Bild aufrufen","url":" ' .. img_url .. ' "},{"text":"Nochmal suchen","callback_data":"gImages: ' .. URL.escape ( input ) .. ' "}]]} ' )
2016-07-05 16:13:57 +02:00
else
2016-07-04 01:29:51 +02:00
result = utilities.send_photo ( self , msg.chat . id , file , nil , msg.message_id , ' {"inline_keyboard":[[{"text":"Seite aufrufen","url":" ' .. context .. ' "},{"text":"Bild aufrufen","url":" ' .. img_url .. ' "},{"text":"Nochmal suchen","callback_data":"gImages: ' .. URL.escape ( input ) .. ' "}]]} ' )
2016-06-21 23:06:35 +02:00
end
if not result then
2016-07-02 14:58:04 +02:00
utilities.send_reply ( self , msg , config.errors . connection , true , ' {"inline_keyboard":[[{"text":"Nochmal versuchen","callback_data":"gImages: ' .. URL.escape ( input ) .. ' "}]]} ' )
2016-06-18 17:22:30 +02:00
return
2016-06-15 20:10:30 +02:00
end
2015-07-03 00:15:52 +02:00
end
2016-07-02 14:58:04 +02:00
return gImages