Skip to content

Commit

Permalink
Merge pull request #20 from SkwalExe/add-ruff
Browse files Browse the repository at this point in the history
Add ruff for linting and formatting
  • Loading branch information
SkwalExe authored Jun 4, 2024
2 parents 9a9713d + 8f5d1d2 commit 84d6c4b
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 98 deletions.
2 changes: 0 additions & 2 deletions .flake8

This file was deleted.

30 changes: 28 additions & 2 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ octologo = "octologo.__main__:main"
[tool.pdm]
distribution = true

[tool.pdm.dev-dependencies]
dev = [
"ruff>=0.4.7",
]

[tool.pdm.scripts]
format = "ruff format"
format-check = "ruff format --check"
lint = "ruff check --fix --show-fixes"
lint-check = "ruff check"
15 changes: 15 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Default formatting rules are pretty good
line-length = 120
[lint]
# Read more here https://beta.ruff.rs/docs/rules/
# By default, Ruff enables Flake8's E and F rules
# Pyflakes - F, pycodestyle - E, W
# flake8-builtins - A
# flake8-annotations - ANN
# flake8-simplify - SIM
# Pylint - PLC, PLE, PLW
# isort - I
select = ['E', 'F', 'W', 'A', 'PLC', 'PLE', 'PLW', 'I', 'SIM', 'ANN']
ignore = [
'ANN101'
]
2 changes: 1 addition & 1 deletion src/octologo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Simple program that generates a logo for your open source projects"""

__version__ = "3.0.0"
__version__ = "3.0.0-dev"
33 changes: 18 additions & 15 deletions src/octologo/__main__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import os
from collections.abc import Generator
from time import time
from octologo.utils import BASE_DIR, style_names, styles, logger
from octologo import __version__
from octologo.wizard import TextQuestion, SelectQuestion, Wizard, inq_ask

from click_extra import ExtraContext, Parameter, extra_command, option
from PIL.Image import Image
from textual.app import App
from textual.widgets import Header, Footer, Label, LoadingIndicator
from textual.validation import Length
from PIL import Image
from textual.events import Key
from click_extra import extra_command, option, ExtraContext, Parameter
from textual.validation import Length
from textual.widgets import Footer, Header, Label, LoadingIndicator

from octologo import __version__
from octologo.utils import BASE_DIR, logger, style_names, styles
from octologo.wizard import SelectQuestion, TextQuestion, Wizard, inq_ask

# from textual import log

Expand All @@ -23,7 +26,7 @@
]


def get_output_filaname(project_name):
def get_output_filaname(project_name: str) -> str:
return f"octologo_{project_name}_{int(time())}.png"


Expand All @@ -38,16 +41,16 @@ class OctoLogoApp(App):
TITLE = "Octo Logo Wizard"
finished: bool = False
save_to: str | None = None
result: Image.Image | None = None
result: Image | None = None
loading_wid: LoadingIndicator = LoadingIndicator(classes="hidden")

async def on_key(self, event: Key):
async def on_key(self, event: Key) -> None:
if event.key == "enter" and self.finished:
await self.action_quit()
elif event.key == "v" and self.finished:
self.result.show()

def on_wizard_finished(self, message: Wizard.Finished):
def on_wizard_finished(self, message: Wizard.Finished) -> None:
# Get the wizard answers and the wizard's id
self.answers.update(message.answers)
finished_wizard_id = message.wizard_id
Expand All @@ -70,7 +73,7 @@ def on_wizard_finished(self, message: Wizard.Finished):
self.set_timer(2, self.final_message)

# Final message
def final_message(self):
def final_message(self) -> None:
self.loading_wid.add_class("hidden")
self.mount(
Label(
Expand All @@ -82,7 +85,7 @@ def final_message(self):
self.result.save(self.save_to)
self.finished = True

def compose(self):
def compose(self) -> Generator:
self.app.title = f"Octo Logo v{__version__}"

yield Header(show_clock=True)
Expand All @@ -95,7 +98,7 @@ def compose(self):
yield self.loading_wid


def disable_ansi(ctx: ExtraContext, param: Parameter, val: bool):
def disable_ansi(ctx: ExtraContext, param: Parameter, val: bool) -> bool:
ctx.color = not val

# We must return the value for the main function no_ansi parameter not to be None
Expand All @@ -106,7 +109,7 @@ def disable_ansi(ctx: ExtraContext, param: Parameter, val: bool):
@option(
"-t", "--no-tui", is_flag=True, help="Dont use the Textual Terminal User Interface"
)
def main(no_tui: bool):
def main(no_tui: bool) -> None:
use_tui = not no_tui

if use_tui:
Expand Down
4 changes: 3 additions & 1 deletion src/octologo/styles/first_letter_underlined.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from PIL.Image import Image

from . import underline_core

display_name = "First letters underlined"
active = True
questions = underline_core.questions


def get_image(answers):
def get_image(answers: dict) -> Image:
return underline_core.get_image(answers)
77 changes: 50 additions & 27 deletions src/octologo/styles/underline_core.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,63 @@
from octologo.wizard import TextQuestion, SelectQuestion
from textual.validation import Number
from octologo.utils import font_list, color_scheme_names, FONTS_DIR, color_schemes, os, get_font_height, get_text_size
from PIL import Image, ImageDraw, ImageFont, ImageColor
import sys

from octologo.utils import (
FONTS_DIR,
color_scheme_names,
color_schemes,
font_list,
get_font_height,
get_text_size,
os,
)
from octologo.wizard import SelectQuestion, TextQuestion
from PIL import Image, ImageColor, ImageDraw, ImageFont
from PIL.Image import Image as ImageClass
from PIL.ImageFont import FreeTypeFont
from textual.validation import Number

sys.path.append("..")


questions = [
SelectQuestion("font", "Select a font", [(font, font) for font in font_list], "Iosevka-Nerd-Font-Complete.ttf"),
SelectQuestion(
"font",
"Select a font",
[(font, font) for font in font_list],
"Iosevka-Nerd-Font-Complete.ttf",
),
SelectQuestion("color", "Select a color scheme", color_scheme_names, "adi1090x"),
TextQuestion("underline_count", "Lettrs to undrline", [Number(minimum=0)], "1", "1"),
TextQuestion(
"underline_count", "Lettrs to undrline", [Number(minimum=0)], "1", "1"
),
TextQuestion("padding_x", "Padding x (px)", [Number()], "200", "200"),
TextQuestion("padding_y", "Padding y (px)", [Number()], "20", "20"),
TextQuestion("gap", "Gap between text and bar (px)", [Number()], "20", "20"),
TextQuestion("bar_size", "Bar weight (px)", [Number()], "20", "20"),
TextQuestion("additionnal_bar_width", "Additionnal bar width (px)", [Number()], "20", "20"),
TextQuestion(
"additionnal_bar_width", "Additionnal bar width (px)", [Number()], "20", "20"
),
]

active = False


def get_image(answers):
def get_image(answers: dict) -> ImageClass:
# Load the selected font
font_size = 500
font = ImageFont.truetype(os.path.join(FONTS_DIR, answers["font"]), font_size)
font: FreeTypeFont = ImageFont.truetype(os.path.join(FONTS_DIR, answers["font"]), font_size)

# Set the colors
background = ImageColor.getrgb(color_schemes[answers['color']]["background"])
text = ImageColor.getrgb(color_schemes[answers['color']]["text"])
accent = ImageColor.getrgb(color_schemes[answers['color']]["accent"])
background = ImageColor.getrgb(color_schemes[answers["color"]]["background"])
text = ImageColor.getrgb(color_schemes[answers["color"]]["text"])
accent = ImageColor.getrgb(color_schemes[answers["color"]]["accent"])

# Get the width and height of the texts
text_width, text_height = get_text_size(answers['name'], font)
text_width, text_height = get_text_size(answers["name"], font)
font_height = get_font_height(font)

# Get the correct image width and height
image_width = 2 * int(answers['padding_x']) + text_width
image_height = 2 * int(answers['padding_y']) + font_height
image_width = 2 * int(answers["padding_x"]) + text_width
image_height = 2 * int(answers["padding_y"]) + font_height

# Create the image
image = Image.new("RGB", (image_width, image_height), background)
Expand All @@ -46,39 +66,42 @@ def get_image(answers):
# Get the text anchor type and position on the image (where the text will be drawn)
# LM = Left/Middle
anchor_type = "lm"
anchor_x = int(answers['padding_x'])
anchor_y = image_height / 2 - (int(answers['gap']) + int(answers['bar_size'])) / 2
anchor_x = int(answers["padding_x"])
anchor_y = image_height / 2 - (int(answers["gap"]) + int(answers["bar_size"])) / 2

anchor_pos = (anchor_x, anchor_y)

if int(answers['underline_count']) > 0:
if int(answers["underline_count"]) > 0:
# Get the bbox of the first n letter to underline
first_letters_bbox = draw.textbbox(
anchor_pos,
answers['name'][:int(answers['underline_count'])],
answers["name"][: int(answers["underline_count"])],
font=font,
anchor=anchor_type)
anchor=anchor_type,
)

# Get the underline position
underline_start_x = first_letters_bbox[0] - int(answers['additionnal_bar_width'])
underline_start_y = first_letters_bbox[3] + int(answers['gap'])
underline_start_x = first_letters_bbox[0] - int(
answers["additionnal_bar_width"]
)
underline_start_y = first_letters_bbox[3] + int(answers["gap"])

underline_end_x = int(answers['additionnal_bar_width']) + first_letters_bbox[2]
underline_end_x = int(answers["additionnal_bar_width"]) + first_letters_bbox[2]

underline_end_y = underline_start_y + int(answers['bar_size'])
underline_end_y = underline_start_y + int(answers["bar_size"])

underline_start = (underline_start_x, underline_start_y)
underline_end = (underline_end_x, underline_end_y)

underline_pos = [underline_start, underline_end]

# Underline the first letter
draw.rectangle(underline_pos, fill=accent, width=answers['bar_size'])
draw.rectangle(underline_pos, fill=accent, width=answers["bar_size"])

# Draw the text
draw.text(
anchor_pos,
answers['name'],
answers["name"],
font=font,
fill=text,
anchor=anchor_type,
Expand All @@ -87,7 +110,7 @@ def get_image(answers):
# Redraw the first letter
draw.text(
anchor_pos,
answers['name'][0],
answers["name"][0],
font=font,
fill=accent,
anchor=anchor_type,
Expand Down
Loading

0 comments on commit 84d6c4b

Please sign in to comment.