Skip to content

Commit 0afdf83

Browse files
committed
1.0.1 - rewrite progress bar+stop button without using storage and project variable
1 parent 05e0a8d commit 0afdf83

15 files changed

Lines changed: 485 additions & 503 deletions

Documentation/Classes/FileTransfer_Dropbox.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ End if
3131
|[.executeCommand](#executecommand)<p>&nbsp;&nbsp;&nbsp;&nbsp;Allows to pass any valid Dropbox command and directly execute it.|
3232
|[.version](#version)<p>&nbsp;&nbsp;&nbsp;&nbsp;returns in result.data version information from Dropbox Command Line Interface Tool|
3333
|[.setPath](#setpath)<p>&nbsp;&nbsp;&nbsp;&nbsp;Allows to use another dbxcli installation.|
34+
|[.enableStopButton](#enablestopbutton)<p>&nbsp;&nbsp;&nbsp;&nbsp;Display stop button in progress dialog.|
3435
|[.setAsyncMode](#setasyncmode)<p>&nbsp;&nbsp;&nbsp;&nbsp;By default all commands are executed synchronously, meaning the command do not return till execution is completed or a timeout occurred. This allows all command to return the result or execution information..|
3536
|[.setTimeout](#settimeout)<p>&nbsp;&nbsp;&nbsp;&nbsp;sets a maximum worker execution time, stopping everything.|
3637
|[.stop](#stop)<p>&nbsp;&nbsp;&nbsp;&nbsp;Terminates the execution of a running operation, such as upload or download.|
@@ -239,6 +240,18 @@ sets a maximum execution time for the worker. By default all operations are stop
239240
The timeout is not considered when asynchronous mode is enabled.
240241

241242

243+
## enableStopButton
244+
245+
### .enableStopButton(enable:Shared Object)
246+
|Parameter|Type||Description|
247+
|---------|--- |:---:|------|
248+
|enable|Object|->|Shared Object with Attribut Stop|
249+
250+
#### Description
251+
Only useable if included or similar ProgressCallback method is used.
252+
If passed it enables the stop button in progress bar, allowing the end user to abort the operation. If Stop button is clicked, attribut of shared object enable.stop is set to true
253+
254+
242255
## setAsyncMode
243256

244257
### .setAsyncMode(async:Boolean)

Documentation/Classes/FileTransfer_GDrive.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ End if
3737
|[.executeCommand](#executecommand)<p>&nbsp;&nbsp;&nbsp;&nbsp;Allows to pass any valid GDrive command and directly execute it.|
3838
|[.version](#version)<p>&nbsp;&nbsp;&nbsp;&nbsp;returns in result.data version information from Gdrive Command Line Interface Tool|
3939
|[.setPath](#setpath)<p>&nbsp;&nbsp;&nbsp;&nbsp;Allows to specify the installation path.|
40+
|[.enableStopButton](#enablestopbutton)<p>&nbsp;&nbsp;&nbsp;&nbsp;Display stop button in progress dialog.|
4041
|[.setAsyncMode](#setasyncmode)<p>&nbsp;&nbsp;&nbsp;&nbsp;By default all commands are executed synchronously, meaning the command do not return till execution is completed or a timeout occurred. This allows all command to return the result or execution information..|
4142
|[.setTimeout](#settimeout)<p>&nbsp;&nbsp;&nbsp;&nbsp;sets a maximum worker execution time, stopping everything.|
4243
|[.stop](#stop)<p>&nbsp;&nbsp;&nbsp;&nbsp;Terminates the execution of a running operation, such as upload or download.|
@@ -350,6 +351,18 @@ Precompiled versions for Mac and Windows can be downloaded from:
350351
[gdrive](https://github.com/prasmussen/gdrive/releases)
351352

352353

354+
## enableStopButton
355+
356+
### .enableStopButton(enable:Shared Object)
357+
|Parameter|Type||Description|
358+
|---------|--- |:---:|------|
359+
|enable|Object|->|Shared Object with Attribut Stop|
360+
361+
#### Description
362+
Only useable if included or similar ProgressCallback method is used.
363+
If passed it enables the stop button in progress bar, allowing the end user to abort the operation. If Stop button is clicked, attribut of shared object enable.stop is set to true
364+
365+
353366
## setAsyncMode
354367

355368
### .setAsyncMode(async:Boolean)

Documentation/Classes/FileTransfer_curl.md

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ For more examples see the method "test_curl".
4343
|[.setCurlPrefix](#setcurlprefix)<p>&nbsp;&nbsp;&nbsp;&nbsp;Allows to use any additional cURL options.|
4444
|[.setPath](#setpath)<p>&nbsp;&nbsp;&nbsp;&nbsp;Allows to use another cURL installation.|
4545
|[.enableProgressData](#enableprogressdata)<p>&nbsp;&nbsp;&nbsp;&nbsp;If enabled, result.data will include progress information text.|
46+
|[.enableStopButton](#enablestopbutton)<p>&nbsp;&nbsp;&nbsp;&nbsp;Display stop button in progress dialog.|
4647
|[.setAsyncMode](#setasyncmode)<p>&nbsp;&nbsp;&nbsp;&nbsp;By default all commands are executed synchronously, meaning the command do not return till execution is completed or a timeout occurred. This allows all command to return the result or execution information..|
4748
|[.setTimeout](#settimeout)<p>&nbsp;&nbsp;&nbsp;&nbsp;sets a maximum worker execution time, stopping everything.|
4849
|[.stop](#stop)<p>&nbsp;&nbsp;&nbsp;&nbsp;Terminates the execution of a running operation, such as upload or download.|
@@ -400,6 +401,17 @@ If enabled, result.data will include progress information text, allowing to get
400401
Depending of total transfer time, the text will include additional lines with progress info.
401402
Automatically enabled if useCallback is enabled.
402403

404+
## enableStopButton
405+
406+
### .enableStopButton(enable:Shared Object)
407+
|Parameter|Type||Description|
408+
|---------|--- |:---:|------|
409+
|enable|Object|->|Shared Object with Attribut Stop|
410+
411+
#### Description
412+
Only useable if included or similar ProgressCallback method is used.
413+
If passed it enables the stop button in progress bar, allowing the end user to abort the operation. If Stop button is clicked, attribut of shared object enable.stop is set to true
414+
403415
## setAsyncMode
404416

405417
### .setAsyncMode(async:Boolean)
@@ -470,7 +482,7 @@ The command returns after given wait time or before if execution is finished.
470482
|Parameter|Type||Description|
471483
|---------|--- |:---:|------|
472484
|callback|4D.Function|->|4d function to call during progress|
473-
|ID|Text|->|unique text to pass to callback method to identify job|
485+
|ID|Text|->|text to display in progress title, such as download file name|
474486

475487
#### Description
476488
Allows to show a progress bar during long running operations or to get informed when command execution is complete.
@@ -481,52 +493,63 @@ The callback method is called whenever a new progress message is available from
481493

482494
```4D
483495
$ftp.useCallback(Formula(ProgressCallback); "Download 4D.dmg")
484-
$ftp.setAsyncMode(True)
485496
$result:=$ftp.download($source; $target)
486-
Repeat
487-
$ftp.wait(1) // needed while our process is running
488-
// wait is not needed if a form would be open or if a worker would handle the job
489-
$status:=$ftp.status()
490-
Until (Bool($status.terminated))
497+
If ($checkstop.stop=True) // user clicked stop button
498+
...
499+
End if
491500
```
492501

493502
Method ProgressCallback
494503

495504
```4D
496-
#DECLARE($ID : Text; $message : Text; $value : Integer)
505+
#DECLARE($ID : Text; $message : Text; $value : Integer; $sharedForProgressBar : Object)
497506
// called from cs.FileTransfer if callback is set via .useCallback()
498507
499508
// $ID is set through code - $message comes from curl
509+
// shared object to pass progress ID back/forth and to share stop button result
500510
501-
var ProgressBarID : Integer
511+
$ProgressBarID:=$sharedForProgressBar.ID
502512
503-
If (ProgressBarID=0)
504-
ProgressBarID:=Progress New
505-
Progress SET MESSAGE(ProgressBarID; $ID)
513+
If (($ProgressBarID=0) && ($value#100))
514+
$ProgressBarID:=Progress New
515+
Use ($sharedForProgressBar)
516+
$sharedForProgressBar.ID:=$ProgressBarID
517+
End use
518+
Progress SET TITLE($ProgressBarID; $ID)
519+
520+
// check if we want stop, if yes, add stop button
521+
If ($sharedForProgressBar.EnableButton#Null)
522+
Progress SET BUTTON ENABLED($ProgressBarID; True)
523+
End if
506524
End if
507525
508-
If ($value=100)
509-
Progress QUIT(ProgressBarID)
510-
ProgressBarID:=0
511-
Else
512-
Progress SET PROGRESS(ProgressBarID; $value/100)
526+
If ($ProgressBarID#0)
527+
If (Progress Stopped($ProgressBarID)) // only if stop button is enabled
528+
Use ($sharedForProgressBar)
529+
$sharedForProgressBar.Stop:=True
530+
Use ($sharedForProgressBar.EnableButton)
531+
$sharedForProgressBar.EnableButton.stop:=True
532+
End use
533+
End use
534+
End if
535+
536+
Case of
537+
: ($value=100)
538+
Progress QUIT($ProgressBarID)
539+
Use ($sharedForProgressBar)
540+
$sharedForProgressBar.ID:=0
541+
End use
542+
: ($value<0)
543+
$message2:=Replace string($message; " "; "") // ignore totally empty messages, happens with gdrive
544+
If ($message2#"")
545+
Progress SET MESSAGE($ProgressBarID; $message)
546+
End if
547+
Else
548+
Progress SET PROGRESS($ProgressBarID; $value/100)
549+
End case
513550
End if
514-
```
515551
516-
To support the stop button in the progress bar, Storage needs to be used to share progress bar and worker IDs. See example in test_curl - download.
517-
```4D
518-
// enable stop button in progress bar
519-
Use (Storage.FileTransfer_Progress)
520-
Storage.FileTransfer_Progress[$progressid]:=New shared object()
521-
End use
522-
$ftp.useCallback(Formula(ProgressCallback); $progressid)
523552
```
524553

525-
After execution of download/upload/etc, check:
526-
```4D
527-
If (Bool(Storage.FileTransfer_Progress[$progressid].Stop)) // check stop button if it was set, remove from storage
528-
// user canceled!!
529-
```
530554

531-
Don't forget to remove the object from storage when done.
532555
See test_curl - download for a full example

Documentation/Readme_curl.MD

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,7 @@ While FTPS is using standard TLS certificates (similar to HTTPS), SFTP is using
9292
[From Wikipedia](https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol)
9393
This protocol assumes that it is run over a secure channel, such as SSH, that the server has already authenticated the client, and that the identity of the client user is available to the protocol.
9494

95-
While you normally do not simply provide credentials (user+password) to login, you need to estabilish upfront a SSH connection to store the ssh key from the SFTP Server in the local keyring. The benefit is that you do not need username+password for login, all goes through keys. But it is possible to use user+password similar as for FTPS, while you need to be aware that in this case you cannot trust that the connection really go to the right server, this is a possible security issue.
96-
97-
Most easiest way to check, exchange and store client and server keys is to open a terminal window (using Terminal on Mac/Terminal or Console on Windows) and enter:
98-
```
99-
ssh username@sftp.servername.com
100-
```
101-
102-
This will request the password and display the ssh hash, asking if you accept to store it in your .ssh/authorized_keys file.
103-
In a similar way you could exchange keys upfront to avoid using passwords at all to enhance security.
104-
Google "ssh key authentication" for more help and examples.
105-
106-
As soon the authentication was done once via ssh (or the key is stored in your authorized_keys file by another way), the class can be used without providing credentials, just the URL is enough.
95+
Using SFTP you might either use username+password as you would do with FTPS, or exchange keys. To use SFTP via keys, establish upfront a SSH connection using Terminal, this setup will be reused from cURL.
10796

10897
# Class Documentation
10998

Project/Sources/Classes/FileTransfer_Dropbox.4dm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ Function setTimeout($timeout : Integer)
111111
Function setAsyncMode($async : Boolean)
112112
This:C1470._async:=$async
113113

114+
Function enableStopButton($enable : Object)
115+
This:C1470._enableStopButton:=$enable
116+
114117
Function stop()
115118
If (This:C1470._worker#Null:C1517)
116119
This:C1470._worker.terminate()
@@ -155,7 +158,7 @@ Function _parseDirListing($success : Object)
155158

156159
Function _runWorker($para : Text)->$result : Object
157160
If (This:C1470._Callback#Null:C1517)
158-
$workerpara:=cs:C1710.SystemWorkerProperties.new("dropbox"; This:C1470.onData; This:C1470._Callback; This:C1470._CallbackID)
161+
$workerpara:=cs:C1710.SystemWorkerProperties.new("dropbox"; This:C1470.onData; This:C1470._Callback; This:C1470._CallbackID; This:C1470._enableStopButton)
159162
Else
160163
$workerpara:=cs:C1710.SystemWorkerProperties.new("dropbox"; This:C1470.onData)
161164
End if

Project/Sources/Classes/FileTransfer_GDrive.4dm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ Function useCallback($callback : 4D:C1709.Function; $ID : Text)
318318
Function setAsyncMode($async : Boolean)
319319
This:C1470._async:=$async
320320

321+
Function enableStopButton($enable : Object)
322+
This:C1470._enableStopButton:=$enable
323+
321324
Function setTimeout($timeout : Integer)
322325
This:C1470._timeout:=$timeout
323326

@@ -373,7 +376,7 @@ Function _parseDirListing($success : Object)
373376

374377
Function _runWorker($para : Text)->$result : Object
375378
If (This:C1470._Callback#Null:C1517)
376-
$workerpara:=cs:C1710.SystemWorkerProperties.new("gdrive"; This:C1470.onData; This:C1470._Callback; This:C1470._CallbackID)
379+
$workerpara:=cs:C1710.SystemWorkerProperties.new("gdrive"; This:C1470.onData; This:C1470._Callback; This:C1470._CallbackID; This:C1470._enableStopButton)
377380
Else
378381
$workerpara:=cs:C1710.SystemWorkerProperties.new("gdrive"; This:C1470.onData)
379382
End if

Project/Sources/Classes/FileTransfer_curl.4dm

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Class constructor($hostname : Text; $username : Text; $password : Text; $protoco
1717
This:C1470._return:=Char:C90(10) //Char(13)+Char(10)
1818
End if
1919
This:C1470._timeout:=0
20+
This:C1470._enableStopButton:=False:C215
2021

2122
//MARK: Settings
2223
Function validate()->$success : Object
@@ -75,6 +76,9 @@ Function setPath($path : Text)
7576
Function enableProgressData($enable : Boolean)
7677
This:C1470._noProgress:=Not:C34($enable)
7778

79+
Function enableStopButton($enable : Object)
80+
This:C1470._enableStopButton:=$enable
81+
7882
Function useCallback($callback : 4D:C1709.Function; $ID : Text)
7983
ASSERT:C1129(Value type:C1509($callback)=Is object:K8:27; "Callback must be of type function")
8084
ASSERT:C1129(OB Instance of:C1731($callback; 4D:C1709.Function); "Callback must be of type function")
@@ -303,7 +307,7 @@ Function _buildURL()->$url : Text
303307

304308
Function _runWorker($para : Text)->$result : Object
305309
If (This:C1470._Callback#Null:C1517)
306-
$workerpara:=cs:C1710.SystemWorkerProperties.new("curl"; This:C1470.onData; This:C1470._Callback; This:C1470._CallbackID)
310+
$workerpara:=cs:C1710.SystemWorkerProperties.new("curl"; This:C1470.onData; This:C1470._Callback; This:C1470._CallbackID; This:C1470._enableStopButton)
307311
Else
308312
$workerpara:=cs:C1710.SystemWorkerProperties.new("curl"; This:C1470.onData)
309313
End if
@@ -338,7 +342,6 @@ Function _runWorker($para : Text)->$result : Object
338342
$command:=$path+" "+$para
339343
$old:=Method called on error:C704
340344
ON ERR CALL:C155(Formula:C1597(ErrorHandler).source)
341-
$workerpara.variables:=New object:C1471("userCancel"; "false")
342345
This:C1470._worker:=4D:C1709.SystemWorker.new($command; $workerpara)
343346
$worker:=This:C1470._worker
344347

@@ -348,25 +351,22 @@ Function _runWorker($para : Text)->$result : Object
348351
Else
349352
$waittimeout:=(This:C1470._timeout=0) ? 60 : This:C1470._timeout
350353
$worker.wait($waittimeout)
351-
If (Bool:C1537($worker.userCancel))
352-
$result:=New object:C1471("responseError"; "Cancel by user"; "success"; False:C215)
353-
Else
354-
If (($worker.responseError#Null:C1517) && ($worker.responseError#""))
355-
$result:=New object:C1471("responseError"; $worker.responseError; "success"; False:C215)
356-
$pos:=Position:C15("curl: "; $worker.responseError; *)
357-
If ($pos>0)
358-
$result.error:=Replace string:C233(Substring:C12($worker.responseError; $pos+6); Char:C90(10); "")
354+
355+
If (($worker.responseError#Null:C1517) && ($worker.responseError#""))
356+
$result:=New object:C1471("responseError"; $worker.responseError; "success"; False:C215)
357+
$pos:=Position:C15("curl: "; $worker.responseError; *)
358+
If ($pos>0)
359+
$result.error:=Replace string:C233(Substring:C12($worker.responseError; $pos+6); Char:C90(10); "")
360+
Else
361+
// seems not to be an error, curl set's process bar in error and no result in response.
362+
If ($worker.response#"")
363+
$result:=New object:C1471("data"; $worker.response; "success"; True:C214)
359364
Else
360-
// seems not to be an error, curl set's process bar in error and no result in response.
361-
If ($worker.response#"")
362-
$result:=New object:C1471("data"; $worker.response; "success"; True:C214)
363-
Else
364-
$result:=New object:C1471("data"; $worker.responseError; "success"; True:C214)
365-
End if
365+
$result:=New object:C1471("data"; $worker.responseError; "success"; True:C214)
366366
End if
367-
Else
368-
$result:=New object:C1471("data"; $worker.response; "success"; True:C214)
369367
End if
368+
Else
369+
$result:=New object:C1471("data"; $worker.response; "success"; True:C214)
370370
End if
371371
End if
372372
Else

0 commit comments

Comments
 (0)