Skip to content

Instantly share code, notes, and snippets.

@akash5100
Created March 31, 2022 12:01
Show Gist options
  • Save akash5100/fa8c66edf9dabf565e159c87490e70ae to your computer and use it in GitHub Desktop.
Save akash5100/fa8c66edf9dabf565e159c87490e70ae to your computer and use it in GitHub Desktop.
A book builder script that I wrote to stitch Google docs as a Book in PDF or ePub format
#!/usr/bin/python
# TODO:
# - Add a way so that the user can choose which chapter goes first (independently of the name of the file)
# - The shared directory should be a parameter of the script
import os
from pathlib import Path
import subprocess
try:
import typer
except ImportError:
print("Please install typer using 'pip install typer' or Run \n'pip install -r requirements.txt' to install complete dependency.")
exit()
try:
import pyfiglet
except ImportError:
typer.secho(
"Depencency 'pyfiglet' not found. Please install using\n'pip install -r requirements.txt'",
fg=typer.colors.RED, bold=True, err=True
)
exit()
from typing import Optional
from get_file_ids import get_file_ids # get the file ids
from add_page_number import add_page_numbers # Add page numbers
from add_metadata import write_information # prompt user metadata details
from add_metadata import extract_information # prompt user metadata details
from tools import remove_space # remove the space from the name
app = typer.Typer(help="Awesome CLI Book Builder.")
@app.command()
def download(shared: Optional[bool] = typer.Option(False, help="Download files from shared drive")):
"""
Download the files from the google drive.
"""
if shared == True:
print('Downloading from shared drive')
# get file ids from shared drive
get_file_ids(shared)
# Download them
from download import downloader
downloader(False)
else:
print('Downloading from user drive')
# get file ids from user drive
get_file_ids(shared)
# Download them
from download import downloader
downloader(False)
# Command to merge pdfs
@app.command()
def merge(path: Path = typer.Argument(..., help="Path to the directory containing the files")):
"""
Merge the pdfs.
"""
if path == None:
typer.secho(
"Please provide the path of the pdfs",
fg=typer.colors.RED, bold=True, err=True
)
return
else:
book_name = input("Enter the name of the book: ")
book_name = remove_space(book_name)
json_content = '{"dirname" :"' + str(path) + \
'",' + '"book_name" :"' + book_name + '"}'
with open("merge_path.json", 'w') as f:
f.write(json_content)
f.close()
print("Merging files")
# run the nodejs app
path = os.getcwd()
result = subprocess.check_output(
['node', f'{path}/MergePDF/merger.js'])
output = result.split(b'\n')[1:-1]
# Print the output of nodejs app
for line in output:
print(line.decode('utf-8'))
# remove the json file
os.remove("merge_path.json")
print("\n*\n*\nBook Created @ '" + os.getcwd() +
"/" + book_name + ".pdf'\n*\n*")
# Command to add pagenumber
@app.command()
def page(
path: Path = typer.Argument(..., help="path to the pdf book."),
skip: Optional[int] = typer.Option(
0, help="Skip adding page number to cover page"),
align: Optional[str] = typer.Option(
"center", help="Align page numbers to the bottom left/right")
):
"""
Add page numbers to the pdf.
"""
if align != "left" and align != "center" and align != "right":
typer.secho(
"Please enter the correct alignment",
fg=typer.colors.RED, bold=True, err=True
)
return
if skip < 0:
typer.secho(
"Please enter the correct skip value",
fg=typer.colors.RED, bold=True, err=True
)
return
if not os.path.exists(path):
typer.secho(
"Please provide correct path of the pdf",
fg=typer.colors.RED, bold=True, err=True
)
return
else:
add_page_numbers(str(path), False, skip, align)
# command to write metadata to the pdf
@app.command()
def metadata(path: Path = typer.Argument(..., help="path to the pdf book.")):
"""
Add metadata to the pdf.
"""
if path == None:
typer.secho(
"Please provide the path of the pdf",
fg=typer.colors.RED, bold=True, err=True
)
return
else:
print("Adding metadata")
write_information(str(path), False)
# Command to get metadata from pdf
@app.command()
def read_metadata(path: Path = typer.Argument(..., help="path to the pdf book.")):
"""
Get metadata from the pdf.
"""
if path == None:
typer.secho(
"Please provide the path of the pdfs",
fg=typer.colors.RED, bold=True, err=True
)
return
else:
extract_information(str(path))
# Command to build the book
@app.command()
def build_pdf(
name: Optional[str] = typer.Option(None, help="Name of the book"),
shared: Optional[bool] = typer.Option(
False, help="Download files from shared drive"),
skip: Optional[int] = typer.Option(
0, help="Skip adding page number to cover page"),
align: Optional[str] = typer.Option(
"center", help="Align page numbers to the bottom left/right")
):
"""
Build the book from documents in google drive in pdf format. Build-pdf command runs all other commands automatically.
"""
if align != "left" and align != "center" and align != "right":
typer.secho(
"Please enter the correct alignment",
fg=typer.colors.RED, bold=True, err=True
)
return
if skip < 0:
typer.secho(
"Please enter the correct skip value",
fg=typer.colors.RED, bold=True, err=True
)
return
if name is None:
name = input("Name of the book: ")
typer.secho(
f"Starting to build '{name}'",
fg=typer.colors.GREEN
)
typer.secho(
f"Downloading files from google drive",
fg=typer.colors.GREEN
)
# 1. get file ids from shared drive
get_file_ids(shared)
# 2. Download them
from download import downloader
downloader(True)
typer.secho(
f"Downloading complete",
fg=typer.colors.GREEN
)
typer.secho(
f"Merging files",
fg=typer.colors.GREEN
)
# 3. run the nodejs app
path = os.getcwd()
result = subprocess.check_output(
['node', f'{path}/MergePDF/pdf-merger.js'])
output = result.split(b'\n')[1:-1]
for line in output:
print(line.decode('utf-8'))
typer.secho(
f"Merging complete",
fg=typer.colors.GREEN
)
# 4. Add page numbers
cwd = os.getcwd()
path = f"{cwd}/output.pdf"
add_page_numbers(path, True, skip, align)
os.remove("output.pdf")
os.rename("output2.pdf", "output.pdf")
# 5. Add metadata
typer.secho(
f"Adding metadata",
fg=typer.colors.GREEN
)
path = f"{cwd}/output.pdf"
write_information(path, True)
os.remove("output.pdf")
os.rename("output2.pdf", f"{remove_space(name)}.pdf")
typer.secho(
f"Building complete\nBook created @ {cwd}/{remove_space(name)}.pdf",
fg=typer.colors.GREEN
)
@app.command()
def build_epub(
name: str = typer.Option(None, help="Name of the book"),
shared: Optional[bool] = typer.Option(
False, help="Download files from shared drive"),
):
"""
Build the book from documents in google drive in epub format.
"""
if name is None:
typer.secho(
f"Please provide the name of the book",
fg=typer.colors.RED, bold=True, err=True
)
return
typer.secho(
f"Starting to build '{name}'",
fg=typer.colors.GREEN
)
typer.secho(
f"Downloading files from google drive",
fg=typer.colors.GREEN
)
# 1. get file ids from shared drive
# get_file_ids(shared)
# 2. Download them
from build_epub.download import downloader
# downloader()
# 3. run __main__ from create.py to create the epub
from build_epub.create import main
name = remove_space(name)
main(name)
if __name__ == '__main__':
figlet_name = (pyfiglet.figlet_format("Book-Builder", font="small"))
typer.secho(
f"{figlet_name}",
fg=typer.colors.MAGENTA
)
app()
######################################
# Which prints
######################################
# book-builder (master) ✗ ./main.py --help
# ___ _ ___ _ _ _
# | _ ) ___ ___| |_____| _ )_ _(_) |__| |___ _ _
# | _ \/ _ \/ _ \ / /___| _ \ || | | / _` / -_) '_|
# |___/\___/\___/_\_\ |___/\_,_|_|_\__,_\___|_|
# Usage: main.py [OPTIONS] COMMAND [ARGS]...
# Awesome CLI Book Builder.
# Options:
# --install-completion Install completion for the current shell.
# --show-completion Show completion for the current shell, to copy it or
# customize the installation.
# --help Show this message and exit.
# Commands:
# build-epub Build the book from documents in google drive in epub...
# build-pdf Build the book from documents in google drive in pdf...
# download Download the files from the google drive.
# merge Merge the pdfs.
# metadata Add metadata to the pdf.
# page Add page numbers to the pdf.
# read-metadata Get metadata from the pdf.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment