B4J Tutorial [ABMaterial] New component ABMFileManager (4.25)

alwaysbusy

Expert
Licensed User
ABMFileManager is a new component in the upcoming ABM 4.25 to manage files on your server (where the .jar file runs), but is not limited to the www folder. This feature makes it very useful on e.g. a Raspberry Pi!

This is an ABMaterial Original, meaning it has been written from the ground up (html,css,js) and not based on an existing library.

This component needs the JSON library to function properly!

Some of ABMFileManagers unique features:
  • Not limited to your www folder
  • Select files (folders on desktop too)
  • Cut/Copy/Paste files (folders on desktop too)
  • Delete files (folders on desktop too)
  • Common file type icons
  • Auto Image thumbnail generation
  • Download files (folders on desktop too)
  • Upload files (drag drop from desktop)
  • Auto zipping of files to download
  • List or grid view
  • Lots of options to tune (.CanCopy/.CanPaste...)
Demo video:


Usage (The source code is for a completely working file manager):

B4X:
Sub Class_Globals 
   ...
   Public DownloadFolder As String = "/www/" & ABMShared.AppName & "/uploads/"
   Public DownloadMaxSize As String = 100*1024
  
   ' For the download
   Dim JobID As Int
   ' For the renaming  
   Dim CurrentOldFileName As String  
   ' the Root folder must be an absolute path on your server
   Dim RootFolder As String = File.DirApp & "/ForTestFileManager"
   ' thumbnail path is a full path and must be the www folder because the internet has to be able to reach it for images!
   Dim ThumbnailFolder As String = File.DirApp & "/www/" & ABMShared.AppName & "/thumbnails"
End Sub
B4X:
public Sub BuildPage()
   ...
   ' lets make sure some folders do exist
   File.MakeDir(File.DirApp, "www/" & ABMShared.AppName & "/thumbnails")
   File.MakeDir(File.DirApp, "www/" & ABMShared.AppName & "/temp")
   ...
End Sub
B4X:
Sub ConnectPage()
   ...
   ' needed to set the height  
   page.Cell(2,1).SetFixedHeight(500, False)
  
   Dim FileManager As ABMFileManager
   FileManager.Initialize(page, "FileManager", RootFolder, "filemanager")
   FileManager.ShowBigIcons = True
   ' needed if you want to allow uploading to the server
   FileManager.SetUploadOptions("/" & ABMShared.AppName & "/" & Name & "/abmuploadhandler", DownloadMaxSize, Null)
   page.Cell(2,1).AddComponent(FileManager)
   ...

   page.Refresh ' IMPORTANT
  
   ' NEW, because we use ShowLoaderType=ABM.LOADER_TYPE_MANUAL
   page.FinishedLoading 'IMPORTANT
  
   page.RestoreNavigationBarPosition
  
   ' AFTER the page has been refreshed
   FileManager.LoadFolder("", ThumbnailFolder, True)
  
   ws.Session.SetAttribute("abmcallback", Me)
   ws.Session.SetAttribute("abmdownloadfolder", DownloadFolder)
   ws.Session.SetAttribute("abmmaxsize", DownloadMaxSize)
   ws.Session.SetAttribute("abmtargetfolder", FileManager.CurrentFullPath)
End Sub
B4X:
Sub FileManager_FolderChange(folder As String)
   Log("folder: " & folder)
   Dim FileManager As ABMFileManager = page.Component("FileManager")
   FileManager.LoadFolder(folder, ThumbnailFolder, True)
   ws.Session.SetAttribute("abmtargetfolder", FileManager.CurrentFullPath)
End Sub

Sub FileManager_RequestForDownload(jsonList As String)
   page.Pause
   Dim FileManager As ABMFileManager = page.Component("FileManager")
  
   Dim json As JSONParser
   json.Initialize(jsonList)
  
   Dim files As List
   files = FileManager.ExtractFullPathFileNamesFromJson(json, FileManager.CurrentFullPath)
  
   JobID = JobID + 1
      
   ABM.Util.Zip(files, File.DirApp & "/www/" & ABMShared.AppName & "/temp", JobID & ".zip")
   FileManager.StartDownload("../temp/" &  JobID & ".zip", "Files.zip", JobID)
End Sub

Sub FileManager_Downloaded(jobcode As String)
   File.Delete(File.DirApp & "/www/" & ABMShared.AppName & "/temp", JobID & ".zip")
   page.Resume
End Sub

Sub FileManager_RequestForDelete(jsonList As String)
   Dim FileManager As ABMFileManager = page.Component("FileManager")
  
   Dim json As JSONParser
   json.Initialize(jsonList)
  
   Dim files As List
   files = FileManager.ExtractFileNamesFromJson(json)
   For i = 0 To files.Size - 1
       DeleteFiles(FileManager.CurrentFullPath, files.Get(i))
       myToastId = myToastId + 1
       page.ShowToast("toast" & myToastId, "toastred", files.Get(i) & " deleted", 3000, False)
   Next
  
   FileManager.LoadFolder(FileManager.CurrentPath, ThumbnailFolder, True)
End Sub

Sub DeleteFiles(FullPath As String, fileName As String)
   If File.IsDirectory(FullPath, fileName) Then
       Dim files As List
       files = File.ListFiles(FullPath & "/" & fileName)
       For i = 0 To files.Size - 1
           DeleteFiles(FullPath & "/" & fileName, files.Get(i))
       Next
   End If
   File.Delete(FullPath,fileName)
End Sub

Sub Page_FileUploaded(FileName As String, success As Boolean)
   myToastId = myToastId + 1
   page.ShowToast("toast" & myToastId, "toastgreen", "Uploaded " & FileName, 3000, False)
End Sub

Sub FileManager_UploadStarted()
   Log("Upload started")
   page.Pause
End Sub

Sub FileManager_Uploaded()
   Log("Uploaded")
   Dim FileManager As ABMFileManager = page.Component("FileManager")
   FileManager.LoadFolder(FileManager.CurrentPath, ThumbnailFolder, True)
   page.Resume
End Sub

Sub FileManager_UploadFailed(status As String, message As String)
   Log("Upload failed: " & message)
   myToastId = myToastId + 1
   page.ShowToast("toast" & myToastId, "toastred", "There was an error uploading the files!", 3000, False)
   page.Resume
End Sub

Sub FileManager_RequestForCopyPaste(fromFolder As String, jsonList As String)
   Dim FileManager As ABMFileManager = page.Component("FileManager")
  
   Dim json As JSONParser
   json.Initialize(jsonList)
  
   Dim files As List
   files = FileManager.ExtractFileNamesFromJson(json)
   For i = 0 To files.Size - 1
       If fromFolder <> "" Then
           Log("Copy " & FileManager.RootFolder & "/" & fromFolder & "/" & files.Get(i) & " to " & FileManager.CurrentFullPath & "/" & files.Get(i))
           CopyFiles(FileManager.RootFolder & "/" & fromFolder, files.Get(i), FileManager.CurrentFullPath, files.Get(i))
       Else ' root
           Log("Copy " & FileManager.RootFolder & "/" & files.Get(i) & " to " & FileManager.CurrentFullPath & "/" & files.Get(i))
           CopyFiles(FileManager.RootFolder, files.Get(i), FileManager.CurrentFullPath, files.Get(i))
       End If
   Next
   FileManager.LoadFolder(FileManager.CurrentPath, ThumbnailFolder, True)
   myToastId = myToastId + 1
   page.ShowToast("toast" & myToastId, "toastgreen", "Files copied and pasted!", 3000, False)
End Sub

Sub CopyFiles(srcFullPath As String, srcfileName As String, tgtFullPath As String, tgtfileName As String)
   If File.IsDirectory(srcFullPath, srcfileName) Then
       File.MakeDir(tgtFullPath, srcfileName)
       Dim files As List
       files = File.ListFiles(srcFullPath & "/" & srcfileName)
       For i = 0 To files.Size - 1
           CopyFiles(srcFullPath & "/" & srcfileName, files.Get(i), tgtFullPath & "/" & tgtfileName, files.Get(i))
       Next
   Else
       Dim counter As Int = 0
       If File.Exists(tgtFullPath, tgtfileName) Then
           Dim tgtFileNameBody As String
           Dim tgtFileNameExt As String
           Dim j As Int = tgtfileName.LastIndexOf(".")
           If j > -1 Then
               tgtFileNameBody = tgtfileName.SubString2(0, j)
               tgtFileNameExt = tgtfileName.SubString(j)
           Else
               tgtFileNameBody = tgtfileName
           End If
           Do While File.Exists(tgtFullPath, tgtfileName)
               counter = counter + 1
               tgtfileName = tgtFileNameBody & " (" & counter & ")" & tgtFileNameExt
           Loop
       End If
       File.Copy(srcFullPath, srcfileName, tgtFullPath, tgtfileName)
   End If
End Sub

Sub FileManager_RequestForCutPaste(fromFolder As String, jsonList As String)
   Dim FileManager As ABMFileManager = page.Component("FileManager")
  
   Dim json As JSONParser
   json.Initialize(jsonList)
  
   Dim files As List
   files = FileManager.ExtractFileNamesFromJson(json)
   For i = 0 To files.Size - 1
       If fromFolder <> "" Then
           Log("Cut " & FileManager.RootFolder & "/" & fromFolder & "/" & files.Get(i) & " to " & FileManager.CurrentFullPath & "/" & files.Get(i))
           CutFiles(FileManager.RootFolder & "/" & fromFolder, files.Get(i), FileManager.CurrentFullPath, files.Get(i))
       Else ' root
           Log("Cut " & FileManager.RootFolder & "/" & files.Get(i) & " to " & FileManager.CurrentFullPath & "/" & files.Get(i))
           CutFiles(FileManager.RootFolder, files.Get(i), FileManager.CurrentFullPath, files.Get(i))
       End If
   Next
   FileManager.LoadFolder(FileManager.CurrentPath, ThumbnailFolder, True)
   myToastId = myToastId + 1
   page.ShowToast("toast" & myToastId, "toastgreen", "Files cut & pasted!", 3000, False)
End Sub

Sub CutFiles(srcFullPath As String, srcfileName As String, tgtFullPath As String, tgtfileName As String)
   If File.IsDirectory(srcFullPath, srcfileName) Then
       File.MakeDir(tgtFullPath, srcfileName)
       Dim files As List
       files = File.ListFiles(srcFullPath & "/" & srcfileName)
       For i = 0 To files.Size - 1
           CutFiles(srcFullPath & "/" & srcfileName, files.Get(i), tgtFullPath & "/" & tgtfileName, files.Get(i))
       Next
       File.Delete(srcFullPath, srcfileName)
   Else
       ABM.Util.MoveFile(srcFullPath, srcfileName, tgtFullPath, tgtfileName)
   End If
End Sub

Sub FileManager_RequestForRename(oldFileName As String)
   CurrentOldFileName=oldFileName
   page.InputBox("RenameInput", "Enter the new name","OK", "CANCEL", True, ABM.INPUTBOX_TYPE_QUESTION, ABM.INPUTBOX_QUESTIONTYPE_TEXT,oldFileName,"", "", "Not a valid name",False, ABM.MSGBOX_POS_CENTER_CENTER,"")
End Sub

Sub FileManager_RequestForCreateFolder()
   page.InputBox("CreateInput", "Enter the new folder name","OK", "CANCEL", True, ABM.INPUTBOX_TYPE_QUESTION, ABM.INPUTBOX_QUESTIONTYPE_TEXT,"","", "", "Not a valid name",False, ABM.MSGBOX_POS_CENTER_CENTER,"")
End Sub

Sub Page_InputboxResult(returnName As String, result As String)
   If result <> "abmcancel" Then
       Select Case returnName
           Case "RenameInput"
               Dim FileManager As ABMFileManager = page.Component("FileManager")
  
               ABM.Util.RenameFile(FileManager.CurrentFullPath, CurrentOldFileName, result)
               FileManager.LoadFolder(FileManager.CurrentPath, ThumbnailFolder, True)
  
               myToastId = myToastId + 1
               page.ShowToast("toast" & myToastId, "toastgreen", "File renamed!", 3000, False)
           Case "CreateInput"
               Dim FileManager As ABMFileManager = page.Component("FileManager")
  
               File.MakeDir(FileManager.CurrentFullPath, result)
               FileManager.LoadFolder(FileManager.CurrentPath, ThumbnailFolder, True)
  
               myToastId = myToastId + 1
               page.ShowToast("toast" & myToastId, "toastgreen", "Folder created!", 3000, False)
       End Select
   End If
End Sub
Also needs a small change in the ABMUploadHandler:

B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
   ...
   ' NEW version 4.25 to handle ABMFileManager
   Dim targetfolder As String
   If  req.GetSession.HasAttribute("abmtargetfolder") Then
       targetfolder = req.GetSession.GetAttribute("abmtargetfolder")
   End If
   ...
       If filePart.IsInitialized Then
           fileName =    filePart.SubmittedFilename
           tmpFileName = filePart.TempFile
          
           ' NEW version 4.25 to handle ABMFileManager
           If targetfolder <> "" Then
               downloadfolder = targetfolder
           End If
          
           If ABM.HandleUpload(downloadfolder, tmpFileName, fileName) Then
   ...
End Sub
 

joulongleu

Active Member
Licensed User
Hi:AlwaysBusy ABMFileManager is very good,how to use open event? Let everyone can open the file directly.
thank you .
 
Top