Photoshop script .DS_Store - photoshop-script

I'm using Photoshop script. I get files from folders. My problem is that when I get the files and place them in an array the array contains hidden files that are in the folder for example ".DS_Store". I can get around this by using:
if (folders[i] != "~/Downloads/start/.DS_Store"){}
But I would like to use something better as I sometimes look in lots of folders and don't know the "~/Downloads/start/" part.
I tried to use indexOf but Photoshop script does not allow indexOf. Does anybody know of a way to check if ".DS_Store" is in the string "~/Downloads/start/.DS_Store" that works in Photoshop script?
I see this answer but I don't know how to use it to test: Photoshop script to ignore .ds_store

For anyone else looking for a solution to this problem, rather than explicitly trying to skip hidden files like .DS_Store, you can use the Folder Object's getFiles() method and pass an expression to build an array of file types you actually want to open. A simple way to use this method is as follows:
// this expression will match strings that end with .jpg, .tif, or .psd and ignore the case
var fileTypes = new RegExp(/\.(jpg|tif|psd)$/i);
// declare our path
var myFolder = new Folder("~/Downloads/start/");
// create array of files utilizing the expression to filter file types
var myFiles = myFolder.getFiles(fileTypes);
// loop through all the files in our array and do something
for (i = 0; i < myFiles.length; i++) {
var fileToOpen = myFiles[i];
open(fileToOpen);
// do stuff...
}

For anybody looking I used the Polyfill found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
indexOf() was added to the ECMA-262 standard in the 5th edition; as
such it may not be present in all browsers. You can work around this
by utilizing the following code at the beginning of your scripts. This
will allow you to use indexOf() when there is still no native support.
This algorithm matches the one specified in ECMA-262, 5th edition,
assuming TypeError and Math.abs() have their original values.

Related

Processing - loadStrings() case-insensitive

Is there any way to load a text file in Processing while ignoring the case of the file name? I am opening multiple csv files, and some have the extension capitalized, ".CSV" rather than the standard ".csv", which results in errors due to the loadStrings() function being case-sensitive.
String file = sketchPath("test.csv");
String[] array = loadStrings(file);
The above gives the error:
This file is named test.CSV not test.csv. Rename the file or change your code.
I need a way to make the case of the file name or extension not matter. Any thoughts?
Short answer: No. The case-sensitivity of files comes from the operating system itself.
Longer answer: you could create code that just tries to load from multiple places.
Another approach would be to use Java's File class, which has functions for listing various files under a directory, then iterating through them and finding the file that you want. More info is available in the Java reference, but it might look something like this:
String[] array = null;
File dir = new File(sketchPath(""));
for(String file : dir.list()){
if(file.startsWith(yourFileNameHere)){
array = loadStrings(file);
break;
}
}
I haven't tested this code so you might have to play with it a little bit, but that's the basic idea. Of course, you might just want to rename your files ahead of time to avoid this problem.
Why not get the new filename from the error itself? To get the error statement into a String, we need to wrap loadStrings in a try and catch statement.
String[] array;
String file = "heLlo.txt";
try {
//if all is good then we load the file
array = loadStrings(file);
}catch(Exception e){
//otherwise when we get the error, we store it in a String
String error = e.toString();
Then we need to use regular expressions to get the filename from the error statement using match. The regex is /named ([^ +])/ (the filename can be assumed not to have any spaces in it).
String[]matches = match(error, "named ([^ ]+)");
The capture group with be in element 1 in the array containing the matches. So that would be the "real" filename,
String realFile = matches[1];
Finally we load the real file and store it in our array.
array = loadStrings(realFile);
}
Sure, if you want, you can put all of this into a function so that you won't have to use this code again and again every time you load a file. But obviously, it would just be easier if you just renamed or checked your filenames ahead in time.

Get the file type of a file using the Windows API

I am trying to identify when a file is PNG or JPG to apply it as a wallpaper. I am using the SHGetFileInfo to get the type name with the .szTypeName variable, but I just realized that it changes if the OS is in another language.
This is my code:
SHFILEINFOW fileInfo;
UINT sizeFile = sizeof(fileInfo);
UINT Flags = SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES;
// Getting file info to find out if it has JPG or PNG format
SHGetFileInfoW(argv[1], 0, &fileInfo, sizeFile, Flags);
This is how I am validating:
if (wcscmp(fileInfo.szTypeName, L"JPG File") == 0)
{
//Code here
}
When the OS is in spanish, the value changes to "Archivo JPG" so I would have to validate against all language, and does not make sense.
Any idea what other function I can use?
This API is meant to be used to produce a user-facing string representation for known file types1). It is not meant to be used to implement code logic.
More importantly, it doesn't try to parse the file contents. It works off of the file extension alone. If you rename an Excel workbook MySpreadsheet.xlsx to MySpreadsheet.png, it will happily report, that this is a "PNG File".
The solution to your problem is simple: You don't have to do anything, other than filtering on the file extension. Use PathFindExtension (or PathCchFindExtension for Windows 8 and above) to get the file extension from a fully qualified path name.
This can fail, in case the user appended the wrong file extension. Arguably, this isn't something your application should fix, though.
As an aside, you pass SHGFI_USEFILEATTRIBUTES to SHGetFileInfoW but decided to not pass any file attributes (second argument) to the call. This is a bug. See What does SHGFI_USEFILEATTRIBUTES mean? for details.
1) It is the moral equivalent of SHGFI_DISPLAYNAME. The only thing you can do with display names is display them.

TypeError: cannot concatenate 'str' and 'pygame.Surface' objects

I am currently teaching myself game programming, and I've started nice and easy with pygame. I went through a tutorial that showed me how to build a simple game, and now that I am finished with it, I am in the process of trying to reorganize the code in a manner that makes sense to me, and also to edit it and add to it.
Part of what I tried to change is that instead of loading one '.png' file for a character, I load a list of them that will be iterated through in a 'move()' function I designed to make the characters look like they are moving. However I keep running into an error and I don't know why. Near the beginning of my code (all I've done is imported necessary modules and initialized pygame and some necessary variables) I tried to do the following code:
badguyimgs = ['badguy.png', 'badguy2.png', 'badguy3.png', 'badguy4.png']
for img in badguyimgs:
badguyimgs.append(pygame.image.load("resources/images/" + img))
badguyimgs.remove(img)
I keep getting the following error:
TypeError: cannot concatenate 'str' and 'pygame.Surface' objects
So far I have tried to initialize a new variable (resource = "resources/images/" + img) and place that at the beginning of the "for" loop and then insert that into the pygame.image.load(). I've also tried using os.path.join("resource/images/" + img). I've tried using the full path name ("c:\\Users\\ . . . \\resources\\images\\" +img). But any time I try to concatenate the pathname with the file name in the list, I get the above error code. I tried looking in the pygame documentation, but didn't see anything that helped in this situation. I've tried googling the error, but get nothing in reference to this. (a lot of issues with people tring to concatenate int types to strings though. . . ) I would appreciate any help anyone could give in pointing out why I am experiencing this, and what could fix it. Thanks.
It looks like what you're doing is appending the pygame.surface object (that you loaded from a png file) to the list while you're iterating through it. You are loading the images successfully. However after your function adds the first image and removes the string, your list looks like this:
badguyimgs = ['badguy2.png', 'badguy3.png', 'badguy4.png', pygame.image]
You are still iterating through the list, so your function starts trying to concatenate the string and the pygame.surface object. I would recommend creating an empty list, and add your loaded images to that list without adding or removing anything from the original. Hope this helped!
Here's an example to go with PlatypusVenom's explanation:
file_names = ['badguy.png', 'badguy2.png', 'badguy3.png', 'badguy4.png']
images = []
for file_name in file_names:
images.append(pygame.image.load("resources/images/" + file_name))
Now the pygame.Surface objects are in images, and the variable names for the lists are less confusing. Another option is to use a list comprehension:
images = [pygame.image.load("resources/images/" + file_name) for file_name in \
("badguy.png", "badguy2.png", "badguy3.png", "badguy4.png")]
This is similar to what you were going for in the code posted. The list of strings will be removed from memory, leaving only pygame.Surface objects in the images list.

Advanced Array Sorting in Ruby

I'm currently working on a project in ruby, and I hit a wall on how I should proceed. In the project I'm using Dir.glob to search a directory and all of its subdirectories for certain file types and placing them into an arrays. The type of files I'm working with all have the same file name and are differentiated by their extensions. For example,
txt_files = Dir.glob("**/*.txt")
doc_files = Dir.glob("**/*.doc")
rtf_files = Dir.glob("**/*.rtf")
Would return something similar to,
FILECON.txt
ASSORTED.txt
FIRST.txt
FILECON.doc
ASSORTED.doc
FIRST.doc
FILECON.rtf
ASSORTED.rtf
FIRST.rtf
So, the question I have is how I could break down these arrays efficiently (dealing with thousands of files) and placing all files with the same filename into an array. The new array would look like,
FILECON.txt
FILECON.doc
FILECON.rtf
ASSORTED.txt
ASSORTED.doc
ASSORTED.rtf
etc. etc.
I'm not even sure if glob would be the correct way to do this (all the files with the same file name are in the same folders). Any help would be greatly appreciated!
Get all your files into a single array with Dir.glob("**/*.{txt,doc,rtf}")
Don't forget that all the filenames have the directory too, so if you want to sort by the basename, then
files = Dir.glob("**/*.{txt,doc,rtf}").sort_by {|f| File.basename f}
Not sure if this is exactly what you need, but you can try to
# first get all files
all_files = Dir.glob('**/*')
# then you can group them by name
by_name = all_files.group_by{|f| m = f.match(/([^\/]+)\.[^.\/]+$/); m[1] if m}
# and by extension
by_ext = all_files.group_by{|f| m = f.match(/[^\/]+\.([^.\/]+)$/); m[1] if m}
BTW, I don't see any relation of the question with sorting.

Pass data from workspace to a function

I created a GUI and used uiimport to import a dataset into matlab workspace, I would like to pass this imported data to another function in matlab...How do I pass this imported dataset into another function....I tried doing diz...but it couldnt pick diz....it doesnt pick the data on the matlab workspace....any ideas??
[file_input, pathname] = uigetfile( ...
{'*.txt', 'Text (*.txt)'; ...
'*.xls', 'Excel (*.xls)'; ...
'*.*', 'All Files (*.*)'}, ...
'Select files');
uiimport(file_input);
M = dlmread(file_input);
X = freed(M);
I think that you need to assign the result of this statement:
uiimport(file_input);
to a variable, like this
dataset = uiimport(file_input);
and then pass that to your next function:
M = dlmread(dataset);
This is a very basic feature of Matlab, which suggests to me that you would find it valuable to read some of the on-line help and some of the documentation for Matlab. When you've done that you'll probably find neater and quicker ways of doing this.
EDIT: Well, #Tim, if all else fails RTFM. So I did, and my previous answer is incorrect. What you need to pass to dlmread is the name of the file to read. So, you either use uiimport or dlmread to read the file, but not both. Which one you use depends on what you are trying to do and on the format of the input file. So, go RTFM and I'll do the same. If you are still having trouble, update your question and provide details of the contents of the file.
In your script you have three ways to read the file. Choose one on them depending on your file format. But first I would combine file name with the path:
file_input = fullfile(pathname,file_input);
I wouldn't use UIIMPORT in a script, since user can change way to read the data, and variable name depends on file name and user.
With DLMREAD you can only read numerical data from the file. You can also skip some number of rows or columns with
M = dlmread(file_input,'\t',1,1);
skipping the first row and one column on the left.
Or you can define a range in kind of Excel style. See the DLMREAD documentation for more details.
The filename you pass to DLMREAD must be a string. Don't pass a file handle or any data. You will get "Filename must be a string", if it's not a string. Easy.
FREAD reads data from a binary file. See the documentation if you really have to do it.
There are many other functions to read the data from file. If you still have problems, show us an example of your file format, so we can suggest the best way to read it.

Resources