How to get all files from folder and subfolder in magento 2 - filesystems

I made a module for uploading images in frontend. Magento 2 saves files in a special way. For example:
uploading file - file.png,
path to file - pub/media/[module_folder]/f/i/file.png.
How to get all files from [module_folder]?

Try the below, use the directorylist class to get the path, and the file class to read the directory :D
public function __construct(
\Magento\Framework\Filesystem\DirectoryList $directoryList,
\Magento\Framework\Filesystem\Driver\File $driverFile,
LoggerInterface $logger)
{
$this->directoryList =$directoryList;
$this->driverFile = $driverFile;
$this->logger = $logger;
}
public function getAllFiles($path = '/import/') {
$paths = [];
try {
//get the base folder path you want to scan (replace var with pub / media or any other core folder)
$path = $this->directoryList->getPath('var') . $path;
//read just that single directory
$paths = $this->driverFile->readDirectory($path);
//read all folders
$paths = $this->driverFile->readDirectoryRecursively($path);
} catch (FileSystemException $e) {
$this->logger->error($e->getMessage());
}
return $paths;
}

Related

sort files by datecreated and remove old files with google apps script

Trying to make a simple google apps script to get files by name and order them by date created. If there are more than 5 files by the same name, delete all but the 5 newest files.
function tryme(){
var files = DriveApp.getFilesByName('thisFile');
var created = files.getDateCreated();
for(i in created) {
if(created[i] > 4){
file.setTrashed(true);}
}
}
You're trying to use a File method on a File Iterator (returns from getFilesByName() method).
Here is a solution for your issue:
function tryme(){
// Get the file Iterator
var files = DriveApp.getFilesByName('New Text File');
var fileArray = [];
// Put file on array
while(files.hasNext()){
var file = files.next();
fileArray.push([file, file.getDateCreated()]);
}
//While you have more than 5 files
while(fileArray.length>5){
var older = ["",new Date()];
var olderIndex;
// Get the older file
for(var i in fileArray){
if(fileArray[i][1].getTime() < new Date(older[1]).getTime()){
olderIndex = i;
older = fileArray[i];
}
}
// Delete the older file
fileArray.splice(olderIndex,1);
older[0].setTrashed(true);
}
}
Edit: I made a mistake by using DriveApp.removeFile() instead of File.setTrashed(true)

Groovy delete specific file from the list

I try to delete files which i can find in folderPath. But I want delete only that, which have in name "Jenkins".
How to define in list to delete only that file.?
Example :
In C:\test\test have 3 files, want delete that which have Jenkins in name :
import groovy.io.FileType
String folderPath = "C:\\test" + "\\" + "test"
def list = []
def dir = new File("$folderPath")
dir.eachFileRecurse (FileType.FILES) { file ->
list << file
}
list.each {
println it.findAll() == "Jenkins" // Just files witch include in list "Jenkins" name
}
Thanks for tips !
Here you go:
Use either of the below two:
import groovy.io.FileType
String folderPath = "C:/test/test"
new File(folderPath).eachFile (FileType.FILES) { file ->
//Delete file if file name contains Jenkins
if (file.name.contains('Jenkins')) file.delete()
}
or
Below one uses FileNameFinder class
String folderPath = "C:/test/test"
def files = new FileNameFinder().getFileNames(folderPath, '**/*Jenkins*')
println files
files.each { new File(it).delete()}

Groovy rename a file

I'm trying to rename files in a directory using Groovy but I can't seem to understand how it works.
Here is my script:
import groovy.io.FileType
def dir = new File("C:/Users/דודו/Downloads/Busta_Rhymes-Genesis-(Retail)-2001-HHI")
def replace = {
if (it == '_') {
' '
}
}
String empty = ""
dir.eachFile (FileType.FILES) { file ->
String newName = file.name
newName = newName.replaceAll(~/Busta_Rhymes/, "$empty")
newName = newName.replaceAll(~/feat/, "ft")
newName = newName.replaceAll(~/-HHI/, "$empty")
newName = newName.replaceAll(~/--/, "-")
newName = newName.collectReplacements(replace)
file.renameTo newName
println file.name
}
When I run this, the names of the files aren't changed as expected. I'm wondering how could I get this to work.
There are a number of things wrong here:
Your dir variable is not the directory; it is the file inside the directory that you actually want to change. Change this line:
dir.eachFile (FileType.FILES) { file ->
to this:
dir.parentFile.eachFile (FileType.FILES) { file ->
The renameTo method does not rename the local name (I know, very counterintuitive), it renames the path. So change the following:
String newName = file.name
to this:
String newName = file.path
Now, for some reason beyond my comprehension, println file.name still prints out the old name. However, if you look at the actual directory afterwords, you will see that the file is correctly renamed in the directory.

How to create a new file name instead of overwriting a file in Groovy

I move a file to a folder. Is there any way to not overwrite a file with that name?
For example, folder contains a file named: file1.pdf. How can I move another file named: file1.pdf into that folder so that the name get changed to e.g. file1-1.pdf, file1-2.pdf to prevent the original file from getting overwritten.
I'm using substring to do that but it's quite long and awful code.
You could use something like this:
def save = { File dir, String name ->
int version = 1
def splitName = name.split(/\./, 0).with { it -> it.length == 1 ? [it[0], ''] : [it[0..-2].join('.'), ".${it[-1]}"] }
def rename = { String prefix, String ext -> "$prefix-$version$ext" }
while (new File(dir, name).exists()) {
name = rename(*splitName)
version++
}
println "Save the file as $name"
}
save(new File('/tmp'), 'file.txt')
Which assuming you have a file /tmp/file.txt and a file /tmp/file-1.txt already, prints out: Save the file as file-2.txt

Composite C1 blog - not using media folder

I have a Composite C1 4.04 site.
The user needs a blog - and they can upload images.
However, the images go into some weird virtual 'media' folder that apparently doesn't exist - and they aren't stored like normal images.
I would like them instead to just go into a regular folder - as I need to manipulate them later - to re-compress them (for example).
How can I do this?
thx
The media files are plugable in Composite C1, in the default implementation media files are represented as
A record in a database, that contains file's meta data (mime type, etc)
A physical file with the content, located under "\App_Data\Media" f.e.
\App_Data\Media\0b11c288-5432-4482-a776-3eb0ac9ad437
This has certain advantages - having a database record allows to keep additional meta data relevant to serving http requests (such as MimeType), apply security to those files, etc.
; also file names don't follow file system restrictions (such as path length and certain reserved names/forbidden characters) - so when you upload a file,
you don't have to care if website folder path + media folder path + file name would exceed 255 characters.
There are also other media archive plug-ings, when f.e. files are kept in a SQL data base or files are fetched from a Facebook album.
If you want to compress the image files, you can iterate over files in \App_Data\Media\ folder. You can get the list of media files by calling Get() on a DataConnection instance.
If you want to export media to a different solution, you can use the following code that copies a Composite C1 media folder to a physical folder:
private int MediaToFiles(string mediaFolder, string physicalFolder)
{
if (!mediaFolder.StartsWith("/"))
{
mediaFolder = "/" + mediaFolder;
}
string mediaFolderPrefix = mediaFolder == "/" ? "/" : mediaFolder + "/";
using (var conn = new DataConnection())
{
var mediaFiles = conn.Get<IMediaFile>().Where(f => string.Equals(f.FolderPath, mediaFolder, StringComparison.OrdinalIgnoreCase)
|| f.FolderPath.StartsWith(mediaFolderPrefix, StringComparison.OrdinalIgnoreCase))
.ToList();
if(mediaFiles.Count == 0) return 0;
Directory.CreateDirectory(physicalFolder);
int newFiles = 0;
foreach (var file in mediaFiles)
{
string targetFolder = file.FolderPath.Length <= mediaFolderPrefix.Length ?
physicalFolder : Path.Combine(physicalFolder, file.FolderPath.Substring(mediaFolderPrefix.Length));
Directory.CreateDirectory(targetFolder);
string targetFilePath = Path.Combine(targetFolder, file.FileName);
if(File.Exists(targetFilePath) && File.GetLastWriteTime(targetFilePath) == file.LastWriteTime) continue;
using (var stream = file.GetReadStream())
{
using (var outputStream = File.Create(targetFilePath, 8192))
{
stream.CopyTo(outputStream);
outputStream.Close();
}
}
File.SetLastWriteTime(targetFilePath, file.LastWriteTime.Value);
newFiles++;
}
return newFiles;
}
}
// Example of usage:
int newFiles = MediaToFiles("/", #"c:\Temp\C1media"); // Copying all the media files
OutPut("New files: " + newFiles);
int newFiles2 = MediaToFiles("/Office", #"c:\Temp\C1media\Office pictures"); // Copying only "Office" media folder
OutPut("New files: " + newFiles2);

Resources