Carl Burks is a software developer for a global financial institution. With over ten years experience in technology and software development for financial organizations and over twenty years of software experience, Carl Burks provides articles, musings and insight into technology issues, software development, and other selected topics.

Random Projects Book Site


Carl Burks

I've been collecting Humble Book bundles for a while and they have been lumping up in a directory and I needed a good way to organize them.

First I discovered that some of them had data in the PDF's exif tags. So I used the exiftool command. That pulled things in pretty well, so I needed to grab the first page for a thumbnail. Imagemagick's convert did just that.

Here is the script:

import os
import subprocess
import json
import uuid
import argparse

class FileProcessor(object):
    """ Operates on a group of Files """

    def __init__(self, thumbnail_path, data_path):
        self._thumbnail_path = thumbnail_path
        self._allowed_extensions = [".PDF",".pdf"]
        self._data_path = data_path
        self._file_actions = [self.process_file_info_from_path, self.save_image_thumbnail_from_path]
            with open(data_path, 'r') as myfile:
            self._info = {}

    def file_processed(self, path):
        return path in self._info.keys()

    def get_exif_info(self, path):
        return subprocess.check_output(f"exiftool -Title -Author -j {path}", shell=True).decode()

    def get_new_outpath(self):
        guid = uuid.uuid4()
        thumbnail = self._thumbnail_path
        return f"{thumbnail}{guid}.png"

    def process_file_info_from_path(self, path):
        self.save_file_info(path, json.loads(self.get_exif_info(path))[0])

    def save_image_thumbnail_from_path(self, path):
        outpath = self.get_new_outpath()
        subprocess.check_output(f"convert -trim {path}[0]  {outpath}[0]", shell=True)
        self.save_file_info(path, {"thumbnail": outpath})

    def save_file_info(self, path, info):
        if path in self._info.keys():
            for key in info.keys():
                self._info[path][key] = info[key]
            self._info[path] = info

    def process_file(self, path):
        if os.path.isfile(path) and not self.file_processed(path):
            _, file_ext = os.path.splitext(path)
            if file_ext in self._allowed_extensions:
                for action in self._file_actions:

    def process_files(self, path):
        for file_name in os.listdir(path):
            self.process_file(os.path.join(path, file_name))
        with open(self._data_path, "w") as outfile:
            json.dump(self._info, outfile, indent=4)

parser = argparse.ArgumentParser()
parser.add_argument("-n","--thumbnail_path", type=str, help="Thumbnail path")
parser.add_argument("-d","--data_path", type=str, help="Data path")
parser.add_argument("-t","--file_path", type=str, help="file path")
args = parser.parse_args()
fp = FileProcessor(args.thumbnail_path, args.data_path)

This made a nice .json file.

Next I built a little site with bootstrap, lodash, and knockout.

I want to rebuild the site with:

Angular 2



Then compare the differences and how easy it was to code.

I've added the Knockout version.

The Knockout version was fairly easy to code so that's a good baseline.