Can I use Basil.js to get images from a URL? - adobe-indesign

I am a novice user at ExtendScript, Basil.js & Javascript.
After seeing the project http://basiljs.ch/gallery/ending-the-depression-through-amazon/ I wondered if it is possible to simply get the Basil.js Script/ Extendscript/Indesign to grab images from a webpage and insert it directly into a indesign document.
I am a beginner so if someone had a complete script, from directory, functions... with example url, import, save, place.... ?
This is in the hope that I could simply put an address into the script and it would harvest all images on the webpage and put them into a indesign document?
I tried their example http://basiljs.ch/tutorials/getting-images-from-urls/
but when I copy that and run it in extend script it is just searching my computer...
UPDATE*
#includepath "~/Documents/;%USERPROFILE%Documents";
#include "basil/basil.js";
function draw() {
var url = "https://raw.github.com/basiljs/basil.js/master/lib/basil.png";
// download the url to a default location, filename according to url:
// -> "the project folder" + data/download/basil.png
//b.download(url);
// download url to a specific location in the project folder:
// -> "the project folder" + data/download_images_files/basil_logo.png
// b.download(url, "download_images_files/basil_logo.png");
// download url to a specific location e.g. to your desktop
// -> ~/Desktop/basil_logo.png
var newFile = new File("~/Desktop/basil_logo.png");
b.download(url, newFile);
}
b.go();
... It finds in Error in Basil's Core.js #
var runDrawOnce = function() {
app.doScript(function() {
if (typeof glob.draw === 'function') {
glob.draw();
}
}, ScriptLanguage.javascript, undef, UndoModes.ENTIRE_SCRIPT);
};
Console says...
Using basil.js 1.08 ...
sh ~/Documents/basiljs/bundle/lib/download.sh /Users/jamestk/Desktop (Address here, I don't have the sufficient reputation on stack overflow)
Basil.js Error -> b.shellExecute(): Error: sh: /Users/jamestk/Documents/basiljs/bundle/lib/download.sh: No such file or directory

The easiest way would probably be to us the b.shellExecute(cmd) command to run a shell script that downloads your images.
You could use wget from shell to download all images from an url, see this question: How do I use Wget to download all Images into a single Folder
You should make sure then to save the images in the documents data directory. After that, you could get all images by using the Folder object's getFiles() method:
var myImagesArray = Folder('~/path/to/my/folder').getFiles();
Finally you could use that array in a loop to place all the images into your document.

Related

Delete metadata descriptions with a Photoshop Script?

Is there an equivalent of deleteProperty(XMPConst.NS_DC, "description”) or some way to clear out EXIF:ImageDescription, XMP-dc:Description and IPTC:Caption-Abstract with a Photoshop Script (ie, JavaScript or AppleScript)?
I am trying to remove the tags/descriptions below from TIF, PSD and PSB images:
[EXIF:IFD0] ImageDescription
[XMP:XMP-dc] Description
[IPTC] Caption-Abstract
I can do this with Exiftool with this code:
exiftool -m -overwrite_original_in_place -EXIF:ImageDescription= -XMP-dc:Description= -IPTC:Caption-Abstract= FILE
While that works great for me, I have lots of vendors that would need this in their workflows so it would be easier for them to use an action with the Photoshop Events Manager "On Document Open", or via an Automator script (Java or AppleScript) in their workflows than installing ExifTool. Looking for some help to do this...
I don’t have much coding experience, but I found the JavaScript code below on PS-Scripts as a starting point. This code doesn't require Photoshop which I like and could be done with Automator, but it only references the one tag. Also, I don’t need to write anything to the tags as this code does (I’d prefer just to delete or wipe the content and/or tags so they don’t show up).
Code: Select allvar f = File("/c/captures/a.jpg");
setDescription(f,"My new description");
function setDescription( file, descStr ){
if ( !ExternalObject.AdobeXMPScript ) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
var xmpf = new XMPFile( File(file).fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE );
var xmp = xmpf.getXMP();
xmp.deleteProperty(XMPConst.NS_DC, "description");
xmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", descStr );
if (xmpf.canPutXMP( xmp )) {
xmpf.putXMP( xmp );
}
xmpf.closeFile( XMPConst.CLOSE_UPDATE_SAFELY );
}
And below is an attempt at the JavaScript that would be used as a Photoshop Event on "Open Document"; but again I don't know how to amend to ensure all 3 tags reference above are cleared:
function removeDescription() {
whatApp = String(app.name);
if(whatApp.search("Photoshop") > 0)
if(!documents.length) {
alert("There are no open documents. Please open a file to run this script.")
return;
}
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta( activeDocument.xmpMetadata.rawData);
xmp.deleteProperty(XMPConst.NS_DC, "description");
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
}
}
removeDescription();
Finally, below was an alternate that was tried that wipes the Description, ImageDescription and Caption-Abstract on TIFFs and PNGs on the first try, but takes running through twice to work on a PSD/PSB/JPG. I think it has to do with the interaction between Description, ImageDescription and Caption-Abstract, and the solution possibly resides with amp.setLocalizedText to nothing?
function removeMetadata() {
whatApp = String(app.name);
if(whatApp.search("Photoshop") > 0) {
if(!documents.length) {
alert("There are no open documents. Please open a file to run this script.")
return;
}
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var xmp = new XMPMeta( activeDocument.xmpMetadata.rawData);
if (xmp.doesArrayItemExist(XMPConst.NS_DC, "description", 1))
{
xmp.deleteArrayItem(XMPConst.NS_DC, "description", 1);
}
app.activeDocument.xmpMetadata.rawData = xmp.serialize();
debugger
}
}
removeMetadata();
Here is an example Python script that uses the Pillow library to remove the metadata descriptions.
from PIL import Image
# Open the image file
image = Image.open('example.jpg')
# Remove the EXIF:ImageDescription metadata field
image.info.pop('EXIF:ImageDescription', None)
# Remove the XMP-dc:Description metadata field
image.info.pop('XMP-dc:Description', None)
# Remove the IPTC:Caption-Abstract metadata field
image.info.pop('IPTC:Caption-Abstract', None)
# Save the modified image file
image.save('example_modified.jpg')
Change "example.jpg" to your needs.
there may be other metadata fields that contain descriptions, depending on the specific image file format and how it was created. You may need to modify the script to remove additional fields if necessary.

Google Advanced Drive API fails on insert of some PDFs but not others

function extractTextFromPDF() {
// PDF File URL
// You can also pull PDFs from Google Drive
// this Fall2019_LLFullCatalog.pdf will not insert - internal error on insert is all the feedback that gets logged"
// doesn't matter if I retrieve it from the university website or if I first copy it to my google drive and then retrieve it from there
//var url = "https://uwf.edu/media/university-of-west-florida/offices/continuing-ed/leisure-learning/docs/Fall2019_LLFullCatalog.pdf";
//var url = "https://drive.google.com/drive/u/0/my-drive/Fall2019_LLFullCatalog.pdf";
// both of these pdfs will insert just fine. Size is not the issue because this one is much larger than the one I need to insert
var url = "https://eloquentjavascript.net/Eloquent_JavaScript_small.pdf";
//var url = "https://img.labnol.org/files/Most-Useful-Websites.pdf";
var blob = UrlFetchApp.fetch(url).getBlob();
var size = blob.getBytes().length;
var resource = {
title: blob.getName(),
mimeType: blob.getContentType()
};
// Enable the Advanced Drive API Service
var file = Drive.Files.insert(resource, blob, {ocr: true, ocrLanguage: "en"});
// Extract Text from PDF file
var doc = DocumentApp.openById(file.id);
var text = doc.getBody().getText();
return text;
}
See comments in code above that describe the problem.
The PDF that I need to insert with OCR is not working - regardless of whether I retrieve it from the original site or retrieve a copy that I put on google drive. However, two other PDF urls will insert just fine and one of them is considerably larger than the one that fails.
What else could be the issue, if not size limitation?
Thanks,
Steve
It could very well be a bug in the Chrome API. Not all PDF software is created equal, check if the PDF can be read in Adobe Acrobat as a simple test.

File access permission in Swift on OSX

I'm using:
let dialog = NSOpenPanel()
to get a file URL.
I'm then reading in the contents of the text file with:
let content = try String( contentsOf: dialog.url)
This works!
I'm then trying to read in another text file in the same directory with a different extension:
let b = dialog.url?.deletingPathExtension()
// Add the new file extension
let c = b?.appendingPathExtension("TSN")
let content2 = try String( contentsOf: c)
With this I get:
"The file “FLO5.TSN” couldn’t be opened because you don’t have permission to view it."
If I try and open the .tsn file with a URL from a NSOpenPanel() dialog result it works. I need to open several data files from this same directory with different extensions. Is there a way to do this?
set off sandbox!!)
Xcode 9 and later enables sandboxing by default, which severely limits interactions with the system.
Select your target, then Capabilities and set Downloads Folder to Read/Write:
In my case, solve it's startAccessingSecurityScopedResource
Example:
let selectedFile = try result.get() // get path to file
do {
// get access to open file
if selectedFile.startAccessingSecurityScopedResource() {
let path = selectedFile.path
let data = NSData(contentsOfFile: path)
print(data) // array bytes
selectedFile.stopAccessingSecurityScopedResource()
}
} catch {
// Couldn't read the file.
print(error.localizedDescription)
}
Apple wiki about this feature https://developer.apple.com/documentation/foundation/nsurl/1417051-startaccessingsecurityscopedreso

Google Script - Import images and list file names

Maybe this is one of the impossible ones, but here goes.
I have a ton of images of qr-codes in a folder. It doesnt matter if its in google drive or in a local folder for me.
I would a script that automaticly loads all images in column A and then the file names in column B. AND automaticly adds new images when uploaded to the google drive folder.
Example:
Qr1.jpeg will be loaded into cell a1 and cell b1 will be "Qr1"
Qr2.jpeg will be loaded into cell a2 and so on..
It would be nice if the images are scaled to 10x10 cm. :)
Is this even possible?
Hope you guys can help!
Thanks!
Oliver
Not the Complete Answer...but it's a part
I've been working on getting thumbnails into my spreadsheet ever since you asked this question. I won't go into all the paths I took but I finally found this Github link in the comments of this issue
Which resulted in the following code:
function myImageFiles()
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('MyImages');
var files = DriveApp.getFiles();
var s='';
var cnt=1;
while(files.hasNext())
{
var fi=files.next();
var type=fi.getMimeType();
if(type==MimeType.GIF || type==MimeType.JPEG || type==MimeType.PNG)
{
sh.appendRow([cnt++,fi.getName(),type,fi.getUrl(),'=IMAGE("' + getThumbNailLink(fi.getId()) + '",1)']);
}
}
}
function getThumbNailLink(fileId)
{
var file=Drive.Files.get(fileId);
return file.thumbnailLink;
}
The result is now I have a spreadsheet with all of my image filenames and thumbnails. You'll need Advanced Drive and take a close look at getThumbNailLink().

Website File and Folder Browser: Should I use Static or Ajax?

Subjective question time!
I'm coding a website that hosts a large amount of files and folders for an open organization that must post all documents online for public scrutiny. I have not yet began coding the actual viewer, as I'm wondering what the standard, most accessible approach is.
The site must be easy to access and available to all devices from desktops to phones. That said, I don't have to code in mind of older, outdated browsers. The previous site used a static approach on Python and Django. This is my first real node.js + Express job, and I'm not sure of performance differences.
At present, I see two ways to accomplish my task:
1. Use Ajax
I know I can shove everyone onto a generic /documents page, and allow them to navigate through the folders themselves. However, I want document links to work if shared, so I'll have to be changing the URL manually as users move around, and submitting plenty of Ajax requests back to the server
I like this approach in that it will likely give a nicer user interaction. I don't like the amount of Ajax requests, and I fear that on less powerful devices like phones and tablets, all that Ajax and DOM manipulation will slow down or not work. Additionally, I'd have to parse the url to a resource with either the back end or front end for retrieval.
2. Go 'Static'
I'm using node.js and Jade on the back end, so I know I can just break apart a url, find the folder hierarchy, and give a whole new page to the user.
I like this approach because it doesn't require the user's machine to do any computation (and will likely be faster on slower devices), and it means not doing a ton of url work. I don't like that desktop users will end up waiting for a bunch of synchronous operations that I'll have to use to prepare the pages with, nor the server load or responsiveness.
Currently
I'm looking into the static approach right now for what I perceive to be a bit more accessibility (even at the cost of page load times), but I'm here for more information to guide the right choice. I'm looking for answers that explain the why of which way to go will be better, and are impartial or share experiences. Thank you in advance for your help!
Right. So no one else responded yet, so I just went ahead and made the file browser anyway.
I ended up doing a static method. It turned out to be relatively easy, besides having to manipulate a bunch of strings, and I can only imagine that twice the work would have been necessary for Ajax.
The response times are fairly long: a generic static page that does no computation on my site takes about 40-70ms, while the new documents one takes twice that at ~150ms. Although in practice 150ms isn't anything to get upset over for my needs, in a large scale environment I'm sure my glob functions in the documents folder would just bog down the system.
For anyone wondering, here's what I did
Code
The hierarchy looks like this
|app
|controllers
|-document.js
|views
|-document.jade
|public
|docs
|
|//folders
|
documents.js
var express = require('express');
var router = express.Router();
var glob = require('glob');
module.exports = function(app) {
app.use('/', router);
};
router.get('/documents*', function serveDocsHome(req, res) {
//this removes %20 from the requested url to match files with spaces
req.originalUrl = req.originalUrl.replace('%20', ' ');
//fun string stuff to make links work
var dir = '/docs' + req.originalUrl.substr(10);
var url = req.originalUrl + '/';
//for moving up a directory
var goUp = false;
var folderName = 'Home';
if (req.originalUrl != '/documents') {
var end = req.originalUrl.lastIndexOf('/');
folderName = req.originalUrl.substr(end + 1);
goUp = true;
}
//get all the folders
var folders = glob.sync('*/', {
cwd : 'public' + dir
});
for (var i = 0; i < folders.length; i++) {
folders[i] = folders[i].substr(0, folders[i].length - 1);
}
//get all the files
var files = glob.sync('*', {
cwd : 'public' + dir,
nodir : true
});
//attach the files and folders
res.locals.folders = folders;
res.locals.files = files;
res.locals.loc = dir + '/';
res.locals.goUp = goUp;
res.locals.url = url;
res.locals.folderName = folderName;
//render the doc
res.render('documents', {
title : 'Documents',
});
});
documents.jade
extends layout
append css
link(rel='stylesheet', href='/css/docs.css')
append js
script(src='/js/docs.js')
block content
.jumbotron(style='background: url(/img/docs.jpg); background-position: center 20%; background-repeat: no-repeat; background-size: cover;')
.container
h1= title
p View minutes, policies, and guiding papers of the [name]
.container#docs
.row
.col-xs-12.col-sm-3.sidebar.sidebar-wrap
h3= folderName
ul.no-style.jumplist
hr
if goUp
li#go-up: a.message(href='./') #[img(src='/img/icons/folderOpen.png')] Up One Folder
each val in folders
li: a(href='#{url + val}'): #[img(src='/img/icons/folder.png')] #{val}
.col-xs-12.col-sm-9
h3 Files
ul.no-style
if files.length != 0
each val in files
li: a(href='#{loc + val}')= val
else
li.message No Files Here
And heres part of the page

Resources