Beispiel #1
0
async def get_talents_image(abilities, hero_id):
	if isinstance(abilities, int):
		abilities = [ abilities ]
	if abilities is None:
		abilities = []
	talent_slots = []
	for ability_id in abilities:
		if ability_id not in ability_infos:
			continue
		ability = ability_infos[ability_id]["entity"]
		if not ability.is_talent:
			continue
		for talent in ability.talent_links:
			if talent.hero_id is None or talent.hero_id == hero_id:
				talent_slots.append(talent.slot)
	talent_slots = sorted(talent_slots, reverse=True)
	uri = f"talents_icon:{'_'.join(map(str, talent_slots))}"
	filename = httpgetter.cache.get_filename(uri)
	if filename and not settings.debug:
		return Image.open(filename)
	filename = await httpgetter.cache.new(uri, "png")

	image = Image.open(settings.resource("images/talents/talent_background.png"))
	for slot in talent_slots:
		slot_image = Image.open(settings.resource(f"images/talents/talent_{slot}.png"))
		image = paste_image(image, slot_image)

	image.save(filename, format="PNG")
	return image
Beispiel #2
0
	def init_local_clipinfo(self):
		infofile = settings.resource("clips/clipinfo.json")
		if os.path.isfile(infofile):
			clipinfos = read_json(infofile)
		else:
			clipinfos = {}
		clipsdir = settings.resource("clips/")
		for root, dirs, files in os.walk(clipsdir):
			for file in files:
				match = re.search(f"clips[/\\\\]((?:.*[/\\\\])?([^/\\\\]+)\.(?:{audio_extensions}))", os.path.join(root, file))
				if match:
					path = match.group(1)
					name = match.group(2)
					if name not in clipinfos:
						found = False
						for clipname in clipinfos:
							if clipinfos[clipname]["path"] == path:
								found = True
								break
						if not found:
							info = { "path": path }
							in_dir = re.search(f"(.+)[/\\\\](?:.+)\.(?:{audio_extensions})", path)
							if in_dir:
								info["tags"] = in_dir.group(1)
							clipinfos[name] = info

		write_json(infofile, clipinfos)
		return clipinfos
Beispiel #3
0
 def __init__(self, bot):
     MangoCog.__init__(self, bot)
     self.reactions = read_json(settings.resource("json/reactions.json"))
     self.questions = read_json(settings.resource("json/questions.json"))
     self.subscripts = read_json(settings.resource("json/subscripts.json"))
     self.superscripts = read_json(
         settings.resource("json/superscripts.json"))
Beispiel #4
0
	async def updateemoji(self, ctx):
		"""Updates the emoji information for the bot"""
		emoji_json = read_json(settings.resource("json/emoji.json"))
		with ctx.channel.typing():
			for emoji in ctx.guild.emojis:
				imgpath = settings.resource(f"images/emojis/{emoji.name}.png")
				with open(imgpath, 'wb+') as f:
					f.write((await httpgetter.get(emoji.url, return_type="bytes")).read())
				emoji_json[emoji.name] = emoji.id
		write_json(settings.resource("json/emoji.json"), emoji_json)
		await ctx.send("done!")
Beispiel #5
0
 def __init__(self, bot):
     MangoCog.__init__(self, bot)
     self.donation_link = "https://www.paypal.me/dillerm"
     self.reactions = read_json(settings.resource("json/reactions.json"))
     self.questions = read_json(settings.resource("json/questions.json"))
     self.subscripts = read_json(settings.resource("json/subscripts.json"))
     self.superscripts = read_json(
         settings.resource("json/superscripts.json"))
     self.showerthoughts_data = read_json(
         settings.resource("json/showerthoughts.json"))
     self.words = load_words()
Beispiel #6
0
	def __init__(self, bot):
		MangoCog.__init__(self, bot)
		self.session = session
		self.criteria_aliases = read_json(settings.resource("json/criteria_aliases.json"))
		self.hero_stat_categories = read_json(settings.resource("json/hero_stats.json"))
		self.hero_aliases = {}
		self.item_aliases = {}
		self.leveled_hero_stats = [] # by level (0 is null, and 1-30 are filled in)
		self.hero_regex = ""
		self.build_helpers()
		self.vpkurl = "http://dotabase.dillerm.io/dota-vpk"
		drawdota.init_dota_info(self.get_hero_infos(), self.get_item_infos(), self.get_ability_infos(), self.vpkurl)
Beispiel #7
0
 def __init__(self, bot):
     MangoCog.__init__(self, bot)
     self.session = session
     self.criteria_aliases = read_json(
         settings.resource("json/criteria_aliases.json"))
     self.item_colors = read_json(
         settings.resource("json/dota_item_colors.json"))
     self.hero_aliases = {}
     self.item_aliases = {}
     self.build_aliases()
     self.vpkurl = "http://dotabase.dillerm.io/dota-vpk"
     drawdota.init_dota_info(self.get_hero_infos(), self.get_item_infos())
Beispiel #8
0
    async def addclip(self,
                      ctx,
                      url,
                      clipname,
                      start,
                      end,
                      start_fade=0.25,
                      end_fade=0.25):
        """Adds a clip from youtube"""
        outfile = settings.resource(f"clips/{clipname}.mp3")
        start = get_time(start)
        end = get_time(end)
        duration = end - start

        matches = [
            re.match(r"https?://(?:www\.)?youtube\.com/watch\?v=([^/]*)", url),
            re.match(r"https?://(?:www\.)?youtu\.be/([^/]*)", url),
            re.match(r"([^/]*)", url)
        ]
        youtube_id = None
        for match in matches:
            if match:
                youtube_id = match.group(1)
                break
        if youtube_id is None:
            raise UserError("This doesnt look like a youtube url or an id")

        video_file = settings.resource(f"cache/youtube/{youtube_id}.mp3")

        if not os.path.exists(video_file):
            await self.youtube_download(youtube_id, video_file)

        fadefilter = f"afade=t=in:ss=0:d={start_fade},afade=t=out:st={duration - end_fade}:d={end_fade}"

        # Converting / Cropping
        run_command([
            "ffmpeg", "-ss",
            str(start), "-t",
            str(duration), "-y", "-i", video_file, "-af", fadefilter, outfile
        ])

        audio = self.bot.get_cog("Audio")
        audio.local_clipinfo[clipname] = OrderedDict([
            ('path', f"{clipname}.mp3"),
            ('source', f"https://www.youtube.com/watch?v={youtube_id}"),
            ('start', start), ('end', end)
        ])
        audio.save_local_clipinfo()

        # Playing
        await self.play_clip(f"local:{clipname}", ctx)
Beispiel #9
0
	async def updateemoji(self, ctx, name=None):
		"""Updates the emoji information for the bot

		passing in a name will target that emoji specifically"""
		emoji_json = read_json(settings.resource("json/emoji.json"))
		with ctx.channel.typing():
			for emoji in ctx.guild.emojis:
				if name is None or name == emoji.name:
					imgpath = settings.resource(f"images/emojis/{emoji.name}.png")
					with open(imgpath, 'wb+') as f:
						f.write((await httpgetter.get(str(emoji.url), return_type="bytes")).read())
					emoji_json[emoji.name] = emoji.id
		write_json(settings.resource("json/emoji.json"), emoji_json)
		await ctx.send("done!")
Beispiel #10
0
async def dota_rank_icon(rank_tier, leaderboard_rank):
    if rank_tier is None:
        rank_tier = 0

    uri = f"dota_rank:{rank_tier}_{leaderboard_rank}"
    print(uri)
    filename = httpgetter.cache.get_filename(uri)
    if filename and not settings.debug:
        return filename

    filename = await httpgetter.cache.new(uri, "png")

    badge_num = rank_tier // 10
    stars_num = min(rank_tier % 10, 7)
    modifier = ""

    if leaderboard_rank and badge_num == 7:
        badge_num = 8  # this is to make consistant with what opendota shows

    if badge_num == 8 and leaderboard_rank:
        stars_num = 0
        if leaderboard_rank <= 10:
            modifier = "c"
        elif leaderboard_rank <= 100:
            modifier = "b"

    image = Image.open(
        settings.resource(f"images/ranks/rank_{badge_num}{modifier}.png"))

    if stars_num > 0:
        stars_image = Image.open(
            settings.resource(f"images/ranks/stars_{stars_num}.png"))
        image = paste_image(image, stars_image, 0, 0)

    if leaderboard_rank:
        draw = ImageDraw.Draw(image)

        box_width = 256
        box_height = 50

        cell = TextCell(leaderboard_rank,
                        color="#feffe5",
                        font_size=50,
                        horizontal_align="center")
        cell.render(draw, image, 0, 232 - box_height, box_width, box_height)

    image.save(filename, "png")

    return filename
Beispiel #11
0
 async def do_tts(self, text, ctx):
     gtts_fixes = read_json(settings.resource("json/gtts_fixes.json"))
     text = text.replace("\n", " ")
     for key in gtts_fixes:
         text = re.sub("\\b({})\\b".format(key), gtts_fixes[key], text,
                       re.IGNORECASE)
     await self.play_clip("tts:" + text, ctx)
Beispiel #12
0
def get_clipdirs():
    result = []
    for root, dirs, files in os.walk(settings.resource("clips/")):
        for d in dirs:
            result.append(d)
    result.sort()
    return result
Beispiel #13
0
    async def dog(self, ctx):
        """Gets a picture of one of my dogs

		These are pictures of my (the developer of mangobyte) dogs. Thier names are Fizzgig and Comet. One is floof. Other is big doggo. Floof older. Both good boys. """
        cat_dir = settings.resource("images/dog")
        imagepath = os.path.join(cat_dir, random.choice(os.listdir(cat_dir)))
        await ctx.send(file=discord.File(imagepath))
Beispiel #14
0
    async def courage(self, ctx, *, hero=None):
        """Generates a challenge build

		Creates a challenge build with a random (or given) hero and a random set of items

		**Examples:**
		`{cmdpfx}courage`
		`{cmdpfx}courage shadow fiend`"""

        all_boots = [
            "travel_boots", "phase_boots", "power_treads", "arcane_boots",
            "tranquil_boots", "guardian_greaves"
        ]

        all_items = read_json(settings.resource("json/courage_items.json"))
        random.shuffle(all_items)
        items = all_items[0:5]
        items.append(random.choice(all_boots))
        random.shuffle(items)

        item_ids = []
        for item in items:
            item_ids.append(
                session.query(Item).filter(
                    Item.name == f"item_{item}").first().id)
        if hero:
            hero_id = self.lookup_hero_id(hero)
            if not hero_id:
                raise UserError(f"Couldn't a hero called '{hero}'")
        else:
            hero_id = session.query(Hero).order_by(func.random()).first().id

        image = discord.File(await drawdota.draw_courage(hero_id, item_ids),
                             "courage.png")
        await ctx.send(file=image)
Beispiel #15
0
	async def do_tts(self, text, ctx):
		gtts_fixes = read_json(settings.resource("json/gtts_fixes.json"))
		text = text.replace("\n", " ")
		for key in gtts_fixes:
			pattern = f"\\b({key})\\b" if not key.startswith("regex:") else re.sub("^regex:", "", key)
			text = re.sub(pattern, gtts_fixes[key], text, re.IGNORECASE)
		await self.play_clip("tts:" + text, ctx)
Beispiel #16
0
	def init_local_clipinfo(self):
		infofile = settings.resource("clips/clipinfo.json")
		if not os.path.isfile(infofile):
			with open(infofile, 'w+') as f:
				f.write("{}")
			return {}
		return read_json(infofile)
Beispiel #17
0
    async def cat(self, ctx):
        """Gets a picture of my cat

		These are pictures of my (the developer of mangobyte) cat. Shes a bit over a year old now. Her name is Minnie. Short for Minerva. Also known as "Kitten", "Sneakerdoodle", or "Noodle." Shes a good kitten. """
        cat_dir = settings.resource("images/cat")
        imagepath = os.path.join(cat_dir, random.choice(os.listdir(cat_dir)))
        await ctx.send(file=discord.File(imagepath))
async def draw_matches_table(matches, game_strings):
	region_data = read_json(settings.resource("json/region_data.json"))	

	border_size = 10
	grey_color = "#BBBBBB"
	table = Table(background=background_color)
	# Header
	headers = [
		TextCell("Hero", padding=0),
		TextCell(""),
		TextCell("Result"),
		TextCell("K", horizontal_align="center"),
		TextCell("D", horizontal_align="center"),
		TextCell("A", horizontal_align="center"),
		TextCell("Duration"),
		TextCell("Type"),
		TextCell("Date")
	]
	table.add_row(headers)
	for cell in table.rows[0]:
		cell.background = trim_color

	table.add_row([ColorCell(color=trim_color, height=6) for i in range(len(headers))])
	first = True
	for match in matches:
		won_match = bool(match["radiant_win"]) == bool(match["player_slot"] < 128)
		game_mode = game_strings[f"game_mode_{match['game_mode']}"]
		lobby_type = game_strings[f"lobby_type_{match['lobby_type']}"]
		if first:
			first = False
		else:
			table.add_row([ColorCell(color=background_color, height=12) for i in range(len(headers))])
		table.add_row([
			ImageCell(img=await get_hero_image(match["hero_id"]), height=48),
			DoubleCell(
				TextCell(get_hero_name(match["hero_id"]), font_size=24),
				TextCell(match.get("match_id"), font_size=12, horizontal_align="left", color=grey_color)
			),
			TextCell("Win" if won_match else "Loss", color=("green" if won_match else "red"), horizontal_align="center"),
			TextCell(match.get("kills")),
			TextCell(match.get("deaths")),
			TextCell(match.get("assists")),
			TextCell(format_duration_simple(match.get("duration")), horizontal_align="center"),
			DoubleCell(
				TextCell(game_mode, font_size=18, padding_right=15, color=grey_color),
				TextCell(lobby_type, font_size=18, padding_right=15, color=grey_color)
			),
			get_datetime_cell(match, region_data)
		])
	image = table.render()

	border_image = Image.new('RGBA', (image.size[0] + (border_size * 2), image.size[1] + border_size), color=trim_color)
	image = paste_image(border_image, image, border_size, 0)

	fp = BytesIO()
	image.save(fp, format="PNG")
	fp.seek(0)

	return fp
Beispiel #19
0
def get_playlist(clipdir):
    clips = []
    for root, dirs, files in os.walk(settings.resource("clips/" + clipdir)):
        for file in files:
            if file.endswith(".mp3") or file.endswith(".wav"):
                clips.append(file[:-4])
    clips.sort()
    return clips
Beispiel #20
0
	async def clips(self, ctx, tag : str=None):
		"""Lists the local audio clips available for the play command

		Calling this command with no arguments gets you a list of all of the clips

		To get the clips that have a specific tag, do `{cmdpfx}clips <tag>`

		To get a list of all of the possible clip tags, try `{cmdpfx}clips tags`

		You can also do `{cmdpfx}clips new` to get the 10 newest clips"""
		message = ""
		clips = []
		sort = True

		if tag is None:
			message += "\n**Clips:**\n"
			for clipname in self.local_clipinfo:
				clips.append(clipname)
		elif tag in [ "recent", "latest", "new" ]:
			clips = {}
			for clipname in self.local_clipinfo:
				clips[clipname] = os.path.getctime(settings.resource(f"clips/{self.local_clipinfo[clipname]['path']}"))
			clips = list(map(lambda x: x[0], sorted(clips.items(), key=lambda x: x[1], reverse=True)))
			clips = clips[:10]
			sort = False
		elif tag in [ "tags", "sections" ]:
			message += "\n**Tags:**\n"
			for clipname in self.local_clipinfo:
				tags = self.local_clipinfo[clipname].get("tags")
				if tags:
					tags = tags.split("|")
					for t in tags:
						if t not in clips:
							clips.append(t)
		else:
			for clipname in self.local_clipinfo:
				info = self.local_clipinfo[clipname]
				tags = info.get("tags")
				if tags:
					tags = tags.split("|")
					if tag in tags:
						clips.append(clipname)
						continue
				if len(tag) > 3 and tag.lower() in info.get("author", "").lower():
					clips.append(clipname)
			if not clips:
				raise UserError("No clips not found for that tag")

		if len(clips) > 0:
			if sort:
				clips.sort()
			clip_format = "`{}` "
			if len(clips) <= 10:
				clip_format = "`{}`\n"
			for clip in clips:
				message += clip_format.format(clip)

		await ctx.send(message)
Beispiel #21
0
def load_words():
    words = {}
    for root, dirs, files in os.walk(settings.resource("words/")):
        for file in files:
            with open(os.path.join(root, file), 'r') as f:
                text = f.read()
            key, ext = os.path.splitext(file)
            words[key] = text.split("\n")
    return words
 def __init__(self, steam_id):
     super().__init__(f"")
     self.embed = discord.Embed(
         description=
         f"It looks like you either haven't played dota on this account, or the matches you've played are hidden. If you've played matches on this account, you should try enabling the **Expose Public Match Data** option in dota (see image below). Once you've done that, go to [your opendota profile](http://www.opendota.com/players/{steam_id}) and click the button under your name that says **REFRESH**"
     )
     self.file = discord.File(
         settings.resource("images/expose_match_data.png"), "tip.png")
     self.embed.set_image(url=f"attachment://{self.file.filename}")
Beispiel #23
0
 def __init__(self, text, bot, ctx):
     tempfile = settings.resource("temp/{}.wav".format(
         int(random.random() * 1000000000)))
     data = botdata.guildinfo(ctx)
     if data:
         tts_save(tempfile, text, data.ttslang)
     else:
         tts_save(tempfile, text)
     Clip.__init__(self, text, tempfile, text)
Beispiel #24
0
    async def restget(self, ctx, url):
        """Gets a json response from a rest api and returns it"""
        await ctx.channel.trigger_typing()
        data = await httpgetter.get(url)

        filename = settings.resource("temp/response.json")
        write_json(filename, data)
        await ctx.send(file=discord.File(filename))
        os.remove(filename)
Beispiel #25
0
	def __init__(self, bot):
		MangoCog.__init__(self, bot)
		self.embed_color = discord.Color.teal()
		dotabase = self.bot.get_cog("Dotabase")
		if not dotabase:
			raise ImportError("The Dotabase cog must be added before the DotaStats cog")
		self.dota_game_strings = read_json(settings.resource("json/dota_game_strings.json"))
		self.hero_info = dotabase.get_hero_infos()
		self.lookup_hero = dotabase.lookup_hero
		self.chat_wheel_info = dotabase.get_chat_wheel_infos()
Beispiel #26
0
 def __init__(self, loop):
     self.loop = loop
     self.cache_dir = settings.resource("cache/")
     self.index_file = self.cache_dir + "cache_index.json"
     self.cache = {}
     self.lock = asyncio.Lock(loop=self.loop)
     if os.path.isfile(self.index_file):
         self.cache = read_json(self.index_file)
     for key in default_cache:
         if key not in self.cache:
             self.cache[key] = default_cache[key]
     self.save_cache()
Beispiel #27
0
    async def editclipinfo(self, ctx, clipname, attribute, *, value):
        """Allows editing of a clip's info

		warning: volume actually edits the clip, and is a multiplier (0.5 cuts in half, 2 doubles)

		Example:
		`{cmdpfx}editclipinfo wow text Waow!`"""
        audio = self.bot.get_cog("Audio")
        if clipname not in audio.local_clipinfo:
            raise UserError("That clip doesn't exist")

        attribs = ["text", "author", "source", "start", "end"]

        if value is None or value == "":
            raise UserError("Gotta gimme a value")

        if attribute == "volume":
            filename = settings.resource(
                "clips/" + audio.local_clipinfo[clipname]["path"])
            temp_file = settings.resource(f"temp/temp_{clipname}" +
                                          os.path.splitext(filename)[1])
            run_command([
                "ffmpeg", "-i", filename, "-af", f"volume={value}", temp_file
            ])
            shutil.copyfile(temp_file, filename)
            os.remove(temp_file)
            await self.play_clip(f"local:{clipname}", ctx)
            await ctx.message.add_reaction("✅")
            return

        if attribute not in attribs:
            attribs_string = "\n".join(attribs)
            raise UserError(
                f"Invalid attribute name, try one of these:```\n{attribs_string}\n```"
            )

        audio.local_clipinfo[clipname][attribute] = value
        audio.save_local_clipinfo()
        await ctx.message.add_reaction("✅")
Beispiel #28
0
def draw_poly_label(draw, point, center, text):
	font = ImageFont.truetype(settings.resource("images/arial_unicode_bold.ttf"), 16)
	font_size = font.getsize(text)
	point = list(point)
	if point[0] < center[0]:
		point[0] -= font_size[0]
	if point[1] < center[1]:
		point[1] -= font_size[1]
	if point[0] == center[0]:
		point[0] -= font_size[0] / 2
	if point[1] == center[1]:
		point[1] -= font_size[1] / 2
	draw.text(tuple(point), text, font=font, fill="#ffffff")
Beispiel #29
0
def get_cache_game_mode_patterns():
	global game_mode_patterns
	if not game_mode_patterns:
		patterns = OrderedDict()
		dota_strings = read_json(settings.resource("json/dota_game_strings.json"))
		for key in dota_strings:
			prefix = "game_mode_"
			if prefix not in key:
				continue
			mode_id = int(key.replace(prefix, ""))
			name = dota_strings[key]
			pattern = name.lower()
			patterns[pattern] = mode_id
		game_mode_patterns = patterns
	return game_mode_patterns
Beispiel #30
0
async def draw_hero_talents(hero):
    talents = hero.talents.split("|")
    talent_rows = [[talents[7], talents[6]], [talents[5], talents[4]],
                   [talents[3], talents[2]], [talents[1], talents[0]]]

    image = Image.open(settings.resource("images/talents.png"))
    draw = ImageDraw.Draw(image)

    header_x = 19
    header_y = 17
    header_width = 655
    header_height = 51

    cell = TextCell(hero.localized_name,
                    color="#dddddd",
                    font_size=28,
                    horizontal_align="center")
    cell.render(draw, image, header_x, header_y, header_width, header_height)

    box_width = 306
    box_height = 73
    box_margin_y = 14

    start_y = 70
    start_x_left = 14
    start_x_right = 370
    start_x = [start_x_left, start_x_right]

    for i in range(0, 4):
        for j in range(0, 2):
            x = start_x[j]
            y = start_y + (i * (box_height + box_margin_y))
            text = talent_rows[i][j]

            cell = TextCell(text,
                            color="#cca770",
                            font_size=20,
                            wrap=True,
                            padding=[0, 15, 0, 15],
                            horizontal_align="center")
            cell.render(draw, image, x, y, box_width, box_height)

    fp = BytesIO()
    image.save(fp, format="PNG")
    fp.seek(0)

    return fp