Skip to content

Commit

Permalink
refactor(formaverter): Ran black; update import paths and improve cod…
Browse files Browse the repository at this point in the history
…e formatting

Updated the import paths to reflect the new package structure, changing from 'src' to 'formaverter'. Improved code readability by reformatting long lines and ensuring consistent use of quotes. These changes enhance maintainability and align with Python's PEP 8 style guide. No functional changes were made, so existing functionality should remain unaffected.
  • Loading branch information
Daethyra committed Dec 15, 2024
1 parent d2498e2 commit 9ae9894
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 52 deletions.
28 changes: 20 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import os
import argparse
from typing import List
from src.image_converter import convert_image
from src.image_collector import collect_images
from formaverter.image_converter import convert_image
from formaverter.image_collector import collect_images


def process_images(input_path: str, output_path: str, output_format: str) -> List[str]:
"""
Expand All @@ -30,7 +31,9 @@ def process_images(input_path: str, output_path: str, output_format: str) -> Lis

if os.path.isfile(input_path):
# Single image processing
output_filename = f"{os.path.splitext(os.path.basename(input_path))[0]}.{output_format}"
output_filename = (
f"{os.path.splitext(os.path.basename(input_path))[0]}.{output_format}"
)
output_file_path = os.path.join(output_path, output_filename)
convert_image(input_path, output_file_path, output_format)
if os.path.exists(output_file_path):
Expand All @@ -41,7 +44,9 @@ def process_images(input_path: str, output_path: str, output_format: str) -> Lis
image_files = collect_images(input_path)

for file_path in image_files:
output_filename = f"{os.path.splitext(os.path.basename(file_path))[0]}.{output_format}"
output_filename = (
f"{os.path.splitext(os.path.basename(file_path))[0]}.{output_format}"
)
output_file_path = os.path.join(output_path, output_filename)
try:
convert_image(file_path, output_file_path, output_format)
Expand All @@ -52,15 +57,22 @@ def process_images(input_path: str, output_path: str, output_format: str) -> Lis

return converted_images


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Convert images to a specified format.")
parser = argparse.ArgumentParser(
description="Convert images to a specified format."
)
parser.add_argument("input_path", help="Path to input image or directory")
parser.add_argument("output_path", help="Path to output image or directory")
parser.add_argument("output_format", help="Desired output format (jpg, png, bmp, webp)")
parser.add_argument(
"output_format", help="Desired output format (jpg, png, bmp, webp)"
)
args = parser.parse_args()

try:
converted_files = process_images(args.input_path, args.output_path, args.output_format)
converted_files = process_images(
args.input_path, args.output_path, args.output_format
)
print(f"Successfully converted {len(converted_files)} images.")
except ValueError as e:
print(f"Error: {str(e)}")
print(f"Error: {str(e)}")
2 changes: 1 addition & 1 deletion src/formaverter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .image_converter import convert_image, ImageConverter
from .image_collector import collect_images
from .image_collector import collect_images
12 changes: 9 additions & 3 deletions src/formaverter/image_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import List
from .image_converter import ImageConverter


def collect_images(input_dir: str) -> List[str]:
"""
Collects all supported image files from the input directory.
Expand All @@ -22,12 +23,17 @@ def collect_images(input_dir: str) -> List[str]:
if not os.path.isdir(input_dir):
raise ValueError(f"Input directory does not exist: {input_dir}")

supported_extensions = set(ImageConverter.SUPPORTED_CONVERSIONS.keys()) # {'.jpg', '.jpeg', '.png', '.bmp', '.webp'}
supported_extensions = set(
ImageConverter.SUPPORTED_CONVERSIONS.keys()
) # {'.jpg', '.jpeg', '.png', '.bmp', '.webp'}
image_files = []

for filename in os.listdir(input_dir):
file_path = os.path.join(input_dir, filename)
if os.path.isfile(file_path) and os.path.splitext(filename)[1].lower() in supported_extensions:
if (
os.path.isfile(file_path)
and os.path.splitext(filename)[1].lower() in supported_extensions
):
image_files.append(file_path)

return image_files
return image_files
37 changes: 24 additions & 13 deletions src/formaverter/image_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import os
from PIL import Image


class ImageConverter:
SUPPORTED_CONVERSIONS = {
'.jpg': {'.jpg', '.png', '.bmp', '.webp'},
'.png': {'.jpg', '.png', '.bmp', '.webp'},
'.bmp': {'.jpg', '.png', '.bmp', '.webp'},
'.webp': {'.jpg', '.png', '.bmp', '.webp'}
".jpg": {".jpg", ".png", ".bmp", ".webp"},
".png": {".jpg", ".png", ".bmp", ".webp"},
".bmp": {".jpg", ".png", ".bmp", ".webp"},
".webp": {".jpg", ".png", ".bmp", ".webp"},
}

def __init__(self, input_path: str, output_path: str, output_format: str):
Expand All @@ -37,15 +38,21 @@ def convert(self) -> None:
output_ext = os.path.splitext(self.output_path)[1].lower()

if input_ext not in self.SUPPORTED_CONVERSIONS:
raise ValueError(f"Unsupported input file format: {input_ext}. {self.supported_conversions()}")
raise ValueError(
f"Unsupported input file format: {input_ext}. {self.supported_conversions()}"
)

if output_ext not in self.SUPPORTED_CONVERSIONS[input_ext]:
raise ValueError(f"Unsupported conversion: {input_ext} to {output_ext}. {self.supported_conversions()}")
raise ValueError(
f"Unsupported conversion: {input_ext} to {output_ext}. {self.supported_conversions()}"
)

if input_ext == output_ext:
# If the input and output formats are the same, move the file instead of re-saving it
## self._move_or_error()
print(f"Skipping conversion for {self.input_path} (already in {self.output_format} format)")
print(
f"Skipping conversion for {self.input_path} (already in {self.output_format} format)"
)
return
else:
self._convert_image(input_ext, output_ext)
Expand All @@ -64,7 +71,9 @@ def _move_or_error(self) -> None:
if self.input_path != self.output_path:
os.replace(self.input_path, self.output_path)
else:
raise ValueError(f"Input and output paths are the same: {self.input_path}. Please provide a different output path.")
raise ValueError(
f"Input and output paths are the same: {self.input_path}. Please provide a different output path."
)

@staticmethod
def supported_conversions() -> str:
Expand All @@ -74,11 +83,13 @@ def supported_conversions() -> str:
Returns:
str: A string with the supported file formats and conversions.
"""
return "Supported file formats and conversions:\n" \
"JPEG: can be converted to JPEG, PNG, BMP, WebP\n" \
"PNG: can be converted to JPEG, PNG, BMP, WebP\n" \
"BMP: can be converted to JPEG, PNG, BMP, WebP\n" \
"WebP: can be converted to JPEG, PNG, BMP, WebP"
return (
"Supported file formats and conversions:\n"
"JPEG: can be converted to JPEG, PNG, BMP, WebP\n"
"PNG: can be converted to JPEG, PNG, BMP, WebP\n"
"BMP: can be converted to JPEG, PNG, BMP, WebP\n"
"WebP: can be converted to JPEG, PNG, BMP, WebP"
)


def convert_image(input_path: str, output_path: str, output_format: str) -> None:
Expand Down
19 changes: 12 additions & 7 deletions tests/test_image_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@
import os
import tempfile
import shutil
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')))

sys.path.insert(
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))
)

from formaverter.image_collector import collect_images
from formaverter.image_converter import ImageConverter


class TestImageCollector(unittest.TestCase):

def setUp(self):
# Create a temporary directory
self.test_dir = tempfile.mkdtemp()

# Create some test files
self.valid_images = ['test1.jpg', 'test2.png', 'test3.bmp', 'test4.webp']
self.invalid_files = ['test5.txt', 'test6.pdf', 'test7']
self.valid_images = ["test1.jpg", "test2.png", "test3.bmp", "test4.webp"]
self.invalid_files = ["test5.txt", "test6.pdf", "test7"]

for filename in self.valid_images + self.invalid_files:
open(os.path.join(self.test_dir, filename), 'a').close()
open(os.path.join(self.test_dir, filename), "a").close()

def tearDown(self):
# Remove the directory after the test
Expand All @@ -37,7 +41,7 @@ def test_collect_images(self):
def test_non_existent_directory(self):
# Test if the function raises a ValueError for a non-existent directory
with self.assertRaises(ValueError):
collect_images('/path/to/non/existent/directory')
collect_images("/path/to/non/existent/directory")

def test_empty_directory(self):
# Test if the function returns an empty list for an empty directory
Expand All @@ -54,5 +58,6 @@ def test_supported_extensions(self):
_, ext = os.path.splitext(image)
self.assertIn(ext.lower(), supported_extensions)

if __name__ == '__main__':
unittest.main()

if __name__ == "__main__":
unittest.main()
47 changes: 27 additions & 20 deletions tests/test_image_converter.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,71 @@
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')))

sys.path.insert(
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))
)

import unittest
import tempfile
import shutil
from PIL import Image
from formaverter.image_converter import ImageConverter, convert_image


class TestImageConverter(unittest.TestCase):

def setUp(self):
self.test_dir = tempfile.mkdtemp()
self.input_jpg = os.path.join(self.test_dir, 'test.jpg')
self.output_png = os.path.join(self.test_dir, 'test.png')
self.output_jpg = os.path.join(self.test_dir, 'test_output.jpg')
self.input_jpg = os.path.join(self.test_dir, "test.jpg")
self.output_png = os.path.join(self.test_dir, "test.png")
self.output_jpg = os.path.join(self.test_dir, "test_output.jpg")

# Create a test JPEG image
with Image.new('RGB', (100, 100), color='red') as img:
with Image.new("RGB", (100, 100), color="red") as img:
img.save(self.input_jpg)

def tearDown(self):
shutil.rmtree(self.test_dir)

def test_convert_jpg_to_png(self):
converter = ImageConverter(self.input_jpg, self.output_png, 'png')
converter = ImageConverter(self.input_jpg, self.output_png, "png")
converter.convert()
self.assertTrue(os.path.exists(self.output_png))
with Image.open(self.output_png) as img:
self.assertEqual(img.format, 'PNG')
self.assertEqual(img.format, "PNG")

def test_convert_jpg_to_jpg(self):
converter = ImageConverter(self.input_jpg, self.output_jpg, 'jpg')
converter = ImageConverter(self.input_jpg, self.output_jpg, "jpg")
converter.convert()
self.assertFalse(os.path.exists(self.output_jpg)) # Should not create a new file
self.assertFalse(
os.path.exists(self.output_jpg)
) # Should not create a new file

def test_unsupported_input_format(self):
invalid_input = os.path.join(self.test_dir, 'test.txt')
with open(invalid_input, 'w') as f:
invalid_input = os.path.join(self.test_dir, "test.txt")
with open(invalid_input, "w") as f:
f.write("This is not an image file")
with self.assertRaises(ValueError):
converter = ImageConverter(invalid_input, self.output_png, 'png')
converter = ImageConverter(invalid_input, self.output_png, "png")
converter.convert()

def test_unsupported_conversion(self):
invalid_output = os.path.join(self.test_dir, 'test.gif')
invalid_output = os.path.join(self.test_dir, "test.gif")
with self.assertRaises(ValueError):
converter = ImageConverter(self.input_jpg, invalid_output, 'gif')
converter = ImageConverter(self.input_jpg, invalid_output, "gif")
converter.convert()

def test_same_input_output_format(self):
output_jpg = os.path.join(self.test_dir, 'test_same.jpg')
converter = ImageConverter(self.input_jpg, output_jpg, 'jpg')
output_jpg = os.path.join(self.test_dir, "test_same.jpg")
converter = ImageConverter(self.input_jpg, output_jpg, "jpg")
converter.convert()
self.assertFalse(os.path.exists(output_jpg)) # Should not create a new file

def test_convert_image_function(self):
convert_image(self.input_jpg, self.output_png, 'png')
convert_image(self.input_jpg, self.output_png, "png")
self.assertTrue(os.path.exists(self.output_png))
with Image.open(self.output_png) as img:
self.assertEqual(img.format, 'PNG')
self.assertEqual(img.format, "PNG")

def test_supported_conversions_string(self):
supported_str = ImageConverter.supported_conversions()
Expand All @@ -69,5 +75,6 @@ def test_supported_conversions_string(self):
self.assertIn("BMP", supported_str)
self.assertIn("WebP", supported_str)

if __name__ == '__main__':
unittest.main()

if __name__ == "__main__":
unittest.main()

0 comments on commit 9ae9894

Please sign in to comment.