Done
This commit is contained in:
commit
aa9e5d95ed
|
@ -7,6 +7,8 @@ utils/__pycache__/
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
env/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
# The default ``config.py``
|
|
||||||
# flake8: noqa
|
|
||||||
|
|
||||||
|
|
||||||
def set_prefs(prefs):
|
|
||||||
"""This function is called before opening the project"""
|
|
||||||
|
|
||||||
# Specify which files and folders to ignore in the project.
|
|
||||||
# Changes to ignored resources are not added to the history and
|
|
||||||
# VCSs. Also they are not returned in `Project.get_files()`.
|
|
||||||
# Note that ``?`` and ``*`` match all characters but slashes.
|
|
||||||
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
|
|
||||||
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
|
|
||||||
# '.svn': matches 'pkg/.svn' and all of its children
|
|
||||||
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
|
|
||||||
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
|
|
||||||
prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
|
|
||||||
'.hg', '.svn', '_svn', '.git', '.tox']
|
|
||||||
|
|
||||||
# Specifies which files should be considered python files. It is
|
|
||||||
# useful when you have scripts inside your project. Only files
|
|
||||||
# ending with ``.py`` are considered to be python files by
|
|
||||||
# default.
|
|
||||||
# prefs['python_files'] = ['*.py']
|
|
||||||
|
|
||||||
# Custom source folders: By default rope searches the project
|
|
||||||
# for finding source folders (folders that should be searched
|
|
||||||
# for finding modules). You can add paths to that list. Note
|
|
||||||
# that rope guesses project source folders correctly most of the
|
|
||||||
# time; use this if you have any problems.
|
|
||||||
# The folders should be relative to project root and use '/' for
|
|
||||||
# separating folders regardless of the platform rope is running on.
|
|
||||||
# 'src/my_source_folder' for instance.
|
|
||||||
# prefs.add('source_folders', 'src')
|
|
||||||
|
|
||||||
# You can extend python path for looking up modules
|
|
||||||
# prefs.add('python_path', '~/python/')
|
|
||||||
|
|
||||||
# Should rope save object information or not.
|
|
||||||
prefs['save_objectdb'] = True
|
|
||||||
prefs['compress_objectdb'] = False
|
|
||||||
|
|
||||||
# If `True`, rope analyzes each module when it is being saved.
|
|
||||||
prefs['automatic_soa'] = True
|
|
||||||
# The depth of calls to follow in static object analysis
|
|
||||||
prefs['soa_followed_calls'] = 0
|
|
||||||
|
|
||||||
# If `False` when running modules or unit tests "dynamic object
|
|
||||||
# analysis" is turned off. This makes them much faster.
|
|
||||||
prefs['perform_doa'] = True
|
|
||||||
|
|
||||||
# Rope can check the validity of its object DB when running.
|
|
||||||
prefs['validate_objectdb'] = True
|
|
||||||
|
|
||||||
# How many undos to hold?
|
|
||||||
prefs['max_history_items'] = 32
|
|
||||||
|
|
||||||
# Shows whether to save history across sessions.
|
|
||||||
prefs['save_history'] = True
|
|
||||||
prefs['compress_history'] = False
|
|
||||||
|
|
||||||
# Set the number spaces used for indenting. According to
|
|
||||||
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
|
|
||||||
# unit-tests use 4 spaces it is more reliable, too.
|
|
||||||
prefs['indent_size'] = 4
|
|
||||||
|
|
||||||
# Builtin and c-extension modules that are allowed to be imported
|
|
||||||
# and inspected by rope.
|
|
||||||
prefs['extension_modules'] = []
|
|
||||||
|
|
||||||
# Add all standard c-extensions to extension_modules list.
|
|
||||||
prefs['import_dynload_stdmods'] = True
|
|
||||||
|
|
||||||
# If `True` modules with syntax errors are considered to be empty.
|
|
||||||
# The default value is `False`; When `False` syntax errors raise
|
|
||||||
# `rope.base.exceptions.ModuleSyntaxError` exception.
|
|
||||||
prefs['ignore_syntax_errors'] = False
|
|
||||||
|
|
||||||
# If `True`, rope ignores unresolvable imports. Otherwise, they
|
|
||||||
# appear in the importing namespace.
|
|
||||||
prefs['ignore_bad_imports'] = False
|
|
||||||
|
|
||||||
# If `True`, rope will insert new module imports as
|
|
||||||
# `from <package> import <module>` by default.
|
|
||||||
prefs['prefer_module_from_imports'] = False
|
|
||||||
|
|
||||||
# If `True`, rope will transform a comma list of imports into
|
|
||||||
# multiple separate import statements when organizing
|
|
||||||
# imports.
|
|
||||||
prefs['split_imports'] = False
|
|
||||||
|
|
||||||
# If `True`, rope will remove all top-level import statements and
|
|
||||||
# reinsert them at the top of the module when making changes.
|
|
||||||
prefs['pull_imports_to_top'] = True
|
|
||||||
|
|
||||||
# If `True`, rope will sort imports alphabetically by module name instead
|
|
||||||
# of alphabetically by import statement, with from imports after normal
|
|
||||||
# imports.
|
|
||||||
prefs['sort_imports_alphabetically'] = False
|
|
||||||
|
|
||||||
# Location of implementation of
|
|
||||||
# rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
|
|
||||||
# case, you don't have to change this value, unless you're an rope expert.
|
|
||||||
# Change this value to inject you own implementations of interfaces
|
|
||||||
# listed in module rope.base.oi.type_hinting.providers.interfaces
|
|
||||||
# For example, you can add you own providers for Django Models, or disable
|
|
||||||
# the search type-hinting in a class hierarchy, etc.
|
|
||||||
prefs['type_hinting_factory'] = (
|
|
||||||
'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
|
|
||||||
|
|
||||||
|
|
||||||
def project_opened(project):
|
|
||||||
"""This function is called after opening the project"""
|
|
||||||
# Do whatever you like here!
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"python.pythonPath": "env\\Scripts\\python3.8.exe"
|
||||||
|
}
|
|
@ -1,43 +1,43 @@
|
||||||
{
|
{
|
||||||
"VERSION": "1.9 testing",
|
"VERSION": "1.9 testing",
|
||||||
"DESCRIPTION": "a minimalist search utility bot for discord, designed by taciturasa.",
|
"DESCRIPTION": "a minimalist search utility bot for discord, designed by taciturasa.",
|
||||||
"REPO": "https://github.com/taciturasa/searchbot-discord",
|
"REPO": "https://github.com/taciturasa/searchbot-discord",
|
||||||
"SERVER": "https://discord.gg/4BpReNV",
|
"SERVER": "https://discord.gg/4BpReNV",
|
||||||
"TOKEN": "",
|
"TOKEN": "",
|
||||||
"CACHE": false,
|
"CACHE": false,
|
||||||
"PREFIX": ["search!"],
|
"PREFIX": ["search!"],
|
||||||
|
|
||||||
"MAINTENANCE": false,
|
|
||||||
"CASE_INSENSITIVE": true,
|
|
||||||
"PREFIXLESS_DMS": true,
|
|
||||||
"MENTION_ASSIST": true,
|
|
||||||
"CUSTOM_HELP": true,
|
|
||||||
|
|
||||||
"PERMS": 378944,
|
"MAINTENANCE": false,
|
||||||
"BLOCKED": [],
|
"CASE_INSENSITIVE": true,
|
||||||
|
"PREFIXLESS_DMS": true,
|
||||||
"BOTLISTS": {
|
"MENTION_ASSIST": true,
|
||||||
"DBL": "",
|
"CUSTOM_HELP": true,
|
||||||
"DBOTS": "",
|
|
||||||
"BOD": "",
|
"PERMS": 378944,
|
||||||
"DBLCOM": "",
|
"BLOCKED": [],
|
||||||
"BLSPACE": "",
|
|
||||||
"TABFT_LINK": "",
|
"BOTLISTS": {
|
||||||
"DAD": ""
|
"DBL": "",
|
||||||
},
|
"DBOTS": "",
|
||||||
|
"BOD": "",
|
||||||
"HOOKS": {
|
"DBLCOM": "",
|
||||||
"INFO_HOOK": "",
|
"BLSPACE": "",
|
||||||
"WARN_HOOK": "",
|
"TABFT_LINK": "",
|
||||||
"ERROR_HOOK": "",
|
"DAD": ""
|
||||||
"DEBUG_HOOK": ""
|
},
|
||||||
},
|
|
||||||
|
"HOOKS": {
|
||||||
"RETHINK": {
|
"INFO_HOOK": "",
|
||||||
"DB": "",
|
"WARN_HOOK": "",
|
||||||
"USERNAME": "",
|
"ERROR_HOOK": "",
|
||||||
"PASSWORD": "",
|
"DEBUG_HOOK": ""
|
||||||
"HOST": "",
|
},
|
||||||
"PORT": null
|
|
||||||
}
|
"RETHINK": {
|
||||||
}
|
"DB": "",
|
||||||
|
"USERNAME": "",
|
||||||
|
"PASSWORD": "",
|
||||||
|
"HOST": "",
|
||||||
|
"PORT": null
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -9,6 +9,7 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import random
|
import random
|
||||||
|
from urllib import parse
|
||||||
import sys
|
import sys
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
@ -29,7 +30,6 @@ class Search(commands.Cog):
|
||||||
with open('searxes.txt') as f:
|
with open('searxes.txt') as f:
|
||||||
self.instances = f.read().split('\n')
|
self.instances = f.read().split('\n')
|
||||||
|
|
||||||
|
|
||||||
async def _search_logic(self, query: str, is_nsfw: bool = False,
|
async def _search_logic(self, query: str, is_nsfw: bool = False,
|
||||||
category: str = None) -> str:
|
category: str = None) -> str:
|
||||||
"""Provides search logic for all search commands."""
|
"""Provides search logic for all search commands."""
|
||||||
|
@ -280,6 +280,178 @@ class Search(commands.Cog):
|
||||||
)
|
)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
|
@commands.command(aliases=['urban', 'ud'])
|
||||||
|
async def urbandictionary(self, ctx, *, query: str):
|
||||||
|
"""Pull data from Urban Dictionary."""
|
||||||
|
|
||||||
|
# Handling
|
||||||
|
async with ctx.typing():
|
||||||
|
number = 1
|
||||||
|
if " | " in query:
|
||||||
|
query, number = query.rsplit(" | ", 1)
|
||||||
|
search = parse.quote(query)
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(f"http://api.urbandictionary.com/v0/define?term={search}") as resp:
|
||||||
|
resp = await resp.json()
|
||||||
|
if not resp["list"]:
|
||||||
|
await ctx.send(f"`{query}`` couldn't be found on Urban Dictionary.")
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
top_result = resp["list"][int(number) - 1]
|
||||||
|
embed = discord.Embed(title=top_result["word"], description=top_result["definition"][0:425] + "...",
|
||||||
|
url=top_result["permalink"], color=ctx.author.color)
|
||||||
|
if top_result["example"]:
|
||||||
|
embed.add_field(name="Example:",
|
||||||
|
value=top_result["example"][0:100] + "...", inline=False)
|
||||||
|
embed.add_field(name="👍", value = top_result["thumbs_up"])
|
||||||
|
embed.add_field(name="👎", value = top_result["thumbs_down"])
|
||||||
|
|
||||||
|
|
||||||
|
embed.set_author(name=top_result["author"],
|
||||||
|
icon_url="https://apprecs.org/gp/images/app-icons/300/2f/info.tuohuang.urbandict.jpg")
|
||||||
|
number = str(int(number) + 1)
|
||||||
|
embed.set_footer(text=str(len(
|
||||||
|
resp["list"])) + f" results were found. To see a different result, use {ctx.prefix}ud {query} | {number}.")
|
||||||
|
try:
|
||||||
|
|
||||||
|
await ctx.send(f"**{top_result['word']}** - <{top_result['permalink']}>", embed=embed)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
await ctx.send(top_result["definition"])
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def anime(self, ctx, *, query: str):
|
||||||
|
"""Lookup anime information online, uses the <https://kitsu.io/> public API."""
|
||||||
|
base = "https://kitsu.io/api/edge/"
|
||||||
|
# Handling
|
||||||
|
async with ctx.typing():
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(base + "anime", params={"filter[text]": query}) as resp:
|
||||||
|
resp = await resp.json()
|
||||||
|
resp = resp['data']
|
||||||
|
if not resp:
|
||||||
|
return await ctx.send("The requested anime coudn't be found")
|
||||||
|
|
||||||
|
anime = resp[0]
|
||||||
|
title = f'{anime["attributes"]["canonicalTitle"]}'
|
||||||
|
anime_id = anime["id"]
|
||||||
|
url = f"https://kitsu.io/anime/{anime_id}"
|
||||||
|
thing = '' if not anime['attributes'][
|
||||||
|
'endDate'] else f' to {anime["attributes"]["endDate"]}'
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title=f"{title}", color=ctx.author.color, url=url)
|
||||||
|
embed.description = anime["attributes"]["synopsis"][0:425] + "..."
|
||||||
|
embed.add_field(name="Average Rating",
|
||||||
|
value=anime["attributes"]["averageRating"])
|
||||||
|
embed.add_field(name="Popularity Rank",
|
||||||
|
value=anime["attributes"]["popularityRank"])
|
||||||
|
embed.add_field(name="Age Rating",
|
||||||
|
value=anime["attributes"]["ageRating"])
|
||||||
|
embed.add_field(
|
||||||
|
name="Status", value=anime["attributes"]["status"])
|
||||||
|
|
||||||
|
embed.add_field(
|
||||||
|
name="Aired", value=f"{anime['attributes']['startDate']}{thing}")
|
||||||
|
embed.add_field(name="Episodes",
|
||||||
|
value=anime['attributes']["episodeCount"])
|
||||||
|
embed.add_field(
|
||||||
|
name="Type", value=anime['attributes']["showType"])
|
||||||
|
embed.set_thumbnail(
|
||||||
|
url=anime['attributes']["posterImage"]["original"])
|
||||||
|
embed.set_footer(
|
||||||
|
text=f"Requested by {ctx.author.name} | Powered by kitsu.io", icon_url=ctx.author.avatar_url_as(format="png"))
|
||||||
|
try:
|
||||||
|
|
||||||
|
await ctx.send(f"**{title}** - <{url}>", embed=embed)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
|
||||||
|
aired = f"{anime['attributes']['startDate']}{thing}"
|
||||||
|
template = f"""
|
||||||
|
url: {url}
|
||||||
|
Title: {title}
|
||||||
|
Average Rating: {anime["attributes"]["averageRating"]}
|
||||||
|
Popularity Rank: {anime["attributes"]["popularityRank"]}
|
||||||
|
Age Rating: {anime["attributes"]["ageRating"]}
|
||||||
|
Status: {anime["attributes"]["status"]}
|
||||||
|
Aired: {aired}
|
||||||
|
Type: {anime['attributes']["showType"]}
|
||||||
|
|
||||||
|
|
||||||
|
Powered by kitsu.io"""
|
||||||
|
await ctx.send(template)
|
||||||
|
|
||||||
|
await session.close()
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def manga(self, ctx, *, query: str):
|
||||||
|
"""Lookup manga information online, uses the <https://kitsu.io/> public API."""
|
||||||
|
base = "https://kitsu.io/api/edge/"
|
||||||
|
# Handling
|
||||||
|
async with ctx.typing():
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(base + "manga", params={"filter[text]": query}) as resp:
|
||||||
|
resp = await resp.json()
|
||||||
|
resp = resp['data']
|
||||||
|
if not resp:
|
||||||
|
return await ctx.send("The requested manga coudn't be found")
|
||||||
|
|
||||||
|
manga = resp[0]
|
||||||
|
title = f'{manga["attributes"]["canonicalTitle"]}'
|
||||||
|
manga_id = manga["id"]
|
||||||
|
url = f"https://kitsu.io/manga/{manga_id}"
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title=f"{title}", color=ctx.author.color, url=url)
|
||||||
|
embed.description = manga["attributes"]["synopsis"][0:425] + "..."
|
||||||
|
if manga["attributes"]["averageRating"]:
|
||||||
|
embed.add_field(name="Average Rating",
|
||||||
|
value=manga["attributes"]["averageRating"])
|
||||||
|
embed.add_field(name="Popularity Rank",
|
||||||
|
value=manga["attributes"]["popularityRank"])
|
||||||
|
if manga["attributes"]["ageRating"]:
|
||||||
|
embed.add_field(name="Age Rating",
|
||||||
|
value=manga["attributes"]["ageRating"])
|
||||||
|
embed.add_field(
|
||||||
|
name="Status", value=manga["attributes"]["status"])
|
||||||
|
thing = '' if not manga['attributes'][
|
||||||
|
'endDate'] else f' to {manga["attributes"]["endDate"]}'
|
||||||
|
embed.add_field(
|
||||||
|
name="Published", value=f"{manga['attributes']['startDate']}{thing}")
|
||||||
|
if manga['attributes']['chapterCount']:
|
||||||
|
embed.add_field(name="Chapters",
|
||||||
|
value=manga['attributes']["chapterCount"])
|
||||||
|
embed.add_field(
|
||||||
|
name="Type", value=manga['attributes']["mangaType"])
|
||||||
|
embed.set_thumbnail(
|
||||||
|
url=manga['attributes']["posterImage"]["original"])
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
await ctx.send(f"**{title}** - <{url}>", embed=embed)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
|
||||||
|
aired = f"{manga['attributes']['startDate']}{thing}"
|
||||||
|
template = f"""
|
||||||
|
url: {url}
|
||||||
|
Title: {title}
|
||||||
|
Average Rating: {manga["attributes"]["averageRating"]}
|
||||||
|
Popularity Rank: {manga["attributes"]["popularityRank"]}
|
||||||
|
Age Rating: {manga["attributes"]["ageRating"]}
|
||||||
|
Status: {manga["attributes"]["status"]}
|
||||||
|
Aired: {aired}
|
||||||
|
Type: {manga['attributes']["showType"]}
|
||||||
|
|
||||||
|
|
||||||
|
Powered by kitsu.io"""
|
||||||
|
await ctx.send(template)
|
||||||
|
|
||||||
|
await session.close()
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
async def rejson(self, ctx):
|
async def rejson(self, ctx):
|
||||||
|
@ -332,7 +504,6 @@ class Search(commands.Cog):
|
||||||
name="Search Results"
|
name="Search Results"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Sends result
|
# Sends result
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ class Logging():
|
||||||
|
|
||||||
async def error(self, error: Exception, ctx: Context, name: Optional[str]):
|
async def error(self, error: Exception, ctx: Context, name: Optional[str]):
|
||||||
"""Logs errors and sends them to the appropriate places."""
|
"""Logs errors and sends them to the appropriate places."""
|
||||||
|
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
error_embed = await self._create_error_embed(error, ctx)
|
error_embed = await self._create_error_embed(error, ctx)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue