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);
Related
I'm trying to, on form submission, copy the files (which appear as links) from google sheets, specifically from column c, only, to a master folder. the links are to the pdfs within a folder, not a folder itself.
I end up with this fail code: Exception: Unexpected error while getting the method or property getFileById on object DriveApp.
copyFilesToMasterFolder # Code.gs:10
My file id is correct. I don't know what to modify?
function copyFilesToMasterFolder() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var fileLinks = sheet.getRange(2, 3, lastRow-1, 1).getValues();
var masterFolder =
DriveApp.getFolderById("1y5ezQEbS0fDr2TcOjum5wOy6xWHHJcy1");
for (var i = 0; i < fileLinks.length; i++) {
var fileLink = fileLinks[i][0];
var fileId = fileLink.split("/")[fileLink.split("/").length - 2];
var file = DriveApp.getFileById(fileId);
file.makeCopy(masterFolder);
}
}
1.In Google Sheets, select "Tools" from the top menu, then select "Script editor".
2.In the Script editor, paste the following code:
function copyFilesFromSheetToDrive() {
var sheet = SpreadsheetApp.getActiveSheet();
var folder = DriveApp.getFolderById("FOLDER_ID"); // Replace with the ID of the target folder
var column = 1; // Column number of the links in the sheet
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
var file = DriveApp.getFileById(data[i][column - 1]);
folder.addFile(file);
}
}
1.Replace "FOLDER_ID" with the ID of the target folder in Google Drive. You can find the ID in the URL of the folder, e.g., "https://drive.google.com/drive/folders/FOLDER_ID".
2.Save the script and close the Script editor.
3.Back in Google Sheets, select the script from the "Run" menu, or run it by clicking the play button in the Script editor.
This script will copy all the files linked in the first column (column 1) of the active sheet to the specified folder in Google Drive. You can modify the script to copy files from a different column or from a different sheet by changing the column and sheet variables, respectively.
This is going to be a really stupid question - how do I open a file in the Filing Cabinet and read it in, line by line, using SuiteScript? Every example I can find online seems to start in the middle, taking for granted knowledge that I don't possess.
Is there a simple example somewhere online I've not found? All I need is for it to:
Open file (giving file name and folder)
Read the first line
Read the second line
....
Close the file.
In Suitescript 2.0 use the N/file module. The module can only be used in server side (not client) scripts. Reference Suite Answer Id: 43524 for N/file module and Suite Answer Id: 43520 for Script Types.
require(['N/file', 'N/record'], function(file, record) {
//use file name and folder and 'N/search' module to find the file id if necessary
// load file
var myFile = file.load({
id: '__' //enter the file internal id, absolute or relative file path
})
//get the # of lines
var arrLines = myFile.getContents().split(/\n|\n\r/);
// loop through each line, skipping the header
for (var i = 1; i < arrLines.length - 1; i++) {
//split the 1 line of data into an array. If the file was a csv file, each array position holds a value from the columns of the 1 line of data
var content = arrLines[i].split(',');
// get values from the columns of a CSV file
var column1 = content[0]; //first column
var column2 = content[1]; //second column
//can use the column data above to i.e. create new record and set default value, update existing records, write the data elsewhere
//to check each line for a given value
arrLines[i].includes('keyword'); //returns true or false
}
});
You can get the suitescript api documentation here
https://docs.oracle.com/cloud/latest/netsuitecs_gs/docs.htm
look at the file module
Let's keep it simple:
For SuiteScript 1.0:
var arrLines = nlapiLoadFile({fileinternalid}).getValue().split(/\n|\n\r/);
For SuiteScipt 2.0:
var arrLines = file.load({
id: {fileinternalid}
});
arrLines.getValue().split(/\n|\n\r/);
arrLines.description = 'My CSV File'
var fileId = arrLines.save();
...
// Add additional code
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)
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;
}
My problem is that I will have 1..n files to merge into a single file. I have a target SPFile on the Sharepoint Server. I have written a method based on web sites about OpenXML and it runs without errors but ends up blank when I review it.
Here is the Method
private void InsertSPFileInto(SPFile target, SPFile source, int index)
{
Stream targetStream = target.OpenBinaryStream();
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(targetStream, true))
{
string altChunkId = "AltChunkId" + index.ToString();
MainDocumentPart mainPart = myDoc.MainDocumentPart;
AlternativeFormatImportPart chunk =
mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML,
altChunkId);
Stream sourceStream = source.OpenBinaryStream();
chunk.FeedData(sourceStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainPart.Document
.Body
.InsertAfter(altChunk,mainPart.Document.Body.LastChild);
mainPart.Document.Save();
}
}
Again it just returns a blank document, but it doesn't corrupt it either.
Thanks.
Tim Daniels
After playing around with it I found the problem I need to add the follow three lines to the method after the line "maindocument.Documents.Save()"
targetDoc.Close();
targetStream.Flush();
target.SaveBinary(targetStream);