Using File Type Array in Extendscript - extendscript

I am trying to integrate an Array containing a list of image file types that can be used in my Extendscript, this is what I have:
DFgroup.DFBtn.onClick = function(){
DFdefault = new Folder(DARKinputFolder); //stores the current folder in case of cancel.
DFdefault = Folder.selectDialog('****Please Select The Folder Where Your DARK FRAMES Are Located****',DARKinputFolder);
if ( DFdefault != null ) {
DARKinputFolder = DFdefault.fsName.toString()
DFgroup.DFlabel.text = DARKinputFolder;
if(DFdefault){DARKinputFolder = DFdefault}; //if cancel is hit, this statement becomes false, and myFolder remains untouched.
//if it's true, then the selected folder from the holdFolder is transferred to myfolder.
var FILE_TYPE, FTlen i;
FILE_TYPE = [".orf", ".tif", ".tiff", ".jpg", ".jpeg"];
FTlen = FILE_TYPE.length;
for (i = 0; i < FTlen; i++){
var SEARCH_MASK = "*" + FILE_TYPE[i];}
var DARKfileList = DARKinputFolder.getFiles(SEARCH_MASK) ;
//if (DARKfileList.length <= 0)
//{
//var FILE_TYPE = ".jpg"; // The type of files that this script works on -- you can change
//var SEARCH_MASK = "*" + FILE_TYPE; // Image file filter to find only those files
//var DARKfileList = DARKinputFolder.getFiles(SEARCH_MASK);
//}
if (DARKfileList.length == 0)
{
alert('The DARK FRAME folder you have chosen is either empty or does not contain image files of the correct type.\r\rPlease locate & select the correct image folder.','DARK FRAME folder error');
DFgroup.DFlabel.text = 'No DARK FRAMES folder has been selected...';
DFdefault = '';
DFgroup.DFlabelQ.text = '';
}
else{
DFgroup.DFlabelQ.text = '[' + DARKfileList.length + ']';
var DFCurrFolder = (new File(DARKinputFolder)).fsName;
DFgroup.DFlabel.helpTip = 'Location of files to process:\r' + DFCurrFolder;
FolderChecker()
}}
} //opens the folder browse UI using you main folder.
When a user hits the 'DFBtn' an open folder dialog appears and they can choose a folder that contains images.
This folder path along with the number of images contained within it are retrieved and output as text label on a dialog box.
The problem is that through testing and choosing a folder that does contain an image and that image is of the allowed type, the script goes straight to the 'Alert' message stating that the "folder you have chosen is either empty....." etc..
Now if I alter a small section of the code as:
if (DARKfileList.length <= 0)
{
var FILE_TYPE, FTlen, i;
FILE_TYPE = [".orf", ".tif", ".tiff", ".jpg", ".jpeg"];
FTlen = FILE_TYPE.length;
for (i = 0; i < FTlen; i++){
var SEARCH_MASK = "*" + FILE_TYPE[i];}
var DARKfileList = DARKinputFolder.getFiles(SEARCH_MASK) ;}
The code now no longer goes straight to the 'Alert' message even if I deliberately choose a folder that is empty.
UPDATE
To aid in finding out what is going on I have added an extra line of code:
var FILE_TYPE, FTlen i;
FILE_TYPE = [".orf", ".tif", ".tiff", ".jpg", ".jpeg"];
FTlen = FILE_TYPE.length;
for (i = 0; i < FTlen; i++){
var SEARCH_MASK = "*" + FILE_TYPE[i];}
var DARKfileList = DARKinputFolder.getFiles(SEARCH_MASK);
alert (SEARCH_MASK);
By just adding this line alert (SEARCH_MASK); straight away I had an insight to what is occurring.
Yes the FILE_TYPE Array is being iterated through but then the SEARCH_MASK is formed using just the last FILE_TYPE in the array, so in the case above the SEARCH_MASK is always created as:
*.jpeg
Therefore it will only be looking for files of that type within the chosen folder.
This is not what I am trying to achieve.
I want to know if the chosen folder contains ANY files of ANY of the types listed in the array.
For instance, the chosen folder could contain all *.tif files or even one of each file type.
How can I achieve what I require the code to do?
Regards..,
UPDATE 2 BOILED DOWN SCRIPT
Here's a boiled down script as requested:
var DARKfileList = '';
var AllowedFileTypes = Array( "orf", "tif", "tiff", "jpg", "jpeg" );
var dlgM = new Window('dialog','***###***###',undefined,{closeButton:false});
dlgM.center();
var DARKinputFolder = new Folder('/C/'); //create a folder to have the dialog start on.
var DFdefault = new Folder(); //create a holding folder for canceling.
DFg = dlgM.add('panel {text:"DARK FRAMES",preferredSize:[450,15]}');
DFg.margins = [5,10,5,10];
DFg.alignChildren = 'left';
DFgroup = DFg.add('group');
DFgroup.DFBtn = DFgroup.add('button{text:"Select Folder...",preferredSize:[100,25]}');
DFgroup.DFBtn.helpTip = 'Please select your DARK FRAMES folder.';
DFgroup.DFlabel = DFgroup.add( 'statictext', undefined, DARKinputFolder, { truncate:'middle' } );
DFgroup.DFlabel.helpTip = 'Location of files to process';
DFgroup.DFlabel.preferredSize.width = '275';
DFgroup.DFlabel.text = 'No DARK FRAMES folder has been selected...';
DFgroup.DFlabelQ = DFgroup.add( 'statictext', undefined, '');
DFgroup.DFlabelQ.helpTip = 'Number of DARK FRAMES to process';
DFgroup.DFlabelQ.preferredSize.width = '40';
DFgroup.DFlabelQ.text = '';
BTNg = dlgM.add('group {alignment: "center"}');
BTNg.ExitBtn = BTNg.add('button{text:"Exit",preferredSize:[105,25]}');
BTNg.ProcessBtn = BTNg.add('button{text:"Process",preferredSize:[105,25]}');
BTNg.ProcessBtn.enabled = false;
DFgroup.DFBtn.onClick = function(){
DFdefault = new Folder(DARKinputFolder); //stores the current folder in case of cancel.
DFdefault = Folder.selectDialog('****Please Select The Folder Where Your DARK FRAMES Are Located****',DARKinputFolder);
if ( DFdefault != null ) {
DARKinputFolder = DFdefault.fsName.toString()
DFgroup.DFlabel.text = DARKinputFolder;
if(DFdefault){DARKinputFolder = DFdefault}; //if cancel is hit, this statement becomes false, and myFolder remains untouched.
//if it's true, then the selected folder from the holdFolder is transferred to myfolder.
var FTlen, i;
FTlen = AllowedFileTypes.length;
for (i = 0; i < FTlen; i++){
var SEARCH_MASK = "*." + AllowedFileTypes[i]};
var DARKfileList = DARKinputFolder.getFiles(SEARCH_MASK) ;
if (DARKfileList.length == 0)
{
alert('The DARK FRAME folder you have chosen is either empty or does not contain image files of the correct type.\r\rPlease locate & select the correct image folder.','DARK FRAME folder error');
DFgroup.DFlabel.text = 'No DARK FRAMES folder has been selected...';
DFdefault = '';
DFgroup.DFlabelQ.text = '';
}
else{
DFgroup.DFlabelQ.text = '[' + DARKfileList.length + ']';
var DFCurrFolder = (new File(DARKinputFolder)).fsName;
DFgroup.DFlabel.helpTip = 'Location of files to process:\r' + DFCurrFolder;
FolderChecker()
}}
} //opens the folder browse UI using you main folder.
BTNg.ExitBtn.onClick = function(){
dlgM.close();
}
function FolderChecker(){
if (DFdefault.exists){
BTNg.ProcessBtn.enabled = true;
}
}
BTNg.ProcessBtn.onClick = function(){
// THIS IS WHERE IMAGE PROCESSING STARTS -- REMOVED THIS HUGE SECTION FOR BREVITY
}
dlgM.show();
UPDATE 3 Final Issue
As per my comment about the need to check for illegal file types etc, here's what I have so far:
if (DARKfileList.length == 0)
{
alert('empty folder!','DARK FRAME folder error');
DFgroup.DFlabel.text = 'No DARK FRAMES folder has been selected...';
DFdefault = '';
DFgroup.DFlabelQ.text = '';
}
else if (DARKfileList.length > 1)
{
alert('too many file types!','DARK FRAME folder error');
DFgroup.DFlabel.text = 'No DARK FRAMES folder has been selected...';
DFdefault = '';
DFgroup.DFlabelQ.text = '';
}
else{
DFgroup.DFlabelQ.text = '[' + DARKfileList.length + ']';
var DFCurrFolder = (new File(DARKinputFolder)).fsName;
DFgroup.DFlabel.helpTip = 'Location of files to process:\r' + DFCurrFolder;
FolderChecker()
}
Now this works perfectly if the chosen folder contains only one file & that file is not in the FILE_TYPE array as DARKfileList.length returns zero. As Required
Similarly if the folder contains more than one of any file no matter what type the check fails. As Required
However, if a chosen folder contains one allowed FILE_TYPE & one file type that is not in the FILE_TYPE array the check fails. Needs Sorting Out
I need something along the lines of:
if (DARKfileList != FILE_LIST)
{
alert('Illegal file type!);
DFgroup.DFlabel.text = 'No DARK FRAMES folder has been selected...';
DFdefault = '';
DFgroup.DFlabelQ.text = '';
}

The problem is that each iteration you overriding the resulting search mask.
You need to merge all the resulting into one array, and then to check if your array is empty:
var DARKfileList = [], FILE_TYPE, FTlen, i, SEARCH_MASK;
FILE_TYPE = ["orf", "tif", "tiff", "jpg", "jpeg"];
FTlen = FILE_TYPE.length;
for (i = 0; i < FTlen; i++) {
SEARCH_MASK = "*." + FILE_TYPE[i];
DARKfileList = DARKfileList.concat(DARKinputFolder.getFiles(SEARCH_MASK));
}
alert('found: ' + DARKfileList.length + ' files');
Alternative: getFiles can get regex as parameter, so if you familiar with regex you can simply use the following regex:
/.+\.(?:jpe?g|tiff?|orf)$/i
Regex explanation: match in the filename any character, then dot character, and then one of the extension option and then the i flag used to ignore case sensitive. In your example you get only files that the extension is in lowercase.
To add another extensions to the regex, just add pipe(|) after orf and then your extension. ex: to add pdf extension:
/.+\.(?:jpe?g|tiff?|orf|pdf)$/i
Usage of regex in your code:
DARKfileList = DARKinputFolder.getFiles(/.+\.(?:jpe?g|tiff?|orf|pdf)$/i);
You can also use array to store all of your extensions and use it like:
var regex = new RegExp('.+\.(?:' + FILE_TYPE.join('|')+ ')$','i');
DARKfileList = DARKinputFolder.getFiles(regex);

Related

File search from a folder from FileCabinet in NetStuite returns only five records?

When I am doing the search, the results always contain only five records (in ascending order). I need to get a list of all files in the folder. What am I doing wrong?
FileSearch fileSearch = new FileSearch();
FileSearchBasic fileSearchBasic = new FileSearchBasic();
// Specify the folder in which the search is to be done.
SearchMultiSelectField folderFilter = new SearchMultiSelectField
{
#operator = SearchMultiSelectFieldOperator.anyOf,
operatorSpecified = true
};
RecordRef[] folder = new RecordRef[1];
folder[0] = new RecordRef
{
// Internal id of the folder where pospay files are stored.
internalId = ns.DataCollection["netSuite:PositivePayFolderInternalId"]
};
folderFilter.searchValue = folder;
fileSearchBasic.folder = folderFilter;
fileSearch.basic = fileSearchBasic;
var result = NSBase.Client.Service.search(fileSearch);
var recordList = result.recordList; // this has ony five results, why?
I found the issue, 'PageSize' was set to 5 in the service client's constructor.

Hybris prettyURL showing PK instead of the real file name

The file-name of any image is appearing like
/de-de/medias/sys_master/images/images/h9c/h5f/8796178743326/8796178743326.jpg in the url.
Instead of 8796178743326.jpg there should be file-name.jpg
I have already set media.legacy.prettyURL=true
8796178743326 is the PK of the image.
Any help!
With the prettyURL, if there is no realfilename value in media instance then URL will end with PK instead real file name.
/medias/sys_master/images/images/h9c/h5f/8796178743326/8796178743326.jpg
If you really want the file name in the URL then you have to edit respective media from the backoffice/impex and assign value to the realFileName attribute.
Have a look into assembleLegacyURL method of LocalMediaWebURLStrategy class
String realFileName = this.getRealFileNameForMedia(mediaSource);
if (realFileName == null) {
basePath = mediaSource.getLocation().substring(0, lastDotIdx);
lastDotIndexForRealFileName = StringUtils.lastIndexOf(basePath, '/');
String fileName = basePath.substring(lastDotIndexForRealFileName + 1);
sb.append(basePath).append("/").append(fileName).append('.').append(fileExtension);
} else {
basePath = location.substring(0, lastDotIdx);
lastDotIndexForRealFileName = realFileName.lastIndexOf(46);
if (lastDotIndexForRealFileName != -1) {
realFileName = realFileName.substring(0, lastDotIndexForRealFileName);
}
sb.append(basePath).append("/").append(realFileName).append('.').append(fileExtension);
}

How to manipulate a xml file and save it to disk?

I have two xml files with exactly same structure. The only difference is the inner text of the tags.
I want to replace the value in the first file with the corresponding value in the second file.
I have tried using the xml2json but the problem is it removed all the comments which I need in the final output.
So currently I am using xmldom.
I am able to manipulate the text but the changes are lost when I try to save the file to the disk.
var DOMParser = require("xmldom").DOMParser;
var serializer = new (require('xmldom')).XMLSerializer;
var fs = require('fs');
let firstXML = `<root>
<!--This is just a comment-->
<string name="one">SOMETHING</string>
</root>`
let secondXML = `<root>
<string name="one">ELSE</string>
</root>`
var firstDoc = new DOMParser().parseFromString(firstXML, "text/xml");
var secondDoc = new DOMParser().parseFromString(secondXML, "text/xml");
let elementsFirst = firstDoc.getElementsByTagName("string");
let elementsSecond = secondDoc.getElementsByTagName("string");
for(let i = 0; i < elementsFirst.length; ++i) {
let el = elementsFirst[i];
let name = el.getAttribute("name");
for(let j = 0; j < elementsSecond.length; ++j) {
if(name = elementsSecond[j].getAttribute("name")) {
el.firstChild.nodeValue = elementsSecond[j].firstChild.nodeValue;
break;
}
}
}
fs.writeFileSync("output.xml", serializer.serializeToString(firstDocs));
//Required output
`<root>
<!--This is just a comment-->
<string name="one">ELSE</string>
</root>`
Please don't ask me why, but if you replace this line
el.firstChild.nodeValue = elementsSecond[j].firstChild.nodeValue;
with this one
el.firstChild.data = elementsSecond[j].firstChild.nodeValue;
it will work as expected.
P.S. You have a typo in your if statement, you need ===, a single = will usually return true
Update: after finding the solution - I found out that it is duplicate of this one

Error Running jsx file from Indesign to export each text frame as a .txt file

Last year my colleague helped to build a script for Indesign.
Subsequently, after a system update we no longer have the script as Indesign CS6 was reinstalled, all we have is a version as below.
Using this code in Adobe Indesign to export each text frame that begins with a particular Paragraph stylesheet "PRODUCT HEADING" however I get an error message when I run the script...
Script is based on the ExportAllStories.jsx bundled with InDesign, plus a few mods found online.
//ExportAllStories.jsx
//An InDesign CS6 JavaScript
/*
###BUILDINFO### "ExportAllStories.jsx" 3.0.0 15 December 2009
*/
//Exports all stories in an InDesign document in a specified text format.
//
//For more on InDesign scripting, go to http://www.adobe.com/products/indesign/scripting/index.html
//or visit the InDesign Scripting User to User forum at http://www.adobeforums.com
//
main();
function main(){
//Make certain that user interaction (display of dialogs, etc.) is turned on.
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if(app.documents.length != 0){
if (app.activeDocument.stories.length != 0){
myDisplayDialog();
}
else{
alert("The document does not contain any text. Please open a document containing text and try again.");
}
}
else{
alert("No documents are open. Please open a document and try again.");
}
}
function myDisplayDialog(){
with(myDialog = app.dialogs.add({name:"ExportAllStories"})){
//Add a dialog column.
myDialogColumn = dialogColumns.add()
with(myDialogColumn){
with(borderPanels.add()){
staticTexts.add({staticLabel:"Export as:"});
with(myExportFormatButtons = radiobuttonGroups.add()){
radiobuttonControls.add({staticLabel:"Text Only", checkedState:true});
radiobuttonControls.add({staticLabel:"RTF"});
radiobuttonControls.add({staticLabel:"InDesign Tagged Text"});
}
}
}
myReturn = myDialog.show();
if (myReturn == true){
//Get the values from the dialog box.
myExportFormat = myExportFormatButtons.selectedButton;
myDialog.destroy;
myFolder= Folder.selectDialog ("Choose a Folder");
if((myFolder != null)&&(app.activeDocument.stories.length !=0)){
myExportAllStories(myExportFormat, myFolder);
}
}
else{
myDialog.destroy();
}
}
}
//myExportStories function takes care of exporting the stories.
//myExportFormat is a number from 0-2, where 0 = text only, 1 = rtf, and 3 = tagged text.
//myFolder is a reference to the folder in which you want to save your files.
function myExportAllStories(myExportFormat, myFolder){
for(myCounter = 0; myCounter < app.activeDocument.stories.length; myCounter++){
myStory = app.activeDocument.stories.item(myCounter);
myID = myStory.id;
switch(myExportFormat){
case 0:
myFormat = ExportFormat.textType;
myExtension = ".txt"
break;
case 1:
myFormat = ExportFormat.RTF;
myExtension = ".rtf"
break;
case 2:
myFormat = ExportFormat.taggedText;
myExtension = ".txt"
break;
}
if (myStory.paragraphs[0].appliedParagraphStyle.name == "PRODUCT HEADING"){
myFileName = myFileName.replace(/\s*$/,' ');
myFileName2 = myFileName.replace(/\//g, ' ');
myFilePath = myFolder + "/" + myFileName2;
myFile = new File(myFilePath);
myStory.exportFile(myFormat, myFile);
}
}
}
This results in an error on
if (myStory.paragraphs[0].appliedParagraphStyle.name == "PRODUCT HEADING"){
Any advice would be appreciated.
There is definitely a block of text with the style PRODUCT HEADING (all caps) in the Indesign File. We run Indesign CS6 as previous
thanks!
Your problem is most likely with this part: myStory.paragraphs[0]. If the story has no paragraphs this will give you an error.
You could add a condition before running this line, like this for example:
if(myStory.paragraphs.length){
if (myStory.paragraphs[0].appliedParagraphStyle.name == "PRODUCT HEADING"){
myFileName = myFileName.replace(/\s*$/,' ');
myFileName2 = myFileName.replace(/\//g, ' ');
myFilePath = myFolder + "/" + myFileName2;
myFile = new File(myFilePath);
myStory.exportFile(myFormat, myFile);
}
}

Drupal 6 / Ubercart - Automatically set Adjustment SKU

Is it possible to automatically set adjustment alternate SKU values for a product in Ubercart?
Basically every product will have a suffix added to it's original SKU based on the adjustment, so it would save a lot of time to populate the adjustment SKU's automatically when the product node is created.
Here's a JavaScript version - it provides a link to automatically generate the SKUs as well as a 'default stock' option on the stock page.
Drupal.behaviors.autoSKU = function(){
//if we're on the product adjustments page, add a button to automatically set sku's
if($('#uc-product-adjustments-form').length > 0){
$('#uc-product-adjustments-form').before($('<a>Automatically set SKU\'s</a>').css('cursor', 'pointer').click(function(){
$base = $('#uc-product-adjustments-form').attr('action').substr(6, 4) + '-';
$('#uc-product-adjustments-form .form-text').each(function(){
$(this).attr('value', $base + $(this).parents('tr').attr('title').toLowerCase().replace(new RegExp(' ', 'g'),'-'));
});
}));
}
//if we're on the stock page, automatically set as active and set default stock level
if($('#uc-stock-edit-form').length > 0){
$('#uc-stock-edit-form').before($('<a>Activate and Set Default Stock</a>').css('cursor', 'pointer').click(function(){
$first = true;
$('#uc-stock-edit-form .form-checkbox').each(function(){
if($first){
$(this).attr('checked', false);
$first = false;
}
else{
$(this).attr('checked', true);
}
});
$set_stock = $('#edit-stock-0-stock').attr('value');
$odd = true;
$('#uc-stock-edit-form .form-text').each(function(){
if($odd){
$(this).attr('value', $set_stock);
}
$odd = !$odd;
});
}));
}
}
This may not be the -right- way to do it, but I created a small module that taps into the nodeapi insert operation:
<?php
function photo_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'photo_node_form'){
$form['base']['model']['#default_value'] = 'placeholder';
}
}
function photo_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch($op){
case 'presave':
if($node->model == 'placeholder')
$node->model = $node->field_image_cache2[0]['filename'];
break;
case 'insert':
$nid = $node->nid;
$sku_dl = $node->model.'d';
//====== Setup Adjustments ======
db_query('INSERT INTO {uc_product_adjustments} (nid,combination,model) VALUES'
.'('.$nid.',"%s","'.$sku_dl.'"),'
.'('.$nid.',"%s","'.$sku_dl.'"),'
.'('.$nid.',"%s","'.$sku_dl.'"),'
.'('.$nid.',"%s","'.$sku_dl.'"),'
.'('.$nid.',"%s","'.$sku_dl.'")'
,serialize(array('1'=>'1'))
,serialize(array('1'=>'3'))
,serialize(array('1'=>'4'))
,serialize(array('1'=>'5'))
,serialize(array('1'=>'6'))
);
//====== Add file download on purchase ======
$file_name = $node->field_image_cache2[0]['filename'];
db_query("INSERT INTO {uc_files} (filename) VALUES ('%s')",$file_name);
db_query("INSERT INTO {uc_file_products} (pfid, fid, model, description, shippable) VALUES (%d, LAST_INSERT_ID(), '%s', '%s', %d)", 0, $sku_dl, '', 1);
db_query('UPDATE {uc_file_products} SET pfid = LAST_INSERT_ID() WHERE fpid = LAST_INSERT_ID() LIMIT 1');
db_query("INSERT INTO {uc_product_features} (pfid, fid, nid, description) VALUES (LAST_INSERT_ID(), '%s', %d, '%s')", 'file', $nid, '<b>Filename</b><br/>'.$file_name.'<br/> <b>Reference</b> : '.$sku_dl);
break;
}
}
Have a look at http://drupal.org/project/uc_product_power_tools
Appears this can be done off the shelf.

Resources