Example of TTMSFMXCloudDropbox.HttpsPut

COMPONENT: TMS FMX Cloud Pack

I have sent this to support, I literally forgot about the forum, so here goes:


I have the VCL cloud pack and am trying the FMX version. Because of limitations with the VCL and FMX TMS component some time ago we had to purchase a different Dropbox component. However i now see that FMX.TMSCloudDropbox has a method called HTTPPUT (as well as other options). This is fantastic news for us and will allow us to use only the TMS components (I do not see the same methods with the VCL version and stumbled onto it in the FMX version by accident). 

TMS documentation is very sparse and really only goes into common aspects as one document tries to be a manual for all cloud services so it is very limited and missing quite a bit. I have looked through the demos and they are equally sparse with no examples of HTTPPUT and have looked through the forum, again nothing. What would the code look like to send the Dropbox command "/sharing/list_folders". I have left in Bold the parts I just don"t know what to put? Since I cannot find any documentation or examples that cover this method (or these methods), can you please complete so that I might continue on with the FMX Cloud Pack Demo (which would be worth purchasing for this feature alone)???

TTMSFMXCloudDropbox.HttpsPut(DROPBOX_BASE_URL + "/sharing/list_folders", tgtdir,  tgtfn, CustomHeaders, CustomData,    hcput);   NOTE: I assume the final parameter is hcput, b ut I could be wrong?

Again, many assumptions, I assume the URL is the full URL of REST call. In this case it is:

       https://api.dropboxapi.com/2/sharing/list_folders

 I further assume the Command (last parameter) is "hcput" which seems redundant since I am performing a HttpsPut? The other parameters then no idea. A little documentation and example would go a long way.

Anyway, any help appreciated especially an example with notes, ie. the URL is XXXX and of the form yyyyy?

As noted, this is a potential big deal for me. I can simply get rid of a component and all of my internal modding to return simply the JSON string result which I already have code that parses it correctly.

Kevin 

Hi,


First of all, please note that the HttpsPut (and related) methods are shared between multiple controls in the TMS FMX Cloud Pack which is why the last parameter so we are able to differentiate what happens for different controls.

About the "tgtdir" and "tgtfn" parameters. These refer to the target directory and target filename which are required when uploading files which the HttpsPut method is used for.

About the "CustomHeaders" and "CustomData" parameters. These can be used to add headers and data to the HttpRequest if required.

The documentation mentions a POST request instead of a PUT request for this particular endpoint.
So I would recommend using HttpsPost instead.

https://www.dropbox.com/developers/documentation/http/documentation#sharing-list_folders

Examples can be found in the TTMSFMXDropBox source code where HttpsPost calls are used in multiple places.

Hi Bart,


Yes a Freudian slip, it should be HTTPSPost (which is what it is in my code using the other component) and not HTTPPut. I see where the he target folder and target file name are required for the Put endpoint. 

As you note, the code is common for many/all types of cloud software. That?s the problem I?m having, in that I?m finding the documentation confusing and (for me at least) incomplete. For example, the HTTPPut / HTTPPost / HTTPxxxx isn?t documented anywhere that I can find and I stumbled on it by accident. I don?t see it with the VCL Cloud Pack, I have no idea whether it?s available. 

For me, I need those methods since TMS CloudItems/TMS Dropboxitems fails to return IMHO VERY IMPORTANT folder properties. Again, for example, I cannot see where the Folder share name is returned (you need this to determine whether the folder is shared). The Dropbox Folder ID is NOT returned. Without that you simply cannot get a list of the folder members (if you could determine whether the folder was shared in the first place).

This is pivotal. Dropbox is about folder and file sharing yet the TMS component (again as far as I can see) does not return the folder properties needed to work out what?s going on with sharing. So the ?workaround? is to use the HTTPPost and do the JSON decode myself.

So thanks for the pointer WRT TTMSFMXDropbox.pas, I?ll follow up there.

Kevin
Adding the required request manually can indeed be a temporary solution until it get's implemented by us in the component.

Please note that the HTTP request methods are also available in the TMS VCL Cloud Pack as most of the base code is shared.
As there is only need to use the HTTP requests when you want to use API functionality that is not already available in the many components. For most users the available functionality is sufficient.
However we'll try to expand and improve the documentation in the future.

By the way, the exact filename where the example HTTP requests for DropBox can be found is: CloudCustomDropBox.pas for TMS VCL Cloud Pack and FMX.TMSCloudCustomDropBox.pas for TMS FMX Cloud Pack.

Hi,


Thanks. I have purchased the VCL cloud pack so can look at the code there. We are evaluating the FMX Cloud Pack so do not have the source so cannot evaluate the code in FMX.TMSCloudCustomDropBox.pas.

Is there any difference in the VCL HttpsPost call and the FMX HttpsPost call?

Kevin

Yes, the code that is executed on Windows is the same, but in the FMX version there is extra code for Android and OSX/iOS.

Apologies, I cannot seem to edit my earlier post.


I am getting this compilation error:

[dcc32 Error] TMSFMXCloudTest.pas(107): E2250 There is no overloaded version of 'HttpsPost' that can be called with these arguments

My Test Code below. The parameters are (string, string, TCoreCloudHeaders, string, string, THTTPCommand) and according to the function template (since there is no documentation I can find) that's what should be expected:


Note: ExtractServer and RemoveServer are in CloudBase.pas and return strings.

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  URL: string;
  headers: TCoreCloudHeaders;
  response: string;
  postdata: string;

begin
  // Form the Post request
  URL := DROPBOX_BASE_URL + '/sharing/list_folders';
  AddHeader(headers, 'Authorization', 'Bearer ' + Token_Access);
  i := DBX.HTTPSPost(ExtractServer(URL), RemoveServer(URL), headers, postdata, response, hcpost);

Any ideas at all why I am getting the compilation error????

Kevin

Can you please try using this form of HTTPSPost call instead?


Example:
AdvDropBox1.HTTPSPost(AdvDropBox1.ExtractServer(URL), AdvDropBox1.RemoveServer(URL), headers, postdata, response)

Hi Bart,


Same error:

  // Form the Post request
  URL := DROPBOX_BASE_URL + '/sharing/list_folders';
  AddHeader(headers, 'Authorization', 'Bearer ' + Token_Access);
  //i := DBX.HTTPSPost(ExtractServer(URL), RemoveServer(URL), headers, postdata, response, hcpost);


//AdvDropBox1.HTTPSPost(AdvDropBox1.ExtractServer(URL), AdvDropBox1.RemoveServer(URL), headers, postdata, response)
  i := DBX.HTTPSPost(DBX.ExtractServer(URL), DBX.RemoveServer(URL), headers, postdata, response);

[dcc32 Error] TMSFMXCloudTest.pas(106): E2250 There is no overloaded version of 'HttpsPost' that can be called with these arguments

Hi,


I'm not sure what's going wrong on your end.
Can you please provide the full source code for your project so I can further investigate this?

Hi Bart,


Apologies, been away. I had zipped the project, but there is nowhere to attach a file, so here's the Project Source:

program TMSCloudTest;

uses
  System.StartUpCopy,
  FMX.Forms,
  TMSFMXCloudTest in 'TMSFMXCloudTest.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

And here's the actual program (it's all very simple):

unit TMSFMXCloudTest;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.TMSCloudBase, FMX.TMSCloudBaseFMX, FMX.TMSCloudCustomDropBox,
  FMX.TMSCloudDropBox, FMX.Controls.Presentation, FMX.StdCtrls,     FMX.Layouts,
  FMX.ListBox;


const
  DROPBOX_BASE_URL = 'https://api.dropboxapi.com/2';
  DROPBOX_CONTENT_URL = 'https://content.dropboxapi.com/2';

type
  TForm1 = class(TForm)
    DBX: TTMSFMXCloudDropBox;
    Button1: TButton;
    LB: TListBox;
    LB1: TListBox;
    Label1: TLabel;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

var
  Token_Access: string;

implementation
procedure AddHeader(var AHeaders: TCoreCloudHeaders; Header: String; Value: String);
begin
  SetLength(AHeaders, Length(AHeaders) + 1);
  AHeaders[Length(AHeaders) - 1].header := Header;
  AHeaders[Length(AHeaders) - 1].value := Value;
end;

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  URL: string;
  headers: TCoreCloudHeaders;
  response: string;
  postdata: string;

begin
  // Form the Post request
  URL := DROPBOX_BASE_URL + '/sharing/list_folders';
  AddHeader(headers, 'Authorization', 'Bearer ' + Token_Access);
  //i := DBX.HTTPSPost(ExtractServer(URL), RemoveServer(URL), headers, postdata, response, hcpost);
  i := DBX.HTTPSPost(DBX.ExtractServer(URL), DBX.RemoveServer(URL), headers, postdata, response);
  showmessage (inttostr(i));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  try
    // have the connection persist its token in a .INI file
    DBX.PersistTokens.Location := plIniFile;
    DBX.PersistTokens.Key := '.\TMS.ini';
    DBX.PersistTokens.Section := 'Credentials';

    if not DBX.Connect then
      Exit
    else
      Token_Access := DbX.TokensAsString;

  finally

  end;
end;

end.

The form has on it:
  1. TTMSFMXCloudDropbox component
  2. TListBox (qty 2)
  3. TButton
  4. A couple of labels
Please make sure to declare these variables as "ansistring" instead of "string"

  response: ansistring;
  postdata: ansistring;

Hi bart,


That actually worked which is VERY confusing because when I hover over any HTTPSPost() I get this:

Which for some reason doesn't work. I have displayed this image in Chrome and in Safari and it displays correctly. Your forum software says it's invalid:

  file:///Users/kevin/Downloads/HTTPSPost.png

Regardless, when I hover over the HTTPSPost command this is displayed and copied directly from the IDE, it is quite explicit:

Parameters

ServerName 

System.string 

Resource 

System.string 

Headers 

FMX.TMSCloudBase.TTMSFMXCloudBase.HttpsPost.TCoreCloudHeaders 

PostData 

System.WideString      <<<<-------

Response 

System.WideString      <<<<--------

HttpCommand 

FMX.TMSCloudBase.THTTPCommand 

Returns

System.Integer


The bottom line is that it shows in the IDE that the required format for both parameters is system.widestring and NOT system.ANSIString.

How can we avoid such confusion in the future?
  • The image you are trying to use is a local image. You would have to upload it to a public server first before it can be displayed.

    - I'm not sure why this is displayed differently on your machine.

Hi Bart,


- The image you are trying to use is a local image. You would have to upload it to a public server first before it can be displayed.

OK, that wasn't obvious and I'm used with just cutting and pasting images.

- I'm not sure why this is displayed differently on your machine.

OK, weird. If I had been able top paste the image, it LOOKS exactly the same as yours except the two fields in the box were system.widestring.

Regardless, working now. I have other question WRT using the component, which I will not conflate, I will create another forum post.

Again, thanks for your help sorting this out.