Downloading Files

In Authoring and Projectors, it is possible to download files using the downloadNetthing Lingo function (this is not available in Shockwave). It works much like the other network lingo functions discussed earlier: starting a network download returns a NetID. You can then monitor the progress of the download.

Here is an example class (script) for managing downloads. It works in a similar way to the other 'netOp' classes available at the LingoWorkshop. Here is some lingo to create an instance of the script and tell it to start downloading the file, making some callbacks to keep us informed of the download progress:

NetOp = script("NetOp.download").new(UpdateURL, localFileName)
NetOp.AddListener (me)
NetOp.Start()

The first line creates a new instance of the script, and specifies the download url and a local file name. The next line adds the current script as a 'listener' (an object the NetOp should send messages to). The third line actually starts the download. When the download is complete, the NetOp will send a DownLoadComplete message to the listener objects.

Downloading multiple files

It is possible to download more than one file at a time. Director will start queuing downloads if you try and initiate too many at once (the network status will be 'connecting...') and multiple concurrent connections might slow down the individual connection. Running 2,3 or even 4 downloads at once seems to be acceptable.

Here is an example script for downloading multiple files. The main method of this script looks like this:

on FetchFiles (me, listOfURLS, directoryToSaveFiles)
  if NOT xtraP("NetLingo") then \
     return "Error - NetLingo Xtra is missing" 
  if NOT listP(listOfURLS) then \
     return "Bad parameter (list of urls is not a list)"
  if NOT folderExists(directoryToSaveFiles) then \
     return "Bad parameter (local folder does not exist)"
  
  UpdateList = listOfURLS
  DownloadDir = directoryToSaveFiles
  if (the last char of DownloadDir <> the last char of the moviePath) then
    DownloadDir = DownloadDir & the last char of the moviePath
  end if
  SuccessCnt = 0
  FileCnt = count(listOfURLS)
  me._GetNextUpdate()
  return "OK"
end

The first three lines simply do some error checking (making sure that the NetLingo Xtra is available and that the parameters are ok). If everything looks good, it calls the _GetNextUpdate method which looks like this:

on _GetNextUpdate (me)
  
  if count(UpdateList) then
    
    if count(CurrentConnnections) < MaxConnections then 
      
      Updating = 1
      f = UpdateList[1]
      localFileName = DownloadDir & basename(f, "/")
      UpdateURL = f &"?v="&random(the milliseconds)
      
      me._UpdateStatus("Fetching file: " & UpdateURL, UpdateURL)
      UpdateList.deleteAt(1)
      
      NetOp = script("NetOp.download").new(UpdateURL, localFileName)
      NetOp.AddListener (me)
      NetOp.SetCallback(#DownloadComplete, #DownloadComplete)
      NetOp.SetCallback(#DownloadStatusUpdate, #DownloadStatus)
      NetOp.Start()
      CurrentConnnections.append(NetOp)
      me._GetNextUpdate()
      
    else
      
      -- need to wait for one of the current operations to finish
      -- and call _GetNextUpdate
      
    end if
    
  else
    if count(CurrentConnnections) = 0 then
      me._UpdateStatus("")
      Updating = false
      me._UpdateStatus("Finished downloading files. \
	  Successfully downloaded " &SuccessCnt&" out of "&FileCnt&" files.")
      call(#FetchFilesComplete, Listeners)
    end if
  end if
  
end

Basically, each time the _GetNextUpdate method is called, it checks whether there is less than the allowed number of connections still active, and if there is, it creates a new download object. Each time a download object is created, the url of the thing being downloaded is sliced off the list. When a download object finishes, it sends a downloadcomplete message back to this script. The download method looks like this:

on DownloadComplete (me, op, args)
  CurrentConnnections.deleteOne(op)
  if args.ilk = #PropList then 
    if args.error = 0 or args.error = 4816 then 
      -- got the file
      if FileExists(args.localAddress) then
        me._UpdateStatus("File downloaded.", args.remoteaddress)
      end if
      SuccessCnt = SuccessCnt + 1
    else
      -- some error handling code here
    end if
  else
    -- some error handling code here
  end if
  me._GetNextUpdate()
end

Here is a demo movie (DIR file) - includes demo of ProxyHelper script (see below)

Dealing with firewalls and other impediments

One problem with downloading files from a projector is getting through firewalls and other devices designed to stop software from downloading things. Director has a lingo function for configuring proxy settings used by the projector which can work. You can either ask your users to provide their proxy address and port number, or use this script and attempt to read their settings from the registry and do it all automatically. Otherwise, you could use an Xtra such as SecureNet from INM (you might have to use an Xtra if the proxy requires a username and password).

Some other issues

I've noticed (so far only on an OSX system running the Apache server) that some files simply refuse to download. Director says there is an error 4165 (bad url) - but the file can be downloaded using a web browser. It might have something to do with the path name or permissions.

Last updated 28th of July, 2006

© 2006 MeccaMedialight. Site Powered by Wrangler 8.