Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import discord
- from discord.ext import commands
- from discord.utils import find as dfind
- import math
- import requests as rq
- from bs4 import BeautifulSoup
- import logging
- TOKEN = "your_token"
- PREFIX = "f:"
- FACTORIO_MOD_BASE_URL = "https://mods.factorio.com/mod/"
- FACTORIO_MOD_SEARCH_BASE_URL = "https://mods.factorio.com/query/"
- FACTORIO_WIKI_BASE_URL = "https://wiki.factorio.com/"
- FACTORIO_WIKI_SEARCH_BASE_URL = ""
- FACTORIO_WIKI_BASE_IMG_URL = "https://wiki.factorio.com/images/"
- USER_AGENT= {'User-Agent': 'Mozilla/5.0'}
- #only takes msgs starting with PREFIX as commands
- bot = commands.Bot(command_prefix=PREFIX)
- logger = logging.getLogger("discord")
- logger.setLevel(logging.INFO)
- handler = logging.FileHandler(filename="discord.log", encoding="utf-8", mode="w")
- handler.setFormatter(logging.Formatter('''%(asctime)s:%(levelname)s:%(name)s:\t%(message)s'''))
- logger.addHandler(handler)
- #Checks
- def is_author():
- def check_condition(ctx):
- return ctx.message.author.id ==289426079544901633
- return commands.check(check_condition)
- @bot.event
- async def on_ready():
- print('We have logged in as {0.user}'.format(bot))
- @bot.event
- async def on_message(message):
- if message.author == bot.user:
- return
- if message.content.startswith('$$abs_test'):
- await message.channel.send('Hello!')
- await bot.process_commands(message)
- @bot.command()
- async def ping(ctx):
- '''This command responds with the current latency. Also this docstring is automagically turned into the output of the help command'''
- latency = bot.latency #included in the API
- #send replies to the message received. This means in the same channel.
- await ctx.send("Latency of {} seconds".format(latency))
- @bot.group(pass_context=True)
- async def mod(ctx):
- '''a suite of commands about Factorio mods'''
- if ctx.invoked_subcommand is None:
- await ctx.send("Couldn't parse command: Not Enough Arguments")
- @mod.command(pass_context=True)
- async def info(ctx, mod_name):
- '''Gives some basic info about any mod avaialble on the mod portal
- you must give the raw name of the mod in order for the bot to find the actual page. If you don't know the mod's raw name search it up with the "search" subcommand.'''
- fields = mod_scrapper(str(mod_name).replace(" ", "-"))
- print(fields)
- embed = discord.Embed(
- title = mod_name,
- description = None,
- colour = discord.Colour.from_rgb(228, 141, 36),
- url = fields[-1]
- )
- embed.set_footer(text="Made with love by Toude#6601")
- #embed.set_image(url="")
- embed.set_thumbnail(url=fields[5])
- # embed.set_author(name="Toude#6601")
- embed.add_field(name="Updated", value=fields[0], inline=True)
- embed.add_field(name="Compatibility", value=fields[1], inline=True)
- embed.add_field(name="Downloads", value=fields[2], inline=True)
- embed.add_field(name="Author", value=fields[4], inline=True)
- embed.add_field(name="Description", value=fields[3], inline=True)
- await ctx.send(embed=embed)
- def mod_scrapper(mod_name):
- full_url = FACTORIO_MOD_BASE_URL + mod_name
- html_page =rq.get(full_url, headers = USER_AGENT)
- soup = BeautifulSoup(html_page.content, "html.parser")
- fields = []
- for field in soup.findAll("div", {"class":"mod-card-info-tag-label"}):
- #print(field.get_text())
- fields.append(str(field.get_text()))
- assert len(fields)==3, "found {} fields instead of 3".format(len(fields))
- for field in soup.findAll("div", {"class": "mod-card-summary"}):
- fields.append(str(field.get_text()))
- assert len(fields)==4, "found {} fields instead of 4".format(len(fields))
- for field in soup.findAll("div", {"class": "mod-card-author"}):
- fields.append(field.get_text().split(" ")[1])
- tmp = []
- for field in soup.findAll("img"):
- tmp.append(field.get("src"))
- if len(tmp)>0:
- fields.append(tmp[0])
- else:
- print("No thumbnail available for {}".format(full_url))
- fields.append(full_url)
- return fields
- @mod.command(pass_context=True)
- async def search(ctx, query):
- '''allows you to browse the mod protal from Discord. Outputs the name and the raw name of the top 6 mods matching the query.'''
- query_list = query.split(" ")
- query_str = ""
- for q in query_list:
- query_str = query_str + "+{}".format(q)
- full_url = str(FACTORIO_MOD_SEARCH_BASE_URL+query_str)
- results, result_urls = mod_search(full_url)
- print(results, result_urls)
- embed = discord.Embed(
- title = "{} result for {}".format(len(results), query),
- description = None,
- colour = discord.Colour.from_rgb(228, 141, 36),
- url = full_url
- )
- if len(results)>6:
- results = results[:6]
- result_urls = result_urls[:6]
- i =0
- for result in results:
- i+=1
- embed.add_field(name="#{}\t{}".format(i, result), value="{}".format(FACTORIO_MOD_BASE_URL+result_urls[i-1]) , inline=False)
- embed.set_footer(text="Made with love by Toude#6601")
- await ctx.send(embed=embed)
- def mod_search(query):
- html_page = rq.get(query, headers=USER_AGENT)
- soup = BeautifulSoup(html_page.content, "html.parser")
- #print(soup.prettify())
- results = []
- result_urls = []
- for field in soup.findAll("h2", {"class": "mod-card-title"}):
- mod_name = field.get_text().strip()
- results.append(mod_name)
- for field in soup.findAll("h2", {"class": "mod-card-title"}):
- mod_url = field.find("a")
- mod_url = mod_url.get("href").split("/")[-1]
- result_urls.append(mod_url)
- return results, result_urls
- @bot.group(pass_context=True)
- async def wiki(ctx):
- '''A tool which allows you to browse factorio wiki directly from Discord'''
- if ctx.invoked_subcommand is None:
- await ctx.send("Couldn't parse {} command: Not Enough Arguments".format(ctx.invoked_subcommand))
- @wiki.command(pass_context=True)
- async def search(ctx, language="en"):
- '''allows you to search the wiki. Language can be any 2-letters country code. Will return "Error: Page not available in specified language" if the page does not exists in this language but in others'''
- pass
- @wiki.command(pass_context=True)
- async def info(ctx, query):
- '''command meant to give basic information about a factorio element with a wiki entry'''
- if type(query)!=str:
- await ctx.send('''Argument Error: query provided isn't a string, try quoting your query like this "query".''')
- fields = wiki_scrapper(query)
- embed = discord.Embed(
- title = fields[0],
- description = None,
- colour = discord.Colour.from_rgb(228, 141, 36),
- url = fields[1]
- )
- embed.set_footer(text="Made with love by Toude#6601")
- if fields[2]!=None:
- embed.set_thumbnail(url=fields[2])
- embed.add_field(name="Description", value=fields[3], inline=True)
- await ctx.send(embed=embed)
- def wiki_scrapper(query):
- fields = []
- fields.append(query.capitalize())
- title = fields[0].replace(" ", "_")
- local_url = FACTORIO_WIKI_BASE_URL+ title
- image_url = check_thumbnail(FACTORIO_WIKI_BASE_IMG_URL+title+".png")
- fields.append(local_url)
- fields.append(image_url)
- html_page =rq.get(local_url, headers = USER_AGENT)
- soup = BeautifulSoup(html_page.content, "html.parser")
- for field in soup.findAll("meta", {"name": "description"}):
- fields.append(field["content"])
- return fields
- def check_thumbnail(url):
- img_page = rq.get(url, headers=USER_AGENT)
- soup = BeautifulSoup(img_page.content, "html.parser")
- for field in soup.findAll("div", {"class": "mw-content-ltr"}):
- if field.get_text().find("There is currently no text in this page.")!=(-1):
- return None
- return url
- @bot.command()
- @is_author()
- async def shutdown(ctx):
- print("Goodbye")
- await bot.change_presence(status=discord.Status.offline)
- #time.sleep(0.1)
- await ctx.send("Goodbye")
- await bot.close()
- await quit()
- bot.run(TOKEN)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement