fix docker implementation

This commit is contained in:
2025-07-20 18:28:26 +00:00
parent 5185f2d9fd
commit a5bf821186
12 changed files with 112 additions and 77 deletions

View File

@@ -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

View File

@@ -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
View File

@@ -1,6 +1,5 @@
*.env
__pycache__/
.venv
*.env
image.jpg
processed.png
interface/
__pycache__/

View File

@@ -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"]

View File

@@ -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).
![Picture of e-ink screen](https://gitea.bubbletea.dev/shibao/szuru-eink-bot/raw/branch/master/eink-screen.jpg)
![Picture of e-ink
screen](https://gitea.bubbletea.dev/shibao/szuru-eink-bot/raw/branch/master/eink-screen.jpg)
## 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).

View File

@@ -1,4 +0,0 @@
#!/bin/bash
# Run the Python script using uv
uv run /app/szuru-eink.py

View File

@@ -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

View File

@@ -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
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
set -ou pipefail
crontab ./crontab && crond -f

View File

@@ -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]

View File

@@ -6,10 +6,10 @@ import random
import requests
import os
import pyszuru
from dotenv import load_dotenv
from PIL import Image
load_dotenv()
from epd.epd_config import palArr, epdArr, EPD_TYPES
from epd.image_processor import getErr, getNear, addVal, procImg

82
uv.lock generated
View File

@@ -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"