Compare commits

...

2 Commits

Author SHA1 Message Date
Simon Bruder bcfa304862
cbz2ebook: Replace with python implementation
It has multiple advantages:

 * It processes the images in memory, without writing intermediary files
 * It supports multithreading
 * It does not spawn an army of subprocesses
 * It shows a better progress bar
 * It is more robust
2021-07-11 11:12:28 +02:00
Simon Bruder 1cb0ab9cf9
Switch to cached-nix-shell 2021-07-11 11:12:28 +02:00
11 changed files with 87 additions and 54 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.tqdm ])" mkvtoolnix-cli
from subprocess import run
from tqdm import tqdm

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p python3 ffmpeg-full
from subprocess import run
import mimetypes

78
cbz2ebook.py Executable file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p python3 python3Packages.pillow python3Packages.tqdm
from PIL import Image
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
from zipfile import ZipFile
import argparse
def should_scale(in_width, in_height, out_width, out_height):
return not (
(in_width == out_width and in_height <= out_height)
or (in_height == out_height and in_width <= out_width)
)
def scaled_size(in_width, in_height, out_width, out_height):
in_aspect_ratio = float(in_width) / float(in_height)
out_aspect_ratio = float(out_width) / float(out_height)
if in_aspect_ratio > out_aspect_ratio:
height = out_width / in_aspect_ratio
width = out_width
else:
width = out_height * in_aspect_ratio
height = out_height
return int(round(width)), round(int(height))
def process_image(im):
# double pages (wider than high) should be rotated
if im.width > im.height:
im = im.transpose(Image.ROTATE_90)
# convert to greyscale
im = im.convert("L")
# resize if necessary
if should_scale(im.width, im.height, args.width, args.height):
im = im.resize(
scaled_size(im.width, im.height, args.width, args.height),
resample=Image.LANCZOS,
)
return im
parser = argparse.ArgumentParser()
parser.add_argument("infile")
parser.add_argument("outfile")
parser.add_argument("-W", "--width", default=1440)
parser.add_argument("-H", "--height", default=1920)
parser.add_argument("-s", "--singlethreaded", action="store_true")
args = parser.parse_args()
srczip = ZipFile(args.infile)
dstzip = ZipFile(args.outfile, "x")
srcfiles = sorted(
map(lambda zi: zi.filename, filter(lambda zi: not zi.is_dir(), srczip.infolist(),),)
)
executor = ThreadPoolExecutor()
if args.singlethreaded:
mapper = map
else:
mapper = executor.map
for idx, im in enumerate(
tqdm(
mapper(process_image, map(Image.open, map(srczip.open, srcfiles)),),
total=len(srcfiles),
)
):
with dstzip.open(f"{idx+1:04d}.jpg", "w") as outpagefile:
im.save(outpagefile, format="JPEG", quality=92)

View File

@ -1,45 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i zsh -p imagemagick unzip zip zsh
set -e
size="1440x1920" # Kobo Forma
#size="768x1024" # Amazon Kindle Paperwhite
vertical_size="$(cut -dx -f2 <<< $size)x$(cut -dx -f1 <<< $size)"
infile="$(realpath $1)"
outfile="$(realpath $2)"
tmpdir=$(mktemp -d)
function cleanup {
rm -rf "$tmpdir"
}
trap cleanup EXIT INT SIGTERM
cd "$tmpdir"
unzip "$infile"
# rename files to have a plain 4 digit filename
i=1
for file in **/*.???; do
mv -n "$file" "$(dirname $file)/$(printf %04d $i).${file##*.}"
i=$((i+1))
done
length=$(ls -1 **/*.??? | wc -l)
position=0
for image in **/*.???; do
width=$(identify -format "%W" "$image")
height=$(identify -format "%H" "$image")
if (($width > $height)); then
mogrify -resize "$vertical_size" -rotate 270 "$image"
else
mogrify -resize "$size" "$image"
fi
position=$(($position + 1))
echo -ne "$(printf '%3s' $((100 * $position / $length))) % "$(printf "%0*d" "$((72 * $position / $length))" 0 | tr '0' '#')'\r'
done
echo
zip "$outfile" **/*.???
cd -

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i bash -p sidplayfp ffmpeg-full
# Creates 4-channel flac file to be played with mpv profile “musicvideo-c64”
# Set HVSC_BASE to point to your HVSC directory, otherwise the output

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p python3
import sys
import subprocess

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.pyyaml ])"
# Set Huion H430P parameters from saved profiles using swaymsg
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ ps.flask ps.requests ])"
from flask import Flask, redirect
import requests

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p python3
# I want to use Anki instead of Quizlet. However, Quizlet only provides a very
# limited “export” functionality, that exports something like csv, but does not

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ ps.pandas ps.numpy ps.tabulate ])"
import pandas as pd
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!/usr/bin/env cached-nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.paho-mqtt ])"
import sys
import paho.mqtt.client as mqtt