SpiceBot-migrated/sopel_modules/SpiceBot/Gif.py
2019-06-17 11:40:44 -04:00

232 lines
9.0 KiB
Python

# coding=utf8
from __future__ import unicode_literals, absolute_import, division, print_function
"""How to handle gifs"""
from sopel.config.types import StaticSection, ValidatedAttribute, ListAttribute
import sopel_modules
from .Config import config as botconfig
from .Tools import read_directory_json_to_dict
from .Commands import commands as botcommands
import spicemanip
import os
from fake_useragent import UserAgent
import urllib
import random
import requests
import json
class SpiceBot_Gif_MainSection(StaticSection):
extra = ListAttribute('extra')
nsfw = ValidatedAttribute('nsfw', default=False)
class GifAPISection(StaticSection):
apikey = ValidatedAttribute('apikey', default=None)
class BotGif():
def __init__(self):
self.setup_gif()
self.badlinks = []
self.header = {'User-Agent': str(UserAgent().chrome)}
self.valid_api = {}
dir_to_scan = []
for plugin_dir in set(sopel_modules.__path__):
configsdir = os.path.join(plugin_dir, "SpiceBot_Configs")
gifcfgdir = os.path.join(configsdir, "gifapi")
dir_to_scan.append(gifcfgdir)
if len(botconfig.SopelGifSearch.extra):
for extragifcfgdir in botconfig.SopelGifSearch.extra:
dir_to_scan.append(extragifcfgdir)
valid_gif_api_dict = read_directory_json_to_dict(dir_to_scan, "Gif API", "SpiceBot_Gif")
for gif_api in list(valid_gif_api_dict.keys()):
botconfig.define_section(gif_api, GifAPISection, validate=False)
self.valid_api[gif_api] = valid_gif_api_dict[gif_api]
self.valid_api[gif_api]["apikey"] = None
self.valid_api[gif_api]["cache"] = dict()
apikey = eval("botconfig." + gif_api + ".apikey")
if apikey:
self.valid_api[gif_api]["apikey"] = apikey
for validgifapi in list(self.valid_api.keys()):
command_dict = {
"comtype": "gif_prefix",
"validcoms": validgifapi
}
botcommands.dict['counts'] += 1
botcommands.register(command_dict)
def setup_gif(self):
botconfig.define_section("SopelGifSearch", SpiceBot_Gif_MainSection, validate=False)
def get_gif(self, searchdict):
# list of defaults
query_defaults = {
"query": None,
"searchnum": 'random',
"gifsearch": list(self.valid_api.keys()),
"gifsearchremove": ['gifme'], # TODO make a config setting
"searchlimit": 'default',
"nsfw": False,
}
# set defaults if they don't exist
for key in query_defaults:
if key not in list(searchdict.keys()):
searchdict[key] = query_defaults[key]
if key == "gifsearch":
for remx in query_defaults["gifsearchremove"]:
searchdict["gifsearch"].remove(remx)
if botconfig.SopelGifSearch.nsfw:
query_defaults["nsfw"] = True
# verify query is there to search
if not searchdict["query"]:
return {"error": 'No Query to Search'}
# Replace spaces in search query
searchdict["searchquery"] = urllib.request.pathname2url(searchdict["query"])
# set api usage
if not isinstance(searchdict['gifsearch'], list):
if str(searchdict['gifsearch']) in list(self.valid_api.keys()):
searchdict['gifsearch'] = [searchdict['gifsearch']]
else:
searchdict['gifsearch'] = list(self.valid_api.keys())
for apis in searchdict['gifsearch']:
if apis not in list(self.valid_api.keys()):
searchdict['gifsearch'].remove(apis)
# Verify search limit
if searchdict['searchlimit'] == 'default' or not isinstance(searchdict['searchlimit'], int):
searchdict['searchlimit'] = 50
# Random handling for searchnum
if searchdict["searchnum"] == 'random':
searchdict["searchnum"] = random.randint(0, searchdict['searchlimit'])
# verify valid search parameters
if not str(searchdict["searchnum"]).isdigit():
return {"error": 'No Search Number or Random Specified'}
# perform search
gifapiresults = []
for currentapi in searchdict['gifsearch']:
# check if query is already cached
if searchdict["searchquery"].lower() in list(self.valid_api[currentapi]["cache"].keys()):
verifygoodlinks = []
for gifresult in self.valid_api[currentapi]["cache"][str(searchdict["searchquery"])]:
if gifresult["returnurl"] not in self.badlinks:
verifygoodlinks.append(gifresult)
self.valid_api[currentapi]["cache"][str(searchdict["searchquery"])] = verifygoodlinks
else:
# assemble url
url = self.gif_url_assemble(currentapi, str(searchdict["searchquery"]), str(searchdict["searchlimit"]), searchdict['nsfw'])
# fetch results
self.fetch_gif_results(currentapi, str(searchdict["searchquery"]), url)
if len(self.valid_api[currentapi]["cache"][searchdict["searchquery"].lower()]):
gifapiresults.extend(self.valid_api[currentapi]["cache"][searchdict["searchquery"].lower()])
if not len(gifapiresults):
return {"error": "No Results were found for '" + searchdict["query"] + "' in the " + str(spicemanip.main(searchdict['gifsearch'], 'orlist')) + " api(s)"}
random.shuffle(gifapiresults)
random.shuffle(gifapiresults)
randombad = True
while randombad:
gifdict = spicemanip.main(gifapiresults, "random")
try:
gifpage = requests.get(gifdict["returnurl"], headers=None)
except Exception as e:
gifpage = str(e)
gifpage = None
if gifpage and not str(gifpage.status_code).startswith(tuple(["4", "5"])):
randombad = False
else:
self.badlinks.append(str(gifdict["returnurl"]))
newlist = []
for tempdict in gifapiresults:
if tempdict["returnurl"] != gifdict["returnurl"]:
newlist.append(tempdict)
gifapiresults = newlist
if not len(gifapiresults):
return {"error": "No Results were found for '" + searchdict["query"] + "' in the " + str(spicemanip.main(searchdict['gifsearch'], 'orlist')) + " api(s)"}
# return dict
gifdict['error'] = None
return gifdict
def fetch_gif_results(self, currentapi, searchquery, url):
try:
page = requests.get(url, headers=self.header)
except Exception as e:
page = e
page = None
if page and not str(page.status_code).startswith(tuple(["4", "5"])):
data = json.loads(urllib.request.urlopen(url).read().decode('utf-8'))
results = data[self.valid_api[currentapi]['results']]
resultsarray = []
for result in results:
appendresult = False
cururl = result[self.valid_api[currentapi]['cururl']]
slashsplit = str(cururl).split("/")
fileextension = slashsplit[-1]
if not fileextension or fileextension == '':
appendresult = True
elif str(fileextension).endswith(".gif"):
appendresult = True
elif "." not in str(fileextension):
appendresult = True
if appendresult:
resultsarray.append(cururl)
# make sure there are results
if len(resultsarray):
# Create Temp dict for every result
tempresultnum = 0
for tempresult in resultsarray:
if tempresult not in self.badlinks:
tempresultnum += 1
tempdict = {
"returnnum": tempresultnum,
"returnurl": tempresult,
"gifapi": currentapi,
}
self.valid_api[currentapi]["cache"][str(searchquery).lower()].append(tempdict)
def gif_url_assemble(self, currentapi, searchquery, searchlimit, searchnsfw):
# url base
url = str(self.valid_api[currentapi]['url'])
# query
url += str(self.valid_api[currentapi]['query']) + str(searchquery)
# limit
url += str(self.valid_api[currentapi]['limit']) + str(searchlimit)
# nsfw search?
if searchnsfw:
url += str(self.valid_api[currentapi]['nsfw'])
else:
url += str(self.valid_api[currentapi]['sfw'])
# api key
url += str(self.valid_api[currentapi]['key']) + str(self.valid_api[currentapi]['apikey'])
return url
gif = BotGif()