After Effects Expression (if layer is a CompItem) - after-effects

I am trying to make slight modification at line 5 of below After Effects expression. Line 5 checks if the layer is visible and active but I have tried to add an extra check that the layer should not be a comp item. (In my project, layers are either text or image layer and I beileve an image layer means a comp item). Somehow the 'instanceof' method to ensure that layer should not be a comp item is not working. Please advise how to fix this error, thanks.
txt = "";
for (i = 1; i <= thisComp.numLayers; i++){
if (i == index) continue;
L = thisComp.layer(i);
if ((L.hasVideo && L.active) && !(thisComp.layer(i) instanceof CompItem)){
txt = i + " / " + thisComp.numLayers + " / " + L.text.sourceText.split(" ").length;
break;
}
}
txt

While compItem is available only in ExtendScript, you can actually check the properties available in the {my_layer}.source object.
Here's a working example (AE CC2018, CC2019 & CC2020): layer_is_comp.aep
The expression would be something similar to:
function isComp (layer)
{
try
{
/*
- used for when the layer doesn't have a ['source'] key or layer.source doesn't have a ['numLayers'] key
- ['numLayers'] is an object key available only for comp objects so it's ok to check against it
- if ['numLayers'] is not found the expression will throw an error hence the try-catch
*/
if (layer.source.numLayers) return true;
else return false;
}
catch (e)
{
return false;
}
}
try
{
// prevent an error when no layer is selected
isComp(effect("Layer Control")(1)) ? 'yes' : 'no';
}
catch (e)
{
'please select a layer';
}
For your second question, you can check if a layer is a TextLayer by verifying that it has the text.sourceText property.
Example:
function isTextLayer (layer)
{
try
{
/*
- prevent an expression error if the ['text'] object property is not found
*/
var dummyVar = layer.text.sourceText;
return true;
}
catch (e)
{
return false;
}
}

You're mixing up expressions and Extendscript. The compItem class is an Extendscript class and I'm pretty sure that it isn't available for expressions.
I'd suggest reading the docs: https://helpx.adobe.com/after-effects/user-guide.html?topic=/after-effects/morehelp/automation.ug.js

Related

How to pass LedgerJournalTrans table in resolve method of InvoiceJournalExpPartcicipantProvider class?

I have literally tried everything but still in vain. This here is InvoiceJournalExpParticipantProvider class that is supposed to provide me partici[ant names inside the workflow (all of this is custom code). Now what i want is to pass the LedgerJounalTrans table instead of the VendInvoiceInfoTable or VendInvoiceInfoLine table. I cannot seem to find a way to do this. I tried using the following code
else if (_context.parmTableId() == tableNum(LedgerJournalTrans))
{
ledgerJournalTrans = LedgerJournalTrans::findRecId(_context.parmRecId(),false);
}
But it constantly gives me an error either telling me that the operand types are of not the same types or the number of arguments passed are invalid although when i go and check the findRecId() method of ledgerJournalTrans table there are only two params being passed.
public WorkflowUserList resolve(WorkflowContext _Context, WorkflowParticipantToken _participantTokenName)
{
WorkflowUserList userList = WorkflowUserList::construct();
VendInvoiceInfoTable vendInvoiceInfoTable;
VendInvoiceInfoLine vendInvoiceInfoLine;
VendInvoiceInfoLine_Project vendInvoiceInfoLine_Project;
WorkflowParticipantExpenToken workflowParticipantExpenToken;
WorkflowParticipantExpenTokenLine workflowParticipantExpenTokenLine;
RefRecId dimensionAttributeSetRecId;
MarkupTrans markupTrans;
CompanyInfo legalEntity;
ProjTable projTable;
HcmWorker worker;
DirPersonUser personUser;
HcmPositionDetail hcmPositionDetail;
HcmPosition hcmPosition;
HcmPositionWorkerAssignment hcmPositionWorkerAssignment;
LedgerJournalTrans ledgerJournalTrans;
// check participant token name is given otherwise throw error
if(!_participantTokenName)
{
throw error('Participant name');
}
userList.add('Admin');
if (!_participantTokenName)
{
throw error("#SYS105453");
}
workflowParticipantExpenToken = WorkflowParticipantExpenToken::findName(
this.documentType(),
_participantTokenName);
if (!workflowParticipantExpenToken)
{
throw error(strFmt("#SYS313865", _participantTokenName));
}
if (_context.parmTableId() == tableNum(VendInvoiceInfoTable))
{
vendInvoiceInfoTable = VendInvoiceInfoTable::findRecId(_context.parmRecId());
}
else if (_context.parmTableId() == tableNum(VendInvoiceInfoLine))
{
vendInvoiceInfoTable = VendInvoiceInfoLine::findRecId(_context.parmRecId()).vendInvoiceInfoTable();
}

How to use if statement for a WebElement

I'm testing a website of Stocks
I have a certain 'clock' in each stock's page that shows if the stock is currently open/closed for trading
closed : class="inlineblock redClockBigIcon middle isOpenExchBig-1"
opened : class="inlineblock greenClockBigIcon middle isOpenExchBig-1014"
The only attribute there is a 'class'. I want to use an 'if' statement so I could distinguished between them, I tried to run it on a 'closed' status (see the code below on 'Check', 12 lines from the bottom).
It throws an exception on the third time of the loop :
org.openqa.selenium.NoSuchElementException: no such element
Why? and please how can I fix it?
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "C:\\automation\\drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.investing.com");
driver.navigate().refresh();
driver.findElement(By.cssSelector("[href = '/markets/']")).click();;
// list |
int size = 1;
for (int i = 0 ; i < size ; ++i) {
List <WebElement> list2 = driver.findElements(By.cssSelector("[nowrap='nowrap']>a"));
//Enter the stock page
size = list2.size();
Thread.sleep(3000);
list2.get(i).click();
**//Check**
WebElement Status = null;
if (Status == driver.findElement(By.cssSelector("[class='inlineblock redClockBigIcon middle isOpenExchBig-1']")))
{
System.out.println("Closed");
}
// Print instrument name
WebElement instrumentName = driver.findElement(By.cssSelector("[class='float_lang_base_1 relativeAttr']"));
System.out.println(instrumentName.getText());
Thread.sleep(5000);
driver.navigate().back();
}
}
}
Try using
WebElement Status = null;
if (Status == driver.findElement(By.className("redClockBigIcon")))
{
System.out.println("Closed");
}
Your loop doesn't run 3 times, but that isn't the issue here.
You're using findElement which returns a WebElement or throws an error if the element is not found. If you're on a page and you don't know if the stock is open or not, you have two options:
Catch any NoSuchElementExceptions. If this error gets thrown, the closed class is not found and therefor the page is open.
Use findElements instead of findElement. This will return a list of elements and no exception is thrown if Selenium could not find any elements. After getting the list, just check the number of elements in the list.
Option 1:
boolean isClosed = false;
try {
isClosed = driver.findElement(By.cssSelector("[class='redClockBigIcon']")).isDisplayed();
}
catch (NoSuchElementException) {
isClosed = false;
}
Option 2:
List<WebElement> closedClockElements = driver.findElements(By.cssSelector("[class='redClockBigIcon']"));
if (closedClockElements.size() > 1) {
System.out.println("Closed");
}
else {
System.out.println("Open");
}

How do you specify multiple Sort fields with Solrj?

I have an application using solr that needs to be able to sort on two fields. The Solrj api is a little confusing, providing multiple different APIs.
I am using Solr 4.10.4
I have tried:
for (int i = 0; i < entry.getValue().size();) {
logger.debug("Solr({}) {}: {} {}", epName, entry.getKey(), entry
.getValue().get(i), entry.getValue().get(i + 1));
if (i == 0) {
query.setSort(new SolrQuery.SortClause(entry.getValue().get(i++), SolrQuery.ORDER.valueOf(entry.getValue().get(i++))));
} else {
query.addSort(new SolrQuery.SortClause(entry.getValue().get(i++), SolrQuery.ORDER.valueOf(entry.getValue().get(i++))));
}
}
When I look at the generated URL I only see the last SortClause sort=sequence+asc
I also tried creating a List and the setSorts SolrQuery method and that too seems to output only as single sort field, always the last one.
I was able to create the correct sort clause by generating it manually with strings.
I have tried addOrUpdateSort as well. I think I've tried most of the obvious combinations. of methods in the Solrj API.
This does work:
StringBuilder sortString = new StringBuilder();
for (int i = 0; i < entry.getValue().size();) {
if (sortString.length() > 0) {
sortString.append(",");
}
logger.debug("Solr({}) {}: {} {}", epName, entry.getKey(), entry
.getValue().get(i), entry.getValue().get(i + 1));
sortString.append(entry.getValue().get(i++)).append(" ").
append(SolrQuery.ORDER.valueOf(entry.getValue().get(i++)));
}
query.set("sort",sortString.toString());
The sort clause I want to see is: sort=is_cited+asc,sequence+asc
The solrj API seems to only output the final clause.
I suspect a bug in solrj 4.10
can you substitute setSort with addSort ie
for (int i = 0; i < entry.getValue().size();) {
logger.debug("Solr({}) {}: {} {}", epName, entry.getKey(), entry
.getValue().get(i), entry.getValue().get(i + 1));
if (i == 0) {
query.addSort(new SolrQuery.SortClause(entry.getValue().get(i++), SolrQuery.ORDER.valueOf(entry.getValue().get(i++))));
} else {
query.addSort(new SolrQuery.SortClause(entry.getValue().get(i++), SolrQuery.ORDER.valueOf(entry.getValue().get(i++))));
}
}
And let me know if this worked
Check out addOrUpdateSort()
Updates or adds a single sort field specification to the current sort
information. If the sort field already exist in the sort information map,
its position is unchanged and the sort order is set; if it does not exist,
it is appended at the end with the specified order..
#return the modified SolrQuery object, for easy chaining
#since 4.2

TrivialDuration of miniprofiler

Can we reduce the time for TrivialDurationThresholdMilliseconds using miniprofiler tool as this code is not showing any effects written inside global.asax.cs
private void StartProfiler()
{
MiniProfiler.Start();
MiniProfiler.Settings.TrivialDurationThresholdMilliseconds = 0.01M;
}
and calling StartProfiler() method inside Application_BeginRequest
As Burkay mentioned in his comment, the TrivialDurationThresholdMilliseconds setting does not appear to be used; so requests of less than 20ms should be recorded and displayed.
If you want to limit only record requests within a range of times you could implement something like this (typically in the Application_EndRequest method of the global.asax.cs)
if (MiniProfiler.Current != null)
{
decimal minimumMillisecondsToRecord = 0.1m;
decimal maximumMillisecondsToRecord = 5.1m;
var durationOfProfiling = DateTime.Now.ToUniversalTime() - MiniProfiler.Current.Started;
if (durationOfProfiling.Milliseconds >= minimumMillisecondsToRecord
&& durationOfProfiling.Milliseconds <= maximumMillisecondsToRecord)
{
MiniProfiler.Stop(discardResults: false);
}
else
{
MiniProfiler.Stop(discardResults: true);
}
}

Adobe DTM Custom rule conditions check for cookies

I have some problems to get a specific rule to fire in DTM. And the documentation on custom rule conditions from Adobe is very basic.
What is should do:
Check if a specific cookie exists (values of the cookie are irrelevant).
When this cookies does not exist fire the rule.
With this script this should work:
var n = document.cookie,
i = "someCookie" + "=",
o = n.indexOf("; " + i);
if (-1 == o) {
if (o = n.indexOf(i), 0 != o) return null
} else {
o += 2;
var r = document.cookie.indexOf(";", o); - 1 == r && (r = n.length)
}
return unescape(n.substring(o + i.length, r))
But it does the exact opposite. When the cookie exists, the rule is fired.
If you want to stick with using a Data > Custom condition, ultimately it must either return (bool) true if you want the condition to pass, or (bool) false if you want the condition to fail.
Simple Example:
Only trigger rule if js var foo equals "bar":
if ((typeof foo!='undefined')&&(foo=='bar'))
return true;
return false;