Updating Director Movies Delivered on CD-ROM, Part 1
March 20, 2002
by Will Turnage
Dear Multimedia Handyman,
Is there a way for movie and cast files to be downloaded from a server for easy updates of a CD-ROM title with one touch of a button? The concept is to author it once, and update it from the server as many times as necessary.
Best Regards,
Steven
Dear Steven,
If you want to give users the option to update the content on their CD-ROM, it can be done, but in order for it to work, your project has to conform to a few basic rules.
First of all, you need to have a place to put the new information. Since you can't really write to a CD-ROM, you're going to have to store this data on the user's hard drive. This is easiest if your application is already installed on the user's hard drive. Then you can just replace your local cxt and dxr files. However, if your project is running off the CD-ROM, then you will need to set up a folder on the user's hard drive where you can store the new data.
The second rule is that before you launch your main Director movie, you will need to start with a movie that will actually check for new content and download it if necessary. If you don't do this, then you risk having an external cast being in use when you are trying to replace it, which can cause problems on an operating system level.
Finally, you need to decide how the updates are going to be triggered on the user's end. Are you going to check for updates once every three months? Are you going to always check to see if a newer file is online, and if so, then download it to the user's hard drive? Are you going to automatically check for updates, or are you going to let the user decide when to update the data?
This week, you'll learn how to check the dates of your files locally, and if they're more than three months old, then check online for new data. Then, next week, you'll learn about some more complex strategies for checking for new online content.
When creating a movie that will check for new content, the first frame of the movie should check the date of your file.
fileObj = new (xtra "fileXtra3")
fileModDate = fileObj.fx_FileGetModDate (the moviePath & "data.cst")
fileObj = 0
This script starts by creating an instance of the FileXtra3 (available for free from http://.kblab.net/xtras/). This Xtra is used to get the modification date of the file that you will always update. In this instance, that file is named data.cst and is in the same folder as your movie. There are many other third party Xtras, such as the BuddyAPI Xtra or the DirectOS Xtra which can also find modification dates for you. You might have to change the sample code here slightly to accomodate the date formats returned by the Xtra but it shouldn't be too hard.
In this case, FileXtra3 returns the date as a UNIX formatted 25-character string like this:
put fileModDate
-- "Sun Mar 17 21:44:46 2002 "
However, in order to use this date with Director's date format, you need to convert it into a ISO formatted date string, like this: "20020317". Getting the day of the month and the year out of this string is easy, but getting the month is a bit more tricky.
if fileModDate <> EMPTY then
monthList = ["Jan": "01", "Feb": "02", "Mar": "03", "Apr": "04", "May": "05", "Jun": "06", "Jul": "07", "Aug": "08", "Sep": "09", "Oct": "10", "Nov": "11", "Dec": "12"]
tempYear = fileModDate.char[21..24]
tempMonth = monthList[fileModDate.char[5..7]]
tempDay = fileModDate.char[9..10]
localFileDate = date (dateString)
daysOld = the systemDate - localFileDate
if daysOld <= 90 then
go movie "main.dir"
end if
end if
This code first checks to make sure that the fileModDate is not empty, meaning that there were no errors from FileXtra3. If there aren't any errors, then you create a property list that contains all of the month abbreviations as properties with their corresponding values being the ISO string value for that month. Once you have this list, then you calculate the year, month, and day from the original date string. Next, you combine those three strings to form a single ISO-formatted string that can be used with Director's date object. Once you make this date object, then you subtract it from the current system date to find out how many days old your file is. In this case, if your file is less than 90 days old, then you automatically jump to your main movie, which is named main.dir.
If the file is more than 90 days old, then the movie doesn't jump and you're taken to the next screen which gives the user the option to download a new file. That screen could look like this:
If the user clicks on the Not right now button, then this code is executed:
on mouseUp me
go movie "main.dir"
end
which just takes them to the movie without checking for or downloading any new content. However if they click the button saying they want an update, then this code is executed.
on mouseUp me
pNetID = downloadNetThing ("http://www.myserver.com/data.cst", the moviePath & "data.cst")
timeout ("checkDownload").new (100, #checkDownload, me)
end
This code starts downloading the new data file off the Internet, telling it to replace the file that resides locally on your hard drive. Next, you set up a timeout object that will execute ten times a second to check on the progress of the download. The checkDownload handler looks like this:
if netDone (pNetID) then
timeout ("checkDownload").forget()
if netError (pNetID) = "OK" or netError (pNetID) = "" then
member ("netStatus").text = "Download completed."
go movie "main.dir"
else
member ("netStatus").text = "There was an error. Please check your net connection and try again."
end if
First you check to see if the net operation is done. If it is finished, then you forget the timeout object so that it will no longer check on the progress of the download. Next, you check to see if there was an error with the download. If there were no errors, then you update the status text on screen and then go to your main movie. If there was an error, then you tell the user there was an error and that they should try again.
If the download isn't finished yet, then you need to give the user some sort of feedback telling them what the download is doing. That code looks like this:
else
downloadState = getStreamStatus(pNetID)
case netStatus.state of
"Connecting":
member ("netStatus").text = "Connecting to the server..."
"Started":
member ("netStatus").text = "Download started..."
"InProgress":
tempPercent = integer ( 100 * (downloadState.bytesSoFar / downloadState.bytesTotal) )
member ("netStatus").text = string (tempPercent) & "% downloaded..."
"Complete":
member ("netStatus").text = "Download completed."
"Error":
member ("netStatus").text = "There was an error. Please check your net connection and try again."
end case
end if
This code starts by getting the streamStatus of the current download. The streamStatus is a property list containing information about the current state of the download. If the download is just connecting, or has finished, then you update the status text field with the appropriate message. However, if the update is actually downloading, you use the information in the downloadState list to calculate the percentage of the download that has actually happened and report that information to the user. This way, they will be notified of the progress of the download.
And that's all there is to it. Next week, you'll learn about some different strategies for keeping your content fresh, as well as some defensive programming techniques to account for when downloads go bad.
A sample Director 8 movie is available for download in ZIP and SIT archives.
All colorized Lingo code samples have been processed by Dave Mennenoh's brilliant HTMLingo Xtra, available from his site at http://www.crackconspiracy.com/~davem/
Copyright 1997-2024, Director Online. Article content copyright by respective authors.