first commit
This commit is contained in:
Executable
+210
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pdf2image import convert_from_path
|
||||
import os
|
||||
import shutil
|
||||
import argparse
|
||||
import threading
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
##################################################
|
||||
# to do:
|
||||
# 1) √ Keep only the SMALLEST file. No need to keep the others
|
||||
# 2) √ Have a concept of "working dir" and "target dir" Use the appropriate one (use tempfile for default working directory)
|
||||
# 3) √ make extraction of PDF into a function
|
||||
# 4) √ ability to skip portions of the program by args
|
||||
# 5) Optimize code - loop things instead of calling them x times
|
||||
# 6) √ Use other image file types (JPG, PNG, etc...)
|
||||
#
|
||||
##################################################
|
||||
|
||||
def zip_jpg(file, image_type):
|
||||
print('Creating ZIP file from images')
|
||||
try:
|
||||
command = f"zip {file}.cbz ./*.{image_type} >/dev/null"
|
||||
os.system(command)
|
||||
except OSError as error:
|
||||
print(f"Command {command} gave the following error: {error}")
|
||||
|
||||
def rar_jpg(file, image_type):
|
||||
print('Creating RAR file from images')
|
||||
try:
|
||||
command = f"rar a {file}.cbr ./*.{image_type} >/dev/null"
|
||||
os.system(command)
|
||||
except OSError as error:
|
||||
print(f"Command {command} gave the following error: {error}")
|
||||
|
||||
def sz_jpg(file, image_type):
|
||||
print('Creating 7z file from images')
|
||||
try:
|
||||
command = f"7z a {file}.cb7 ./*.{image_type} >/dev/null"
|
||||
os.system(command)
|
||||
except OSError as error:
|
||||
print(f"Command {command} gave the following error: {error}")
|
||||
|
||||
def gtar_jpg(file, image_type):
|
||||
print('Creating GZ file from images')
|
||||
try:
|
||||
command = f"tar czfP {file}.gz.cbt ./*.{image_type} >/dev/null"
|
||||
os.system(command)
|
||||
except OSError as error:
|
||||
print(f"Command {command} gave the following error: {error}")
|
||||
|
||||
def btar_jpg(file, image_type):
|
||||
print('Creating BZ file from images')
|
||||
try:
|
||||
command = f"tar cjfP {file}.bz.cbt ./*.{image_type} >/dev/null"
|
||||
os.system(command)
|
||||
except OSError as error:
|
||||
print(f"Command {command} gave the following error: {error}")
|
||||
|
||||
def xtar_jpg(file, image_type):
|
||||
print('Creating XZ file from images')
|
||||
try:
|
||||
command = f"tar cJfP {file}.xz.cbt ./*.{image_type} >/dev/null"
|
||||
os.system(command)
|
||||
except OSError as error:
|
||||
print(f"Command {command} gave the following error: {error}")
|
||||
|
||||
def convert_bytes(num):
|
||||
"""
|
||||
this function will convert bytes to MB.... GB... etc
|
||||
"""
|
||||
for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
|
||||
if num < 1024.0:
|
||||
return "%3.2f %s" % (num, x)
|
||||
num /= 1024.0
|
||||
|
||||
def file_size(file_path):
|
||||
"""
|
||||
this function will return the file size
|
||||
"""
|
||||
if os.path.isfile(file_path):
|
||||
file_info = os.stat(file_path)
|
||||
return file_info.st_size
|
||||
else:
|
||||
return 'File Not found ' + file_path
|
||||
|
||||
def extract_pdf(origin_file, work_dir, image_type):
|
||||
print ("Saving images from PDF to memory")
|
||||
images = convert_from_path(origin_file)
|
||||
num = len(images)
|
||||
|
||||
print (f"Saving {num} images from memory to disk ({image_type.upper()} {work_dir})")
|
||||
for i in range(num):
|
||||
images[i].save(f"{work_dir}/page{i}.{image_type}", image_type)
|
||||
|
||||
def report_save_smallest(type_dict, file, dest_dir):
|
||||
print ("Reporting compressed file sizes")
|
||||
small_size = 0.0
|
||||
small_file = ''
|
||||
for key, value in type_dict.items():
|
||||
now_file = file + value
|
||||
now_size = file_size(now_file)
|
||||
if small_size == 0.0 or now_size < small_size:
|
||||
small_size = now_size
|
||||
small_file = now_file
|
||||
size_str = convert_bytes(now_size)
|
||||
print (f"Size of {key}: {size_str}")
|
||||
print(f"Copying smallest file ({small_file}) to destination ({dest_dir})")
|
||||
shutil.copy2(small_file, dest_dir)
|
||||
|
||||
def clean_work_dir(work_dir, filename, image_extension):
|
||||
for p in Path(work_dir).glob(filename+".*"):
|
||||
p.unlink()
|
||||
for p in Path(work_dir).glob("page*."+image_extension):
|
||||
p.unlink()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="Convert a PDF file to multiple Comic Book reading formats")
|
||||
parser.add_argument('--pdf', type=str, help='Name of PDF to convert', required=True)
|
||||
parser.add_argument('--ofn', type=str, help='Output File Name: Name of the comic book files to create (no extension! It will be added accordingly to the file type)', required=True)
|
||||
parser.add_argument('--odn', default=os.getcwd(), type=str, help='Output Directory Name: Destination folder for the output file (default: current folder)')
|
||||
parser.add_argument('--work_dir', default=None, type=str, help='Name of the folder to save the images and multiple compressed files (working folder). Contents in the folder will be aggressively deleted. If none, temp folder will be used.')
|
||||
parser.add_argument('--skip_clean', default=None, action='store_const', const=True, help='do NOT clean up the working directory, leave the images and compressed files (only works if work_dir is specified)')
|
||||
parser.add_argument('--skip_extract', default=None, action='store_const', const=True, help='do NOT extract the PDF. Go to work_dir and start compressing the images there.')
|
||||
parser.add_argument('--skip_compress', default=None, action='store_const', const=True, help='do NOT create the compressed comic book files.')
|
||||
parser.add_argument('--image_type', default='webp', choices=['webp', 'jpeg', 'png', 'tiff', 'bmp', 'ppm'], help='Convert PDF to this type of image. Default=webp')
|
||||
|
||||
args = parser.parse_args()
|
||||
type_dict = {
|
||||
'Zip': '.cbz',
|
||||
'Rar': '.cbr',
|
||||
'7zip': '.cb7',
|
||||
'Gtar': '.gz.cbt',
|
||||
'Btar': '.bz.cbt',
|
||||
'Xtar': '.xz.cbt'
|
||||
}
|
||||
|
||||
if args.skip_clean and (args.work_dir == None):
|
||||
print("\nIf you want to skip_clean, you must give me a work_dir. Otherwise the app will use a 'temp system' that gets auto-deleted when the app exits\n")
|
||||
exit()
|
||||
|
||||
if args.skip_extract and (args.work_dir == None):
|
||||
print("\nIf you want to skip_extract, you must tell me where to start compressing the images - give me a word_dir\n")
|
||||
exit()
|
||||
|
||||
initial_cwd = os.getcwd()
|
||||
|
||||
origin_file = args.pdf
|
||||
target_name = args.ofn
|
||||
image_type = args.image_type
|
||||
if not os.path.exists(args.odn):
|
||||
os.mkdir(args.odn)
|
||||
|
||||
if args.work_dir != None:
|
||||
use_temp_dir = False
|
||||
if not os.path.exists(args.work_dir):
|
||||
os.mkdir(args.work_dir)
|
||||
created_work = True
|
||||
else:
|
||||
created_work = False
|
||||
work_dir = args.work_dir
|
||||
else:
|
||||
use_temp_dir = True
|
||||
temp_obj = tempfile.TemporaryDirectory(dir=args.work_dir, delete=True)
|
||||
work_dir = temp_obj.name
|
||||
|
||||
if not args.skip_extract:
|
||||
extract_pdf(origin_file, work_dir, image_type)
|
||||
|
||||
if not args.skip_compress:
|
||||
print (f"Compressing images into comic book files ({target_name}) on work folder: {work_dir}")
|
||||
os.chdir(work_dir)
|
||||
zip = threading.Thread(target=zip_jpg, args=(target_name,image_type))
|
||||
rar = threading.Thread(target=rar_jpg, args=(target_name,image_type))
|
||||
sz = threading.Thread(target=sz_jpg, args=(target_name,image_type))
|
||||
gtar = threading.Thread(target=gtar_jpg, args=(target_name,image_type))
|
||||
btar = threading.Thread(target=btar_jpg, args=(target_name,image_type))
|
||||
xtar = threading.Thread(target=xtar_jpg, args=(target_name,image_type))
|
||||
xtar.start()
|
||||
btar.start()
|
||||
sz.start()
|
||||
zip.start()
|
||||
rar.start()
|
||||
gtar.start()
|
||||
xtar.join()
|
||||
btar.join()
|
||||
sz.join()
|
||||
zip.join()
|
||||
rar.join()
|
||||
gtar.join()
|
||||
report_save_smallest(type_dict, target_name, args.odn)
|
||||
|
||||
os.chdir(initial_cwd)
|
||||
|
||||
size = convert_bytes(file_size(origin_file))
|
||||
print (f"Size of source PDF: {size}")
|
||||
|
||||
if not args.skip_clean:
|
||||
# print("____________________skip: "+args.skip_clean )
|
||||
print("\nClean up of work_dir...")
|
||||
if use_temp_dir:
|
||||
temp_obj.cleanup()
|
||||
else:
|
||||
clean_work_dir(work_dir, target_name, image_type)
|
||||
if created_work:
|
||||
shutil.rmtree(work_dir)
|
||||
|
||||
print("\nWe be done")
|
||||
Reference in New Issue
Block a user