Quick Tool Updates on GitHub

I’ve recently gotten my act together and shared to GitHub a bunch of tools and scripts I’ve written. Here’s a compilation of a few of them.

PHP Image Grid Slicer: A simple command-line tool to slice an image into a grid using PHP.

  • Allows a one-liner command to slice up an image into many components, which may be helpful for some automations. I originally wrote this for slicing images of a predictable format for processing with Hazel, for example. Sample one-liners:

    # Slice image.png into 12 images, using 3 rows and 4 columns
    php image-grid-slicer.php image.png 3 4


    # Use more explicit parameters to do the same kind of thing
    php image-grid-slicer.php image.png --rows 3 --columns 4
    php image-grid-slicer.php image.png --columns 6 --rows 1
  • Relies on core PHP functionality and the Imagick PHP extension but has no other dependencies.
  • Released under the MIT License.
  • I’m working on this one from time to time and expect to release a version that can be used on the command line or imported as a class, but I don’t have a release date for that.

MySQL Audit Table Creator: A PHP class to log changes to the data in a MySQL table. It works by creating a new table for each table being tracked and saving a full, versioned copy of each row affected by an INSERT, UPDATE, or REPLACE command. MyISAM and InnoDB tables are supported; other engines may or may not work correctly.

  • This library’s purpose was to enable rapidly adding versioning support to apps that otherwise would lack it entirely, especially legacy apps in which the underlying code cannot be reasonably/safely modified.
  • It’s essentially a middle-ground between having no versioning at all for data and a full-blown Event Sourcing paradigm. In general, I would err toward Event Sourcing or some more-robust, built-in versioning system for key data. This library is a stop-gap for rapidly adding some auditing or logging capabilities to legacy systems or systems in which modifying the underlying PHP to add versioning would be difficult or impossible.
  • Minimal dependencies for development, native PHP and MySQL features only for production.
  • Relies on creation of MySQL triggers for most of its functionality. This has pros and cons.
    • Pros:
      • No modification of existing PHP required; this library is self-contained, and all of the logic after the initial setup lives in MySQL.
      • Because the necessary triggers are set up only once, and because MySQL fires them automatically on appropriate events, the actual PHP code is only needed when setting up the auditing tables (i.e., once). One that is done, you could theoretically delete the code from your server and/or delete or modify the permissions of the MySQL user used to run it.
    • Cons:
      • Requires (for one-time use) a MySQL user with extensive permissions, including ALTER TABLE, CREATE TABLE, CREATE TRIGGER, SHOW TABLES, SHOW TRIGGERS, and possibly SUPER (see the notes in src/AuditTableCreator.php for why I say “possibly”).
      • Does not currently support logging of rows affected by DROP TABLE or TRUNCATE TABLE.
  • This comes with a number of caveats (including, of course, the “AS IS” and no-warranty provisions of the MIT license):
    • I have not used or tested this in some time. It worked perfectly well when I last used it (c. 2015, on PHP 5.x and MySQL 5.x), but it may or may not work on new versions of PHP and MySQL.
    • The library does not natively support any changes to the underlying table being tracked. A brief summary (from memory) of how such changes would affect your auditing:
      • If you add a column to the underlying table, the triggers should keep running correctly, but your new column would not be tracked. You would need to add that column to the audit table, delete the trigger, and create a new trigger to capture data in those new columns.
      • If you alter or delete a column in the underlying table, your triggers will probably break.
      • Adding or deleting indexes—especially modifying the primary key—on your base table may have undesired consequences.
    • Because this (1) stores a full version of every row affected by an INSERT, UPDATE, or REPLACE statement, (2) indexes that data in (basically) the same way as the underlying data, and (3) has no built-in data-retention limits (deleting data after a certain amount of time for example), it can be very noisy and burn through storage quickly. You are therefore urged to exercise caution before tracking any very large tables or tables with very frequent additions or modifications of data. I found it most useful for tracking tables containing data that changes infrequently but is critically important to retain for some reason, such as product descriptions or legal terms.
    • As I said above, I would err toward using Event Sourcing or an in-app solution toward versioning. This would be much more flexible, support better version control, keep the login in-app rather than in triggers, allow better use of migrations, allow more selectivity in which types of changes to track (you probably don’t want to store an indexed copy of the whole row just because some column like last_viewed_by updates, for example), etc.
  • Released under the MIT License.

Command-Line PDF Encryption and Decryption Using qpdf: A pair of simple scripts to encrypt and password-protect a PDF using the open-source tool qpdf.

  • One-liner tools to encrypt or decrypt PDFs from the command line, particularly the Mac terminal, with a (reasonably) secure password prompt, rather than taking the password as a command-line argument.
  • Released under the MIT License.

Various Gists on GitHub: Lots of short snippets of code, handy Markdown fragments, or other bits and bobs. Many of these focus on Obsidian or TextExpander.

  • Unless I’ve stated otherwise in the gist, these come with no license, no rights reserved, and no warranty of any kind; use them however you like.

I hope some of these are helpful to someone.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *