Access storage directory through JS Laravel - javascript

Is there is a way to access the storage directory, which is already linked to the public directory in JS?
I'm trying to make an upload image form.
Validation script:
if ($request->hasFile('photos')) {
$marker->photos = $request->photos->store('uploads');
}
It saves image in /storage/app/uploads/
I can't use this image, because website is in public folder, and can't have access to any other folders, so I did php artisan storage:link to create a sublink to storage folder.
Now, how can I access the image using 1) PHP 2) JS?

Yes, you have to use the public disk to store the file:
if ($request->hasFile('photos')) {
$marker->photos = Storage::disk('public')->putFile('uploads', $request->file('photos'));
}
This syntax, similar to the one you are using, it's also possible to specify 'public' disk:
$marker->photos = $request->file('photos')->store(
'uploads', 'public'
);
Then you'll can access to it by the url.
Laravel:
$url = asset('storage/uploads/filename.png');
$url = asset( Storage::url('uploads/filename.png') );
JS:
let imgSrc = "http://yourdomain/storage/uploads/filename.png";
References:
File Storage File Uploads.
File Storage The Public Disk.
File Storage File URLs.

From PHP, you would use something like this to access your storage/ directory:
if(file_exists('storage/app/uploads/photo.jpg')){
$marker->photo = Storage::disk('local')->get('public/app/uploads/photo.jpg');
// or to get the directory, which you can append ->response('png') to the end...
$marker->photo = public_path('storage/app/uploads/photo.jpg');
}
To serve it from JS, you would do something similar, but have a Controller output the image when receiving an AJAX Request. Easiet method to achieve this without all this, if possible, would be through a blade template:
<img src = "{{asset('/storage/app/uploads/photo.jpg')}}">
which generates a link to the uploaded file by Laravel.

Related

I want to load an in vue that has been by post request using flask and response is its path

I already have tried many methods available on StackOverflow. Most of them ask to use require.context that will load all images path and then use image path that I have got from post response.
But my problem lies here, I ask user to upload the Image then save it locally in assets folder, process the image and save output in assets folder.
This image name has to be unique, so I use uuid.uuid4() in python- which is completely random.
require.context cannot load my image path since it was not available at time when webpack was being complied, Hence the error - Cannot find module '../assets/9a5d60e2-4c2c-4fd9-a617-5dcdde4db6cc.jpg'.
<TwentyTwenty
:before="getImgUrl(resp['original'])"
:after="getImgUrl(resp['dreamed'])"
beforeLabel='Orignal'
afterLabel="Dreamed"
keyboardStep=0.01 />
getImgUrl(pet) {
var images = require.context('../assets/', false, /\.jpg$/)
return images('' + pet + ".jpg")
}
Once your Vue application is built, there is no assets folder. You cannot require / import anything that doesn't exist at bundle-time.
What you should be doing is have your Python app save the uploaded images into a location that is accessible via HTTP (eg static/uploads or as you've indicated, your Flask app root).
You then just use a plain old, regular URL to display the image in your Vue app, eg
# .env file
VUE_APP_API_BASE=http://localhost:8080
<TwentyTwenty
:before="`${apiBase}/${resp.original}.jpg`"
:after="`${apiBase}/${resp.dreamed}.jpg)`"
beforeLabel='Orignal'
afterLabel="Dreamed"
keyboardStep="0.01" />
data: () => ({
apiBase: process.env.VUA_APP_API_BASE, // get API base URL from .env
resp: {
// whatever
}
})

Finding number of files in directory with ajax

I am totally new to ajax. I have a URL that points to a directory on a server and I need to find a way to return the number of files in that directory. I tried both of the "up voted" responses in the link, but no luck. Does anybody have experience with this?
How to get the count of file in a directory using jquery?
At backend server you have to run any of these method depending upon your language from where you can send file count back to ajax call. However client side javascript is not capable of reading directory unless you use file api and ask user to select all files which is really not a solution.
PHP
$directory = "/dir";
$files = scandir($directory);
$num_files = count($files)-2;
NODEJS
var shell = require('shelljs');
var num_files = shell.exec("cd destinationFolder || exit; ls -d -- */ | grep 'page-*' | wc -l", { silent:true }).output;
ASP
int num_files Directory.EnumerateFiles(path, "*.*").Count()

ajax call not working when deployed in live domain

My ajax call is working on localhost but not when i upload the files in domain. Using ajax I am searching all jpg/png files in a folder called 'images' and showing them in my webpage. The code is -
<script>
//Use ajax to load all images (jpe?g|png|gif) from a folder to a page called Gallery
//images folder should be in the same folder as the file
var folder = "../images/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
// create 'img' element using JS and dynamically add image source and class
var imgSrc = document.createElement('img');
imgSrc.src= folder + val;
imgSrc.className = 'imageThumbnails';
$("#spanImage").append(imgSrc);
}
});
}
});
</script>
please change
var folder = "../images/";
to
var folder = "images/";
hope this helps.. cheers
Ok, so as you saw when you tried accessing the folder directly in your browser, your web server does not allow this, which is common on web servers. Very few people actually want visitors to be able to see a list of all files in a folder, for security reasons.
The quick and dirty way to do this would be to allow listing files in that folder, through a htaccess file, using Options +Indexes, but I strongly recommend you do not do that
Instead, I would suggest you place a file inside your images folder called index.php and have that file build you a list of files placed alongside it, in the images folder. That way you have control over which files you show and which ones you don't. The index.php file can return a simple text output, one file name per line or something like that. Then your ajax call should work as it used to.
Hope this helps!

How to create a folder in Firebase Storage?

So the new Firebase has support for storage using Google Cloud Platform.
You can upload a file to the images folder using:
var uploadTask = storageRef.child('images').put(file, metadata);
What if you want to create a subfolder images/user1234 dynamically using code?
The offical sample does not show how to do that, nor the official guide or reference docs.
Is the Firebase Console the only place where folders can be created manually?
The Firebase Storage API dynamically creates "folders" as intermediate products: if you create a file at images/user1234/file.txt, all intermediate "folders" like "images" and "user1234" will be created along the way. So your code becomes:
var uploadTask = storageRef.child('images/user1234/file.txt').put(file, metadata);
Note that you need to include the file name (foo.txt for example) in the child() call, since the reference should include the full path as well as the file name, otherwise your file will be called images.
The Firebase Console does allow you to create a folder, since it's the easiest way to add files to a specific folder there.
But there is no public API to create a folder. Instead folders are auto-created as you add files to them.
You most certainly can create directories... with a little bit of playing with the references I did the following.
test = (e,v) => {
let fileName = "filename"
let newDirectory = "someDir"
let storage = firebase.storage().ref(`images/${newDirectory}/${fileName}`)
let file = e.target.files[0]
if(file !== undefined && file.type === "image/png" ) {
storage.put(file)
.then( d => console.log('you did it'))
.catch( d => console.log("do something"))
}
}
String myFolder = "MyImages";
StorageReference riversRef = storageReference.child(myFolder).child("images/pic.jpg");
Firebase is lacking very important functionality, there's always the need to be doing some tricks to emulate behaviours that should be standard.
If you create a folder manually from the Firebase console it will
persist even when there are no more files in it.
If you create a folder dynamically and all files get deleted at some
point, the folder will disappear and be deleted as well.
I implemented a file manager using Firebase Storage so when a user wants to upload a file he can do it through this interface not from something external to the app as is the Firebase Console. You want to give the user the option to reorganize the files as he wants, but something as common as creating a new folder cannot be done without tricks, why? just because this is Firebase.
So in order to emulate this behaviour what I came up with was the following:
Create a reference with the new folder name.
Create a reference for a "ghost" file as child of the folder's reference and give it always the same fixed name, eg. '.ghostfile'
Upload the file to this newly created folder. Any method is valid, I just use uploadString.
Every time I list the files of a reference, exclude any file named as before. So this "ghost" file is not shown in the file manager.
So an example to create a foler:
async function createFolder (currentRef: StorageReference, folderName: string) {
const newDir = ref(currentRef, name)
const ghostFile = ref(newDir, '.ghostfile')
await uploadString(ghostFile, '')
}
And an example to list the files:
async function loadLists (ref: StorageReference) {
const { prefixes, items } = await listAll(ref)
return {
directories: prefixes,
files: items.filter(file => file.name !=== '.ghostfile')
}
}
Firebase console allows you to create a folder. I don't think there is another way to create a folder.

How do I retrieve an image uploaded to Amazon S3 via CollectionFS:S3

In a Meteor project I am using CollectionFS:S3 to save images to a bucket in S3. I'm not able to see how to load them back into the project.
I have tried to use the FSFile.url() method as show in the code below but it's returning:
/cfs/files/images/e6jQ4Txgvb37GisEQ/imagename.jpg?token=XXX
I was expecting an Amazon S3 url as in s3-eu-west-1.amazonaws.com/mybucket/myfolder/imagename.jpg
view.html:
{{#each images}}
URL: {{this.url}}
<img src="{{this.url}}" alt="thumbnail">
{{/each}}
view.js
images: function () {
return images.find();
}
All examples I can see on the CollectionFS github page use the url method so can't see why I'm not able to access the images.
This how it worked for me.
In client side (template or client folder)
Insure that store variable is defined before, and has corresponding values. Should be the same names as you defined them in S3 configuration. Example:
store = {
bucket: 'my bucket name',
folder: 'folder name where files are stored'
}
Define S3Url function:
FS.File.prototype.S3Url = function(storeName) {
var self = this;
var store = self.getCollection().storesLookup[storeName];
var urlHost = 'https://s3.amazonaws.com/';
var urlPath = [store.bucket, store.folder, this.copies[storeName].key].join('/');
return urlHost + urlPath;
}
After use it like:
{{#each images}}
URL: {{this.S3Url}}
<img src="{{this.S3Url}}" alt="thumbnail">
{{/each}}
Hope it helps.
PS. Insure that store.bucket and store.folder are set in the Client.
That's actually correct. You're getting a url from the server which the server redirects to the correct file on S3.
In other words conceptually the server serves as a proxy to S3 that serves temporary access to files on S3 (hence the token at the end).
If you inspect the image collection server-side (meteor shell) you'll see that it's pointing to the relative path within your S3 collection.
If it's not displaying the image correctly there's something else going on, but it should with the url provided by cfs.

Categories

Resources