Compare commits
	
		
			2 Commits
		
	
	
		
			804b8a637b
			...
			7699bdd305
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7699bdd305 | |||
| a5bf821186 | 
@@ -1,6 +1,11 @@
 | 
			
		||||
*.env
 | 
			
		||||
__pycache__/
 | 
			
		||||
.gitignore
 | 
			
		||||
.tool-versions
 | 
			
		||||
.venv
 | 
			
		||||
*.env
 | 
			
		||||
docker-compose.yml
 | 
			
		||||
Dockerfile
 | 
			
		||||
eink-screen.jpg
 | 
			
		||||
image.jpg
 | 
			
		||||
processed.png
 | 
			
		||||
interface/
 | 
			
		||||
__pycache__/
 | 
			
		||||
README.md
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
SZURU_URL=YOUR_SZURU_URL
 | 
			
		||||
SZURU_USER=YOUR_SZURU_USER
 | 
			
		||||
SZURU_TOKEN=YOUR_SZURU_TOKEN
 | 
			
		||||
EPD_TYPE=YOUR_EPD_TYPE # e.g., 7.5b V2, 5.65f
 | 
			
		||||
EINK_IP=YOUR_EINK_IP
 | 
			
		||||
DITHERING_MODE=YOUR_DITHERING_MODE # e.g., mono, color
 | 
			
		||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,5 @@
 | 
			
		||||
*.env
 | 
			
		||||
__pycache__/
 | 
			
		||||
.venv
 | 
			
		||||
*.env
 | 
			
		||||
image.jpg
 | 
			
		||||
processed.png
 | 
			
		||||
interface/
 | 
			
		||||
__pycache__/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,28 +1,9 @@
 | 
			
		||||
# Use a lightweight Python base image
 | 
			
		||||
FROM python:3.13-slim-bookworm
 | 
			
		||||
FROM python:3.11.5-alpine
 | 
			
		||||
 | 
			
		||||
# Set the working directory in the container
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
RUN pip install uv
 | 
			
		||||
COPY . .
 | 
			
		||||
RUN uv sync
 | 
			
		||||
RUN chmod +x entrypoint.sh
 | 
			
		||||
 | 
			
		||||
# Install uv and dependencies
 | 
			
		||||
COPY pyproject.toml ./
 | 
			
		||||
RUN apt-get update && apt-get install -y cron \
 | 
			
		||||
    && rm -rf /var/lib/apt/lists/*
 | 
			
		||||
RUN pip install uv && uv sync
 | 
			
		||||
 | 
			
		||||
# Copy the application code
 | 
			
		||||
COPY szuru-eink.py ./
 | 
			
		||||
COPY epd/ ./epd/
 | 
			
		||||
 | 
			
		||||
# Copy the cron job script and crontab file
 | 
			
		||||
COPY cron_job.sh /usr/local/bin/cron_job.sh
 | 
			
		||||
COPY crontab /etc/cron.d/szuru-eink-cron
 | 
			
		||||
 | 
			
		||||
# Give execution rights on the cron job script
 | 
			
		||||
RUN chmod +x /usr/local/bin/cron_job.sh
 | 
			
		||||
 | 
			
		||||
# Apply cron job
 | 
			
		||||
RUN crontab /etc/cron.d/szuru-eink-cron
 | 
			
		||||
 | 
			
		||||
# Run cron
 | 
			
		||||
CMD ["cron", "-f"]
 | 
			
		||||
ENTRYPOINT ["./entrypoint.sh"]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								README.md
									
									
									
									
									
								
							@@ -5,14 +5,15 @@ for e-ink displays, and uploads them to a e-ink screens running on the
 | 
			
		||||
[Waveshare E-Paper ESP32 Driver
 | 
			
		||||
Board](https://www.waveshare.com/wiki/E-Paper_ESP32_Driver_Board).
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
- Fetches random images from a configurable Szurubooru instance.
 | 
			
		||||
- Resizes and dithered images for e-ink display compatibility.
 | 
			
		||||
- Supports monochrome and color dithering (for compatible displays).
 | 
			
		||||
- Uploads processed images to a Waveshare 7.5b V2 e-ink screen.
 | 
			
		||||
- Uploads processed images to a Waveshare e-ink screen.
 | 
			
		||||
- Configurable via environment variables.
 | 
			
		||||
- Designed to run as a Docker container on a cron job.
 | 
			
		||||
 | 
			
		||||
@@ -35,9 +36,8 @@ cd szuru-eink
 | 
			
		||||
 | 
			
		||||
### 2. Configure Environment Variables
 | 
			
		||||
 | 
			
		||||
Create a `.env` file in the root directory of the project (if it doesn't exist)
 | 
			
		||||
and populate it with your Szurubooru API details and e-ink screen configuration.
 | 
			
		||||
You can use the `.env.sample` as a reference for the required variables.
 | 
			
		||||
Modify `docker-compose.yml` with the environment variables specified for your
 | 
			
		||||
display.
 | 
			
		||||
 | 
			
		||||
**Note:** For `EPD_TYPE`, refer to the `epd/epd_config.py` file for a full list
 | 
			
		||||
of supported display types and their corresponding string labels. For color
 | 
			
		||||
@@ -55,32 +55,24 @@ docker-compose up --build -d
 | 
			
		||||
This command will:
 | 
			
		||||
- Build the Docker image based on the `Dockerfile`.
 | 
			
		||||
- Create and start a Docker container named `szuru-eink-bot`.
 | 
			
		||||
- Copy the environment variables from your `.env` file to `docker-compose.yml`
 | 
			
		||||
  for the container.
 | 
			
		||||
- Configure the environment variables in `docker-compose.yml` for the container.
 | 
			
		||||
- Set up a cron job inside the container to run the `szuru-eink.py` script at a
 | 
			
		||||
  specified interval (default: every 15 minutes).
 | 
			
		||||
- Create a bind mount for logs in `./logs` directory on your host machine.
 | 
			
		||||
 | 
			
		||||
### 4. Verify Logs
 | 
			
		||||
 | 
			
		||||
You can check the logs generated by the cron job in the
 | 
			
		||||
`./logs/szuru-eink-cron.log` file on your host machine.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
tail -f logs/szuru-eink-cron.log
 | 
			
		||||
```
 | 
			
		||||
You can check the logs by doing `docker-compose logs -f szuru-eink-bot`.
 | 
			
		||||
 | 
			
		||||
## Project Structure
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
.dockerignore
 | 
			
		||||
.env
 | 
			
		||||
.gitignore
 | 
			
		||||
.tool-versions
 | 
			
		||||
Dockerfile
 | 
			
		||||
README.md
 | 
			
		||||
crontab
 | 
			
		||||
cron_job.sh
 | 
			
		||||
entrypoint.sh
 | 
			
		||||
docker-compose.yml
 | 
			
		||||
epd/
 | 
			
		||||
├── epd_config.py
 | 
			
		||||
@@ -94,7 +86,6 @@ szuru-eink.py
 | 
			
		||||
 | 
			
		||||
- `uv` (for dependency management)
 | 
			
		||||
- `Pillow` (for image processing)
 | 
			
		||||
- `python-dotenv` (for loading environment variables in local testing)
 | 
			
		||||
- `pyszuru` (for interacting with Szurubooru API)
 | 
			
		||||
- `requests` (for HTTP requests)
 | 
			
		||||
- `black` (development dependency for code formatting)
 | 
			
		||||
@@ -110,8 +101,16 @@ is not guaranteed without further testing and potential adjustments to
 | 
			
		||||
 | 
			
		||||
### Driver Board and Flashing
 | 
			
		||||
 | 
			
		||||
The e-ink screen used in this project is driven by the [Waveshare E-Paper ESP32 Driver Board](https://www.waveshare.com/wiki/E-Paper_ESP32_Driver_Board). The board was flashed with the sample `Loader_esp32wf` project provided by Waveshare, which exposes the web interface that this Python script interacts with.
 | 
			
		||||
The e-ink screen used in this project is driven by the [Waveshare E-Paper ESP32
 | 
			
		||||
Driver Board](https://www.waveshare.com/wiki/E-Paper_ESP32_Driver_Board). The
 | 
			
		||||
board was flashed with the sample `Loader_esp32wf` project provided by
 | 
			
		||||
Waveshare, which exposes the web interface that this Python script interacts
 | 
			
		||||
with.
 | 
			
		||||
 | 
			
		||||
### 3D Printed Casing
 | 
			
		||||
 | 
			
		||||
The 3D printed casing for the e-ink screen shown in the preview image was sourced from [lmarzen/esp32-weather-epd](https://github.com/lmarzen/esp32-weather-epd). I covered it in walnut because I like walnut, sourced from [Amazon](https://www.amazon.com/dp/B08SVQBVJN).
 | 
			
		||||
The 3D printed casing for the e-ink screen shown in the preview image was
 | 
			
		||||
sourced from
 | 
			
		||||
[lmarzen/esp32-weather-epd](https://github.com/lmarzen/esp32-weather-epd). I
 | 
			
		||||
covered it in walnut because I like walnut, sourced from
 | 
			
		||||
[Amazon](https://www.amazon.com/dp/B08SVQBVJN).
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Run the Python script using uv
 | 
			
		||||
uv run /app/szuru-eink.py
 | 
			
		||||
							
								
								
									
										2
									
								
								crontab
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								crontab
									
									
									
									
									
								
							@@ -1 +1 @@
 | 
			
		||||
*/15 * * * * root /usr/local/bin/cron_job.sh >> /var/log/szuru-eink-cron.log 2>&1
 | 
			
		||||
*/15 * * * * /usr/local/bin/uv run --project /app /app/szuru-eink.py >/proc/1/fd/1 2>&1
 | 
			
		||||
 
 | 
			
		||||
@@ -11,5 +11,3 @@ services:
 | 
			
		||||
      - EPD_TYPE=YOUR_EPD_TYPE # e.g., '7.5 V2', 5.65f
 | 
			
		||||
      - EINK_IP=YOUR_EINK_IP
 | 
			
		||||
      - DITHERING_MODE=YOUR_DITHERING_MODE # e.g., mono, color
 | 
			
		||||
    volumes:
 | 
			
		||||
      - ./logs:/var/log'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								entrypoint.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								entrypoint.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
set -ou pipefail
 | 
			
		||||
 | 
			
		||||
crontab ./crontab && crond -f
 | 
			
		||||
@@ -9,7 +9,6 @@ dependencies = [
 | 
			
		||||
    "pyszuru==0.3.1",
 | 
			
		||||
    "Requests==2.31.0",
 | 
			
		||||
    "Pillow==11.3.0",
 | 
			
		||||
    "python-dotenv==1.1.1",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[project.optional-dependencies]
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,8 @@ import random
 | 
			
		||||
import requests
 | 
			
		||||
import os
 | 
			
		||||
import pyszuru
 | 
			
		||||
from dotenv import load_dotenv
 | 
			
		||||
from PIL import Image
 | 
			
		||||
from PIL import Image, ImageSequence, UnidentifiedImageError
 | 
			
		||||
 | 
			
		||||
load_dotenv()
 | 
			
		||||
 | 
			
		||||
from epd.epd_config import palArr, epdArr, EPD_TYPES
 | 
			
		||||
from epd.image_processor import getErr, getNear, addVal, procImg
 | 
			
		||||
@@ -29,7 +27,7 @@ highest_post = next(booru.search_post("sort:id type:image", page_size=1))
 | 
			
		||||
 | 
			
		||||
post = None
 | 
			
		||||
while post is None:
 | 
			
		||||
    random_id = random.randint(0, highest_post.id_)
 | 
			
		||||
    random_id = 10455  # For testing, always use ID=10455 which is a gif
 | 
			
		||||
    temp_post = booru.getPost(random_id)
 | 
			
		||||
    if temp_post and temp_post.mime.startswith("image/") and temp_post.content:
 | 
			
		||||
        post = temp_post
 | 
			
		||||
@@ -57,7 +55,7 @@ while not image_downloaded:
 | 
			
		||||
        img.close()
 | 
			
		||||
        image_downloaded = True
 | 
			
		||||
        print("[DEBUG] Image successfully verified.")
 | 
			
		||||
    except (PIL.UnidentifiedImageError, requests.exceptions.RequestException) as e:
 | 
			
		||||
    except (UnidentifiedImageError, requests.exceptions.RequestException) as e:
 | 
			
		||||
        print(
 | 
			
		||||
            f"[ERROR] Failed to process downloaded file (Error: {e}). Retrying with a new post..."
 | 
			
		||||
        )
 | 
			
		||||
@@ -67,7 +65,7 @@ while not image_downloaded:
 | 
			
		||||
        # Find a new post
 | 
			
		||||
        post = None
 | 
			
		||||
        while post is None:
 | 
			
		||||
            random_id = random.randint(0, highest_post.id_)
 | 
			
		||||
            random_id = 10455  # For testing, always use ID=10455 which is a gif
 | 
			
		||||
            temp_post = booru.getPost(random_id)
 | 
			
		||||
            if temp_post and temp_post.mime.startswith("image/") and temp_post.content:
 | 
			
		||||
                post = temp_post
 | 
			
		||||
@@ -81,6 +79,13 @@ while not image_downloaded:
 | 
			
		||||
 | 
			
		||||
    # Process and upload
 | 
			
		||||
    img = Image.open("image.jpg")
 | 
			
		||||
    if post.mime == "image/gif":
 | 
			
		||||
        # Seek to a random frame
 | 
			
		||||
        random_frame_index = random.randint(0, img.n_frames - 1)
 | 
			
		||||
        print(f"[DEBUG] Detected GIF, selecting frame: {random_frame_index}")
 | 
			
		||||
        img.seek(random_frame_index)
 | 
			
		||||
        # Convert the frame to an RGB image to discard GIF palette and alpha for processing
 | 
			
		||||
        img = img.convert("RGB")
 | 
			
		||||
 | 
			
		||||
# Get configuration from environment variables
 | 
			
		||||
try:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										82
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										82
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							@@ -112,6 +112,22 @@ wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/4a/45/ec96b29162a402fc4c1c5512d114d7b3787b9d1c2ec241d9568b4816ee23/base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2", size = 5621, upload-time = "2021-10-30T22:12:16.658Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "black"
 | 
			
		||||
version = "24.4.2"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
dependencies = [
 | 
			
		||||
    { name = "click" },
 | 
			
		||||
    { name = "mypy-extensions" },
 | 
			
		||||
    { name = "packaging" },
 | 
			
		||||
    { name = "pathspec" },
 | 
			
		||||
    { name = "platformdirs" },
 | 
			
		||||
]
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/47/c9997eb470a7f48f7aaddd3d9a828244a2e4199569e38128715c48059ac1/black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d", size = 642299, upload-time = "2024-04-26T00:32:15.305Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/0f/89/294c9a6b6c75a08da55e9d05321d0707e9418735e3062b12ef0f54c33474/black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c", size = 205925, upload-time = "2024-04-26T00:32:12.495Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "certifi"
 | 
			
		||||
version = "2025.7.14"
 | 
			
		||||
@@ -143,6 +159,18 @@ wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "click"
 | 
			
		||||
version = "8.2.1"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
dependencies = [
 | 
			
		||||
    { name = "colorama", marker = "sys_platform == 'win32'" },
 | 
			
		||||
]
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "colorama"
 | 
			
		||||
version = "0.4.6"
 | 
			
		||||
@@ -278,6 +306,15 @@ wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a", size = 12313, upload-time = "2025-06-30T15:53:45.437Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "mypy-extensions"
 | 
			
		||||
version = "1.1.0"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "netaddr"
 | 
			
		||||
version = "1.3.0"
 | 
			
		||||
@@ -287,6 +324,24 @@ wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/12/cc/f4fe2c7ce68b92cbf5b2d379ca366e1edae38cccaad00f69f529b460c3ef/netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe", size = 2262023, upload-time = "2024-05-28T21:30:34.191Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "packaging"
 | 
			
		||||
version = "25.0"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "pathspec"
 | 
			
		||||
version = "0.12.1"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "pillow"
 | 
			
		||||
version = "11.3.0"
 | 
			
		||||
@@ -320,6 +375,15 @@ wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "platformdirs"
 | 
			
		||||
version = "4.3.8"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "propcache"
 | 
			
		||||
version = "0.3.2"
 | 
			
		||||
@@ -439,15 +503,6 @@ version = "1.2.2"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/33/d0/9297d7d8dd74767b4d5560d834b30b2fff17d39987c23ed8656f476e0d9b/python-baseconv-1.2.2.tar.gz", hash = "sha256:0539f8bd0464013b05ad62e0a1673f0ac9086c76b43ebf9f833053527cd9931b", size = 4929, upload-time = "2019-04-04T19:28:57.17Z" }
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "python-dotenv"
 | 
			
		||||
version = "1.1.1"
 | 
			
		||||
source = { registry = "https://pypi.org/simple" }
 | 
			
		||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" }
 | 
			
		||||
wheels = [
 | 
			
		||||
    { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "requests"
 | 
			
		||||
version = "2.31.0"
 | 
			
		||||
@@ -489,18 +544,23 @@ dependencies = [
 | 
			
		||||
    { name = "aioipfs" },
 | 
			
		||||
    { name = "pillow" },
 | 
			
		||||
    { name = "pyszuru" },
 | 
			
		||||
    { name = "python-dotenv" },
 | 
			
		||||
    { name = "requests" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[package.optional-dependencies]
 | 
			
		||||
dev = [
 | 
			
		||||
    { name = "black" },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[package.metadata]
 | 
			
		||||
requires-dist = [
 | 
			
		||||
    { name = "aioipfs", specifier = "==0.6.5" },
 | 
			
		||||
    { name = "black", marker = "extra == 'dev'", specifier = "==24.4.2" },
 | 
			
		||||
    { name = "pillow", specifier = "==11.3.0" },
 | 
			
		||||
    { name = "pyszuru", specifier = "==0.3.1" },
 | 
			
		||||
    { name = "python-dotenv", specifier = "==1.1.1" },
 | 
			
		||||
    { name = "requests", specifier = "==2.31.0" },
 | 
			
		||||
]
 | 
			
		||||
provides-extras = ["dev"]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "tqdm"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user