U-C-S / Hurl

Choose the browser on the click of a link
MIT License
254 stars 8 forks source link

Automatic Rules #18

Closed U-C-S closed 11 months ago

rp1231 commented 1 year ago

Automatic rules would be great!

U-C-S commented 1 year ago

Currently i put this at the last priority.

My only issue with this feature is that It impacts a app startup times a bit. I'm looking to separate this feature into a separate project itself while also integrating with Hurl.

Any suggestions on it's architecture or design or working are welcome

rp1231 commented 1 year ago

I'm not really a programmer, I'm a power user, so unfortunately I can't help with any of that. I currently use browser picker because of the automatic rules. It seems to work fine for me (regarding startup time), So maybe you can have a look at their code?

U-C-S commented 1 year ago

@mix3d lets discuss here

Only thing I fear is how the startup times might be impacted here. and put the feature into last priority for more experimentation.

Expanding from prev comment, Im thinking to put automatic rules into a C++/Rust project and generate a hurl launcher binary from it for faster iteration of url rules and specific usecase of mutexes and single-instancing.

rp1231 commented 1 year ago

I would like to add a feature request of regex for rules whenever this is implemented.

mix3d commented 1 year ago

@U-C-S I don't see how having a simple map of

*.xyz.com -> chrome
google.com -> prompt user
reddit.com -> firefox
youtube.com -> edge

would affect performance to any noticeable degree.

Let's set an upper bounds of maybe 100 sites at 20 characters in length. That's a measly 2kb to store and keep in memory.

Some brief research says that's about the average number of different sites a person visits in a month, and realistically, I can't imagine myself setting up more than 10-20 specific "this site this browser" patterns.

U-C-S commented 1 year ago

Makes sense, I was just being crazy over those minor differences since the requirement of needing to loop over all the regex rules every time whether or not there exists a rule for it.


Few ways I thought I could do this:

Maybe I will go with option 1 for now, then see to option 2 later

molohov commented 1 year ago

Any update on automatic rules? I'd help, but I have no experience with C# :)

U-C-S commented 1 year ago

I'm considering it for the next version. Since Most of the Hurl main UI is now done (outside of minor stuff and Hurl Settings app). I'll try prototype this feature soon.

I put out a similar feature "Timed default browser" in newer v0.7. though it need some polish with accessibility and optimization for faster startup.

vignesh-seven commented 1 year ago

rules when?

U-C-S commented 1 year ago

Soon™

its the highest priority feature of next version....

vallerydelexy commented 1 year ago

yay yay!! automatic rules for the win

U-C-S commented 1 year ago

Current Idea:

image

RED Circle : New Dropdown menu for 2 types of selection when a browser is clicked. (will add one more)

YELLOW Circle : URL editing is now possible when option 1 is chosen. which also makes it possible for editing the Rule before storing it into the rule list for a browser when option 2.

TODO:

jjafuller commented 1 year ago

Before I begin: I can help with this work. I'm a software architect and have years of experience with .NET and C# in particular.

Being able to define rules via UI is a nice feature. But I suspect to get the largest benefit is by being able to define handlers based on RegEx matching rules. This is what I used to do on macOS with the Finicky tool: https://github.com/johnste/finicky. It worked really well.

I can certainly understand the reluctance to process a bunch of matching rules since .NET isn't actually known for performant regex. Luckily, this was one of the major priorities in .NET 7 (https://devblogs.microsoft.com/dotnet/regular-expression-improvements-in-dotnet-7/), so we may be able to get a massive performance boost just by upgrading the version of .NET we're targeting.

My suggestion would be to expand the UserSettings file to include a handlers section where these rules can be defined.

There are a couple of way we could handle the automatic selection. Ideally, the matching is fast enough that matches can be directly executed prior to launching the UI. If not, we could do the matching async and set the selection in the UI with a short timeout once the match comes back.

U-C-S commented 1 year ago

The way Finicky handles this is really cool. I think it's using Node or some Js engine internally to execute the Javascript code at runtime. It might be a extra dependency.

That perf improvements and the blog post are crazy !! I will move to .NET 7 as soon as possible.

expand the UserSettings file to include a handlers section where these rules can be defined

Im currently doing this. Problem is how I do put priority if a rule is repeated twice. the way im storing the rules is appending a rule property to each browser in UserSettings, which stores the array of rules. And I loop over from the start. So, I couldn't handle the priority. Any Suggestions are welcome here.

ideally, the matching is fast enough that matches can be directly executed prior to launching the UI.

I decided to go with this way for now. I will look for alternative approaches in the future. I feel this is better for UX, but might also put negative experience if the number of rules are large (maybe more threads for divide and conquer...?). Im not sure I understood how async way works here.

Also, Any feedback on UI design as mentioned above ur comment ?


SideNote: You could build the Hurl in ur system to test couple of the changes I made as part of this issue. At the moment I'm using Glob patterns instead of Regex for their simplicity. Might check back to regex before the release. And, I feel alien to the WPF design ways.

jjafuller commented 1 year ago

Im currently doing this. Problem is how I do put priority if a rule is repeated twice. the way im storing the rules is appending a rule property to each browser in UserSettings, which stores the array of rules. And I loop over from the start. So, I couldn't handle the priority. Any Suggestions are welcome here.

That is an interesting way of organizing it. I probably would have inverted that and have a list of matching rules defined that point to the desired browser. That would help with the explicit priority aspect. However, either way you'd want to do some cursory analysis of how the match handlers are defined to find opportunities for concurrent execution. 🤔

U-C-S commented 1 year ago

I probably would have inverted that

You mean like the way Finicky does it... like for each browser

{
  "rules": [...],
  "browser": { "name": "....", "exepath": "...." }
}
jjafuller commented 1 year ago

Not exactly. I like the way that browsers are currently defined in Hurl. I think it makes sense to explicitly define them like that. I would just reference them by key in the match handlers.

jjafuller commented 1 year ago

Maybe something along these lines:

{
  "LastUpdated": "2/12/2023 4:13:58 PM",
  "Version": "0.7.1",
  "Browsers": {
    "Brave": {
      "ExePath": "C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"
    },
    "Firefox": {
      "ExePath": "C:\\Program Files\\Mozilla Firefox\\firefox.exe"
    },
    "Google Chrome": {
      "ExePath": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
    },
    "Microsoft Edge": {
      "ExePath": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"
    }
  },
  "AutoRoutingRules": [
    {
      "Match": ["microsoft.com/*", "msft.org/*"],
      "Browser": "Microsoft Edge"
    },
    {
      "Match": "/workplace/",
      "Browser": "Firefox"
    },
    {
      "Match": [
        "google.com/*",
        "*.google.com/*"
      ],
      "Browser": "Google Chrome"
    }
  ]
}
U-C-S commented 1 year ago

Oh makes sense.... can also help with quick remapping and further extension. I will think over this.

U-C-S commented 1 year ago

A ambiguous situation and I don't know whether its a good idea:

image

image

Some might prefer globs for simplicity and quickly putting a rule, while regex mode for more complex queries and finally a raw string incase of direct comparison

jjafuller commented 1 year ago

If we want to support multiple matching methods I would go the more verbose route which makes things explicit and doesn't require any complicated parsing logic. For example:

"Rules": [
  { "MatchType": "strict", "Rule": "google" },
  { "MatchType": "regex", "Rule": "keepx\\.google\\.com" },
  { "MatchType": "glob", "Rule": "*.google.com/*" }
]
U-C-S commented 1 year ago

Haha, Earlier i was bit influenced by the format used by the bcrypt. And thought it's less error prone unlike JSON objects here.

I will be building UI anyway, I'll go along as u suggested

andrew-hill commented 1 year ago

Something worth considering in the implementation is email URL protection systems. For the most part, my rules are (sub)domain-based, or matching a subnet of IPs. But some companies I work with have URL protection software that mangles URLs so they can scan it for malicious content and block it at the time of clicking, if necessary. Two I'm aware of:

Mimecast

Outlook safelinks:

I originally thought you'd need to resolve these and then apply auto-matching on the resolved URLs, but I think blob and regex could work in most cases (certainly these two). Anyone who uses such an email system commonly might have to double-up on some rules, but it's probably a lot cleaner from a UI + dev point of view.

If you want to match outlook.com but also deal with 'safelinks' protected URLs, you'd need to ensure you can set the order of rules, so safelinks can be matched before say *.outlook.com.

I think you've already thought of this (if i'm reading right) - but also would be useful to have a way to force manual browser selection for a URL (e.g. hold a key combo while opening, or use URL history to re-open differently).

pk-2023 commented 1 year ago

Would this allow me to set hurl to open all links in a default browser, except for the list given? I just want one url to open in Edge, but everything else to open in Firefox by default.

So the list is an exception list

U-C-S commented 1 year ago

@pk-2023 yes, it is possible to do that

@andrew-hill for the moment I am just trying to implement a simpler rule check.... since its already few months since last version. I will look back into that safelinks immediately after the release

APKiwi commented 1 year ago

Awesome to hear. @pk-2023 this is also my use case exactly.

U-C-S commented 1 year ago

This feature is available for testing in the alpha release

Usage reference: https://github.com/U-C-S/Hurl/discussions/69#discussioncomment-5574032

U-C-S commented 11 months ago

Closing this since its available in new v0.8 release. Please open new issues for anything related to this