adriangibbons/php-fit-file-analysis

Not able to access the file from s3

Opened this issue · 12 comments

I am storing Garmin files into a s3 bucket. But when I try to fetch the file from s3 it is displaying file not found. This is the error which I am getting
phpFITFileAnalysis->__construct(): file 'https://s3-us-west-2.amazonaws.com/uploadedimg/garmin_upload/6465920425' does not exist! in [project_root]/vendor/adriangibbons/php-fit-file-analysis/src/phpFITFileAnalysis.php on line 944

Here is the code provided in my controller

$filepath = 'https://s3-us-west-2.amazonaws.com/uploadedimg/garmin_upload/6465920425';
$options = ['units' => 'statute'];
$pFFA = new \adriangibbons\phpFITFileAnalysis($filespath,$options);
$grCnt = $pFFA->data_mesgs['session'];

Hey @ileafsolutions, it's not just a typo?

$filepath = 'https://s3-us-west-2.amazonaws.com/uploadedimg/garmin_upload/6465920425';

$pFFA = new \adriangibbons\phpFITFileAnalysis($filespath, $options);

You've used a slightly different variable name when instantiating the class: file_S_path

Do you need to retrieve the file first?

If I go to https://s3-us-west-2.amazonaws.com/uploadedimg/garmin_upload/6465920425 then I just get an error:

This XML file does not appear to have any style information associated with it. The document tree is shown below. <Error> <Code>NoSuchKey</Code> <Message>The specified key does not exist.</Message> <Key>garmin_upload/6465920425</Key> <RequestId>DE1D5212401A3BB0</RequestId> <HostId> QqkRIx9XM0nexYiRYAPx8eeNLXOmA86jSjGNaNDIp7BvAOENDwKcwjPZhR0BPwiEDFzmK5XskAI= </HostId> </Error>

Like you mentioned I have corrected the variable passed in phpFITFileAnalysis. But still gets file does not exist.
Actually this file exist in s3 bucket. But even I get same error when I try to retrieve the file via postman. If you provide this same url in browser I get the file downloaded. What could be wrong?

Modified the code:
$files = Storage::disk('s3')->files($s3folder);
$options = ['units' => 'statute'];
$pFFA = new \adriangibbons\phpFITFileAnalysis($files,$options);

Now the error is
file_exists() expects parameter 1 to be a valid path, array given in [project_root]/vendor/adriangibbons/php-fit-file-analysis/src/phpFITFileAnalysis.php on line 943

Please help!

Hey, I think it's partly because I have built the class assuming people would always be accessing local files. I'll have to drag myself into 2016 at some point ;)

Therefore, I am not sure that the PHP utilities that I am using to read files will behave as expected for remote files on AWS (I have no experience of this)

e.g. file_exists() and file_get_contents() on lines 943 and 957 respectively of the class source code

In your code, could you do a var_dump($files); die(); after the first line you posted above?

$files looks like it will be an array of all the files in the folder? My class expects only one file at a time so you could try passing $files[0] or something like $files[0]['the element with the file path'] I am not sure that it'll work though. If you want to process all files in the folder then you'll need to use a foreach() or something to iterate through the files but let's see if we can get it working first...

A work-around may be to retrieve your file from AWS and storing it locally temporarily so that it can be processed by the php-fit-file-analysis class.

  1. Fetch file 'bar.fit' from AWS and store in folder 'foo/'
  2. Instantiate class:
// Retrieve file: Storage::disk('s3')->files($s3folder)
$file = '[...path to file...]/foo/bar.fit';
$options = ['units' => 'statute'];
$pFFA = new \adriangibbons\phpFITFileAnalysis($file, $options);
// Delete the temporary file foo/bar.fit

How can you identify the file provided by garmin is .fit or .tcx ? As you know we get the push from garmin without an extension.

FIT files are binary (i.e. not very user friendly to ready, but compact); TCX files are a Garmin implementation of XML (i.e. easier for humans to read, but not efficient when it comes to file sizes) and ASCII. Therefore, a few options spring to mind:

  1. Try and parse the file using my class. If it is not a FIT file, then it will throw an exception - see this line

  2. Read some of the file into memory using PHP utils (e.g. file_get_contents) and see if ".FIT" is in there (e.g. using strpos). As per Table 3-1. Byte Description of File Header from v2.2 of the FIT protocol:

    A FIT binary file opened with a text editor will contain a readable “.FIT” in the first line.

  3. http://stackoverflow.com/questions/632685/how-to-check-if-file-is-ascii-or-binary-in-php

Now I am facing another issue. Could you help me on this.
If the file which I am getting is .tcx then I have provided the local storage url inside simplexml_load_file($contents) function. $content contains the local storage url.

But I am getting this error :
simplexml_load_file(): https:/s3-us-west-2.amazonaws.com/uploadedimg/garmin_upload/6508703709-bb2004f5-c9b0-4934-a07c-b8e99f6c8971:1: parser error : Start tag expected, '<' not found in [project_root]/app/Http/Controllers/Api/v1/GarminController.php on line 83

Hmmmm strange, an XML file should always start with a '<'

Are you sure the URL is correct? Trying to load it myself, it says "no such key..." rather than displaying the contents of an XML file. Also, the URL appears to be remote on AWS, rather than local storage?

Apologies, I don't have any experience of using AWS or simple xml reader so can't help you much.

Adrian.

Thanks a lot for lending a helping hand. I got the file working. As you mentioned downloaded the file from s3 to my local and then parsing the file to plugin.

No worries, glad you got it working! I'll close this issue...