Dojo (HowTo)







  Easter Eggs




  Martial Arts

CM Scripting
Using AppleScript for Configuration Management

By:David K. Every
©Copyright 1999

Since I am doing some AppleScript for MacKiDo, I figured I could explain what I am doing, and why, so that others might understand more about the power of AppleScript (and the Mac) -- and for those doing Web Sites Management, with more than one person, they can get some concept ideas -- and example solutions.

AppleScript is a great way to get the basics of programming, for a few reasons. Being free, is a good one. But also that many of the concepts are pretty simple is another. The hardest part about AppleScript is figuring out what Objects you can interact with for a particular program (and some of the Syntax quirks). The best part of AppleScript is that you can control multiple programs, and actually program THEM, to add functionality to them, and create custom solutions -- which is exactly what I needed to do.

The Problem

The MacKiDo Home Page (named "index.html") has two people altering it (Fred, and me) -- for now, but it may get worse in the future. Every time I want to edit the home page, I download the latest version from the remote site (to my local drive), edit it, and put it back up. If after I have "grabbed" my copy (to my local drive), Fred has altered the page (saves a newer version with some "update"), which can be common since we both do some updates in the morning, then the version on my machine is out of date. If I don't notice that he has made those changes since I've grabbed a copy (and I usually don't), then I will finish my fixes and save my version back up to the site -- and stomp on his changes. (I put my version, over his "updated" version -- and my version doesn't have his most recent changes).

This "data overwriting" is a common problem with computers. It is often handled by people (or other computer programs) that do "configuration management", or by only allowing one user to work with a file at a time (which can be annoying). Multi-User database programmers are also very familiar with the problem -- and there are all sorts of programming techniques to solve this stomping problem -- which is also called data-collision, overwriting, or by various four-lettered monikers.

The Solution

My solution is simple -- have both of us work on the different files (then there can be no overwriting). Neither of us can directly alter the home page file ("index.html").

So I broke the home page, into file fragments (partial pages). Whenever we alter our fragments, we run a script.

What the script does is as follows:

  1. First the script synchronizes the file fragments (so I get the latest copy of the fragments from the server on my local machine, and the Web server gets the latest version of my file fragment as well).
  2. Then the script consolidates the files (compiles the home page) -- it builds index.html out of the parts (fragments).
  3. Then of course it uploads the index.html to the server.

It is almost impossible for us to walk on each other, since we are building the latest home page, from the latest parts -- and the script runs so quickly, that it would be highly unlikely that we were both running it at the exact same time (before, it might take me 10 or 15 minutes to update the home page file -- now the script takes about 10 or 15 seconds -- a much smaller window for either of us to mess things up). Since I copy only my fragment up (not Fred's), and Fred's script only copies his fragment up to the server, there is no way that I can walk over his fragment. So even if we were to update at the exact same time, the fragments are still right. Is all this making sense?

How it works

I use special tags (called meta-tags). These metatags are really just comments to HTML, meaning that HTML ignores those comments and the text doesn't get displayed, but I can use them as special "Keys" (something to look for, or key off of). In HTML, anything that is inside of <!-- here --> is a comment.

I named my files with the exact same name as the metatags that they were replacing. This is easy for me in programming, but can be a little complex to explain, so watch carefully for whether I call <!--something--> either a file or a tag.

So I created some files, including:

  1. An empty template file, called "source.html". This file contains all of the basic formatting for the home page (think of it as an empty shell) -- but it contains none of the content
  2. I have the leader story, the brief description of the latest article that's been added to MacKiDo, called "<!--Leader-->".
  3. I have the contents, the little index that has links to all the most recent additions to MacKiDo, called "<!--Contents-->".
  4. And of course there is Fred's AppleBits fragment, which contains all the stuff that he adds, called "<!--AppleBits-->".

The AppleScript then uses Fetch to copy files up and back from the server, and it uses BBedit to do the text search and replace (to move parts around). These are all cool programs.

The professional version of BBEdit can do FTP on its own -- but since Fred has the Lite version, I could not use that capability, and instead used Fetch.

The first thing I do is as follows:

set theurl to "ftp://siteName:sitePassword@siteRootPath"
set thePath to "MacKiDo:Scripts:"  -- path to file
-- synchronize parts (both ways)
tell application "Fetch 3.0.3"
	set appleBitsURL to theurl & "Parts/<!--AppleBits-->"
	set appleBitsAlias to thePath & "Parts:<!--AppleBits-->" as alias
	store appleBitsAlias url appleBitsURL -- move local to remote
	set theLeaderURL to theurl & "Parts/<!--Leader-->"
	set theLeaderAlias to thePath & "Parts:<!--Leader-->" as alias
	fetch theLeaderAlias url theLeaderURL -- get local from remote
	set theContentsURL to theurl & "Parts/<!--Contents-->"
	set theContentsAlias to thePath & "Parts:<!--Contents-->" as alias
	fetch theContentsAlias url theContentsURL -- get local from remote
end tell

Nothing here is too complex.

I create a URL for the site, and the local path (on my hard drive) to the local files. Before you could use this AppleScript, you will have to set these to the right names for your site.

NOTE: Remember an Alias to a file must exist or you will get an error -- so you must make sure there is a file where you say there is one.

I then tell the program "Fetch" to move some files around.

If you notice, I am Store'ing "AppleBits" up to the server, and fetch'ing the other two fragments to the local drive (assuming that the "source.html" file will change infrequently). That means that this is Fred's version of the Script. My version is the exact same, except I fetch the AppleBits fragment, and store my two fragments.


The next thing done is:

-- consolidate file parts
tell application "BBEdit 4.0"
	-- copy template from source	
	open (thePath & "Parts:source.html")
	find "<HTML>([^*]+)</HTML>" with grep
	-- put template into index	
	open (thePath & "Parts:index.html")
	find "<HTML>([^*]+)</HTML>" with grep
	save window 1
	close window 1
	-- insert leader
	open (thePath & "Parts:<!--Leader-->")
	find "<P><!--StartLeader-->([^*]+)<!--EndLeader--></P>" with grep
	close window 1
	open (thePath & "Parts:index.html")
	find "<P><!--Leader-->"
	save window 1
	close window 1
	-- insert contents
	open (thePath & "Parts:<!--Contents-->")
	find "<P><!--StartContents-->([^*]+)<!--EndContents--></P>" with grep
	close window 1
	open (thePath & "Parts:index.html")
	find "<P><!--Contents-->"
	save window 1
	close window 1
	-- insert AppleBits
	open (thePath & "Parts:<!--AppleBits-->")
	find "<P><!--StartAppleBits-->([^*]+)<!--EndAppleBits--></P>" with grep
	close window 1
	open (thePath & "Parts:index.html")
	find "<!--AppleBits-->"
	-- go away
	save window 1
	close window 1
end tell

Now this is long -- but all basic stuff.

I open the source file, and copy everything. Then I open the index file, and replace everything in it with the stuff from source file -- this lets me start from a clean slate.

After that I open the leader file, and find everything from start leader to end leader metatag, and copy that out. Then I open the index file, find my custom metatag (leader), and replace it with the stuff I copied from the leader file.

That is it. Of course, I repeat it for the other file fragments, contents and AppleBits, but it is all pretty basic stuff.


The last thing done is:

-- update remote index
tell application "Fetch 3.0.3"
	set indexURL to theurl & "index.html"
	set indexAlias to thePath & "Parts:index.html" as alias
	store indexAlias url indexURL -- move local to remote
end tell

I just update the remote version of index (using Fetch). And everything is done.


So with a couple hours work (at most) on my part, I wrote an AppleScript that makes updating my site far easier than it was before. That is the power of AppleScript -- making custom solutions, with little effort. It dramatically increases my productivity, to not have to do all this stuff manually.

AppleScript is not magic, it just requires a little patience (to figure out exact syntax). I hope to do more Articles explaining, on how to use AppleScript to make site management far easier, and to make the Mac far more powerful.

I usually don't get so detail (implementation) oriented. But there are a lot of concepts there, that can help a lot of people with different solutions. So I hope this gives people some help in understanding either AppleScript or Site Management. I'm sure there are at least a couple web-masters out there who will appreciate the implementation details offered here.

Created: 2/25/98
Updated: 11/09/02

Top of page

Top of Section