Created
March 31, 2022 12:01
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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