[RSS] An overengineered color related addition

This commit is contained in:
aikaterna
2020-09-21 21:47:52 -04:00
parent b1b5b75336
commit 263a4e3c1a
3 changed files with 119 additions and 13 deletions

84
rss/color.py Normal file
View File

@@ -0,0 +1,84 @@
import discord
from scipy.spatial import KDTree
import webcolors
class Color:
"""Helper for color handling."""
@staticmethod
async def _color_converter(hex_code_or_color_word: str):
"""
Used for user input on rss embed color
Input: discord.Color name, CSS3 color name, 0xFFFFFF, #FFFFFF, FFFFFF
Output: 0xFFFFFF
"""
# #FFFFFF to 0xFFFFFF
hex_code = hex_code_or_color_word.replace("#", "0x")
# FFFFFF to 0xFFFFFF
# 0xFFFFFF checking
try:
int(hex_code, 16)
if hex_code[:2] != "0x":
if len(hex_code) == 6:
hex_code = f"0x{hex_code}"
except ValueError:
pass
# discord.Color checking
if hasattr(discord.Color, hex_code_or_color_word):
hex_code = str(getattr(discord.Color, hex_code_or_color_word)())
hex_code = hex_code.replace("#", "0x")
return hex_code
# CSS3 color name checking
try:
hex_code = webcolors.name_to_hex(hex_code_or_color_word, spec="css3")
hex_code = hex_code.replace("#", "0x")
return hex_code
except ValueError:
pass
return hex_code
async def _hex_to_css3_name(self, hex_code: str):
"""
Input: 0xFFFFFF
Output: CSS3 color name string closest match
"""
hex_code = await self._hex_validator(hex_code)
rgb_tuple = await self._hex_to_rgb(hex_code)
names = []
positions = []
for hex, name in webcolors.css3_hex_to_names.items():
names.append(name)
positions.append(webcolors.hex_to_rgb(hex))
spacedb = KDTree(positions)
dist, index = spacedb.query(rgb_tuple)
return names[index]
async def _hex_to_rgb(self, hex_code: str):
"""
Input: 0xFFFFFF
Output: (255, 255, 255)
"""
return webcolors.hex_to_rgb(hex_code)
async def _hex_validator(self, hex_code: str):
"""
Input: 0xFFFFFF
Output: #FFFFFF or None
"""
if hex_code[:2] == "0x":
hex_code = hex_code.replace("0x", "#")
try:
# just a check to make sure it's a real color hex code
hex_code = webcolors.normalize_hex(hex_code)
except ValueError:
hex_code = None
return hex_code

View File

@@ -5,6 +5,6 @@
"description": "Read RSS feeds",
"tags": ["rss"],
"permissions": ["embed_links"],
"requirements": ["feedparser>=6.0.0", "bs4"],
"requirements": ["bs4", "feedparser>=6.0.0", "scipy", "webcolors==1.3"],
"min_bot_version" : "3.4.0"
}

View File

@@ -17,6 +17,7 @@ from urllib.parse import urlparse
from redbot.core import checks, commands, Config
from redbot.core.utils.chat_formatting import bold, box, escape, pagify
from .color import Color
from .quiet_template import QuietTemplate
from .rss_feed import RssFeed
from .tag_type import INTERNAL_TAGS, VALID_IMAGES, TagType
@@ -24,7 +25,7 @@ from .tag_type import INTERNAL_TAGS, VALID_IMAGES, TagType
log = logging.getLogger("red.aikaterna.rss")
__version__ = "1.1.0"
__version__ = "1.1.1"
class RSS(commands.Cog):
@@ -343,12 +344,13 @@ class RSS(commands.Cog):
pass
@_rss_embed.command(name="color", aliases=["colour"])
async def _rss_embed_color(self, ctx, feed_name: str, *, color: discord.Color = None):
async def _rss_embed_color(self, ctx, feed_name: str, *, color: str):
"""
Set an embed color for a feed.
Use this command with no color to reset to the default.
`color` must be a hex code like #990000 or a [Discord color name](https://discordpy.readthedocs.io/en/latest/api.html#colour)
`color` must be a hex code like #990000, a [Discord color name](https://discordpy.readthedocs.io/en/latest/api.html#colour),
or a [CSS3 color name](https://www.w3.org/TR/2018/REC-css-color-3-20180619/#svg-color).
"""
rss_feed = await self.config.channel(ctx.channel).feeds.get_raw(feed_name, default=None)
if not rss_feed:
@@ -370,13 +372,23 @@ class RSS(commands.Cog):
f"{embed_state_message}The color for {bold(feed_name)} has been reset. "
"Use this command with a color argument to set a color for this feed."
)
return
async with self.config.channel(ctx.channel).feeds() as feed_data:
feed_data[feed_name]["embed_color"] = f"0x{str(color).lstrip('#')}"
color = color.replace(" ", "_")
hex_code = await Color()._color_converter(color)
user_facing_hex = hex_code.replace("0x", "#")
color_name = await Color()._hex_to_css3_name(hex_code)
await ctx.send(f"Embed color for {bold(feed_name)} set to {str(color)}.")
# 0xFFFFFF actually doesn't show up as white in an embed
# so let's make it close enough to count
if hex_code == "0xFFFFFF":
hex_code = "0xFFFFFE"
async with self.config.channel(ctx.channel).feeds() as feed_data:
# data is always a 0xFFFFFF style value
feed_data[feed_name]["embed_color"] = hex_code
await ctx.send(f"Embed color for {bold(feed_name)} set to {user_facing_hex} ({color_name}).")
@_rss_embed.command(name="image")
async def _rss_embed_image(self, ctx, feed_name: str, image_tag_name: str = None):
@@ -563,21 +575,31 @@ class RSS(commands.Cog):
return
space = "\N{SPACE}"
embed_toggle = "[ ] Embed off" if not rss_feed["embed"] else "[X] Embed on"
embed_toggle = f"[ ] Embed:{space*16}Off" if not rss_feed["embed"] else f"[X] Embed:{space*16}On"
embed_image = (
"[ ] Embed image off"
f"[ ] Embed image tag:{space*6}None"
if not rss_feed["embed_image"]
else f"[X] Embed image tag:{space*6}${rss_feed['embed_image']}"
)
embed_thumbnail = (
"[ ] Embed thumbnail off"
f"[ ] Embed thumbnail tag:{space*2}None"
if not rss_feed["embed_thumbnail"]
else f"[X] Embed thumbnail tag:{space*2}${rss_feed['embed_thumbnail']}"
)
hex_color = rss_feed.get("embed_color", None)
if hex_color:
color_name = await Color()._hex_to_css3_name(hex_color)
hex_color = hex_color.lstrip("0x")
embed_color = (
f"[ ] Embed hex color:{space*6}None"
if not hex_color
else f"[X] Embed hex color:{space*6}{hex_color} ({color_name})"
)
template_info = f"{embed_toggle}\n{embed_image}\n{embed_thumbnail}"
embed_settings = f"{embed_toggle}\n{embed_color}\n{embed_image}\n{embed_thumbnail}"
rss_template = rss_feed["template"].replace("\n", "\\n").replace("\t", "\\t")
await ctx.send(f"Template for {bold(feed_name)}:\n\n`{rss_template}`\n{box(template_info, lang='ini')}")
await ctx.send(f"Template for {bold(feed_name)}:\n\n`{rss_template}`\n{box(embed_settings, lang='ini')}")
@rss.command(name="template")
async def _rss_template(self, ctx, feed_name: str, *, template: str):