Building a local version of Giphy - Part 1 LiveCoding

September - 2020

NOTE: Currently commented out to get working with MDX - TODO: Get working with MDX

<iframe width="560" height="315" src="https://www.youtube.com/embed/b7xJsSXSIto" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Goal

A web page on my local MAMP server that displays my collection of gifs and lets me drop the one I want into Discord.

Details

I have an ever expanding collection of gifs. I like using them instead of the ones that come with apps/sites. But, the more I acquire, the harder it is to find them. Right now, I just scroll down in the finder trying to remember the name of the one I'm looking for. It takes a while and I can't easily look through them.

What I want is a page on my local tools web site that displays all my gifs and lets me drag the one I want onto Discord, Twitter, whatever...

Progress

Figured out that you can't drop an image from one page onto another one. Came up with the work around of copying the gif to a known location and then opening the folder in the finder. Tried using Automator for that, but it was slow. Switched to using launchd and it worked great.

All images in the source directory are previewed at a standard width by making resized copies of them. Those resized copies aren't cached so they get made every time. That makes the page slow to load, but that's okay for the first version. The resized images also don't animate. But, again, that's fine for the first version. I can still tell what's what. Clicking on an image copies the file over to the target directory and then launches the directory so I can grab it and send it.

First version complete.

Notes

  • I originally tried to get PHP to open the Finder window by running an AppleScript with an exec() using oascript. I hit a point where I was asked for permissions to let the web server interact with the finder. Even though this is just a local web server, I don't want that. PHP can do some interaction, but when it flashed the security dialog in front of me, that was a deal breaker.

    After toying with Automator, I ended up with the launchd solution below.

Snippets

  1. launchd code to watch a folder and open it when something changes.

    ```xml{numberLines: true}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
        <string>com.alanwsmith.open_current_gif</string>
    <key>ProgramArguments</key>
        <array>
            <string>/bin/bash</string>
            <string>-c</string>
            <string>open /Users/alans/woodshed/launchpad/html-prod/gifs/_current_gif</string>
        </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/alans/woodshed/launchpad/html-prod/gifs/_current_gif</string>
    </array>
</dict>
</plist>```
  1. Automator Storage Location

    The following are default storage locations for Automator Workflows. Putting these in here because I created a Folder Action in Automator that I wanted to delete. It's non-obvious where the files are stored.

    • Workflow: Last Saved location. (Use: ~/Automator/Workflows)
    • Application: Last Saved location. (Use: ~/Automator/Applications)
    • Service: ~/Library/Services/
    • Folder Action: ~/Library/Workflows/Applications/Folder Actions
    • Print Plugin: ~/Library/Workflows/Applications/iCal
    • iCal Alarm: ~/Library/Workflows/Applications/iCal
    • Image Capture Plugin: ~/Library/Workflows/Applications/iCal
  1. Move the Finder to the Front via AppleScript

    I didn't end up using this, but it feels like it's worth hanging onto.
    
    ```bash
    

    osascript -e 'tell application "Finder" to set frontmost to true'

    Also, need to look into `activate` which might also work.

  
4. Copy a file in PHP
    
    That's right! I had to look up how to do a basic copy in PHP. I don't really use the language that much so I have to look up pretty much everything. I'm not bothered by that in the least. It's how I get things done.

```php{numberLines: true}
# Copy to the new location
# overwriting if the destination is already there
copy('foo/test.php', 'bar/test.php');

# There is also rename() which moves the file.
rename('foo/test.php', 'bar/test.php');
  1. PHP code to resize the gifs and output the previews and links
### get all the source gif files
$gif_files = glob("source/*.gif");

### loop through all the source files
foreach($gif_files as $gif_file) {

    ### create an 'image resource' from each individual gif file
    $source_gif_resource = imagecreatefromgif($gif_file);

    ### resize the image
    $source_gif_resized = imagescale($source_gif_resource, 200);

    ### set the path for where to store the resized image
    $resized_file_path = str_replace('source', 'resized_cache', $gif_file);

    ### save the resized image resource to the new path
    imagegif($source_gif_resized, $resized_file_path);

    ### output a link to the launcher page for the specific gif and an image call to display it
    echo "<a href='launch-gif.php?gif=$gif_file'><img src='$resized_file_path' /></a>" ;
}