Apache and AppleScriptby David Miller
The purpose of this article is twofold:
The former is the web server that powers most of the Internet and runs on pretty much any modern operating system and hardware platform, while the latter is a scripting language whose sole purpose is to automate repetitive tasks in the Mac OS. The only thing that ties the two together is the fact that both are included with Mac OS X.
AppleScript traditionally interacts with Mac applications such as FileMaker, the
Office suite, and countless other scriptable applications. However, it can also invoke UNIX utilities through its
do shell script command, which opens up a whole new can of worms for scripters to play with. This article will take a closer look at a few of these worms and exactly how they connect Apache and AppleScript.
Mac OS X: Server and Client Rolled Into One
Mac OS X has united the two (traditionally distinct) sides of computing--the server side and client side--under one operating system. With its *BSD foundation and Macintosh interface, OS X is equally capable when crunching numbers on a G5 cluster node as it is when installed on an iBook for editing video, touching up images, or surfing the Web and sending/receiving email. OS X is by no means the first operating system to allow this convergence, but it is the first to do it in such an elegant manner. Those who don't need the command line will never have to look at a Terminal window, and those who work with shell scripts and pipes may never need the Finder.
One key component of Mac OS X's server capabilities is the Apache web server. While it's included in the installation, most non-technical end users probably don't even know that it can be toggled on and off in System Preferences.
AppleScript, however, is a technology that has never been used on the server side for a variety of reasons, the most obvious being the fact that it wasn't even available on a true server platform until the release of Mac OS X. All of the servers out there running Linux, *BSD, Solaris, and even Windows use other languages (such as PHP, Perl, Ruby, or the shell) to accomplish their necessary scripting tasks.
But these languages excel where AppleScript was never intended to go; the original Mac OS never had a command line and typically needed a specialized port of a language in order for it to be compatible (such as MacPerl). Indeed, AppleScript is a language used to accomplish what traditional scripting languages are unable to do: exchange information between applications on a higher level than is possible through plain-text pipes on the command line; Perl has no idea how to automate Photoshop, and AppleScript has poor text-processing abilities and rather poor performance in terms of raw speed.
AppleScript, of course, also has its advantages. Through it you can gain access to information that is inaccessible to the cross-platform scripting languages (or even high-level languages such as Java and C's derivatives) mentioned above. For example, virtually every programming language under the sun can access the standard information regarding a file stored on your hard drive, such as:
- Its location in the file system
- Its parent and child files/folders (if any)
- Its size
- The date and time it was last modified
However, the HFS(+) filesystem also uses resource forks to store metadata for files, which "traditional" languages can't access without special methods. It is here, in the resource forks, where a file's metadata are stored (such as its label and comment).
What does this have to do with Apache? Well, I'm about to get to that.
Playing With Apache
In my previous article, "Mo' Betta Indexes," I outlined how to customize Apache's index pages to match the look and feel of their surrounding site by changing virtually everything about the page's appearance, including:
- The fonts and graphics used on the page
- The icons used for the directory listing
- Which columns are displayed and the information that they should contain
In doing so, I turned a stock Apache page into something a little more pleasing to the eye:
One other part of the index that we altered was the Description, which allows a brief comment to be added to a file (or group of files) using the
AddDescription "description" filename
For example, the following excerpt of a configuration file was used to add the descriptions shown in the above screenshot (line breaks have been added for display purposes, but each directive should only be one line):
AddDescription "<strong>Please read me</strong>" *README AddDescription "<a title=\"PHP: Hypertext Preprocessor\" href=\"http://www.php.net\">PHP</a> Page" *.php AddDescription "<acronym title=\"HyperText Markup Language\">HTML</acronym> Page" *.html *.htm AddDescription "<acronym title=\"Portable Network Graphics\">PNG</acronym> Image" *.png AddDescription "<acronym title=\"Graphics Interchange Format\">GIF</acronym> Image" *.gif AddDescription "<acronym title=\"Joint Photographic Experts Group\">JPEG</acronym> Image" *.jpg *.jpeg AddDescription "Plain-text Document" *.txt AddDescription "<acronym title=\"Motion Picture Experts Group Audio Layer 3\">MP3</acronym> Audio File" *.mp3 AddDescription "Zip Archive" *.zip AddDescription "<a href=\"http://www.apple.com/quicktime/\" title=\"Quicktime\">QuickTime</a> Movie" *.mov
The descriptions listed above serve as great defaults, but they are by no means the most detailed descriptions for files. For example, every HTML file (one that ends with .htm or .html, according to the definition given above) will have the exact same description as every other HTML file.
This problem can be solved by adding detailed descriptions for files through more
AddDescription directives. However, this brings about the problem of maintainability--every time a file is added to the web documents folder, another directive will need to be added to override the default value. This won't be a problem for a small static site, but sites that have hundreds of frequently changing files will have problems keeping abreast of any changes. Thankfully, AppleScript and a little bit of UNIX knowledge can solve our problem.
Since AppleScript gives scripters access to the metadata--including comments--for files, we are able to automatically generate all of the
AddDescription directives without having to manually edit any configuration files. Instead, we'll simply use the Finder's Get Info window to enter our comments and let our script take care of the rest.
Before we get started, there is an important design factor that must be taken into consideration; this is the fact that there are two possible places that we can place our
- Place all of the directives within a central configuration file, which will then act as a repository of descriptions.
- Place the directives for the files in a folder within a plain-text access file contained within that folder, thereby breaking the information up into bite-sized chunks.
Each method has its pros and cons; Apache will read access files every time a request is made for a file in the folder, which results in more disk activity than if the directives were placed in a configuration file that is only read when the daemon is started. However, configuration files can be modified while the daemon is running, which will allow us to generate the files and have them take effect immediately, whereas the daemon will have to be restarted in order for a change in a configuration file to take effect.
I chose to take the second method. However, in the event that the first method suits your needs better, the script can be easily modified to make use of it (although this will be one of those exercises that the author leaves to the reader to attempt).
It should be noted that there is also one minor configuration change that might be required for the access files to take effect: by default, most Apache installations don't permit access files to override the global configuration settings. Because our
AddDescription directives will be placed in access files, we will have to instruct Apache to use them by replacing the command
in /private/etc/httpd/httpd.conf with the following:
Or, if you are already using access files, simply add the
Indexes keyword to the list of options to allow:
AllowOverride AuthConfig Indexes
There is one more directive that will affect how our script operates, and it tells Apache what the name of the access file is. So if for some reason you need to use a different name, you can do it with the following directive:
These files are given the name .htaccess so that they won't show up in the Finder (or a directory listing in the Terminal) or in Apache's own directory listings by default. Thus, the directive in Apache's standard configuration file is:
Important: Always be careful when editing configuration files; it is never a bad idea to create a backup, even for minor changes, in the event that you make a catastrophic typo and are unable to restore it to a working state. More information on the
AccessFileName directives can be found in Apache's manual. With that in mind, let's move on to the script.
We now know what the script must do, but we have yet to design exactly how it will do its job. The following guideline outlines the script's requirements while executing:
- Initialize the .htaccess file in the selected folder.
- Add an
AddDescriptiondirective for each file in the folder that has a comment.
- Repeat for each sub-folder of the selected folder, thereby drilling down into the document tree and visiting all sub-folders.
Pretty simple, no? Apart from that whole recursion thing, of course. And while the basic algorithm listed above glosses over the details of exactly how to implement each step, we'll cover that in the rest of this article. If you prefer not to go through the code line by line, here is a zipped copy of the script so that you can get going right away. For those who are not well-versed in AppleScript and wish to learn a new trick or two, or are just curious how it works, read on.
I should note that, for the sake of brevity, not all of the script will be described in detail; as a large portion of it is trivial and need not be dissected. Instead, only the more important aspects will be covered. However, the source code is thoroughly documented so that even those new to AppleScript will be able to understand its operation.
Pages: 1, 2