Previous  |  Main  |  Next
AppleScript Logo

Open Several from FTP Server

Script for: BBEdit
Copyright: Matthias Steffens, use at your own risk!
Description: For use in conjunction with Anarchie. Let's you open several files from
your FTP server at once.

This script requires that you have a mirror of your web site on your local
machine and that it is specified as 'local site root' within the BBEdit HTML
Preferences (Edit:Preferences:HTML Web Site). Additionally your server
URL and the site path on the server must be specified there.

The script will scan a specified folder (inside your local mirror folder)
for files of a certain type (e.g. HTML or perl). The files found will be
presented within a list, where you can choose those you'd like to edit.
All selected files are fetched by Anarchie from the ftp server and opened
in BBEdit. After you're done Anarchie will save them back to the server.

Upon the first start the script will ask you for your user name and password,
which will be remembered until you specify a new server URL or path within
the BBEdit HTML Preferences or recompile the script.
(Caution: Your password will not be encrypted!)

Note that since this script builts upon the BBEdit HTML Prefs it can only
handle one site at a time. If you need to edit files located on different servers,
you might want to check Walter Ian Kaye's "BBE FTP Open..." script.
Necessary: StandardAdditions.hqx from MacOS 8.5.x or greater  (command: "choose from list")
Tanaka's osax 2.0  (command: "MT List Files")
Choose Files & Folders  (command: "LNS choose folder")
ACME Script Widgets 2.5 (or greater)  (commands: "trim", "ACME replace", "ACME sort", "tokenize")
Note that this Scripting Addition is shareware.
Download: OpenSeveral_from_FTP.hqx
The Script:
-- This list defines the file types that are initially available (they can be edited easily from within the script):
property AvailableFileTypes : {".html", ".shtml", ".txt", ".pl", ".css"}

-- do not edit these three properties, the script will ask you for necessary information when needed
property FTPhost : 0
property FTPuser : 0
property FTPpassword : 0

-- you don't need to edit this one:  (the script will give you the possibility to choose the file types)
property ChoosenFileTypes : {".html", ".txt", ".css"}

property FolderToScan : 0 -- do not edit this one, the script will ask you for the folder to scan

global NameofFolderToScan, theHTMLprefsRoot, theHTMLprefsServerPath, FileTypesForDisplay

-- let's get started and check if relevant information in the BBEdit Prefs has been changed:
set Die to my CheckHTMLPrefs()

if not Die then -- check if the formerly specified search folder exists
	tell application "Finder"
		try
			my MergeFileTypesForDisplay(ChoosenFileTypes)
			if (exists file FolderToScan) then
				tell application "Finder" to set NameofFolderToScan to name of FolderToScan -- necessary if folder was renamed
				my MainDialog()
			else
				-- if folder wasn't found (script was newly compiled or due to other errors) the script will ask for a search folder:
				my GetFolderToScan()
			end if
		on error ErrText number errNo
			if errNo is not -128 then -- if user didn't press 'cancel':
				if errNo is 32768029 then -- "file not found"
					my GetFolderToScan()
				else -- present an error message
					display dialog "The following error has occurred:" & return & return & ErrText & return & ¬
						"(Error Code: " & errNo & ")" with icon caution buttons {"OK"} default button 1
				end if
			end if
		end try
	end tell
end if


on MainDialog() -- the main dialog
	set dialogResult to display dialog ¬
		"Scan folder: \"" & NameofFolderToScan & "\"" & return & return & ¬
		"Path: " & "\"" & FolderToScan & "\"" & return & return & ¬
		"Scan for files of type: " & FileTypesForDisplay ¬
		buttons {"Set File Types", "Choose Folder|Cancel", "Scan Folder"} default button 3
	if button returned of dialogResult is "Scan Folder" then
		my BuiltFileList()
	end if
	if button returned of dialogResult is "Choose Folder|Cancel" then
		my GetFolderToScan()
	end if
	if button returned of dialogResult is "Set File Types" then
		my SetFileTypes()
	end if
end MainDialog


on BuiltFileList() -- builts a list of files that match the file types specified
	set nothingFound to {}
	set FilesFound_RelativePath to {}
	
	repeat with FileType in ChoosenFileTypes
		set FilesFound_FullPath to MT List Files FolderToScan name contains FileType of attribute {visible:true} return as string with sub folders -- uses "Tanaka's osax 2.0"
		if FilesFound_FullPath is not {} then
			copy 1 to end of nothingFound
			repeat with filepath in FilesFound_FullPath
				if filepath starts with theHTMLprefsRoot then
					set temp to trim theHTMLprefsRoot off filepath from front side -- make a relative path (uses "ACME Script Widgets")
					set temp to ACME replace ":" in temp with "/" -- make an URL out of it (uses "ACME Script Widgets")
					if temp is not in FilesFound_RelativePath then
						copy temp to end of FilesFound_RelativePath
					end if
				end if
			end repeat
		else
			copy 0 to end of nothingFound
		end if
	end repeat
	
	if 1 is not in nothingFound then
		set dialogResult to display dialog "No files were found matching the file types specified." with icon note buttons {"Cancel", "Start Again"} default button 2
		if button returned of dialogResult is "Start Again" then
			my MainDialog()
		end if
	else
		if FilesFound_RelativePath is not {} then
			set FilesFound_RelativePath to ACME sort FilesFound_RelativePath -- uses "ACME Script Widgets"
			-- presents a list with all the files found:
			set dialogResult to choose from list FilesFound_RelativePath with prompt ¬
				"Choose one or more files to edit:" OK button name "Get File(s)" cancel button name ¬
				"Back" default items "index.html" with multiple selections allowed without empty selection allowed
			if dialogResult is not false then -- if false: user pressed "Back"
				set FilesToEdit to dialogResult
				my FetchFiles(FilesToEdit)
			else
				my MainDialog()
			end if
		else
			my Compare_FolderToScan_WITH_theHTMLprefsRoot(FolderToScan, true) -- check if the FolderToScan still is in the root directory
		end if
	end if
end BuiltFileList


on FetchFiles(FilesToEdit) -- get the selected files with Anarchie
	tell application "Anarchie"
		repeat with FileToEdit in FilesToEdit
			set Err to edit host FTPhost user FTPuser password FTPpassword path FileToEdit
		end repeat
	end tell
end FetchFiles


on GetFolderToScan() -- choose the folder that will be scanned for files to edit
	-- requires the scripting addition "Choose Files & Folders":
	-- by using this scripting addition your local site root can be displayed by default within the dialog
	-- note that the FolderToScan must be *within* your local site root directory!
	-- (if you specify a folder *outside* of your root directory you'll be prompted to choose a folder again)
	set dialogResult to LNS choose folder with prompt "Choose your local site root or a folder within:" starting at theHTMLprefsRoot
	
	set Die to my Compare_FolderToScan_WITH_theHTMLprefsRoot(dialogResult, true) -- check if the FolderToScan still is in the root directory
	
	if not Die then
		set FolderToScan to dialogResult
		tell application "Finder" to set NameofFolderToScan to name of FolderToScan
		my MainDialog()
	end if
end GetFolderToScan


on SetFileTypes() -- presents a list where you can choose the recognized file types (or edit the list of available file types)
	set dialogResult to choose from list AvailableFileTypes with prompt ¬
		"Recognized file types:" & return & "(multiple selections allowed)" OK button name "OK" cancel button name ¬
		"Edit List | Cancel" default items ChoosenFileTypes with multiple selections allowed without empty selection allowed
	if dialogResult is not false then -- if false: user pressed "Edit List"
		set ChoosenFileTypes to dialogResult
		my MergeFileTypesForDisplay(ChoosenFileTypes)
		my MainDialog()
	else
		my MergeFileTypesForDisplay(AvailableFileTypes)
		set dialogResult to display dialog "Edit the list of available file types:" & return & ¬
			"(separating entries with spaces will suffice)" default answer FileTypesForDisplay with icon note buttons {"Cancel", "Back", "Change"} default button 3
		if button returned of dialogResult is "Change" then
			set AvailableFileTypes to tokenize (text returned of dialogResult) with delimiters {"\"", ",", " ", return} without null tokens -- uses "ACME Script Widgets"
			my SetFileTypes()
		else if button returned of dialogResult is "Back" then
			my SetFileTypes()
		end if
	end if
end SetFileTypes


on MergeFileTypesForDisplay(TheItems) -- merge the list of file types for display purposes:
	set old_delims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "\", \""
	copy TheItems as text to FileTypesForDisplay
	set FileTypesForDisplay to "\"" & FileTypesForDisplay & "\""
	set AppleScript's text item delimiters to old_delims
end MergeFileTypesForDisplay


on CheckHTMLPrefs() -- get's the current 'server URL', the 'site path on server' and the path to the 'local site root' from your BBEdit HTML Prefs
	tell application "BBEdit 5.1" -- local paths will be checked for availability and server URL & path will be compared with the stored data
		set Die to true
		get html preferences
		set theHTMLprefs to result
		set theHTMLprefsRoot to root directory of theHTMLprefs as text -- will be used as default directory
		try
			tell application "Finder" -- check if root directory exists
				if (not (exists file (theHTMLprefsRoot as alias))) then -- errors if root directory was renamed or deleted
					set Die to true
					error
				else
					set Die to my Compare_FolderToScan_WITH_theHTMLprefsRoot(FolderToScan, false) -- check if the FolderToScan still is in the root directory
				end if
			end tell
		on error number errNo
			if errNo is not -128 then
				set Die to true
				set dialogResult to display dialog "Can't find the root directory:" & return & return & ¬
					"\"" & theHTMLprefsRoot & "\"" & return & return & ¬
					"If you've renamed it while BBEdit is running try to specify it again. " & ¬
					"(\"Edit>Preferences>HTML Web Site\")" with icon caution buttons {"Cancel"} default button 1
			end if
		end try
		if not Die then
			set theHTMLprefsServerPath to trim {"http://", "ftp://"} off (server url of theHTMLprefs as text) from front side
			
			if theHTMLprefsServerPath = "" then -- there is no web server name specified within the BBEdit HTML Prefs
				set dialogResult to display dialog "No web server name specified in the BBEdit HTML Prefs!" & return & return & ¬
					"Please supply the server URL and the server path to your site." & return & return & ¬
					"(\"Edit>Preferences>HTML Web Site\")" with icon caution buttons {"OK"} default button 1
				set Die to true
			else
				set theHTMLprefsServerPath to theHTMLprefsServerPath & (server path of theHTMLprefs as text)
				
				if theHTMLprefsServerPath is not FTPhost then -- either the server URL and/or the site path on server was changed within the BBEdit Prefs
					set FolderToScan to 0 -- "set ... to 0" causes the script to prompt for these data again
					set FTPuser to 0
					set FTPpassword to 0
					set Die to my CheckFTPuserFTPpassword()
					if not Die then set FTPhost to theHTMLprefsServerPath
				else
					set Die to false
				end if
			end if
		end if
	end tell
	return Die
end CheckHTMLPrefs


on CheckFTPuserFTPpassword() -- if user name and/or password are not specified (because it's the first run or 'cause a new site was specified) this will ask again for these data
	set Die to false
	if FTPuser = 0 then
		set dialogResult to display dialog "Enter the user name for the Web Site:" & return & return & "\"" & theHTMLprefsServerPath & "\"" default answer "" with icon note buttons {"Cancel", "OK"} default button 2
		if button returned of dialogResult is "OK" then
			set FTPuser to text returned of dialogResult
		else
			set Die to true
		end if
	end if
	
	if not Die then
		if FTPpassword = 0 then
			set dialogResult to display dialog "Enter the password for the Web Site:" & return & return & "\"" & theHTMLprefsServerPath & "\"" default answer "" with icon note buttons {"Cancel", "OK"} default button 2
			if button returned of dialogResult is "OK" then
				set FTPpassword to text returned of dialogResult
			else
				set Die to true
			end if
		end if
	end if
	
	return Die
end CheckFTPuserFTPpassword


on Compare_FolderToScan_WITH_theHTMLprefsRoot(FolderToCheck, DisplayWarning) -- check if the FolderToScan is in the root directory
	if (FolderToCheck as text) does not start with theHTMLprefsRoot then -- true if either the root directory was changed or the FolderToScan was deleted or a folder outside the current root directory was choosen
		if DisplayWarning then
			set dialogResult to display dialog "You have to stick to your local site root folder in order to use this script." with icon note buttons {"Cancel", "Choose Folder"} default button 2
			if button returned of dialogResult is "Choose Folder" then
				set Die to false
				my GetFolderToScan()
			else
				set Die to true -- cancel
			end if
		else -- no warning if this happens at startup of the script
			set Die to false
			set FolderToScan to 0
		end if
	else -- everything's fine
		set Die to false
	end if
	
	return Die
end Compare_FolderToScan_WITH_theHTMLprefsRoot

 


Contact: Matthias Steffens  |  Previous  |  Main  |  Next  |  Last Updated: 15-Mar-05