Randomly select file from folder in JS without an array - javascript

I have this code to randomly grab a file from a folder path, and load it via jQuery:
var path = '/path-to-files/',
files = ['1.php', '2.php', '3.php', '4.php', '5.php', '6.php'],
i = Math.floor(Math.random()*files.length);
var url = (path+files[i]);
$("#my-div").load(url);
It's great, it works well. But I would prefer a method to randomly grab files from the path without building an array. Is that possible?

You can't get a list of files from a directory using just JavaScript(jQuery is JavaScript), it would have to be handled from the server. You could request a server-file that then returns the content of a random file from a directory.

var i = Math.floor(Math.random() * 6) + 1;
$("#my-div").load('/path-to-files/' + i + '.php');

You'll need to make a server request to get the array of possible files. This is the only way to do this without sticking to a naming convention or a set list of files.

Related

Normalize file path in JavaScript front-end

The short story:
Is there simple way to normalize file path in JavaScript, like in Java we have Paths.get("/a/b/../c").normalize() so /a/../../c would become /c. I seen many same questions here, but they are Node.js solutions, and I need pure JS or JQuery approach so it can be used in browser.
The long story:
I have a file server with web UI, that allows to browse files and download them. UI is written in spring and accessible at mysite.com/ui/
The file storage located at mysite.com/files/ which is plain Apache directory, so its possible to get direct link to file.
The real storage directory on server is /var/www/files
Path passing to back-end as mysite.com/ui/?path=/a/../../c, so back-end will normalize path variable separately to /c and then append it to base dir and so retrieving content of /home/storage/c, so it works perfectly.
The problem comes when user tries to download file like this with direct link. I.e. if user tries to download /a/../../c/d file from file server root, it appending to base storage url, which mysite.com/files/, and it becomes mysite.com/files/a/../../c/d so it will point to /var/www/d instead of /var/www/files/d so file can't be downloaded even if it is visible from web UI.
So I need to normalize relative file path first on front-end like on back-end when retrieving content of directory but I don't know how it can be done in JS. Is there function for it, or I have to write my own one?
So I ended up writing my own function on JS. It might be not what "path normalization" stands for, but anyway its exactly what I need
function normalizePath(path) {
// remove multiple slashes
path = path.replace(/\/+/g, '/');
// remove leading slash, will be added further
if (path.startsWith("/"))
path = path.substring(1)
// remove trailing slash
if (path.endsWith("/"))
path = path.slice(0, -1);
let segments = path.split("/");
let normalizedPath = "/";
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
if (segments[segmentIndex] === "." || segments[segmentIndex] === "") {
// skip single dots and empty segments
continue;
}
if (segments[segmentIndex] === "..") {
// go up one level if possible
normalizedPath = normalizedPath.substring(0, normalizedPath.lastIndexOf("/") + 1);
continue;
}
// append path segment
if (!normalizedPath.endsWith("/"))
normalizedPath = normalizedPath + "/"
normalizedPath = normalizedPath + segments[segmentIndex];
}
return normalizedPath;
}
Still, I won't mark this as accepted answer as it's more of a quick fix, and I'm not JS expert so it definitely must be more elegant solution.

JavaScript get all image files from folder and append their names to array

I have this code:
function randombg(){
var bigSize = [
"url('images/1.jpg')",
"url('images/2.jpg')",
"url('images/3.jpg')",
"url('images/4.jpeg')",
"url('images/5.jpeg')",
"url('images/6.jpeg')",
"url('images/7.jpeg')",
"url('images/8.jpeg')",
"url('images/9.jpeg')",
"url('images/10.jpeg')",
"url('images/11.jpeg')",
"url('images/12.jpeg')",
"url('images/13.jpeg')",
"url('images/14.jpeg')",
"url('images/15.jpeg')",
"url('images/16.jpeg')",
"url('images/17.jpeg')",
"url('images/18.jpeg')",
"url('images/19.jpeg')",
"url('images/20.jpeg')",
"url('images/21.jpeg')",
"url('images/22.jpeg')",
"url('images/23.jpeg')"
];
var random = Math.floor(Math.random() * bigSize.length) + 0;
document.getElementById("random").style.backgroundImage = bigSize[random];
console.log('image loading function end');
}
which generates a random background picture. I have more than 100 high-resolution photos, and it would be masochism to rename them all and the add their names to an image array.
So I'm searching for a solution (in code) that gets all the images from an image folder resource and adds their names to an array. I have both .jpg and .jpeg formats.
You cannot access local files using JavaScript (security reasons) unless you are using node.
A possible solution would be to use the File API but you still need to give permission.

store and access image file paths when templating (from cloudinary or other service)

I’m using gulp and nunjucks to automate some basic email templating tasks.
I have a chain of tasks which can be triggered when an image is added to the images folder e.g.:
images compressed
new image name and dimensions logged to json file
json image data then used to populate template when template task is run
So far so good.
I want to be able to define a generic image file path for each template which will then concatenate to each image name (as stored in the json file). So something like:
<img src="{{data.path}}{{data.src}}" >
If I want to nominate a distinct folder to contain the images for each template generated then cloudinary requires a mandatory unique version component to be applied in the file path. So the image path can never be consistent throughout a template.
if your public ID includes folders (elements divided by '/'), the
version component is mandatory, (but you can make it shorter. )
For example:
http://res.cloudinary.com/demo/image/upload/v1312461204/sample_email/hero_image.jpg
http://res.cloudinary.com/demo/image/upload/v1312461207/sample_email/footer_image.jpg
Same folder. Different path.
So it seems I would now need to create a script/task that can log and store each distinct file path (with its unique id generated by cloudinary) for every image any time an image is uploaded or updated and then rerun the templating process to publish them.
This just seems like quite a convoluted process so if there’s an easier approach I’d love to know?
Else if that really is the required route it would great if someone could point me to an example of the kind of script that achieves something similar.
Presumably some hosting services will not have the mandatory unique key which makes life easier. I have spent some time getting to know cloudinary and it’s a free service with a lot of scope so I guess I'm reluctant to abandon ship but open to all suggestions.
Thanks
Note that the version component (e.g., v1312461204) isn't mandatory anymore for most use-cases. The URL could indeed work without it, e.g.,:
http://res.cloudinary.com/demo/image/upload/sample_email/hero_image.jpg
Having said that, it is very recommended to include the version component in the URL in cases where you'd like to update the image with a new one while keeping the exact same public ID. In that case, if you'd access the exact same URL, you might get a CDN cached version of the image, which may be the old one.
Therefore, when you upload, you can get the version value from Cloudinary's upload response, and store it in your DB, and the next time you update your image, also update the URL with the new version value.
Alternatively, you can also ask Cloudinary to invalidate the image while uploading. Note that while including the version component "busts" the cache immediately, invalidation may take a while to propagate through the CDN. For more information:
http://cloudinary.com/documentation/image_transformations#image_versions
This is the solution I came up with. It's based on adapting the generic script I use to upload images from a folder to cloudinary and now stores the updated file paths from cloudinary and generates a json data file to publish the hosted src details to a template.
I'm sure it could be a lot better semantically so welcome any revisions offered if someone stumbles on this but it seems to do the job:
// points to the config file where we are defining file paths
var path = require('./gulp.path')();
// IMAGE HOSTING
var fs = require('fs'); // !! not installed !! Not required??
var cloudinary = require('cloudinary').v2;
var uploads = {};
var dotenv = require('dotenv');
dotenv.load();
// Finds the images in a specific folder and retrurns an array
var read = require('fs-readdir-recursive');
// Set location of images
var imagesInFolder = read(path.images);
// The array that will be populated with image src data
var imgData = new Array();
(function uploadImages(){
// Loop through all images in folder and upload
for(var i = 0; i < imagesInFolder.length;i++){
cloudinary.uploader.upload(path.images + imagesInFolder[i], {folder: path.hosted_folder, use_filename: true, unique_filename: false, tags: 'basic_sample'}, function(err,image){
console.log();
console.log("** Public Id");
if (err){ console.warn(err);}
console.log("* Same image, uploaded with a custom public_id");
console.log("* "+image.public_id);
// Generate the category title for each image. The category is defined within the image name. It's the first part of the image name i.e. anything prior to a hyphen:
var title = image.public_id.substr(image.public_id.lastIndexOf('/') + 1).replace(/\.[^/.]+$/, "").replace(/-.*$/, "");
console.log("* "+title);
console.log("* "+image.url);
// Add the updated src for each image to the output array
imgData.push({
[title] : {"src" : image.url}
});
// Stringify data with no spacing so .replace regex can easily remove the unwanted curly braces
var imgDataJson = JSON.stringify(imgData, null, null);
// Remove the unwanted [] that wraps the json imgData array
var imgDataJson = imgDataJson.substring(1,imgDataJson.length-1);
// Delete unwanted braces "},{" replace with "," otherwise what is output is not valid json
var imgDataJson = imgDataJson.replace(/(},{)/g, ',');
var outputFilename = "images2-hosted.json"
// output the hosted image path data to a json file
// (A separate gulp task is then run to merge and update the new 'src' data into an existing image data json file)
fs.writeFile(path.image_data_src + outputFilename, imgDataJson, function(err) {
if(err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
});
}
})();
A gulp task is then used to merge the newly generated json to overide the existing json data file:
// COMPILE live image hosting data
var merge = require('gulp-merge-json');
gulp.task('imageData:comp', function() {
gulp
.src('src/data/images/*.json')
.pipe(merge('src/data/images.json'))
.pipe(gulp.dest('./'))
.pipe(notify({ message: 'imageData:comp task complete' }));
});

How to create file(.apk) from URL in Jaggery?

I have application store and applications have their url. I want to download apks from those urls to my jaggery server. Although below code(my first solution) create myApp.apk successfully, its not work properly.
First i tried to below code,
var url = "http://img.xxx.com/006/someApp.apk";
var data = get(url, {});
var file = new File("myApp.apk");
file.open("w");
file.write(data.data);
file.close();
when i print data.data value, its look like
i also tried,
var file = new File("http://img.xxx.com/006/someApp.apk");
file.saveAs("myApp.txt");
Can anyone help me?
.apk files are Android application files, and they are expected to start with PK, because they are actually zip archives!
They're not meant to be unzipped, although you can do it to see some of the application resources (but there are better ways for reverse engineering .apk files such as Apktool, if that's what you're looking for).
According to jaggery documentations, file.write is writing the String representation of the object to the file. So that's why you are getting an apk file which cannot be installed.
However you can make it work using copyURLToFile in apache commons-io java library as follows since jaggery supports java itself and all of WSO2 products have apache commons-io library in their class path.
<%
var JFileUtils = Packages.org.apache.commons.io.FileUtils;
var JUrl = Packages.java.net.URL;
var JFile = Packages.java.io.File;
var url = new JUrl("http://img.xxx.com/006/someApp.apk");
JFileUtils.copyURLToFile(url, new JFile("myApp.apk"));
print("done");
%>
Your file will be stored on $CARBON_HOME directory by default, unless you specified relative or absolute path to the file.

random images from a folder

I am trying to rewrite my code below to search a folder for all the images (they will be numbered but there maybe gaps, ie not 1.jpg,2.jpg,3.jpg but instead 1.jpg,15.jpg,60.jpg for this reason i would like to search the folder, put all the images into an array and then pick one randomly each time its looped.
Any help would be greatly appreciated.
Firstly i am currently specifying image total above the main script below:
imgWidth = 160,
imgHeight = 95,
imgTotal = 22,
total = 0,
tiles;
//create the HTML for the tiles and append that to the bg element
function makeTiles(count){
var html = '', imgNum;
while(count--){
imgNum = Math.floor(Math.random()*imgTotal + 1);
html += "<div class='tile' style='background:url(public/images/portfolio/all/"+imgNum+".jpg) 0 0 no-repeat;' ><img style='opacity:0; filter:alpha(opacity=0);' src='public/images/portfolio/all/"+imgNum+"-c.jpg' alt='' /></div>\r";
}
$bg.append(html);
}
You'll need to create a list of available images with something else than javascript, since it has no filesystem access, even though in the end, you are accessing the images via their url.
Workaround: enable some directory listing for the images, then access this page via javascript, parse the image files and construct an array out of them; but frankly, there are shorter and more robust ways to accomplish this ...
pseudocode ..
$ ls -1 *jpg > imagesfilelist.txt
$ cp imagefilelist.txt /some/publicly/accessible/folder
js/jquery ..
$.get("/some/publicly/accessible/folder/imagefilelist.txt", function(data){
alert("My image files: " + data);
});
...
javascript can not access local folders. point.
I repeat: there is no way you can "search folder" to get "array of images" in JS. You could do that part (server only!) in PHP or such server-side language and return results via AJAX.
To do what you want you need to know what the images are called. JavaScript cannot access folder directly as commented above. You would need to use a server side script to provide an array of the images for the JS to pick at random to do this.
Javascript will not be able to browse folders. What you need to do is to create an array of available images and then select a random one. You could do this using any server side technology (php, rails, java, .net ...).
The way you're trying to do it is a wrong one.But iwth a bit of tricks it could work though, but it's very wrong way to do this kind of things.
You can generate file list with php and feed it to your script. You can even create php script which will generate your script already populated with needed data but it's not the best to do this too.
So, the best ways are:
- create html with list of filenames/images(visible or invisible) by php, then manipulate it by javascript;
- create html and javascript wich will do AJAX query to php script which will return filename list(formated as JSON if you wish).
Why not upload your images to a free hosting site (like Flickr) grab the feed from your image group and select the random image from there?

Categories

Resources