Extension Autodesk Forge: My control panel doesn't connect to the Revit model after adding my own extension to the package - autodesk-forge

I used this package (https://github.com/petrbroz/forge-iot-extensions-demo). After that, I added my own extension code (RobotExt.js). The Control panel and Icon of the my extension were added to the Autodesk Forge website. But unfortunately, the control panel doesn't work.
There are these errors:
This is the source code of the my extension file:
class RobotExtension extends Autodesk.Viewing.Extension {
constructor(viewer, options) {
super(viewer, options);
this.viewer = viewer;
//this.tree = null;
this.tree = this.viewer.model.getData().instanceTree;
this.defaultState = null;
this.customize = this.customize.bind(this);
this.createUI = this.createUI.bind(this);
this.setTransformation = this.setTransformation.bind(this);
this.getFragmentWorldMatrixByNodeId = this.getFragmentWorldMatrixByNodeId.bind(this);
this.assignTransformations = this.assignTransformations.bind(this);
this.findNodeIdbyName = this.findNodeIdbyName.bind(this);
}
load() {
console.log('RobotExtension is loaded!');
this.createUI();
this.setTransformation();
return true;
}
unload() {
console.log('RobotExtension is now unloaded!');
this.viewer.restoreState(this.defaultState);
return true;
}
setTransformation() {
let tree = this.tree;
/* ====================== right 0 ================= */
let ID_BaseRod = 4806;
let ID_LowerArmBody = 4806;
let Pivot_BaseRod = new THREE.Mesh(new THREE.BoxGeometry(20, 20, 20), new THREE.MeshBasicMaterial({ color: 0xff0000 }));
let Position_BaseRod = this.getFragmentWorldMatrixByNodeId(ID_BaseRod).matrix[0].getPosition().clone();
//print the returned value from getFragmentWorldMatrixByNodeId method and using this we can inspect the....
// output of the fucntion(method) whether working or not
console.log(Position_BaseRod);
//console.log(position);
Pivot_BaseRod.position.x = 0;
Pivot_BaseRod.position.y = Position_BaseRod.y;
Pivot_BaseRod.position.z = Position_BaseRod.z-2.84;
viewer.impl.scene.add(Pivot_BaseRod);
let Helper_LowerArmBody = new THREE.Mesh();
let Position_LowerArmBody = this.getFragmentWorldMatrixByNodeId(ID_LowerArmBody).matrix[0].getPosition().clone();
Helper_LowerArmBody.position.x = - Position_LowerArmBody.x + Math.abs(Position_LowerArmBody.x - Pivot_BaseRod.position.x);
Helper_LowerArmBody.position.y = - Position_LowerArmBody.y + Math.abs(Position_LowerArmBody.y - Pivot_BaseRod.position.y);
Helper_LowerArmBody.position.z = - Position_LowerArmBody.z + Math.abs(Position_LowerArmBody.z - Pivot_BaseRod.position.z);
Pivot_BaseRod.add(Helper_LowerArmBody);
console.log(Position_LowerArmBody);
// // /* ====================== left 0 ================= */
let ID_BaseRod10 = 4851;
let ID_LowerArmBody10 = 4851;
let Pivot_BaseRod10 = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial({ color: 0xff0000 }));
let Position_BaseRod10 = this.getFragmentWorldMatrixByNodeId(ID_BaseRod10).matrix[0].getPosition().clone();
//print the returned value from getFragmentWorldMatrixByNodeId method and using this we can inspect the....
// output of the fucntion(method) whether working or not
console.log(Position_BaseRod10);
Pivot_BaseRod10.position.x = 0;
Pivot_BaseRod10.position.y = Position_BaseRod10.y;
Pivot_BaseRod10.position.z = Position_BaseRod10.z-2.84;
viewer.impl.scene.add(Pivot_BaseRod10);
console.log(Pivot_BaseRod10);
let Helper_LowerArmBody10 = new THREE.Mesh();
let Position_LowerArmBody10 = this.getFragmentWorldMatrixByNodeId(ID_LowerArmBody10).matrix[0].getPosition().clone();
Helper_LowerArmBody10.position.x = Position_LowerArmBody10.x + Math.abs(Position_LowerArmBody10.x - Pivot_BaseRod10.position.x);
Helper_LowerArmBody10.position.y = -Position_LowerArmBody10.y + Math.abs(Position_LowerArmBody10.y - Pivot_BaseRod10.position.y);
Helper_LowerArmBody10.position.z = -Position_LowerArmBody10.z + Math.abs(Position_LowerArmBody10.z - Pivot_BaseRod10.position.z);
Pivot_BaseRod10.add(Helper_LowerArmBody10);
console.log(Position_LowerArmBody10);
let ID_BaseRod15 = 4886;
let ID_LowerArmBody15 = 4886;
let Pivot_BaseRod15= new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial({ color: 0xff0000 }));
let Position_BaseRod15 = this.getFragmentWorldMatrixByNodeId(ID_BaseRod15).matrix[0].getPosition().clone();
//print the returned value from getFragmentWorldMatrixByNodeId method and using this we can inspect the....
// output of the fucntion(method) whether working or not
console.log(Position_BaseRod15);
Pivot_BaseRod15.position.x = 0;
Pivot_BaseRod15.position.y = Position_BaseRod15.y;
Pivot_BaseRod15.position.z = Position_BaseRod15.z-2.84;
viewer.impl.scene.add(Pivot_BaseRod15);
console.log(Pivot_BaseRod15);
let Helper_LowerArmBody15 = new THREE.Mesh();
let Position_LowerArmBody15 = this.getFragmentWorldMatrixByNodeId(ID_LowerArmBody15).matrix[0].getPosition().clone();
Helper_LowerArmBody15.position.x = Position_LowerArmBody15.x + Math.abs(Position_LowerArmBody15.x - Pivot_BaseRod15.position.x);
Helper_LowerArmBody15.position.y = -Position_LowerArmBody15.y + Math.abs(Position_LowerArmBody15.y - Pivot_BaseRod15.position.y);
Helper_LowerArmBody15.position.z = -Position_LowerArmBody15.z + Math.abs(Position_LowerArmBody15.z - Pivot_BaseRod15.position.z);
Pivot_BaseRod15.add(Helper_LowerArmBody15);
console.log(Position_LowerArmBody15);
There was an error for limitation character in Stackoverflow I had to delete some parts of my code.
[![enter image description here][2]][2]

In the setTransformation method of your extension class, you have the following line of code:
viewer.impl.scene.add(Pivot_BaseRod1);
The viewer variable is not defined, however. The line of code should instead look like this:
this.viewer.impl.scene.add(Pivot_BaseRod1);

Related

Having some problems making relative reference work with an ArrayFormula

I'm trying to use the ArrayFormula of Google Sheets to set an auto-fill system where the contents of one column update as I add more data to another column, but, with the formula I'm using, the first set of cells will just use the first value in the second set, making every cell have the same content(which is the opposite of what I want). Here's an idea of what I'm trying to do.
I ended up using Google Apps Script to solve my issue, since regular formulas proved to be inefficient for what I was trying to do. Below is the code I ended up using, which populates some more fields aside from the name and icon, which still has some issues, but they're beyond the scope of this question.
function setHeroData(ss_id, column, row, valueInputOption) {
try {
var sheet = SpreadsheetApp.getActiveSheet();
let range = sheet.getName() + "!" + column + row;
sheet.setColumnWidth(1, 50);
let domain = "https://gamepress.gg";
let response = UrlFetchApp.fetch(`${domain}/feheroes/heroes`);
let page = Cheerio.load(response.getContentText());
const heroes = new Array(page(".icon\-cell").length+1);
const profiles = new Array(page(".icon\-cell").length);
const vas = new Array(page(".icon\-cell").length);
const illus = new Array(page(".icon\-cell").length);
let profile;
let va;
let ill;
heroes[0] = [];
heroes[0].push("Icon");
heroes[0].push("Hero");
heroes[0].push("Hero Epithet");
heroes[0].push("");
heroes[0].push("Weapon");
heroes[0].push("")
heroes[0].push("Movement");
heroes[0].push("Rarity");
heroes[0].push("Origin");
heroes[0].push("VA (EN)");
heroes[0].push("VA (JP)");
heroes[0].push("Illustrator");
page(".icon\-cell").each(function (i, elem) {
let img = domain + page(elem).find(".hero\-icon").children("img").attr("src");
heroes[i+1] = [];
heroes[i+1].push(`=image("${img}", 3)`);
heroes[i+1].push(page(elem).find(".adventurer\-title").text());
profile = domain + page(this).children("a").attr("href");
profiles[i] = profile;
va = page(elem).parent().attr("data-va");
vas[i] = va;
ill = page(elem).parent().attr("data-ill");
illus[i] = ill;
});
let prof_pages = UrlFetchApp.fetchAll(profiles);
// Get epithets from profile pages
for (let i = 0; i<heroes.length-1; ++i) {
let prof_page = Cheerio.load(prof_pages[i].getContentText());
let attrib = prof_page(".vocabulary-attribute").find(".field--name-name").text();
let attrib_img = domain + prof_page(".vocabulary-attribute").find("img").attr("src");
let move_type = prof_page(".vocabulary-movement").find(".field--name-name").text();
let move_type_img = domain + prof_page(".vocabulary-movement").find("img").attr("src");
let stars = prof_page(".vocabulary-obtainable-stars").find(".field--name-name").text()[0];
let origin = prof_page(".field--name-field-origin").text().trim();
// Populate hero data
heroes[i+1].push(prof_page(".field--name-title").siblings("span").text().replace(" - ", ""));
heroes[i+1].push(`=image("${attrib_img}")`);
heroes[i+1].push(attrib);
heroes[i+1].push(`=image("${move_type_img}")`);
heroes[i+1].push(move_type);
heroes[i+1].push(`=image("https://gamepress.gg/sites/fireemblem/files/2017-06/stars${stars}.png", 3)`)
heroes[i+1].push(origin);
// https://stackoverflow.com/questions/36342430/get-substring-before-and-after-second-space-in-a-string-via-javascript
// Separate the EN and JP voice actors names
let index = vas[i].includes(".") ? vas[i].indexOf(' ', vas[i].indexOf('.') + 2) : vas[i].indexOf(' ', vas[i].indexOf(' ') + 1);
let en_va = index >= 0 ? vas[i].substr(0, index) : vas[i].substr(index + 1);
let jp_va = index >= 0 ? vas[i].substr(index + 1) : "";
if (en_va.toLowerCase() === "Cassandra Lee".toLowerCase()) {
en_va = en_va.concat(" Morris");
jp_va = jp_va.replace("Morris", "");
// Logger.log(en_va);
// Logger.log(jp_va);
}
heroes[i+1].push(en_va.trim());
heroes[i+1].push(jp_va.trim());
heroes[i+1].push(illus[i]);
Logger.log((i*100)/(heroes.length-1));
}
let first_col = column.charCodeAt(0) - 64;
Sheets.Spreadsheets.Values.update({values: heroes}, ss_id, range, valueInputOption);
sheet.autoResizeColumns(first_col, heroes[0].length).autoResizeRows(row, heroes.length);
sheet.setRowHeights(row+1, (heroes.length-1)+row, 50);
sheet.setColumnWidth(first_col, 50);
sheet.setColumnWidth(first_col + 3, 30);
sheet.setColumnWidth(first_col + 5, 30);
sheet.setColumnWidth(first_col + 7, 100);
sheet.setColumnWidth(first_col + 8, 319);
}
catch (err) {
Logger.log(err);
}
}
It uses a two-dimensional array to set up the info for each row, and, using the Sheets API, populates the appropiate cells.
IMPORTXML is already an array-type formula (able to return arrays) therefore it is not supported under ARRAYFORMULA eg:
=ARRAYFORMULA(IMPORTXML("https://gamepress.gg/feheroes/heroes",
"//td[#class='icon-cell'][a/div[2]='"&B2:B&"']/a/div[1]/img/#src"))
will not work.
try:
=ARRAYFORMULA(IMAGE("https://gamepress.gg"&
IMPORTXML("https://gamepress.gg/feheroes/heroes", "//a/div[1]/img/#src")))

How to use external data plot a multi lineseries chart

I am using amcharts4 plugin to plot a multi-lineseries graph.
But the plotted points do not locate at the right position (Blue dot at the edge of y-axe)
Here is the output chart that I get. (pls see the attached above)
Not sure what had done wrong with the following codes. Hope someone can help me out.
Thanks in advance!
var chart = am4core.create("chartdiv", am4charts.XYChart);
//Create axes
var categoryAxis = chart.xAxes.push(new
am4charts.CategoryAxis()); categoryAxis.dataFields.category = "date";
categoryAxis.title.text = "Month-Year";
categoryAxis.title.fontWeight = "bold";
/* Create value axis */
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.title.text = "Total Sales ($)";
valueAxis.title.fontWeight = "bold";
/* Add data */
var ds = new am4core.DataSource();
ds.url = window.location.origin+"/home/salesVolumnVersusPeriod"; //Sample of external JSON DATA = [{"date":"02-2020","FS":6288, 'IO':2342}]
ds.events.on("done", function(ev) {
chart.config = ev.data;
var u = ev.data; var data =
ev.target.data[0]; var datakey = Object.keys(data);
var text = '';
for (var i = 1; i < datakey.length; i++) {
addSeries(datakey[i], u);
text += datakey[i]+' : {'+datakey[i]+'}'+"\n";
}
$('#chartdiv').append('<div id="test">'+text+'</div>');
});
ds.load();
/* Create series */
function addSeries(b, data) {
// Create series
var series = new am4charts.LineSeries();
series.data = data;
series.dataFields.valueY = b;
series.dataFields.categoryX = "date";
series.name = b;
series.strokeWidth = 3;
series.tensionX = 0.7;
series.bullets.push(new am4charts.CircleBullet());
series = chart.series.push(series);
series.events.on("hidden", updateTooltipText);
series.events.on("shown", updateTooltipText);
}
function getToolstipItemValue(text) {
return `[bold]Date {categoryX}[/]
---- `+text;
}
/* Set up tooltip attachment to other series whenever series is hidden */
function updateTooltipText() {
var added = false;
tooltipText = $('#test').text();
chart.series.each(function(series)
{
if (series.visible && !added) {
series.tooltipText = getToolstipItemValue(tooltipText);
added = true;
}
else {
series.tooltipText = "";
}
});
}
/* Add legend */
chart.legend = new am4charts.Legend();
/* Create a cursor */
chart.cursor = new am4charts.XYCursor();
Finally knew what is wrong. It should use chart.data instead of chart.config.
Now the graph works. Hope this could help you too. Cheers!
chart.config = ev.data;

How do you render a line markup with the Markups Extension?

I previously asked question about if there was a programatic way to render markups with the markups extension. This worked, or at least, for text markups! Now I am trying to do the same thing with line markups; however, I am stuck with one issue. How do you add the locations to the markup? I have an array of locations that I am trying to assign to it, but there doesn't seem to be a function, and when I try to directly assign locations with markup.location = [etc], for some reason it changes all the numbers to infinity.
So, how can I assign the location array to the markup?
This is how I am loading them:
let MarkupsCore = Autodesk.Viewing.Extensions.Markups.Core;
let line = new MarkupsCore.MarkupFreehand(25, markupTool); //eslint-disable-line
line.locations = [{x: 2, y: 3}]; //something like this
markupTool.addMarkup(line);
line.setSize({ x: markup.x, y: markup.y}, markup.width, markup.height);
line.updateStyle(true);
The MarkupFreehand cannot be used directly, it should be replaced by EditModeFreehand. It's also not easy to archive your request, to create a line markup, in a few codes. Here is the code snippet I used to create a line markup with the MarkupCore extension:
function createLineStartPt( mousePosX, mousePosY, editor ) {
const editMode = markup.editMode;
editor.snapper && editor.snapper.clearSnapped();
editMode.lastX = editMode.initialX = mousePosX;
editMode.lastY = editMode.initialY = mousePosY;
//set the starting point
const position = editMode.position = editor.clientToMarkups( mousePosX, mousePosY );
editMode.movements = [position];
const size = editMode.size = editor.sizeFromClientToMarkups( 1, 1 );
// Create pen.
editor.beginActionGroup();
const markupId = editor.getId();
const createPen = editMode.createPen( markupId, position, size, 0, [{x: 0, y: 0 }] );
createPen.execute();
editMode.createAbsolutePath( position );
editMode.selectedMarkup = editor.getMarkup( markupId );
editMode.creationBegin();
}
function createLineEndPt( mousePosX, mousePosY, editor ) {
const editMode = markup.editMode;
const selectedMarkup = editMode.selectedMarkup;
if( !selectedMarkup || !editMode.creating )
return;
const movements = editMode.movements;
const location = editor.clientToMarkups( mousePosX, mousePosY );
const dx = editMode.lastX - mousePosX;
const dy = editMode.lastY - mousePosY;
const moveTol = 25; // 5^2, compare to square to avoid using square root of distance
if( movements.length > 1 && (dx*dx + dy*dy) < moveTol ) {
movements[movements.length - 1] = location;
editMode.removeFromAbsolutePath( 1 );
} else {
movements.push( location );
editMode.lastX = mousePosX;
editMode.lastY = mousePosY;
}
editMode.addToAbsolutePath([location]);
const appendPen = editMode.setPen( editMode.position, editMode.size, editMode.absolutePath, true );
appendPen.execute();
}
function endLineDrawing( editor ) {
const editMode = markup.editMode;
if( !editMode.creating )
return editMode.creationEnd();
let movements = editMode.movements;
const cameraWidth = editMode.viewer.impl.camera.right - editMode.viewer.impl.camera.left;
const cameraHeight = editMode.viewer.impl.camera.top - editMode.viewer.impl.camera.bottom;
const cameraDiagSq = cameraWidth * cameraWidth + cameraHeight * cameraHeight;
movements = Autodesk.Viewing.Extensions.Markups.Core.Utils.simplify( movements, cameraDiagSq * 0.00000001, true );
const xs = movements.map(function(item) { return item.x });
const ys = movements.map(function(item) { return item.y });
const l = Math.min.apply(null, xs);
const t = Math.min.apply(null, ys);
const r = Math.max.apply(null, xs);
const b = Math.max.apply(null, ys);
const width = r - l; // Already in markup coords space
const height = b - t; // Already in markup coords space
const position = {
x: l + width * 0.5,
y: t + height * 0.5
};
const size = editMode.size = {x: width, y: height};
// Adjust points to relate from the shape's center
const locations = movements.map(function(point){
return {
x: point.x - position.x,
y: point.y - position.y
};
});
const endPen = editMode.setPen( position, size, locations, false );
endPen.execute();
editMode.creationEnd();
}
Then call them in this way:
// Load the extionsion
let markup;
viewer.loadExtension( 'Autodesk.Viewing.MarkupsCore' )
.then(function( markupsExt ) {
markup = markupsExt;
});
// Enter markup editer mode and change it to freehand mode
markup.enterEditMode();
const freehand = new Autodesk.Viewing.Extensions.Markups.Core.EditModeFreehand( markup );
markup.changeEditMode( freehand );
// Create start point of the line
createLineStartPt( 360.03125, 191.3125, markup );
// Create end point of the line
createLineEndPt( 460.03125, 191.3125, markup );
// Tell the markup tool to finish drawing
endLineDrawing( markup );
Here is the result of the above codes:
Note. All mousePos prefixed variables are coordinates in the client coordinate system in the browser viewport, see below link for details. After getting the mosue's clientX or clientY, you have to minus markup.svg.getBoundingClientRect() to adjust their values.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems#Client
Hope it helps!

Parsing JSON values from media file metadata on OSX

This is my very first attempt at Swift 3 and Xcode 8.3.3. I'm trying to parse a JSON metadata extracted from a file through the command-line application Exiftool.
let task = Process()
let filePath = url.path
let etPath = "/usr/local/bin/exiftool"
task.launchPath = etPath
task.arguments = ["-a", "-g1", "-json", filePath]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
// Get the data
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
let mydata = output?.data(using: String.Encoding.utf8.rawValue)!
do {
let myJson = try JSONSerialization.jsonObject(with: mydata!, options: []) as AnyObject
if let XMPdc = myJson["XMP-dc"] as AnyObject? {
if let creator = XMPdc["Creator"] as! NSArray? {
print(creator)
}
}
} catch let error as NSError {
print(error)
}
The first part of the script works well, allowing me to get the JSON data into the variable myJson. If I print that variable out, I obtain this:
(
{
Composite = {
ImageSize = 100x100;
Megapixels = "0.01";
};
ExifIFD = {
ColorSpace = Uncalibrated;
ExifImageHeight = 100;
ExifImageWidth = 100;
};
ExifTool = {
ExifToolVersion = "10.61";
};
File = {
ExifByteOrder = "Little-endian (Intel, II)";
FileType = TIFF;
FileTypeExtension = tif;
MIMEType = "image/tiff";
};
"ICC-header" = {
CMMFlags = "Not Embedded, Independent";
ColorSpaceData = "RGB ";
ConnectionSpaceIlluminant = "0.9642 1 0.82487";
DeviceAttributes = "Reflective, Glossy, Positive, Color";
DeviceManufacturer = KODA;
DeviceModel = ROMM;
PrimaryPlatform = "Microsoft Corporation";
ProfileCMMType = KCMS;
ProfileClass = "Display Device Profile";
ProfileConnectionSpace = "XYZ ";
ProfileCreator = KODA;
ProfileDateTime = "1998:12:01 18:58:21";
ProfileFileSignature = acsp;
ProfileID = 0;
ProfileVersion = "2.1.0";
RenderingIntent = "Media-Relative Colorimetric";
};
"ICC_Profile" = {
BlueMatrixColumn = "0.03134 9e-05 0.82491";
BlueTRC = "(Binary data 14 bytes, use -b option to extract)";
DeviceMfgDesc = KODAK;
DeviceModelDesc = "Reference Output Medium Metric(ROMM) ";
GreenMatrixColumn = "0.13519 0.71188 0";
GreenTRC = "(Binary data 14 bytes, use -b option to extract)";
MakeAndModel = "(Binary data 40 bytes, use -b option to extract)";
MediaWhitePoint = "0.9642 1 0.82489";
ProfileCopyright = "Copyright (c) Eastman Kodak Company, 1999, all rights reserved.";
ProfileDescription = "ProPhoto RGB";
RedMatrixColumn = "0.79767 0.28804 0";
RedTRC = "(Binary data 14 bytes, use -b option to extract)";
};
IFD0 = {
Artist = Autore;
BitsPerSample = "16 16 16";
Compression = LZW;
ImageDescription = "Creator: Test ; Date: 1900";
ImageHeight = 100;
ImageWidth = 100;
ModifyDate = "2017:08:10 10:58:42";
Orientation = "Horizontal (normal)";
PhotometricInterpretation = RGB;
PlanarConfiguration = Chunky;
ResolutionUnit = inches;
RowsPerStrip = 100;
SamplesPerPixel = 3;
Software = "Adobe Photoshop CC 2015 (Macintosh)";
StripByteCounts = 1037;
StripOffsets = 11450;
SubfileType = "Full-resolution Image";
XResolution = 300;
YCbCrPositioning = "Co-sited";
YResolution = 300;
};
Photoshop = {
DisplayedUnitsX = inches;
DisplayedUnitsY = inches;
GlobalAltitude = 30;
GlobalAngle = 90;
HasRealMergedData = Yes;
IPTCDigest = 00000000000000000000000000000000;
PhotoshopThumbnail = "(Binary data 557 bytes, use -b option to extract)";
PixelAspectRatio = 1;
PrintPosition = "0 0";
PrintScale = 1;
PrintStyle = Centered;
ReaderName = "Adobe Photoshop CC 2015";
SlicesGroupName = "";
"URL_List" = (
);
WriterName = "Adobe Photoshop";
XResolution = 300;
YResolution = 300;
};
"XMP-dc" = {
Creator = Autore;
Description = "Creator: Test ; Date: 1900";
Format = "image/tiff";
Publisher = "-";
Rights = "-";
Subject = "-";
Title = tite;
};
"XMP-pdf" = {
Producer = "-";
};
"XMP-photoshop" = {
ColorMode = RGB;
ICCProfileName = "ProPhoto RGB";
};
"XMP-x" = {
XMPToolkit = "Image::ExifTool 10.53";
};
"XMP-xmp" = {
CreateDate = 1900;
CreatorTool = "Adobe Photoshop CC 2015 (Macintosh)";
MetadataDate = "2017:08:10 10:58:42-04:00";
ModifyDate = "2017:08:10 10:58:42-04:00";
ThumbnailFormat = "-";
ThumbnailImage = "(Binary data 48 bytes, use -b option to extract)";
};
"XMP-xmpRights" = {
Marked = 1;
};
}
)
However, I don't understand how to correctly parse the data in order to store a specific value, let's say the value that corresponds to the object { "XMP-dc" = {Creator = Autore } }, within my variable creator.
What am I doing wrong?
Try to downcast your json and xmp-dc to the dictionary
let myJson = try JSONSerialization.jsonObject(with: mydata!, options: []) as? [String: Any]
if let XMPdc = myJson?["XMP-dc"] as? [String: Any?] {
//print that dictionary to be sure that al is correct
print(XMPdc)
//I'm not sure that the value Creator is an Array, honestly I don't understand what is the type of that object, but anyway, few fixes for your code
if let creator = XMPdc["Creator"] as? NSArray {
print(creator)
}
}
Again, I'm not sure about the type of the variable Creator, but at least you will know this when you will make print(XMPdc), then you can change the downcast for the creator to the String or whatever.
Let me know if you need something

Upload pre-selected file with actionscript

I'm creating a photoshop extension where I need to save the file people are working on and upload it to a server. So I want the extension to be able to automatically choose the current file and upload it to my server.
Problem is I don't know how to pre-select a file for people. Here's my code so far:
var app:Application = Photoshop.app;
var doc:Document = app.documents.add();
doc.selection.selectAll();
var color:RGBColor = new RGBColor();
color.red = 0;
color.green = 0;
color.blue = 255;
doc.selection.fill(color);
var saveOptions:JPEGSaveOptions = new JPEGSaveOptions();
//Add other PDF save options here.
doc.saveAs(File.applicationStorageDirectory, saveOptions);
var jsonOBJ:Object = {};
jsonOBJ.option = "iphone";
jsonOBJ.title = "c";
jsonOBJ.description = "s";
jsonOBJ.app_store_url = "iphone";
jsonOBJ.tags = "c";
jsonOBJ.temp_number = 1;
var _service:HTTPService = new HTTPService();
_service.url = "http://localhost:3000/designs";
_service.method = "POST";
_service.contentType = "application/json";
_service.resultFormat = "text";
_service.useProxy = false;
_service.makeObjectsBindable = true;
_service.addEventListener(FaultEvent.FAULT,faultRX);
_service.addEventListener(ResultEvent.RESULT,resultRX);
_service.showBusyCursor = true;
_service.send( JSON.encode( jsonOBJ ) );
function resultRX():void
{
trace(ResultEvent.RESULT);
}
function faultRX():void
{
trace(FaultEvent.FAULT);
}
var file:FileReference;
var filefilters:Array;
var req:URLRequest;
filefilters = [ new FileFilter('Images', '*.jpg') ]; // add other file filters
file.browse(filefilters);
It's a photoshop extension. I ended up using FileReference and link to the file. it worked. I dunno how to actually upload the image though. When I use file.upload(requestUrl), it sends along a wrong content type. –