152 lines
4 KiB
Python
152 lines
4 KiB
Python
from os import makedirs
|
|
from os.path import isfile, join
|
|
from pathlib import Path
|
|
from random import choice
|
|
from sys import argv
|
|
from urllib.request import urlretrieve
|
|
|
|
from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont
|
|
|
|
zodiac_signs = [
|
|
"Belier",
|
|
"Cancer",
|
|
"Balance",
|
|
"Capricorne",
|
|
"Taureau",
|
|
"Lion",
|
|
"Scorpion",
|
|
"Verseau",
|
|
"Gemeaux",
|
|
"Vierge",
|
|
"Sagittaire",
|
|
"Poissons",
|
|
]
|
|
|
|
|
|
image_dir = join(Path(argv[0]).parent.resolve(), "images")
|
|
|
|
|
|
def generate_horoscope() -> dict[str, dict[str, str]]:
|
|
"""Generate horoscope predictions"""
|
|
horoscope = {}
|
|
for sign in zodiac_signs:
|
|
love = choice(["+++", "++", "+", "-", "- -"])
|
|
work = choice(["+++", "++", "+", "-", "- -"])
|
|
horoscope[sign] = {"love": love, "work": work}
|
|
return horoscope
|
|
|
|
|
|
def get_path(image: str):
|
|
"""Return the path of an image"""
|
|
return join(image_dir, f"{image.lower()}.png")
|
|
|
|
|
|
def get_sign_image(image: str):
|
|
"""Get sign image"""
|
|
sign_image = Image.open(get_path(image)).convert("RGBA")
|
|
|
|
# Add thickness
|
|
alpha = sign_image.split()[3]
|
|
bold_mask = alpha.filter(ImageFilter.MaxFilter())
|
|
sign_image.putalpha(bold_mask)
|
|
|
|
# Add contrast
|
|
enhancer = ImageEnhance.Contrast(sign_image)
|
|
enhanced_image = enhancer.enhance(2.0)
|
|
|
|
enhanced_image.thumbnail((100, 105))
|
|
return enhanced_image
|
|
|
|
|
|
def vertical_text(text: str, font: ImageFont.ImageFont | ImageFont.FreeTypeFont):
|
|
"""Image with vertical text"""
|
|
text_img = Image.new("RGBA", (135, 24), (255, 255, 255, 0))
|
|
|
|
text_draw = ImageDraw.Draw(text_img)
|
|
text_draw.text((0, 0), f"{text:^15}", font=font, fill="black")
|
|
text_draw = text_img.rotate(90, expand=True)
|
|
|
|
return text_draw
|
|
|
|
|
|
def create_horoscope_image(horoscope: dict[str, dict[str, str]]):
|
|
"""Generate horoscope images"""
|
|
img_width, img_height = 1200, 425
|
|
image = Image.new("RGBA", (img_width, img_height), color=(255, 255, 255, 0))
|
|
draw = ImageDraw.Draw(image)
|
|
|
|
size_emoji = (30, 30)
|
|
|
|
font_sign = ImageFont.load_default(24)
|
|
font_prediction = ImageFont.load_default(40)
|
|
|
|
x, y = 10, 10
|
|
for sign, prediction in horoscope.items():
|
|
sign_image = get_sign_image(sign)
|
|
image.paste(sign_image, (x + 20, y), sign_image)
|
|
|
|
# Sign text
|
|
text_draw = vertical_text(sign, font_sign)
|
|
image.paste(text_draw, (x - 10, y - 10), text_draw)
|
|
|
|
# Love prediction
|
|
love = Image.open(join(image_dir, "love.png")).convert("RGBA")
|
|
love.thumbnail(size_emoji)
|
|
image.paste(love, (x + 125, y + 20), love)
|
|
draw.text(
|
|
(x + 160, y + 10),
|
|
prediction["love"],
|
|
fill="black",
|
|
font=font_prediction,
|
|
)
|
|
|
|
# Work prediction
|
|
work = Image.open(join(image_dir, "work.png")).convert("RGBA")
|
|
work.thumbnail(size_emoji)
|
|
image.paste(work, (x + 125, y + 60), work)
|
|
draw.text(
|
|
(x + 160, y + 50),
|
|
prediction["work"],
|
|
fill="black",
|
|
font=font_prediction,
|
|
)
|
|
|
|
x += 320
|
|
if x > 1200:
|
|
x = 10
|
|
y += 150
|
|
|
|
return image
|
|
|
|
|
|
def download_images():
|
|
"""Download images from source"""
|
|
url = "https://git.mylloon.fr/Anri/Horoscope/raw/branch/main/images/"
|
|
|
|
makedirs(image_dir, exist_ok=True)
|
|
for el in zodiac_signs + ["love", "work"]:
|
|
path = get_path(el)
|
|
if not isfile(path):
|
|
image = el.lower() + ".png"
|
|
print(f"Download {image}...")
|
|
urlretrieve(url + image, path)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(argv) > 2 or (len(argv) == 2 and argv[1] != "online"):
|
|
exit(1)
|
|
|
|
if len(argv) == 2:
|
|
print("Fetch missing images...")
|
|
download_images()
|
|
|
|
# Generate new horoscope
|
|
new_horoscope = generate_horoscope()
|
|
|
|
# Create and save the image
|
|
horoscope_image = create_horoscope_image(new_horoscope)
|
|
|
|
png = "nouvel_horoscope.png"
|
|
horoscope_image.save(png)
|
|
|
|
print(f"Nouvel horoscope généré et sauvegardé sous '{png}'")
|