Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Jasondm007

  1. Thanks a ton, @lari!! That was incredibly kind of you. The workflow works great! I really appreciate it. Can't thank you enough.
  2. @deanishe Thanks for getting back to me. Yeah, I figured it was something complicated like that. Ha Yeah, it'd be great if @Andrew would be willing to share an icon pack for Alfred 🙏️❓️ SVGs or Illustrator files would be great, but I'd be ecstatic about even plain old PNG or JPGs, too!! Thanks again!
  3. @deanishe By chance, do you know if it's possible to extract Alfred's icons? I ask, not because I want to change them, but because I regularly create my own workflows based on adaptations of some of Alfred's functions (e.g., Universal Actions, Bookmarks, etc.) and I like keeping the iconography similar. As a result, I prefer to start with the actual icon, and then just make alterations to it that I will use for my own workflow (e.g., color changes, etc.). That way, I don't have to reinvent the wheel. And, by keeping the iconography similar, it also makes it easier for me to remember things. As you point out, there are very few traditional icon/image files in the app (as far as I can tell). And, there doesn't appear to be an asset catalog (car file) either, which would make it easy to extract them. Any ideas how to get them? Thanks for any help you can lend!
  4. Hi @dfay I hate to admit it, but after spending a ton of time tailoring the workflow to my needs, I ultimately stopped using it. I don’t mean to be critical of the workflow, as it works great for what was intended. I also found it super helpful for adapting, since most of this stuff is way over my head and I really appreciated @Bruno’s willingness to share it. If I recall correctly, however, I ultimately stopped using it because I wanted something that was more dynamic. My changes to the workflow’s cache also just made things worse because I: (1) set the max level to something ridiculous, like 8 or 10 (which is way too deep if you need to refresh it often), (2) opened it up to local smart groups, and (3) had it save the icons of the groups to a folder in the workflow (I have some problems with my eyes, so the iconography and colors are probably a little more important to me than most). In some iterations of the script, I also added a match string which included the parent group for easier hierarchy searching, which only slowed things down further (again, entirely, my fault). In case it’s helpful, I’ve shared my garish abomination of the workflow here: https://gofile.io/d/9yllTc You’ll find some things in the “dtp-list-groups” script that are specific to me, which you will want to edit out (e.g., icons for some specific databases, inboxes, etc.). However, this should give you a good start. I never used the workflow to move or create groups, so I have no idea how that portion of it performs. In addition, just be aware that when you run the cache update for the first time that it will take forever, especially if you’ve set the group level as high as I did. If you come up with a better approach to things, please let me know. Since I usually index everything, at the moment, I just use Alfred to search for folders/groups, and then use my own open or reveal workflow to effectively mimic the behavior. Obviously, the approach won’t work for internal files, such as smart groups. But it’s more responsive to my needs. Cheers
  5. I figured you had some things up your sleeves, @Andrew! Thanks for sneaking the "Jump To" feature in at the last minute. Can't wait to see what's next!!
  6. Thanks a ton, @Andrew! I've been using the "Jump To" option for a few different things all morning, and it works great. This is fantastic. Though, I'm with @GuiB, in that I'd love to have the ability to directly call other Universal Actions (i.e., true user created universal actions and even selecting from custom web searches would be nice). But I'm loving the current iteration anyway!! Although this issue is not specific to the "Jump To" feature, one thing to think about down the road - which has come up in the past with regard to Alfred's Navigation/Browse GUI - is to consider providing users with more controls over its appearance (or if you wanted to go crazy, theme-like controls). As it pertains to universal actions, I find the text at the bottom of the window - which indicates what the universal action is doing - to be very difficult to see and almost illegible for user created universal actions due to the length of the text. While it might not be a big deal when entering a universal action through the usual menu, when entered directly from a shortcut - such as when the "Jump To" option is being used, and you're effectively skipping straight to the second step - it can be a little discombobulating. Requiring users to rely solely on that tiny little text at the bottom of the screen to remember, for example, that they're in the "Open With..." action, is going to be tough for new users and people with tons of shortcuts, etc. There are a lot of different ways you could do it, but I think the name and iconography of the universal action should be visible during the second step (which only applies to actions with two steps - e.g., open with, move to, copy to, etc.). For example, on the second step, any of the following would work: (A) put the action's name and icon (exactly how the user would see it from the first step) at the top where the file names remain listed or add it below them, (B) place them somewhere on the preview/right-side of the panel, which is mostly open space anyways unless they selected tons of things, or (3) millions of other options. I've illustrated part of option A for you below, but there are tons of other ways you could accomplish the same thing. In any case, it's a relatively minor thing. I'm loving the new additions to 4.5!! Thanks again, @Andrew! You rock!!
  7. Thank you, @Andrew!! I've been dying for this one! And, congrats on the big update! This is all great news. Universal Actions are awesome.
  8. @deanishe & @vitor Thanks a ton for getting back to me! I'm sorry that I missed your responses earlier this week. I accidentally setup an email rule that was being a little too aggressive with messages from the forum! Ha I tried several different ways. But was never able to get the website to submit its query properly. For example, I can get search terms into the form by using some version of the following: searchSafari("Yahoo", "searchText") of me on searchSafari(theQuery, theFormId) tell application "Safari" activate open location "https://developer.uspto.gov/ptab-web/#/search/decisions" delay 3.0 do JavaScript "document.getElementById('" & theFormId & "').value ='" & theQuery & "';" in document 1 end tell end searchSafari I even tried separating out for form's submission, like the following example, but most of the time, it wouldn't actually work. Interestingly, the website will display the search graphic, but it doesn't actually submit the query appropriately (e.g., if you clear it out and submit the search manually, you'll get different results). searchSafari("Apple", "searchText", "btn btn-primary") on searchSafari(theQuery, theFormId, theButtonClass) tell application "Safari" activate open location "https://developer.uspto.gov/ptab-web/#/search/decisions" delay 3.0 do JavaScript "document.getElementById('" & theFormId & "').value ='" & theQuery & "';" in document 1 delay 2.0 do JavaScript "document.getElementsByClassName('" & theButtonClass & "')[0].click()" in document 1 end tell end searchSafari Any ideas how to get this working? Or is there a more generalizable solution, like what you mentioned above? I assume by "API Endpoints" you're referring to actually viewing the results in the script filter, right? While that sounds cool, honestly, I was just looking for something a little more simple, like running the search on their page. Here's the most relevant portion of the website (highlighted portion is the search box): This was a really cool suggestion. While I looked at that portion of the inspector prior to my post, I had no idea that you could actually see what was going on this way, too. I'm sure this is a stupid question, but how do I take the curl and open it back up in Safari through the website? For example, here's the full code for a search for "test": curl 'https://developer.uspto.gov/ptab-api/decisions/json' \ -X 'POST' \ -H 'Accept: application/json, text/plain, */*' \ -H 'Content-Type: application/json' \ -H 'Origin: https://developer.uspto.gov' \ -H 'Cookie: _4c_=XVLBjpswEP2VyueQ2MY4kNtW6mGl1SrSVpV6QsYeghUCyDhQNsq%2Fd5wE0q6RrPF7z2%2FMzFzIWEFDdkzil25TGrOEr8gRpp7sLsQ0YR%2FIjhgo1bn2ZEX%2B3NQZTWjKGUvj64rYzj90yDC%2BFciINPmiRSRoZ0f11evOu%2FFpdSdiueX%2FSwMSpNbMZkUpaFEoFhmR8UiUEEdFRnWUFiKRQhRlVvI5H2eUU55xEYd8unt4XIhuDaAXy9aMrRnK%2FSceI8EpxtCEPL0%2FYHx2NcaV912%2F22zGcVyf%2B86360M7bGwXdW1t9RQi5b3SFUSdaw9Onf6FtHIArkc3JM1Z%2B9xPXUg%2FQvGtN0ckDAxWQz5a46vwLiHoE63AHiosO8noDe1ckGA02sa043IrE%2BkTXC7JWCK6Vx4aj50m73j66ZSBk3LHGXjd529qzPe338lfm7JF4jcSvwDd3IwE6cugbJ3%2FqEF71zZW59%2FtZ%2F4xLU6Nr%2FMX7e1gvYUlIfTentpmyj86ACzKnbjOzZY4SYzhUxm2wmPJUyloWKgYljliUgsoCx3JmGPrsb1RQRMWJSpmW1XKbRyzZdRwyLMELRP5sGTp3fF6%2FQs%3D; _ga_CD30TTEK1F=GS1.1.1616187700.10.1.1616187803.0; _ga=GA1.1.1333116393.1612822856' \ -H 'Content-Length: 138' \ -H 'Accept-Language: en-us' \ -H 'Host: developer.uspto.gov' \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15' \ -H 'Referer: https://developer.uspto.gov/ptab-web/' \ -H 'Accept-Encoding: gzip, deflate, br' \ -H 'Connection: keep-alive' \ --data-binary '{"dateRangeData":{},"facetData":{},"parameterData":{},"recordTotalQuantity":25,"searchText":"test","sortDataBag":[],"recordStartNumber":0}' And, I noticed that I could still get it to work when trimmed down to the following: curl 'https://developer.uspto.gov/ptab-api/decisions/json' \ -H 'Content-Type: application/json' \ --data-binary '{"dateRangeData":{},"facetData":{},"parameterData":{},"recordTotalQuantity":25,"searchText":"test","sortDataBag":[],"recordStartNumber":0}' Or, did you mention using curl as a possible substitute for using their website? Thank you both for all of your help!! I really appreciate it.
  9. Can I ask you guys a very basic question about how to run searches on these types of websites (i.e., ones whose URLs don't change after being run via javascript)? Admittedly, whenever I come across one of these websites that I’d like to put in Alfred’s web searches, I always wind up throwing in the towel out of frustration. I can never figure out how to even find the name of the appropriate function. For example, in @FreeeG's room website, @deanishe where did you find “getRooms()”? I’m ashamed to admit that I tried looking through the inspector using Safari, Chrome, and Firefox - and I still can’t find it. As @vitor points out, I’m sure it’s at the top line of something I’m overlooking. Where did you find that in the inspector? In any case, the reason I ask is that I’ve been trying to do something similar on the US Patent Office's website. While they've recently developed several APIs for building your own tools, I don't mind just using their GUIs to run the queries. Unfortunately, however, I can’t can’t figure out what function to call from their website. I’d just like to kick off the query with Alfred, like with normal websites whose URL parameters change. While these websites are all pretty similar, here’s one that allows you to search for Board decisions. URL: https://developer.uspto.gov/ptab-web/#/search/decisions ID: searchText Function? And, here’s a few screenshots from different browsers in case I’m overlooking something that’s directly in front of my face (Safari - Chrome - Firefox): Can anyone help me find the appropriate function to call here? Depending on the panel, this website looks like it has millions. Or, if you’re anyone is aware of another forum post or something with a working example, then I could certainly try to work my way backwards. That's what I was trying to do with the rooms website posted here anyways. In fact, after updating the ID (which I can actually find - searchText) in @deanishe's workflow, I can get the text in the search box, but just can't figure out how to run it for obvious reasons. Side Note: although I’m not terribly interested in building my own thing, it’s pretty easy to run a search with the patent office’s API (which just spits out its JSON results). In case it’s helpful to others, here’s a example: https://developer.uspto.gov/ptab-api/decisions?partyName=test Of course, my preference would be to just see everything visualized in their GUI. Thanks for any help you can lend!
  10. @deanishe I can't thank you enough for all of your help with this script. But hope the beer will help. Thanks a ton for the script, and for including the notation. I'm really looking forward to pouring through it, and applying elements from it to other scripts I was working on. As you know, I was struggling with some basic python and Alfred-related things, and I can now see how the two are integrated. Honestly, I can't thank you enough!
  11. @deanishe Sure - here you go: https://gofile.io/d/ELbM9L Thanks again!
  12. Sure - no problem! Thanks a ton for offering to take a closer look it. I've uploaded the workflow for you here: https://gofile.io/d/qeVPit Thanks again for all of your help!
  13. @deanishe Thanks a ton for all of the helpful notes and suggestions above. Among other things, you're absolutely right that I kept screwing up what was being compared, in my previous attempts. I was having a hard time adapting some of the python tutorials I found online. And, as for the unknown variable, matchSG, while this wasn't the cause of my prior failed attempts, I mistakenly added to my simplified example posted above (the real version uses this term instead of match, since it's matching more than one thing). I might be doing something wrong again, but I wasn't able to get your suggested approach to work - though it's definitely closer! In layman's terms, it seems to connect each search term with an OR, where I'd prefer it to be an AND. For example, using this OR/AND description, consider the following: User's Query: term1 term2 Items Item 1: term1 term2 term3 Match under all approaches Item 2: term2 term1 term3 Match under both OR/AND approaches, which my prior approach did not accommodate Item 4: term4 term1 Match under current/OR approach, but would prefer for this not to match In short, using the example above, I'd prefer it only to match queries where term1 and term2 are present, though I don't care about their order or whether there are other terms between them. Does that make sense? My apologies for the, admittedly idiotic, description. Thanks again for all of your help!
  14. @deanishe I was wondering if I could pick your brain once more? After doing some more testing, I realized that this approach requires your query to match the string exactly (ignoring case, of course). However, I'd prefer for to be a little less strict about this and include circumstances where the elements of a query in the string, but not in the same order. For example, if the user types in "term1 term2" I'd like it to also match scenarios where the string is "term1 term3 term2". At the moment, it will only with match strings with term1 and term2 right next to each other. After doing some reading on this issue, it seemed apparent that I needed to first split my query into a list as follows: theQuery = theQueryDirty.split() Then, it probably made sense to try and use an "all" statement when looking for matches. Is that correct? I've tried numerous iterations of this approach, but I continue screwing them up. Here's a simplified version of the OLD matching approach. for plobj in plObjListSG: match = "smart group sg " + plobj["name"] # ignore items that don't match query if theQuery and theQuery.lower() not in match.lower(): continue result["items"].append({ "title": plobj["name"], "subtitle": "Global Smart Group", "match": match, # ... # ... }) And, here's one of my many iterations of the NEW approach that does not work. for plobj in plObjListSG: match = "smart group sg " + plobj["name"] # ignore items that don't match query if all((theQuery and theQuery.lower() not in matchSG.lower()) for element in theQuery): continue result["items"].append({ "title": plobj["name"], "subtitle": "Global Smart Group", "match": match, # ... # ... }) Thanks for any help you can lend!
  15. @Andrew Thanks for the explanation! I should have thought to test whether that window behavior option had any bearing on the "Browse in Alfred" stacking option. In fact, I didn't realize that it could even carry through an intermediary object, such as a Junction or Replace object. That's great news (and everything is working perfectly fine now)! Thanks a ton!
  16. @Andrew I'm not sure if this is a bug or a related feature request, but I was wondering if the "Browse in Alfred" object's new stacking option could escape back to the last visible Alfred window? For example, if you have a Junction or Replace object between a File Filter or something else that you've got connected to the Browse object, the new stacking option won't escape back to the File Filter (e.g., (1) File Filter, (2) Replace, (3) Browse in Alfred). Thanks again!
  17. @deanishe I can't thank you enough for all your patience and helpful explanations. I was completely confused by the order of operation, and ready to throw in the towel last evening. But, thanks to your help, I finally have everything working - which is super helpful for me to build from, etc. Thanks a ton! For others that may see this in the future, I made one minor change to the script above. After noticing that it was matching trailing spaces in a way that differed from Alfred's usual filtering, I just added a line to remove them. So, now the upper portion reads something like this: if len(sys.argv) < 2: theQuery = "" else: theQueryDirty = sys.argv[1] theQuery = theQueryDirty.strip() You rock @deanishe
  18. Hahaha @deanishe Your script looked so "simple" to me, that I thought you published Google's search algorithm or IBM Watson's thoughts In layman's terms, I wanted the script to perform exactly how it usually does, with the only exception being that I wanted to be able hit a modifier key ⌘ that would pass my current query to another script, in circumstances where I wasn't able to find what I was looking for. Because I haven't had any success implementing things, at the moment, I just let Alfred do the filtering and have my modifier pass an empty argument - which gets me where I want to go, but requires me to type the same thing into the next search. From what now understand about script filters - thanks to your help - is that I'd like Alfred to keep rerunning the script as the user types. That way, I can actually feed the query into the modifier's JSON argument. In addition, I'd like my script to filter the output using the item's title or match criteria, if one is provided (similar to the way it usually does). So, when the user types, the stuff that doesn't match, simply goes away from Alfred's output ... just like it usually does. To be honest, I'm a little surprised that there isn't any easier way of doing this already, given how common this request seems like it would be (e.g., an option in Alfred to recall the query, etc.).
  19. Sure thing,@Andrew - I think the new workflow feature is fantastic! I'm glad to hear that you'll be adding some version of it to the default navigation options, too. Even if it's the more simple version, with a checkbox, that's great news! Thanks a ton.
  20. @deanishe Thanks for getting back to me. I appreciate your suggestions, but I'm afraid this stuff is way over my head. Honestly, your "simple" example almost made my head explode. And I really don't understand where to even add the code that you suggested. I really didn't want to try to do the filtering myself. But I was under the impression that I had to, if I wanted to capture the query? When Alfred does the filtering, the script only runs once - which makes it impossible to capture the query, right? (unless you require the argument beforehand, etc.) Is there a way that Alfred can do the filtering and I still the final query (as an argument to pass on)? Thanks for your patience with everything!
  21. @Andrew The new view stack option, which allows users to define the escape behavior of the Browse object, was a brilliant addition to version 4.3.2! And, I was wondering if you'd be willing to take things a litte further? Namely, would you consider adding this option to Alfred's default navigation settings (File Search > Navigation)? When using Alfred's normal and quick file search modes, I regularly find myself dipping into a document or a folder to find something, and then wanting to escape right back into the query (because I didn't find what I was looking for). However, when you escape from those modes, at the moment, Alfred closes altogether - requiring the user to open Alfred's search again, etc. Personally, I'd love to be able to just escape back into the query (that'd be enough to make me ecstatic)! However, I could also imagine you expanding things a bit. For example, I could imagine a drop down in the File Search > Navigation menu that provides a few options, such as: (1) Escape Everything (which is how it currently operates), (2) Escape to Query, and (3) Escape to a Workflow - wherein the user could select, or write in, an external trigger from one of their workflows. Thanks for your consideration!
  22. @deanishe Got it! Thanks for your patience, and excellent explanation above. This all makes perfect sense (now, anyways 🤦‍♂️️)! So, if I'd like to pass my query, how do I get my script to filter the results as the user inputs their query (similar to Alfred)? In layman's terms, how do I get the script filter to remove items from Alfred's visible output as the user inputs their query (based on the "match" criteria)? As you correctly pointed out, my script just dumps all of the results into Alfred - meaning that they all just kind of sit there. Is this update as easy as adding a line or two of code to the script above? Or is it something that is going to require a more fundamental rethinking of everything? And, relatedly, since I'm not even sure where to start researching this sort of thing, do you have any suggestions for my code above, or other python-related workflows that you could point me to, where I might be able to learn how to accomplish this? Surprisingly, I only have a small handful of python workflows installed on my machine, and none appear to operate in this manner (at least from what my neophyte eyes can tell, anyways). Thanks again @deanishe!! You rock.
  23. @deanishe As usual, you're absolutely right! Unfortunately, this issue is probably beyond my limited python skillset. After doing some research into what you suggested, I incorporated an IF statement that adds the query or just an empty placeholder for the argument: if len(sys.argv) < 2: theQuery = "" else: theQuery = sys.argv[1] Then, I just set the mods as follows: "mods": { "cmd": { "subtitle": "Text Here", "arg": theQuery, "icon": {"path": "iconhere.png"}, }, }, Is this what you had in mind? Or is there a better approach? The reason I ask is that I can't quite figure out to set Alfred's run behavior using this approach. Before I incorporated this change, I used to just have Alfred filter everything. But Alfred doesn't appear to update quick enough, as it always just gives the blank argument back. But when I try changing the different options, I can't find one that actually returns query while still filtering things. To avoid scrolling up this thread, below you will find a simplified version of the script below that includes these amendments: #!/usr/bin/python # -*- coding: UTF-8 -*- import plistlib import os import json import sys titles_remove = {"- - - - - - - - - -", "- - - - - - - -"} filePathSG = os.path.expanduser("~/Library/Application Support/DEVONthink 3/SmartGroups.plist") if len(sys.argv) < 2: theQuery = "" else: theQuery = sys.argv[1] if os.path.exists(filePathSG): if os.path.exists(filePathF): if os.path.exists(filePathSR): result = {"items": []} plObjListSG = plistlib.readPlist(filePathSG) for plobj in plObjListSG: result["items"].append({ "title": plobj["name"], "subtitle": "Global Smart Group", "match": "smart group sg " + plobj["name"], "icon": {"path": "sg1.png"}, "uid": plobj["name"], "arg": "x-devonthink-smartgroup://" + plobj["sync"]["UUID"], "mods": { "cmd": { "subtitle": "Text", "arg": theQuery, "icon": {"path": "icon1.png"}, }, }, }) result['items'] = [d for d in result['items'] if d['title'] not in titles_remove] print(json.dumps(result)) else: print('{"items": [{"title": "Error","subtitle": "No Global Smart Groups Found"}]}') Thanks again for all of your help!
  24. @deanishe Sorry about that! I should have thought to include the error message. Code 1: Traceback (most recent call last): File "/Users/jasonjohndumont/Library/Caches/com.runningwithcrayons.Alfred/Workflow Scripts/96A60515-7183-4C13-8C1F-1D650947A1C7", line 36, in <module> "arg": sys.argv[1], IndexError: list index out of range Thanks again!
  • Create New...