Safe place to store user-defined parameters
-
Non-ASCII characters in file names/paths cause issues with some of Ruby's File commands [in the flavor of Ruby shipped with PC SketchUp].
So you will get a false 'false
' result if you test for its existence, even when the folder actually exists:
So if you test for its existence, and then hope to make it if it doesn't exists, e.g.:
Dir.mkdir('C:/Users/Usersname/AppData/Local/XXXé') unless File.exist?('C:/Users/Usersname/AppData/Local/XXXé')
you will crash and burn because of the falsefalse
that results from theé
!The way to do this safely is...
begin Dir.mkdir('C:/Users/Usersname/AppData/Local/XXXé') rescue end
Which will make the folder, BUT if it does exists there's a silent error because it exists already...
Either way you'll get the specified folder !This is not ideal but ca trap for some false
false
File test issues... -
But that doesn't help anything. You cannot write to that folder in any way.
-
@tig said:
BUT...
No one has still answered my question...
What is wrong with using the container folder for the ENV for the OS's user's 'Temp' folder?
That is easily found for either OS and is writable, like the Temp folder itself...
Once you have the path to the user's 'Temp' folder we can then make an app-specific subfolder to hold our temporary files...
AND from File.dirname(Temp) we can get the container-location into which we can make an app-specific subfolder to hold our 'permanent' files...
I do it without problems on all OS's - the rest of you seem to obsessed with finding 'the exact right folder that we must use', when in truth there are several valid possibilities, and my earlier posts cover much of this too... KISS ?The temp directory is easy to get (
require 'tmpdir'; Dir.tmpdir
) but only useful for temporary files.If you're writing something to the temp directory with the intention of reading it later, you're doing it wrong
. The temp directory is for files that have no consequence if they are removed at a later date. The temp directory is for writing, and reading only when you've been explicitly told to.
The "correct" place for persistent data for an application that is not part of the installation is the appdata location. These directories are separate for each user and guaranteed to be readable/writable for the associated user. This is normally were things like plugins/extensions would exist, also.
A good example of this (if you have it installed) is Sublime Text. (On windows) it is installed to
%PROGRAMFILES%/Sublime Text
, which contains all required binaries and application defaults. Then in%LOCALAPPDATA%/Sublime Text/
(or%APPDATA%/Sublime Text 2/
for st2 user level information is available, including plugins, settings, key configurations, ...Driven has posted what appears to be the MAC equivalent of
LOCALAPPDATA || APPDATA
.So, the search order for a path to write to should be: (keeping in mind I'm no MAC expert)
%LOCALAPPDATA% (win) %APPDATA% (win) ~/Library/???/Sketchup/ [or similar] (MAC) ["~" -> "/Users/<username>/"] Sub-directory in SketchUp directory [plugin-data or similar] (if writable) temp directory (last resort)
-
@unknownuser said:
The "correct" place for persistent data for an application that is not part of the installation is the appdata location. These directories are separate for each user and guaranteed to be readable/writable for the associated user. This is normally were things like plugins/extensions would exist, also.
But as I mentioned - Ruby 1.8 cannot handle non-ASCII characters. Usernames might include Unicode characters and then all file operations on the user directory will simply fail.
-
I will release the new versions of LibFredo6
- with ENV["LOCALAPPDATA"] on Windows
- with TIG's method on Mac, that is the parent directory of the ENV["TMPDIR"] folder. I think using ENV["HOME"] with some hidden subfolder would have been considered too intrusive.
These will be root folders into which I will create the LibFredo6 subfolders for persisting data.
I think in both cases these folder won't contain non-ascii characters, as they are defined and created by the system itself.
Fredo
-
On windows the Local path (ENV["LOCALAPPDATA"]) could return as say
f=ENV["LOCALAPPDATA"]) 'C:\Users\TIGé\AppData\Local'
which will return 'false
' in aFile.exist?(f)
test when it actually exists, just because the user-name contains an accented character!So use my 'safe' way [a few post ago] to make the folder, even if it exists already!
-
@thomthom said:
But as I mentioned - Ruby 1.8 cannot handle non-ASCII characters. Usernames might include Unicode characters and then all file operations on the user directory will simply fail.
All the more reason to update the ruby installation. The provided order would still "work" if you checked each of the directories existed (because the check would "simply fail"), but it's certainly no supplement for the actual feature.
It seems to be reoccurring that the SketchUp ruby API will gives you "clipped wings". I'm excited to see where it can go, but also impatient with its shortcomings (even though this one isn't really SU fault).
Side-note: No unicode support seems strange for something coming out of japan
-
@fredo6 said:
I will release the new versions of LibFredo6
- with ENV["LOCALAPPDATA"] on Windows
- with TIG's method on Mac, that is the parent directory of the ENV["TMPDIR"] folder. I think using ENV["HOME"] with some hidden subfolder would have been considered too intrusive.
These will be root folders into which I will create the LibFredo6 subfolders for persisting data.
I think in both cases these folder won't contain non-ascii characters, as they are defined and created by the system itself.
Fredo
ENV["LOCALAPPDATA"]
may contain non-ascii characters, as it contains the current users username. Also, you should useENV["LOCALAPPDATA"] || ENV["APPDATA"]
so you can support XP at no extra effortBonus:
-
Just to test things I created a user account "tæst" under Windows7. And ran some tests in the Ruby Console:
ENV['HOMEPATH'] \Users\t‘st ENV["LOCALAPPDATA"] C;\Users\t‘st\AppData\Local ENV["APPDATA"] C;\Users\t‘st\AppData\Roaming file = File.join( ENV['LOCALAPPDATA'], 'FooBar.txt' ) C;\Users\t‘st\AppData\Local/FooBar.txt File.open( tempfile, 'wb' ) { |file| file.puts 'Hello world' } Error; #<Errno;;ENOENT; (eval);0;in `initialize'; No such file or directory - C;\Users\t‘st\AppData\Local/FooBar.txt> (eval) (eval);0;in `open' (eval);0 ENV['TEMP'] C;\Users\TST~1\AppData\Local\Temp tempfile = File.join( ENV['TEMP'], 'FooBar.txt' ) C;\Users\TST~1\AppData\Local\Temp/FooBar.txt File.open( tempfile, 'wb' ) { |file| file.puts 'Hello world' } nil
Interesting observations:
Most
ENV
has some strange character replacements. Is this a Ruby thing?ENV['TEMP']
returned a path in the format of the old DOS 8.3 format. And this could be written to.ENV.each { |k,v| puts "#{k}\t#{v}" } ALLUSERSPROFILE C;\ProgramData APPDATA C;\Users\t‘st\AppData\Roaming CommonProgramFiles C;\Program Files (x86)\Common Files CommonProgramFiles(x86) C;\Program Files (x86)\Common Files CommonProgramW6432 C;\Program Files\Common Files COMPUTERNAME ARC-CU-10-09 ComSpec C;\Windows\system32\cmd.exe FP_NO_HOST_CHECK NO HOMEDRIVE C; HOMEPATH \Users\t‘st LOCALAPPDATA C;\Users\t‘st\AppData\Local LOGONSERVER \\ARC-CU-10-09 NUMBER_OF_PROCESSORS 8 OS Windows_NT PATHEXT .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC PROCESSOR_ARCHITECTURE x86 PROCESSOR_ARCHITEW6432 AMD64 PROCESSOR_IDENTIFIER Intel64 Family 6 Model 26 Stepping 5, GenuineIntel PROCESSOR_LEVEL 6 PROCESSOR_REVISION 1a05 ProgramData C;\ProgramData ProgramFiles C;\Program Files (x86) ProgramFiles(x86) C;\Program Files (x86) ProgramW6432 C;\Program Files PSModulePath C;\Windows\system32\WindowsPowerShell\v1.0\Modules\ PUBLIC C;\Users\Public SESSIONNAME Console SystemDrive C; SystemRoot C;\Windows TEMP C;\Users\TST~1\AppData\Local\Temp TMP C;\Users\TST~1\AppData\Local\Temp ULTRAMON_LANGDIR C;\Program Files\UltraMon\Resources\en USERDOMAIN arc-cu-10-09 USERNAME t‘st USERPROFILE C;\Users\t‘st windir C;\Windows
The TEMP path seem to be the only one using this format.
So, question is, is it possible to monkey-patch this so one can extract the user directory in DOS8.3 format and use that to replace the mangled paths of the other variables?And what does it return under other Windows versions? (Win8, Vista, XP)
What about chineese/japanese types or characters - does the same thing apply?
-
@unknownuser said:
Also, you should use
ENV["LOCALAPPDATA"] || ENV["APPDATA"]
so you can support XP at no extra effortWhat folders does this yield on XP? Under Win7 it's both in the user directory.
-
I will use the parent of ENV["TMPDIR"] only on Mac. Apparently, this directory has a long cryptic name, which I assume will only contain valid characters.
On Windows, this is more of a problem is ENV["LOCALAPPDATA"] cannot be manipulated from Ruby dues to non Ascii characters. It's not only for creating subfolders there, but also to manage filepaths of files to be created and updated.
The best I can do is to check if the username contains non-ascii characters and then simplify the name to Ascii, and create a folder with that simplified name in C:\users. This really becomes convoluted!!
There must be a trick however, because when Sketchup installs, it sets the default file locations pointing to the "MyDocuments" folder, whose name also contains the username (something like
C:\Userfiles\<username>\Documents\
). But maybe these locations are not used from Ruby.Fredo
-
@fredo6 said:
The best I can do is to check if the username contains non-ascii characters and then simplify the name to Ascii, and create a folder with that simplified name in C:\users. This really becomes convoluted!!
Creating random folder directly in the location where user folders are? I don't think people would too happy about this. I'd like to explore if we can get the 8.3 filename for the appdata folder.
@fredo6 said:
There must be a trick however, because when Sketchup installs, it sets the default file locations pointing to the "MyDocuments" folder, whose name also contains the username (something like
C:\Userfiles\<username>\Documents\
). But maybe these locations are not used from Ruby.Correct - SketchUp itself has no problems with Unicode paths. It's the Ruby 1.8 core.
-
@thomthom said:
@unknownuser said:
Also, you should use
ENV["LOCALAPPDATA"] || ENV["APPDATA"]
so you can support XP at no extra effortWhat folders does this yield on XP? Under Win7 it's both in the user directory.
Actually as I use both, LOCALAPPDATA first and then APPDATA.
For info, on WindowsXP, ENV["APPDATA"] is defined and uses the old Windows user directory in the form of
C:\Documents and Settings\<username>\Application Data
.Fredo
-
@fredo6 said:
For info, on WindowsXP, ENV["APPDATA"] is defined and uses the old Windows user directory in the form of
C:\Documents and Settings\<username>\Application Data
.Got a full list of ENV variables under XP?
Btw- if I recall correctly "Documents and Settings" is localized to the user's language, isn't it? (without the shim that Vista,Win7, win8 uses)
-
We could also substitute <username> in the paths by
Default
on Win7, Vista, Win8All users
on XP
At least this will avoid the problem of unicode in the username.
Fredo
-
@fredo6 said:
We could also substitute <username> in the paths by
Default
on Win7, Vista, Win8All users
on XP
At least this will avoid the problem of unicode in the username.
And the setting would not be per-use - but per computer. ...which might not be a big issue since the plugin folder is shared by all users.
But again I raise my concern that XP paths might be translated. "All users" I think is "Alle brukere" in Norwegian XP. (I can dig out my old XP machine and test.)
-
Just found a BIG PROBLEM with the 'TIG' and new 'FREDO' path trick on my mac.
My User 'private' settings for 'BOTH' are now available to any account on my computer or connected to my network.
By stepping up stream, external to
ENV["TMPDIR"]
you are bypassing the LOCK to other user accounts and network traffic.So my SFC Password Cookie and my Fredo settings are usable from any account, I do not expect a Plugin to share this type of information with the world.
Please move these back into User Space asap.
This could be a huge problem on a work or university network...
john
-
@driven said:
Just found a BIG PROBLEM with the 'TIG' and new 'FREDO' path trick on my mac.
My User 'private' settings for 'BOTH' are now available to any account on my computer or connected to my network.
By stepping up stream, external to
ENV["TMPDIR"]
you are bypassing the LOCK to other user accounts and network traffic.So my SFC Password Cookie and my Fredo settings are usable from any account, I do not expect a Plugin to share this type of information with the world.
Please move these back into User Space asap.
This could be a huge problem on a work or university network...
john
Confirm: the parent of ENV[TMPDIR] has permissions drwxr-xr-x on my Mac - that means it is readable by anyone, though only the owner (me) can write new files there. ENV[TMPDIR] itself is drwx------, which means it is inaccessible to anyone but me. This is not a big deal if you are the only user on your computer, but a serious issue if anyone else has access.
Steve
-
I think I will default to the old method of DEFPARAM_Dir in the SU Plugins directory
-
Using Win32 API calls I've been able to get short (DOS 8.3 style) path name to appdata. I need to run some tests to make sure it works under XP etc.
Advertisement