APP REQUEST: "Ultimate Description Writer" *CODED*

Started by Jingo, July 08, 2017, 08:13:22 PM

Previous topic - Next topic

Jingo

#50
Well.. I made adjustments to the program to make things look a bit different and to fix a few of the bugs that were found.




Changes:
 

  • New Dark Theme
  • Modified Search/Replace

So, while not spending the time to go as far as John has, I did switch to a dark theme and changed a few of the other colored bits.  This looks good to me so I won't be making many more changes... but the logic is there should anyone wish to go for it.

I significantly altered the Search/Replace logic to make it work more correctly.  The Search will now create a sublist of files that match the search criteria and only those files will be updated when the replace is performed.  I also display a count of files that match the search criteria and modified the Replace button logic to display a warning/info box before performing the code replace. This same logic has also been applied to the other modification buttons...

I also cleaned up a few bits here and there to make things a bit nicer...  I have tested it and it appears to work well... look forward to hearing from others!  The only file that really needs to be replaced is index.html but I included all files for completeness and updated the original link as well.  Enjoy!

Enjoy - Andy.

DigPeter

Thanks Andy. I have downloaded the new version and will test it in a couple of days.

Jingo

Quote from: DigPeter on August 06, 2017, 11:26:31 PM
Thanks Andy. I have downloaded the new version and will test it in a couple of days.

My pleasure.. look forward to your feedback.

JohnZeman

Hi Andy.  I've found one issue with your latest version. 

Searching for characters like parenthesis ( or ) or square brackets [ or ] returns no result when one or more of those characters are in the descriptions.  Other than that it seems to be working very well.  From what I can tell your previous version did not have this issue.

Jingo

#54
Thx John -  The old version was simply using the op:replace so all is handled by IMatch (rather sophisticated I would guess).  The new version uses the v1/search/metadata to look for values so I might need to defer to Mario to see why the pattern passed in does not get found using this logic (shouldn't it also be sophisticated? ;-) ):

$('#btn-find').click(function(e) {

            FoundFiles = '';
            IMWS.get('v1/search/metadata', {
                    scope: 'idlist',
                    idlist: IMatch.idlist.fileWindowSelection,
                    pattern: document.getElementById('search').value,
                    tag: 'XMP::dc\\description\\Description\\0'
                }).then(function(response) {
                    resultInfo.text(JSON.stringify(response, null, 2));

                    // loop through results and create comma seperated list of ids
                    response.files.forEach(function(element) {
                        FoundFiles = element["id"] + ',' + FoundFiles;
                    });

                    // remove trailing , and any spaces using regex
                    FoundFiles = FoundFiles.replace(/,\s*$/, "");

                    // setup variables for number of files found in search
                    FoundFilesNum = response.files.length;
                    document.getElementById('findnum').innerHTML = response.files.length;

                    //console.log('Found: ' + FoundFiles);
                }),
                function(error) {
                    displayError(error);
                }
        });

JohnZeman

Ok thanks Andy. For the time being I'm using both the old and the new version of your app.  The old for when I need to search for () or [].

I've also adapted your latest version for my needs and it works very nicely but I also would like to see what Mario has to say about this.

Jingo

Thx John... I await Mario's explanation as well...

Mario

QuoteSearching for characters like parenthesis ( or ) or square brackets [ or ] returns no result when one o

pattern is a regular expression. Do you properly escape special characters like () or [] before you send the regular expression to IMatch?

In your code fragment it looks like you are handing over whatever is in the <input> tag...this won't work if somebody tries to find a ( or [ or / ...



PS.:

document.getElementById('search').value is old-school direct DOM access logic.

$('#search)'.val()

would do it with jQuery (which is by default included with every IMatch app, unless you changed that).
Simpler and faster (jQuery caches a lot internally).
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

Jingo

interesting... yeah - I am starting to get more familiar with the JQuery syntax.. though there is only so much JS one can learn in a month!  Maybe next month I'll add JQuery in   ;)

So.. I tried the following - but it didn't work... thoughts?





SearchVal = new RegExp(document.getElementById('search').value);

            IMWS.get('v1/search/metadata', {
                    scope: 'idlist',
                    idlist: IMatch.idlist.fileWindowSelection,
                    pattern: SearchVal,
                    tag: 'XMP::dc\\description\\Description\\0'
                }).then(function(response) {



SearchVal shows as a regEx but the response fails - even with text that should work such as 'desc' - SearchVal becomes '/desc/'

thrinn

You are creating a RegExp object, then passing it to the get call. The GET call expects a string argument, so the RegExp is silently converted back to a string representation. But this does not escape the critical chars.
According to https://stackoverflow.com/questions/32846782/how-to-escape-special-characters-in-regular-expressions, you could use a function like this to convert the input from the user to a string with escaped specials chars:

function escapeRegExp(string){
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}


I woud have expected some standard function in JavaScript (or jQuery) to to this, but did not find one.
Thorsten
Win 10 / 64, IMatch 2018, IMA

Mario

Quote from: Jingo on August 10, 2017, 12:51:08 AM
So.. I tried the following - but it didn't work... thoughts?
al shows as a regEx but the response fails - even with text that should work such as 'desc' - SearchVal becomes '/desc/'

No, wrong approach. You don't hand over a RegExp object (or the string form) to IMWS. IMWS treats the pattern param as a regular expression in standard IMatch (PERL) syntax. See the documentation for the /search/metadata endpoint.

This means when your search pattern contains characters with a special meaning in regular expressions, like [ or ( or you need to escape them so IMWS treats them as literals:

Searching for beach will just work, no special characters in the search term. But to find all files starting with (Top) you would need to supply \(Top\).* as the pattern. ( and ) have a special meaning in regular expressions. So do [ and ] or \. You can use the function provided by thrinn above escape your pattern if you don't want it treated as a regular expression.

-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

DigPeter

#61
@Andy
Your current version works well, in particular in only operating on files that need to be changed rather than all selected files - thank you very much.  I have some comments of a cosmetic nature.

The width of the dialog needs to be resized to display complete lines.  Could you arrange for automatic word-wrap in the 2 description boxes?

The dialog allows for change to either the focused file or to the selected files.  I believe that the mail purpose of the app is to make batch changes to files with different descriptions.  A single file or a selection of files with identical descriptions can be changed more easily direct in the metadata panel.  You could simplify the layout by not displaying the row of "focussed" buttons.

Would it be possible to compress the dialog vertically in its initial opening condition? 

Again thanks for doing this.

Jingo

Hello... thx for confirmation that the app is working appropriately now!

I'm a bit confused on the multi-line and vertical compress requests.. can you explain further and/or show an example that doesn't work?

I have my App Panel open on a 2nd monitor in full screen mode so perhaps I don't see what you are discussing.. the Image Description of Focused File does allow for multi-lines since it is a textarea...

Always happy to make changes to make the app better! - Andy.

DigPeter

#63
Quote from: Jingo on August 13, 2017, 09:16:49 PM
Hello... thx for confirmation that the app is working appropriately now!

I'm a bit confused on the multi-line and vertical compress requests.. can you explain further and/or show an example that doesn't work?

I have my App Panel open on a 2nd monitor in full screen mode so perhaps I don't see what you are discussing.. the Image Description of Focused File does allow for multi-lines since it is a textarea...

Always happy to make changes to make the app better! - Andy.
My monitor is 900 pixels verically.  When the app opens only about the top 2 thirds is visible. so I have to scroll down.  Perhaps smaller fonts, line spacing and boxes might reduce the height of the dialog?

Jingo

Quote from: DigPeter on August 13, 2017, 09:27:10 PM
Quote from: Jingo on August 13, 2017, 09:16:49 PM
Hello... thx for confirmation that the app is working appropriately now!

I'm a bit confused on the multi-line and vertical compress requests.. can you explain further and/or show an example that doesn't work?

I have my App Panel open on a 2nd monitor in full screen mode so perhaps I don't see what you are discussing.. the Image Description of Focused File does allow for multi-lines since it is a textarea...

Always happy to make changes to make the app better! - Andy.
My monitor is 900 pixels verically.  When the app opens only about the top 2 thirds is visible. so I have to scroll down.  Perhaps smaller fonts, line spacing and boxes might reduce the height of the dialog?

Hmm... I thought the Container-fluid DIV I'm using would do this automatically... perhaps I do not have this setup correctly?  Any thoughts Mario?  I didn't specific a specific size for the window but I do see that it does not resize horizontally like some of the other sample apps do..

JohnZeman

#65
Andy your html has 1 missing closing </tr> tag and 6 missing closing </td> tags/ which may or may not contribute to the display problem but it's not helping the display any by their not being there.

On another note regarding this app have you had any luck resolving the issue of searching for () and [] characters?  I'm really happy with what you've done so far with this app but it would sure be nice if we could search for those characters too.

Edit:  I looked too quickly.  Instead of a closing </tr> tag you're missing an opening <tr> tag on line 77.

Missing closing </td> tags are on lines 35, 49, 53, 55, 120 and 124 (with word wrap disabled in the editor).

Mario

If tags are missing or not properly closed, the browser makes a "best guess" approach - and this may break complex or fluid layouts.

The breaking points of Bootstrap (between lg, md, sm and xs) are explained here: https://getbootstrap.com/docs/3.3/css/#responsive-utilities
Even Boostrap has its limits and sometimes some manual tricks are required to make a layout behave properly between 600 pixel and 8000 pixel  ;D

QuoteMy monitor is 900 pixels verically.

This is a rather small size (Notebook or tablet, probably).
I recommend you use the built-in scaling for App Panels (Edit > Preferences > Application: User Interface > App Panel Scale. Try something like -2 or -3 for good results.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

DigPeter

Thanks mario - I will try that.  The computer is a fairly large laptop (Aspire 7750G), which I use as my main machine.

DigPeter

Andy - I have scaled the app panel as suggested by Mario, which has fixed my problem with dialog scaling.

Jingo

Thx Peter.. glad that worked for you but I'll correct my tags and see if that allows it to "auto-scale".. and will also fix the search criteria today... thx!

Jingo

#70
Quote from: Mario on August 10, 2017, 08:26:13 AM
Quote from: Jingo on August 10, 2017, 12:51:08 AM
So.. I tried the following - but it didn't work... thoughts?
al shows as a regEx but the response fails - even with text that should work such as 'desc' - SearchVal becomes '/desc/'

No, wrong approach. You don't hand over a RegExp object (or the string form) to IMWS. IMWS treats the pattern param as a regular expression in standard IMatch (PERL) syntax. See the documentation for the /search/metadata endpoint.

This means when your search pattern contains characters with a special meaning in regular expressions, like [ or ( or you need to escape them so IMWS treats them as literals:

Searching for beach will just work, no special characters in the search term. But to find all files starting with (Top) you would need to supply \(Top\).* as the pattern. ( and ) have a special meaning in regular expressions. So do [ and ] or \. You can use the function provided by thrinn above escape your pattern if you don't want it treated as a regular expression.

Hmm... I'm still having trouble with this.. results are not being found even though the special characters are escaped.  Any thoughts on what I'm doing wrong?

Image description:  Pumpkins on the table [from Dreamy Farm]

Search field entered by user: [from

Code:

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

        // Narrow idlist from selected images to only those that contain search phrase in description - create list of ids for replacement
        $('#btn-find').click(function(e) {

            FoundFiles = '';
            var SearchVal = escapeRegExp(document.getElementById('search').value);

            console.log("Pattern: "+SearchVal);

            IMWS.get('v1/search/metadata', {
                    scope: 'idlist',
                    idlist: IMatch.idlist.fileWindowSelection,
                    pattern: SearchVal,
                    tag: 'XMP::dc\\description\\Description\\0'
                }).then(function(response) {
                    resultInfo.text(JSON.stringify(response, null, 2));

                    // loop through results and create comma seperated list of ids
                    response.files.forEach(function(element) {
                        FoundFiles = element["id"] + ',' + FoundFiles;


Console displays: Pattern: \[from

FoundFiles = 0

I also noticed that this now produces false positives as well... like searching for: z still returns a found file... hmmmmm


Mario

You are searching for what, exactly? In your post I cannot see the actual search term.

I tried


            var pattern = '[from Dreamy Farm]';

            IMWS.get('v1/search/metadata', {
                    scope: 'idlist',
                    idlist: IMatch.idlist.fileWindowSelection,
                    pattern: pattern,
                    tag: 'XMP::dc\\description\\Description\\0'


which returns the file with the description Pumpkins on the table [from Dreamy Farm]

Note: The parameter name is tags, not tag.  I think you have that wrong in at least one of your posted code fragments. But this just means that IMWS will search in all tags.

But I found a bug, the pattern is treated as a contains, not as a regular expression. This is not correct, at least not according to my own documentation.

IMWS hands over the string to the search engine in IMatch. This is basically the same as when you the file window search bar, without the regular expression option. The capabilities and syntax of the search engine is documented in the IMatch help, in the Search Engine topic.

The search engine supports complex patterns like beach AND daytona or beach NOT (Hawaii or Barbados). It also supports escaped/quoted strings: "A day at the (Beach)" means that IMWS does not interpret the content enclosed in "" in any special way and that it actually searches for (Beach).

Solution to your problem would be thus (I assume) to just quote the string you send to IMWS. Just add a " and " in front and back, to force IMWS to treat the search string literally.

The /search/metadata endpoint was one of the first I've written last year. I need to check why I did not use the flag for regular expressions internally. Probably I wanted to make this an endpoint option and then forgot about it. I have made a note and I will revisit this and refactor as needed as soon as a free time slot becomes available.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

Mario

Correction.

I figured it out. I forgot to list the op parameter for /search/metadata.  It is listed for search/attributes so you can look there in the mean time ('between' is not supported by /search/metadata).

If no op is specified for search/metadata it uses the 'contains' search which finds all files where the specified data contains the pattern. This is all still in IMatch search engine snytax, which means that if your pattern contains ( or ) or AND or OR or NOT you need to quote it using ".

If you don't want to 'reveal' the search engine power in your app (to simplify it for users) always quote whatever the user is entering and use the op=contains mode.

I have updated automatic documentation for /search/metadata to list the op parameter and to mention that the pattern is in IMatch search engine syntax.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

Jingo

Thanks Mario... I thought I was going crazy over here!!

Now - it all works. I will be updating a new version shortly that corrects this issue and also corrects the issue where 'z' was found... it was because of the "tag" vs "tags" item you mentioned (oops!).

Much appreciated! - Andy.

Jingo

Ok.. wanted to post an updated version with the corrected search/replace logic that now finds symbols...

Enjoy! - Andy.

sinus

Hey Andy,

Thanks, great.  :D

Looks good, although I have not used it really.
But I will   :D
Best wishes from Switzerland! :-)
Markus

DigPeter


JohnZeman

Andy thanks from me also.  Your app works great for me now...almost.

The only thing that fails for me now is a search for either a single ( or ).

If I search for (b or t) it finds a match but not when I search for only a ( or ).

A search for [ or ] works fine now though.

Mario

Quote from: JohnZeman on August 29, 2017, 06:52:05 PM
The only thing that fails for me now is a search for either a single ( or ).

This may be a glitch in how IMatch interprets the search query. I tried in the file window search bar, and it does not work there either.
Since both the endpoint and the search bar use the same code internally, I will have to check this.
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

JohnZeman


Mario

The problem is that ( and ) have special meaning in search expressions.
Searching only for a ( should work, if it is properly escaped. But the query parser did not handle a search pattern consisting only of a single escaped ( correctly.
Works in the next release. Since this was undiscovered so far, I doubt many people searched in IMatch 5 or 2017 for single ( ...
-- Mario
IMatch Developer
Forum Administrator
http://www.photools.com  -  Contact & Support - Follow me on 𝕏 - Like photools.com on Facebook

JohnZeman

Thanks Mario.

Since it looks like we're getting all the problems solved now I'll go ahead and release my latest version of Andy's ultimate description writer app.

This version has Andy's latest code changes plus I've added quite a number of confirmation and nag modal dialogs to minimize the chances of user errors when using this app.

In other words you will see a confirmation modal dialog before you can actually change the descriptions in any way.

Also there are modals that will display if you have not selected any files or have not entered text in the correct place.

Append and prepend operations will display a confirmation modal giving you a preview of what the descriptions will look like after you have appended or prepended text.  This allows you to verify your appending or prepending will look the way you want it to before you make any changes to the descriptions.

Jingo

Looks really good John... since this was your app to begin with (as in your script from previous versions) - I'm not sure it makes sense for there to 2 be versions..  I'll keep my other version in this thread (which has the additional functionality on focused files] in case someone could use it...but will also link yours as the master version in the pinned app discussion so that is the one folks would download.  If we need to tweak or expand future, then we can make those changes to your version moving forward (so long as you are ok with this).

Nice work all around!

DigPeter


JohnZeman

Thanks guys.

Andy I'm fine with whatever you want to do with the app. :)