So I wanted to use the $.now() along with the persons IP address as a type of random number generator to attach to the front of file names to insure that if a file with the same name was uploaded it would not overwrite the first one.
the code I came up with was as follows:
var ipadd = '';
var filename = 'name';
var militime = 't';
var uploadname = '';
var ipid = '';
$(window).load(function() {
militime = $.now();
console.log(militime);
$('a.next-btn').on('click', function() {
$.get("https://ipinfo.io", function(response) {
ipadd = response.ip;
ipid = ipadd + militime;
}, "jsonp");
});
$('.file-uploader-form input[name="floor_plan_upload"]').live('change', function() {
var filename = $('.flow-section input[name="floor_plan_upload"]').val().split('\\').pop();
uploadname = ipid + filename;
$('input[name="file_path"]').val(uploadname).change();
});
});
I tested it in chrome on mac and it worked fine, it also works fine in firefox on windows but not chrome or microsoft edge on windows, it only displays the IP address.
Ive also tryed using Date.now(); and new Date().getTime(); to the same ends.
I did notice though that when I remove the militime = $.now(); from after the $(window).load(function(){ that it doesn't even print what I made the default value for militime 't', so that suggests that there is something else wrong here, I just don't know what.
You should not use the user provided filename as the filename on the server. So, generate the unique filename on the server instead.
OK this doesn't solve the problem, but then again you're solving it wrong...
Related
I'm trying to save the activeDocument as a .psd but its returning this error
ERROR: General Photoshop error occurred. This functionality may not be available in this version of Photoshop.
my script:
#target photoshop
var fileRef = new File(app.path.toString() + "/Samples/template.psd");
var docRef = open(fileRef);
//target text layer
var layerRef = app.activeDocument.layers.getByName("Text");
//user input
var newText = prompt("Editing " + layerRef.name, "enter new text: ");
//change contents
layerRef.textItem.contents = newText;
//save
var savePath = "/Samples/" + newText + ".psd";
var saveFile = new File(savePath);
var saveOptions = new PhotoshopSaveOptions();
saveOptions.alphaChannels = false;
saveOptions.annotations = false;
saveOptions.embedColorProfile = true;
saveOptions.layers = true;
saveOptions.spotColors = false;
app.activeDocument.saveAs(saveFile, saveOptions, true, Extension.LOWERCASE);
app.activeDocument.close();
what I want to do is basically, duplicate a template file over and over, only replacing the contents of a text layer then saving it under the string I replace in the text layer.
any tips or help is greatly appreciated.
Resolved
I fixed my problem, by a work around. I moved both the script and the template file into the Photoshop directory and added app.path.toString() to the saveFile output variable. So it seems that the path needed to be converted to a string before saving.
As of yet I am unsure how to work outside the Photoshop directory but for me this works so I'm happy. It's a fairly crude but I'm open to suggestion. So if anyone is having a similar issue they can use this for reference.
#target photoshop
var loop = true;
var filePath = "/Samples/template.psd";
while(loop) {
openTemplate(filePath);
var layerRef = app.activeDocument.layers.getByName("Text"); //target text layer
var newText = prompt("Editing " + layerRef.name, "enter new text: "); //user input
if(newText == "stop") { //stop loop by entering 'stop'
loop = false;
}
layerRef.textItem.contents = newText;
var savePath = app.path.toString() + "/Samples/" + newText + ".psd";
var saveFile = new File(savePath);
savePSD(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
function openTemplate(filePath) { //open template.psd
var fileRef = new File(app.path.toString() + filePath);
var docRef = open(fileRef);
}
function savePSD(saveFile) { //saveas newText.psd
var saveOptions = new PhotoshopSaveOptions();
saveOptions.alphaChannels = false;
saveOptions.annotations = false;
saveOptions.embedColorProfile = true;
saveOptions.layers = true;
saveOptions.spotColors = false;
app.activeDocument.saveAs(saveFile, saveOptions, true, Extension.LOWERCASE);
}
I suspect the problem with your original attempt is that you are not specifying a full path. I always provide a full path - even if it is just to a temporary location like '/c/temp/myfile.psd'.
app.path returns a File object, not a string. In your case, you most likely want the platform-specific fullpath string:
var appPath = app.path.fsName; // "C:\Program Files\Adobe\Adobe Photoshop 2022"
Regardless if paths are correct, if you're attempting to save anything to a directory located inside the Photoshop installation directory, you will probably need to run Photoshop as administrator.
I am starting out in photoshop with a .tif file. I run a script which adds some layers etc and then i save the file as a .psd in a new folder.
The problem i am having is checking to see if a .psd file already exists with the same name. My goal is to simply close down the .tif file without saving if a .psd with the same name appears in the folder.
Here is my save code:
//Save document
var savePath = Folder(doc.path.parent) + "/new_folder/";
saveFile = new File(savePath);
saveOptions = new PhotoshopSaveOptions;
saveOptions.embedColorProfile = true;
if ( WHAT SHOULD I BE ASKING HERE? ) {
doc.saveAs(saveFile, saveOptions, false, Extension.LOWERCASE);
} else {
doc.close(SaveOptions.DONOTSAVECHANGES);
}
I'm stuck with what add to the if function? I've tried .exists but it's not working because the current file is still in .tif mode and hasn't saved to .psd yet. So it just keeps on saving and overwriting the previous saved .psd
Any help would be most welcome. :)
EDIT:
Thought i had it working with this but still no luck:
//Strip .tif and add .psd to file name
var docName = doc.name;
PSDName = docName.substr(0,docName.length-3);
PSDName = PSDName + "psd";
//Save document
var savePath = Folder(doc.path.parent) + "/new_folder/";
saveFile = new File(savePath);
saveOptions = new PhotoshopSaveOptions;
saveOptions.embedColorProfile = true;
var savedFile = savePath + "/" + PSDName
if (! savedFile.exists ) {
doc.saveAs(saveFile, saveOptions, false, Extension.LOWERCASE);
} else {
doc.close(SaveOptions.DONOTSAVECHANGES);
}
the if statement is returning false every time and the doc is not saving. If i take away the ! it saves every time.
Make a new variable with the filename that you want to test - i.e. the name of the .PSD file and use that. For example, strip off the TIF and replace it with PSD then use .exists.
var ImageName = activeDocument.name;
PSDName = ImageName.substr(0,ImageName.length-3); // Strip "TIF" from end
PSDName = PSDName + "psd"; // Add on "PSD" instead
If you need to debug your script, you can do something like this:
// Change Debug=1 for extra debugging messages, Debug=0 for no messages
var Debug=1;
...
if(Debug)alert(PSDName);
...
if(Debug)alert("File exists");
Right now I'm using the following command to run phantomJS
exec('./phantomjs table.js',$op,$er);
table.js
var page = require('webpage').create();
page.open('table.php', function () {
page.render('table.png');
phantom.exit();
});
This serves the purpose. But now I'm required to work with a dynamic variable, namely date. So is it possible to pass a PHP or Javascript variable inside the exec command line so that I can use that variable inside table.js?
Update
I tried modifying my code according to a solution posted here Passing a variable to PhantomJS via exec
exec('./phantomjs table.js http://www.yahoo.com',$op,$er);
table.js
var args = require('system').args;
var page = require('webpage').create();
var address = system.args[1];
page.open(address, function () {
page.render('table.png');
phantom.exit();
});
But this results in 2 problems:
The whole process takes about 3-4 minutes to finish
After that I get "Server Not Found" message
If I remove the modified code, everything works as expected.
More Debugging
Inside table.js I used this:
var args = require('system').args;
args.forEach(function(arg, i) {
console.log(i+'::'+arg);
});
var page = require('webpage').create();
var address = 'http://www.gmail.com';
page.open(address, function () {
page.render('github.png');
phantom.exit();
});
On running this, my $op (from exec command) printout out this:
Array ( [0] => 0::table.js [1] => 1::http://www.yahoo.com )
So far so good. But as soon as I put the below code, the same problems are encountered
var args = require('system').args;
var page = require('webpage').create();
var address = system.args[1]; // <--- This line is creating problem, the culprit
page.open(address, function () {
page.render('github.png');
phantom.exit();
});
Seems like that is not the correct syntax. Anything obvious that I'm unable to see?
The problem with your code is a simple oversight.
You have already stored the args using
var args = require('system').args;
So when you need to reference them you only have to do:
var address = args[1];
The use of "system" is looking in a completely different array
I had to do this and this answers pointed me to find my final answer however as some people expressed here my browser was crashing... I found the problem and solution and thought was worth sharing...
This will work perfectly fine if:
exec('phantomjs phdemo.js http://google.com', $o, $e); ?>
var page = require('webpage').create();
var system = require('system');
var address = system.args[1];
page.open(address, function () {
page.render('output.pdf');
phantom.exit();
});
However if you want to pass more than une parameter in the url address for example google.com?searchteext&date=today I found that the character '&' crashes the browser as it expects it as a different command
My solution was to use the same but instead of putting & I used # sign so the url will look something like google.com?searchteext#date=today
then at the other end I added a string replace
var address = address.replace(/#/gi,"&");
Then everything works perfectly fine.... There may be other ways of doing it but this worked perfectly for me
Well, I found an alternative to the above problem. Instead of using
var address = system.args[1];
I'm doing it by following the below modification
var args = require('system').args;
var address = '';
args.forEach(function(arg, i) {
if(i == 1)
{
address = arg;
}
});
var page = require('webpage').create();
page.open(address, function () { // <-- use that address variable from above
page.render('github.png');
phantom.exit();
});
How to get the path of a shell folder like "Local Settings" or "Local Appdata" for a specific user other than the current user?
While there are methods for getting special folder paths in Windows Script Host — WshShell.SpecialFolders and Shell.NameSpace — they return paths for the current user only. Getting other users' special folder paths is a bit tricky.
The proper way to do this is to use the Windows API SHGetKnownFolderPath function (or SHGetFolderPath on Windows versions prior to Vista). But the problem is, Windows Script Host doesn't support calling WinAPI functions, so to make use of these functions in your script you'll have to expose them via a custom-written COM component.
Another possible but undocumented solution is to read the special folder paths from that user's registry hive, specifically, the HKEY_USERS\<user_SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders key.
The paths in the User Shell Folders key are typically specified using the %USERPROFILE% environment variable; so to get fully-qualified paths you'll have to substitute this variable with the ProfileImagePath value from the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<user_SID> key.
Also, the HKEY_USERS\<user_SID> key is only available when the corresponding user is currently logged on. For a general solution, you would have to load the user's hive (<UserProfile>\ntuser.dat) into a temporary registry key (say, HKEY_USERS\Temp) and read values from this key instead.
Below is sample JScript code that demonstrates how your task can be accomplished. On Windows 7 and Vista, you may need to run the script as Administrator depending on your UAC settings.
NOTE: This method is discouraged, as Raymond Chen explains in his article The long and sad story of the Shell Folders key. There's no guarantee it will keep working in future versions of Windows.
var strUser = "foo";
var strDomain = "bar";
// If the account is local, domain name = computer name:
// var strDomain = getComputerName();
var strSID = getSID(strUser, strDomain);
var strProfilePath = getProfilePath(strSID);
// Load the user's registry hive into the HKEY_USERS\Temp key
var strTempKey = "Temp";
loadHKUHive(strTempKey, strProfilePath + "\\ntuser.dat");
// Get unexpanded path, e.g. %USERPROFILE%\AppData\Roaming
//var strAppData = getAppData(strSID);
var strAppData = getAppData(strTempKey);
WScript.Echo(strAppData);
// Expand the previous value to a fully-qualified path, e.g. C:\Users\foo\AppData\Roaming
strAppData = strAppData.replace(/%USERPROFILE%/i, strProfilePath);
WScript.Echo(strAppData);
// Unload the user's registry hive
unloadHKUHive(strTempKey);
function getComputerName() {
var oShell = new ActiveXObject("WScript.Shell");
return oShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
}
function getSID(strUser, strDomain) {
var oAccount = GetObject("winmgmts:root/cimv2:Win32_UserAccount.Name='" + strUser + "',Domain='" + strDomain + "'");
return oAccount.SID;
}
function getProfilePath(strSID) {
var oShell = new ActiveXObject("WScript.Shell");
var strValue = oShell.RegRead("HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + strSID + "\\ProfileImagePath");
return strValue;
}
function getAppData(strSID) {
var oShell = new ActiveXObject("WScript.Shell");
var strValue = oShell.RegRead("HKEY_USERS\\" + strSID + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData");
return strValue;
}
function loadHKUHive(strKeyName, strHiveFile) {
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run("reg load HKU\\" + strKeyName + " " + strHiveFile, 0, true);
}
function unloadHKUHive(strKeyName) {
var oShell = new ActiveXObject("WScript.Shell");
oShell.Run("reg unload HKU\\" + strKeyName, 0, true);
}
I'm trying to do something like a C #include "filename.c", or PHP include(dirname(__FILE__)."filename.php") but in javascript. I know I can do this if I can get the URL a js file was loaded from (e.g. the URL given in the src attribute of the tag). Is there any way for the javascript to know that?
Alternatively, is there any good way to load javascript dynamically from the same domain (without knowing the domain specifically)? For example, lets say we have two identical servers (QA and production) but they clearly have different URL domains. Is there a way to do something like include("myLib.js"); where myLib.js will load from the domain of the file loading it?
Sorry if thats worded a little confusingly.
Within the script:
var scripts = document.getElementsByTagName("script"),
src = scripts[scripts.length-1].src;
This works because the browser loads and executes scripts in order, so while your script is executing, the document it was included in is sure to have your script element as the last one on the page. This code of course must be 'global' to the script, so save src somewhere where you can use it later. Avoid leaking global variables by wrapping it in:
(function() { ... })();
All browsers except Internet Explorer (any version) have document.currentScript, which always works always (no matter how the file was included (async, bookmarklet etc)).
If you want to know the full URL of the JS file you're in right now:
var script = document.currentScript;
var fullUrl = script.src;
Tadaa.
I just made this little trick :
window.getRunningScript = () => {
return () => {
return new Error().stack.match(/([^ \n])*([a-z]*:\/\/\/?)*?[a-z0-9\/\\]*\.js/ig)[0]
}
}
console.log('%c Currently running script:', 'color: blue', getRunningScript()())
✅ Works on: Chrome, Firefox, Edge, Opera
Enjoy !
The accepted answer here does not work if you have inline scripts in your document. To avoid this you can use the following to only target <script> tags with a [src] attribute.
/**
* Current Script Path
*
* Get the dir path to the currently executing script file
* which is always the last one in the scripts array with
* an [src] attr
*/
var currentScriptPath = function () {
var scripts = document.querySelectorAll( 'script[src]' );
var currentScript = scripts[ scripts.length - 1 ].src;
var currentScriptChunks = currentScript.split( '/' );
var currentScriptFile = currentScriptChunks[ currentScriptChunks.length - 1 ];
return currentScript.replace( currentScriptFile, '' );
}
This effectively captures the last external .js file, solving some issues I encountered with inline JS templates.
Refining upon the answers found here I came up with the following:
getCurrentScript.js
var getCurrentScript = function() {
if (document.currentScript) {
return document.currentScript.src;
} else {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1].src;
}
}
// module.exports = getCurrentScript;
console.log({log: getCurrentScript()})
getCurrentScriptPath.js
var getCurrentScript = require('./getCurrentScript');
var getCurrentScriptPath = function () {
var script = getCurrentScript();
var path = script.substring(0, script.lastIndexOf('/'));
return path;
};
module.exports = getCurrentScriptPath;
BTW: I'm using CommonJS
module format and bundling with webpack.
I've more recently found a much cleaner approach to this, which can be executed at any time, rather than being forced to do it synchronously when the script loads.
Use stackinfo to get a stacktrace at a current location, and grab the info.file name off the top of the stack.
info = stackinfo()
console.log('This is the url of the script '+info[0].file)
I've coded a simple function which allows to get the absolute location of the current javascript file, by using a try/catch method.
// Get script file location
// doesn't work for older browsers
var getScriptLocation = function() {
var fileName = "fileName";
var stack = "stack";
var stackTrace = "stacktrace";
var loc = null;
var matcher = function(stack, matchedLoc) { return loc = matchedLoc; };
try {
// Invalid code
0();
} catch (ex) {
if(fileName in ex) { // Firefox
loc = ex[fileName];
} else if(stackTrace in ex) { // Opera
ex[stackTrace].replace(/called from line \d+, column \d+ in (.*):/gm, matcher);
} else if(stack in ex) { // WebKit, Blink and IE10
ex[stack].replace(/at.*?\(?(\S+):\d+:\d+\)?$/g, matcher);
}
return loc;
}
};
You can see it here.
Refining upon the answers found here:
little trick
getCurrentScript and getCurrentScriptPath
I came up with the following:
//Thanks to https://stackoverflow.com/a/27369985/5175935
var getCurrentScript = function() {
if (document.currentScript && (document.currentScript.src !== ''))
return document.currentScript.src;
var scripts = document.getElementsByTagName('script'),
str = scripts[scripts.length - 1].src;
if (str !== '')
return str ;
//Thanks to https://stackoverflow.com/a/42594856/5175935
return new Error().stack.match(/(https?:[^:]*)/)[0];
};
//Thanks to https://stackoverflow.com/a/27369985/5175935
var getCurrentScriptPath = function() {
var script = getCurrentScript(),
path = script.substring(0, script.lastIndexOf('/'));
return path;
};
console.log({path: getCurrentScriptPath()})
Regardless of whether its a script, a html file (for a frame, for example), css file, image, whatever, if you dont specify a server/domain the path of the html doc will be the default, so you could do, for example,
<script type=text/javascript src='/dir/jsfile.js'></script>
or
<script type=text/javascript src='../../scripts/jsfile.js'></script>
If you don't provide the server/domain, the path will be relative to either the path of the page or script of the main document's path
I may be misunderstanding your question but it seems you should just be able to use a relative path as long as the production and development servers use the same path structure.
<script language="javascript" src="js/myLib.js" />
I've thrown together some spaghetti code that will get the current .js file ran (ex. if you run a script with "node ." you can use this to get the directory of the script that's running)
this gets it as "file://path/to/directoryWhere/fileExists"
var thisFilesDirectoryPath = stackinfo()[0].traceline.substring("readFile (".length, stackinfo()[0].traceline.length - ")".length-"readFile (".length);
this requires an npm package (im sure its on other platforms as well):
npm i stackinfo
import stackinfo from 'stackinfo'; or var {stackinfo} = require("stackinfo");
function getCurrnetScriptName() {
const url = new URL(document.currentScript.src);
const {length:len, [len-1]:last} = url.pathname.split('/');
return last.slice(0,-3);
}