Exclude Folder with Laravel File::allFiles - image

I am currently using the following function:
public function recentImages(){
foreach(\File::allFiles("up") as $path){
$files[] = pathinfo($path);
}
return view('recent-images-view')->with('files',$files);
}
To list all images in my upload folder, however this also include the thumbnails that are separated in a separated folder called "thumbs".
I was wondering if there's any way to tell the allFiles function to exclude the folders with the name thumbs. Or should I handle this completely differently?
Thanks for any information in advance.

File::allFiles() will get all of the files from the given directory recursively. Try using File::files() which will get all files from the given directory only.
Update
Since you have other directories which you need. I came up with following solution.
public function images(){
foreach(\File::directories('up') as $dir) { // Get all the directories
if(str_contains('thumbs', $dir)) { // Ignore thumbs directory
continue;
}
foreach(\File::files($dir) as $path) { // Get all the files in each directory
$files[] = pathinfo($path);
}
}
return view('recent-images-view')->with('files',$files);
}
Didn't test it, the concept is get all the directories and get all the files inside those directory by ignoring the unwanted directory.

Related

Laravel Model Event: delete() doesn't delete files fromstorage

I am using FilePond for the image upload. It generates random strings for the images uploaded and is saved in database as Array.
I tried to do the following, it deletes the record but doesn't delete the files associated with it.
Since it's an array, I tried this:
foreach($this->attachments as $attachment) {
if(File::exists(storage_path($attachment))) {
Storage::delete($attachment);
}
}
Also tried this:
if(Storage::exists($this->attachments))
{
Storage::delete($this->attachments);
}
Note:
I am using Filament as the admin dashboard.
The files are being saved at storage/app/public/vehicle-images
I did php artisan storage:link, so the public folder shows ``public/storage/vehicle-images```
In this example, the file exists in: Laravel/storage/app/public/vehicle-images
$filename = 'test.txt';
if(\File::exists(storage_path('app/public/vehicle-images/'.$filename))){
\File::delete(storage_path('app/public/vehicle-images/'.$filename));
}
To better understand where the files are, and after that you can simply foreach loop check/delete.
You can read more on this here: https://laravel.com/docs/9.x/filesystem#the-public-disk
You can also later on specify a disk for that folder to make things easier to access.
Finally:
foreach($this->attachments as $attachment) {
//Option #1: if $attachment == file.txt
//use this code:
if(\File::exists(storage_path('app/public/vehicle-images/'.$attachment))){
\File::delete(storage_path('app/public/vehicle-images/'.$attachment));
}
//Option #2: if $attachment == vehicle-images/file.txt
//use this code:
if(\File::exists(storage_path('app/public/'.$attachment))){
\File::delete(storage_path('app/public/'.$attachment));
}
}
If you can show me how the filePond array looks like, I can adjust the code to work with it.
I got it. FilePond doesn't only store the image name, it also stores the url/folder the image was saved in. So instead of image.png, it is vehicle-images/image.png.
The code should be:
File::exists('storage/' . $attachment)
Which will read as: storage/ + vehicle-images/image.png.
Working code block:
foreach ($this->attachments as $attachment) {
if (File::exists('storage/' . $attachment)) {
File::delete('storage/' . $attachment);
}
}

How to copy files into flat directory in Gradle

I'm trying to write a Gradle task to copy specific files from a deep tree into a flat folder.
First Try:
task exportProperties << {
copy {
from "."
into "c:/temp/properties"
include "**/src/main/resources/i18n/*.properties"
}
}
This copies the correct files, but does not flatten the structure, so I end up with every single folder from my original project, and most of them are empty.
Second try, based on answers I saw here and here:
task exportProperties << {
copy {
from fileTree(".").files
into "c:/temp/properties"
include "**/src/main/resources/i18n/*.properties"
}
}
This time, it is not copying anything.
Third Try:
task exportProperties << {
copy {
from fileTree(".").files
into "c:/temp/properties"
include "*.properties"
}
}
Almost works, except it is copying every *.properties file when I only want the files in particular paths.
I solved the issue in a way similar to this:
task exportProperties << {
copy {
into "c:/temp/properties"
include "**/src/main/resources/i18n/*.properties"
// Flatten the hierarchy by setting the path
// of all files to their respective basename
eachFile {
path = name
}
// Flattening the hierarchy leaves empty directories,
// do not copy those
includeEmptyDirs = false
}
}
I got it to work like this:
task exportProperties << {
copy {
from fileTree(".").include("**/src/main/resources/i18n/*.properties").files
into "c:/temp/properties"
}
}
You can modify a number of aspects of copied files on the fly by feeding a closure into the Copy.eachFile method including target file path:
copy {
from 'source_dir'
into 'dest_dir'
eachFile { details ->
details.setRelativePath new RelativePath(true, details.name)
}
}
This copies all files directly into the specified destination directory, though it also replicates the original directory structure without the files.
I was able to solve this in a similar way to Kip but inverted:
distributions {
main {
// other distribution configurations here...
contents {
into('config') {
exclude(['server.crt', 'spotbugs-exclusion-filters.xml'])
from fileTree('src/main/resources').files
}
}
}
}
There are no issues with empty directories when the CopySpec is configured this way.

How to do test coverage with blanket and mocha in sailsjs

I have a Sails project with a test/ folder containing all my mocha tests and want to create a test coverage report using following command:
mocha --require blanket --reporter html-cov > coverage.html
The blanket configuration inside my package.json looks following:
"blanket": {
"pattern": ["lib", "api", "config"],
"data-cover-never": "node_modules",
"data-cover-reporter-options": {
"shortnames": true
}
}
I included both Sails folders api/ and config/ as they probably contain testable code and a folder lib/ containing most of my application's logic.
Sadly the blanket coverage module only covers files that are directly included in my test files. Since Sails loads most of my files in api/ and config/ dynamically they don't show up in my coverage reports.
Any ideas in how to integrate the Sails framework with blanket?
I am unfamilair with Sails but I had the same problem using Blanket.js and posted a comment with a work-around on the Blanket.js bugtracker, here it is:
https://github.com/alex-seville/blanket/issues/361#issuecomment-34002054
The workaround I suggested there felt very much like a hack. I eventually abandoned Blanket in favor of Istanbul: https://github.com/gotwarlost/istanbul
Istanbul gives you both more metrics (statement, line, function and branch coverage) and outputs an excellent bunch of .html files allowing you to analyze how to improve your code.
Blanket.js appears not to be maintained very well given the 79+ open issues currently.
If you do want to stick to blanket.js you can follow the suggestion I posted on the Blanket.js bug tracker and try to include all files within the test run by recursively looping through all relevant code directories. The code I used to do that at the time was as the following (I would definitely refactor this, but it shows the intent):
'use strict';
/**
* This file is loaded by blanket.js automatically before it instruments code to generate a code coverage report.
*/
var fs = require('fs');
var log = require('winston');
var packageJson = require('./package.json');
// For some reason the blanket config in package.json does not work automatically, set the settings manually instead
require('blanket')({
// Only files that match this pattern will be instrumented
pattern: packageJson.config.blanket.pattern
});
/**
* Walks through a directory structure recursively and executes a specified action on each file.
* #param dir {(string|string[])} The directory path or paths.
* #param action {function} The function that will be executed on any files found.
* The function expects two parameters, the first is an error object, the second the file path.
*/
function walkDir(dir, action) {
// Assert that action is a function
if (typeof action !== "function") {
action = function (error, file) {
};
}
if (Array.isArray(dir)) {
// If dir is an array loop through all elements
for (var i = 0; i < dir.length; i++) {
walkDir(dir[i], action);
}
} else {
// Make sure dir is relative to the current directory
if (dir.charAt(0) !== '.') {
dir = '.' + dir;
}
// Read the directory
fs.readdir(dir, function (err, list) {
// Return the error if something went wrong
if (err) return action(err);
// For every file in the list, check if it is a directory or file.
// When it is a directory, recursively loop through that directory as well.
// When it is a file, perform action on file.
list.forEach(function (file) {
var path = dir + "/" + file;
fs.stat(path, function (err, stat) {
if (stat && stat.isDirectory()) {
walkDir(path, action);
} else {
action(null, path);
}
});
});
});
}
};
// Loop through all paths in the blanket pattern
walkDir(packageJson.config.blanket.pattern, function (err, path) {
if (err) {
log.error(err);
return;
}
log.error('Including ' + path + ' for blanket.js code coverage');
require(path);
});
My advice would be to drop Blanket.js for something else.

elFinder not showing Folder or File with umlaute

i encountered a problem with elFinder.
When on the server there is a file or a folder containing one of the letters öäü, the directory(file) wont be shown in el finder and i get an error in
lFinderConnector.class.php json_encode(): Invalid UTF-8 sequence in
argument
but if i upload a file with elFinder itself like: Test ö.png its shown correctly and on the server it looks like this: Test ö.png. Same goes for directorys.
My problem is i have a millions of files that may countain umlaute (ö,ü ,ä) and elFinder cant show them.
Does any one else got problem like this or got any idea or tip how to solwe it?
setlocale(LC_ALL, 'de_DE');
function array_walk_deep(&$items){
foreach ($items as &$item) {
if(is_array($item)) {
array_walk_deep($item);
} else {
if (!strpos($item ,'ö')) {
$item = iconv('UTF-8', 'ASCII//TRANSLIT', utf8_encode($item)) ;
}
}
}
}
array_walk_deep($data);
so i just made a workaround on this. In the elFinderConnector i just use this piece of code before i return the array to javascript this will change the ö->oe the ä->ae and the ü-> ue will no longer cause any problems and the directorys will be shown. Directory and files can be renamed afterward by the users.
Hope some one will finde this usefull.
regrads
Your solution replaces the umlauts by ASCII chars, for me it worked by just using utf8_encode() on the items of $data array before json_encode() and outputting it (it keeps the umlauts).
I took your snippet, modified it and added it to the elFinderConnector class.
protected function array_walk_deep(&$items){
foreach ($items as &$item) {
if(is_array($item)) {
$this->array_walk_deep($item);
} else {
$item = utf8_encode($item);
}
}
Then call it on the $data array in the output() method.
$this->array_walk_deep($data);
exit(json_encode($data));

How to recursively list all the files in a directory in C# and copy all files to another directory

I am trying to write a c# console application that recursively reads through a certain folder.
In these folders are thousands of .jpg images
The folder structure is very deep in some levels and an example look like this:
Scc-LocalPhoto/testfiles/1997/JAN-JUN
1997/APRIL 1997/7.4.97 -
11.4.97/FRI11.4.97/
As you can see the folder structure is quite messy, however I do not have control over this.
My task is to read through all the folders. Retract the Meta data from the images and store in XML file. I then need to copy all the folders in the same layout and paste them in a new folder.
I think I will be able to read though all the directories and extract the meta data from the images and save it to an xml file.
What I do not know how to do is copy and past all the folders and images and paste them in a new directory maintaining the same folder structure.
Does anybody know of an efficient way to perform this task or is there any project, code available I could use as a starting point.
I am fairly new to C# and writing console apps.
Thanks for your time.
Parsing Directories Recursively
static void ParseDirectories(string root)
{
ProcessDirectory(new DirectoryInfo(root));
string[] subDirectories = Directory.GetDirectories(root);
// No more directories to explore
if (subDirectories.Length == 0)
return;
foreach (string subDirectory in subDirectories)
{
ParseDirectories(subDirectory);
}
}
Processing the Files in a Directory
static void ProcessDirectory(DirectoryInfo directory)
{
foreach (FileInfo file in directory.EnumerateFiles("*.jpg")
{
// record metadata and do other work on each file here
}
}
Copying a Directory tree
static void CopyDirectoryTree(DirectoryInfo source, DirectoryInfo dest)
{
if (!Directory.Exists(dest.FullName))
Directory.CreateDirectory(dest.FullName);
bool overwrite = true;
// Copy files
foreach (FileInfo file in source.EnumerateFiles())
{
file.CopyTo(Path.Combine(dest.ToString(), file.Name), overwrite);
}
// Copy Sub-directories
foreach (DirectoryInfo subDirectory in source.GetDirectories())
{
DirectoryInfo newDirectory = destination.CreateSubdirectory(subDirectory.Name);
CopyDirectoryTree(subDirectory, newDirectory);
}
}
Sample usage
static void Main(string[] args)
{
// Process each directory
string initialDirectory = #"C:\path_to_folder";
ParseDirectories(initialDirectory);
// Copy directory tree
string destinationDirectory = #"C:\path_to_new_root_directory";
CopyDirectoryTree(
new DirectoryInfo(initialDirectory),
new DirectoryInfo(destinationDirectory));
}
Hope this helps!
May I suggest the following, which is, in my opinion, a little bit more straightforward
public static void CopyFolderTree(string sourcePath, string targetPath)
{
var sourceDir = new DirectoryInfo(sourcePath);
var targetDir = new DirectoryInfo(targetPath);
targetDir.Create();
foreach(var file in sourceDir.GetFiles())
file.CopyTo(Path.Combine(targetPath, file.Name), true);
foreach(var subfolder in sourceDir.GetDirectories())
CopyFolderTree(subfolder.FullName, Path.Combine(targetPath, subfolder.Name));
}

Resources