Blog

MDM Zinc – FTP Manager

Hello.
This is a class I’ve done long time ago. I’m quite sure it will be helpfull to some people (at least one, the one who sent me an email asking for this class šŸ˜‰ ).

First the class:
[as]
/*
* Class written by Xavier MARTIN (xxlm or zeflasher)
* http://dev.webbymx.net
* http://www.webbymx.net
* If you are using this class, I will be glad to receive a postcard of your place šŸ™‚
* To do so please visit http://dev.webbymx.net and go in the about page do get my details…
*/
import mdm.*;
// for the delegate class inside
import com.bourre.commands.*;
// log event
import com.bourre.log.*;
import com.bourre.utils.LuminicTracer;

import net.webbymx.zinc.DateManager;
import net.webbymx.zinc.FileSystemManager;

dynamic class net.webbymx.zinc.FTPManager {
/******************************************************************************
* PRIVATE VARIABLES
******************************************************************************/
// EventDisptacher
private var dispatchEvent:Function;
public var addEventListener:Function;
public var removeEventListener:Function;

// ftp log
private var _ftp_server:String;
private var _ftp_port:String;
private var _ftp_username:String;
private var _ftp_password:String;
private var _ftp_folder:String;

// MDM ftp connection
private var _ftp:mdm.FTP;

// ftp management
private var _ftp_connected:Boolean;
private var _ftp_siInterval:Number;
private var _ftp_row:Number;
private var _ftp_file:Number;

// ftp informations
private var _ftp_localFiles:Array;
private var _ftp_remoteFiles:Array;
private var _ftp_localFile:String;
private var _ftp_remoteFile:String;
private var _ftp_totalBytes:Number;
private var _ftp_currentBytes:Number;
private var _ftp_lastCachedBytes:Number;
private var _ftp_fileTansfered:Boolean;
private var _ftp_localRoot:String;
private var _ftp_start:Boolean;
private var _ftp_root:String;
private var _ftp_actualdir:String;

// Dispatched
public var aborted:Function;
public var busy:Function;
public var connected:Function;
public var dirChanged:Function;
public var dirCreated:Function;
public var dirDeleted:Function;
public var error:Function;
public var fileDeleted:Function;
public var fileReceived:Function;
public var fileRenamed:Function;
public var fileSent:Function;
public var fileTransfered:Function;
public var indexFileReceived:Function;
public var listingDone:Function;
public var loggedIn:Function;
public var quit:Function;
public var ready:Function;
public var resolvedLinks:Function;

public var scanLocalCompleted:Function;
public var scanRemoteCompleted:Function;
public var progress:Function;
public var write:Function;

/******************************************************************************
* CONSTRUCTOR
******************************************************************************/
// FTPManager(server:String, port:String, username:String, pwd:String [,localRoot:String, folder:String])
function FTPManager(server:String, port:String, username:String, pwd:String) {
// dispatching event
mx.events.EventDispatcher.initialize(this);
// FTP events (from zinc)
addEventListener(“aborted”, this);
addEventListener(“busy”, this);
addEventListener(“connected”, this);
addEventListener(“dirChanged”, this);
addEventListener(“dirCreated”, this);
addEventListener(“dirDeleted”, this);
addEventListener(“error”, this);
addEventListener(“fileDeleted”, this);
addEventListener(“fileReceived”, this);
addEventListener(“fileRenamed”, this);
addEventListener(“fileSent”, this);
addEventListener(“fileTransfered”, this);
addEventListener(“indexFileReceived”, this);
addEventListener(“listingDone”, this);
addEventListener(“loggedIn”, this);
addEventListener(“quit”, this);
addEventListener(“ready”, this);
addEventListener(“resolvedLinks”, this);

// FTP events added
addEventListener(“scanLocalCompleted”, this);
addEventListener(“scanRemoteCompleted”, this);
addEventListener(“progress”, this);
addEventListener(“write”, this);

// init variables
_ftp_server = server;
_ftp_port = port;
_ftp_username = username;
_ftp_password = pwd;

_ftp_connected = false;
_ftp_localFiles = new Array();
_ftp_remoteFiles = new Array();
_ftp_localFile = null;
_ftp_remoteFile = null;

// preloader
_ftp_totalBytes = null;
_ftp_currentBytes = null;
_ftp_lastCachedBytes = null;
_ftp_fileTansfered = true;
_ftp_start = true;

if (arguments[4] != undefined && typeof(arguments[4]) == “string”) {
_ftp_localRoot = arguments[4];
if(!mdm.FileSystem.folderExists(_ftp_localRoot)) mdm.FileSystem.makeFolder(_ftp_localRoot);
}
if (arguments[5] != undefined && typeof(arguments[5]) == “string”) _ftp_folder = arguments[5];
else _ftp_folder = “none”;
}

/******************************************************************************
* PRIVATE FUNCTIONS
******************************************************************************/
private function getTransferProgress(Void):Void {
// get bytes transfered
_ftp_currentBytes = _ftp.bytesTransfered;
if (_ftp_fileTansfered == false) {
// if current bytes is not a Number
if (isNaN(_ftp_currentBytes)) return;
if (_ftp_currentBytes != _ftp_lastCachedBytes) {
_ftp_lastCachedBytes = _ftp_currentBytes;
dispatchEvent({type: “progress”, target: this, bytesTransfered:_ftp_currentBytes, totalBytes:_ftp_totalBytes});
} else return;
} else {
_ftp_lastCachedBytes = null;
dispatchEvent({type: “progress”, target: this, bytesTransfered:_ftp_currentBytes, totalBytes:_ftp_totalBytes});
}
}

// dispatch the event write with the string passed in param
private function updateStatus(s:String):Void {
dispatchEvent({type: “write”, target: this, txt:s});
}

// OK
// Event Handler for the FTP
private function ftpEventHandler(event:Object) {
//updateStatus(“\nid: “+event.id+” \nsevent: “+event.type);
//updateStatus(“\nlast server reply: “+_ftp.lastReply);
var eventType:String = String(event.type).toUpperCase();

// ABORTED EVENT
if (eventType == “ABORTED”) {
dispatchEvent({type: “aborted”, target: this});
// nothing
return;
}

// BUSY EVENT
if (eventType == “BUSY”) {
dispatchEvent({type: “busy”, target: this});
// nothing
return;
}

// FTP CONNECTED EVENT
if (eventType == “CONNECTED”) {
dispatchEvent({type: “connected”, target: this});
// nothing
return;
}

// FTP DIR CHANGED EVENT
if (eventType == “DIRCHANGED”) {
// show directory
updateStatus(“\n\n************************************”);
updateStatus(“\nCurrent directory: “+_ftp.currentDir+”\n”);
if (_ftp_start) {
_ftp_start = false;
_ftp_root = _ftp.currentDir;
dispatchEvent({type: “loggedIn”, target: this});
}
return;
}

// FTP DIR CREATED EVENT
if (eventType == “DIRCREATED”) {
dispatchEvent({type: “dirCreated”, target: this});
// show directory
return;
}

// FTP ERROR EVENT
if (eventType == “ERROR”) {
_ftp_fileTansfered = true;
clearInterval(_ftp_siInterval);
var lastError = _ftp.error;
dispatchEvent({type: “error”, target: this});
updateStatus(“\nError details: “+lastError);
return;
}

// FTP FILE DELETED
if (eventType == “FILEDELETED”) {
dispatchEvent({type: “fileDeleted”, target: this});
// show directory
return;
}

// FTP FILE RECEIVED EVENT
if (eventType == “FILERECEIVED”) {
clearInterval(_ftp_siInterval);
_ftp_fileTansfered = true;
getTransferProgress();
dispatchEvent({type: “fileReceived”, target: this});
}

// FTP FILE RENAMED EVENT
if (eventType == “FILERENAMED”) {
clearInterval(_ftp_siInterval);
dispatchEvent({type: “fileRenamed”, target: this});
}

// FTP FILE SENT EVENT
if (eventType == “FILESENT”) {
_ftp_fileTansfered = true;
clearInterval(_ftp_siInterval);
//getTransferProgress();
updateStatus(“\nlocal file: “+_ftp_localFile);
updateStatus(“\nremote file: “+_ftp_remoteFile);
updateStatus(“\ntransfer time: “+_ftp.transferTime);

updateStatus(“\nDone”);

// going to the next file
_ftp_file++;
// if there is no more file to upload for this directory
if (_ftp_file >= _ftp_localFiles[_ftp_row][1].length) {
// going to the next one
_ftp_row++;
// reset file index
_ftp_file = 0;
// if there is still directory
if (_ftp_row < _ftp_localFiles.length) { var dir:String = _ftp_localFiles[_ftp_row][0]; mdm.Dialogs.prompt("row: "+_ftp_row+", "+_ftp_localFiles[_ftp_row]); mdm.Dialogs.prompt("dir: "+_ftp.currentDir+"/"+dir); if (!_ftp.dirExists(dir, mdm.SYNC)) _ftp.makeDir(dir, mdm.SYNC); var success = _ftp.success; mdm.Dialogs.prompt(success) _ftp.refresh(mdm.SYNC); _ftp.chDir(_ftp.currentDir+"/"+_ftp_localFiles[_ftp_row][0], mdm.SYNC); mdm.Dialogs.prompt("Current dir: "+_ftp.currentDir); var success = _ftp.success; mdm.Dialogs.prompt(success) uploadNextFile() } else { updateStatus("\n\nNo others files to upload"); // endUpdate(); } } else uploadNextFile(); // check if there is still file to dldl for this dir return; } // FTP FILE TRANSFERED if (eventType == "FILETRANSFERED") { clearInterval(_ftp_siInterval); dispatchEvent({type: "fileTransfered", target: this}); } // FTP INDEX FILE RECEIVED if (eventType == "INDEXFILERECEIVED") { clearInterval(_ftp_siInterval); dispatchEvent({type: "indexFileReceived", target: this}); } // FTP LISTING DONE if (eventType == "LISTINGDONE") { clearInterval(_ftp_siInterval); dispatchEvent({type: "listingDone", target: this}); } // FTP LOGGED EVENT if (eventType == "LOGGEDIN") { updateStatus("\nLogged in"); if (_ftp_connected == false) { _ftp_connected = true; // switch directory if required if (_ftp != null && _ftp_folder != "none") { _ftp.chDir(_ftp_folder, mdm.SYNC); } else dispatchEvent({type: "loggedIn", target: this}); } return; } // FTP QUIT EVENT if (eventType == "QUIT") { dispatchEvent({type: "quit", target: this}); // nothing return; } // FTP READY EVENT if (eventType == "READY") { dispatchEvent({type: "ready", target: this}); // nothing return; } // FTP RESOLVED LINKS EVENT if (eventType == "RESOLVEDLINKS") { dispatchEvent({type: "resolvedLinks", target: this}); // nothing return; } } function uploadNextFile(Void):Void { // get the row [dir, [fileinfo, ...]] var dir:String = _ftp_localFiles[_ftp_row][0]; mdm.Dialogs.prompt("dir: "+dir+", file: "+dir+_ftp_localFiles[_ftp_row][0]+_ftp_localFiles[_ftp_row][1][_ftp_file][0]) var filesize:Number = mdm.FileSystem.getFileSize(dir+_ftp_localFiles[_ftp_row][0]+_ftp_localFiles[_ftp_row][1][_ftp_file][0]); updateStatus("\n\nUploading new file"); updateStatus("\n - filename: "+_ftp_localFiles[_ftp_row][1][_ftp_file][0]); updateStatus("\n - filesize: "+String(Math.round(filesize / 1024 * 100)/100)+" Kb ("+filesize+" Bytes)"); // tweenFileTo = Math.round( (KbUplded+filesize) * 100 / KbToUpld); // tweening the file bar // mc_progressbar.mc_file.gotoAndStop(tweenFileTo); // loading the file upload(_ftp.currentDir+dir+_ftp_localFiles[_ftp_row][1][_ftp_file][0], dir, _ftp_localFiles[_ftp_row][1][_ftp_file][0], filesize); } /****************************************************************************** * PUBLIC FUNCTIONS ******************************************************************************/ function scanFolder(scanTo:String, returnArray:Array):Void { var rootPath:String; var dispatch:Boolean = true; // adding the "/" at the end of the string if not here if (scanTo.charAt(scanTo.length-1) != "/") scanTo += "/"; rootPath = scanTo; // changing the directory of the ftp _ftp.chDir(scanTo, mdm.SYNC); switch (arguments.length) { case 5: // if we are in a recursive call if (arguments[4] != undefined && typeof(arguments[4]) == 'boolean') dispatch = arguments[4]; case 4: // if we have scan exception or if we are in a recursive call if (arguments[3] != undefined && typeof(arguments[3]) == 'object' && arguments[3].length > 0) var exception:Array = arguments[3];
else if (arguments[3] != undefined && typeof(arguments[3]) == ‘boolean’) dispatch = arguments[3];
case 3:
// path to the root
if (arguments[2] != undefined && typeof(arguments[2]) == ‘string’) rootPath = arguments[2];
break;
}

// get all the file of the folder
var tmpFiles:Array = _ftp.getFileList();
for (var i:Number = 0; i 0) returnArray.push([rootPath, tmpFiles]);

// get all the folder of the folder
var tmpFolder:Array = _ftp.getFolderList();
var allFolder:Array = new Array();
for (var i:Number = 0; i filesize
public function download(r:String, l:String):Void {

var infos:Array = new Array();
infos = getPath(r);

var linfos:Array = new Array();
linfos = getPath(l);

// if the directory is not the same, changing it
if (_ftp.currentDir != infos[1]) _ftp.chDir(infos[1]);

// creating the folder if it not existing
if (!mdm.FileSystem.folderExists(linfos[1])) mdm.FileSystem.makeFolder(linfos[1]);

updateStatus(“\ndownloading “+infos[0]);
if (r != undefined) {
_ftp_localFile = l;
_ftp_remoteFile = infos[0];
_ftp_totalBytes = _ftp.getFileSize(_ftp_remoteFile);
if (isNaN(_ftp_totalBytes)) {
_ftp_totalBytes == null;
updateStatus(“\nCannot get remote file size”);
return;
}
updateStatus(“\nRemote file size: “+_ftp_totalBytes);
_ftp_fileTansfered = false;
if (_ftp != null) {
_ftp_siInterval = setInterval(this, “getTransferProgress”, 500);
// creating the folder in the ftp folder
_ftp.getFile(_ftp_remoteFile, _ftp_localFile, mdm.ASYNC);
}
} else {
_ftp_fileTansfered = true;
updateStatus(“\nCannot get remote file information”);
}
}

// uploading a file
public function upload(lf:String, rd:String, rf:String, fs:Number):Void {
updateStatus(“\nUploading “+lf);
if (fs != undefined) {
_ftp_localFile = lf;
_ftp_remoteFile = rf;
_ftp_totalBytes = fs;
if (isNaN(_ftp_totalBytes)) {
_ftp_totalBytes == null;
updateStatus(“\nCannot get local file size”);
return;
}
updateStatus(“\nLocal file size: “+_ftp_totalBytes);
_ftp_fileTansfered = false;
if (_ftp != null) {
// creating the folder in the ftp folder
_ftp.sendFile(_ftp_localFile, _ftp_remoteFile, mdm.ASYNC);
}
_ftp_siInterval = setInterval(this, “getTransferProgress”, 500);
} else {
_ftp_fileTansfered = true;
updateStatus(“\nCannot get local file size”);
}
}

public function close(Void):Void {
_ftp.close();
}

/******************************************************************************
* GET & SET
******************************************************************************/
public function get ftp_localFiles():Array {return _ftp_localFiles}
public function get ftp_localFile():String {return _ftp_localFile}
public function set ftp_remoteFiles(a:Array) {_ftp_remoteFiles = a}
public function get ftp_remoteFiles():Array {return _ftp_remoteFiles}
public function get ftp_root():String {return _ftp_root}
public function get local_root():String {return _ftp_localRoot}
public function get ftp():mdm.FTP {return _ftp}
} //END CLASS
[/as]

[Download id not defined]

Check the class. I have no time to provide an example nor to explain how it works. But it’s kinda simple. You have a couple of helpfull public function, and in the ftpEventHandler function you can see that events are dispached. So just create your function like eg
[as]
myftp.fileReceived = function () {
// code here
}
[/as]

I know as well that the way I used to call this function is not good. I could simply reference them in the var declaration and called them in my code and then not dispatching any events. I know. Maybe I will revised this code soon…
Anyway it works this way, so if you wanna use it you can…

Cheers

  • leonardo

    hi, i am very impressed by your work. i get very dizzy with all that code. but i have a question šŸ™‚
    how i can list the ftp content in a tree component?
    if you can helpme i will be more than pleased.

    thanks.

  • leonardo

    hi, i am very impressed by your work. i get very dizzy with all that code. but i have a question šŸ™‚
    how i can list the ftp content in a tree component?
    if you can helpme i will be more than pleased.

    thanks.

  • zeflasher

    When scanning the ftp you can have an array of folder. So you jsut need to get this array and have your tree displaying it…
    Check the scanFolder function ( returns an array )
    ++

  • zeflasher

    When scanning the ftp you can have an array of folder. So you jsut need to get this array and have your tree displaying it…
    Check the scanFolder function ( returns an array )
    ++

  • Waldorocko

    Esta clase no me funciona el zinc ahora devuelve otra cadena si el aƱo