jarun / googler

:mag: Google from the terminal
GNU General Public License v3.0
6.11k stars 529 forks source link

Interactive script as url-handler? #385

Closed 097115 closed 4 years ago

097115 commented 4 years ago

Would be great if one could use an interactive script as --url-handler option.

Example workflow:

Or another take:

For now, as far as I can tell, googler doesn't allow to achieve that (but then again, may be I'm just plain wrong?)

jarun commented 4 years ago

I am not sure if it works. I just use the script for reading news in non-interactive way. If it's not working please raise a PR to fix it. I don't think we can spend time on it.

jarun commented 4 years ago

Your change would probably go into function open_url(), the first condition:

if hasattr(open_url, 'url_handler'):
zmwangx commented 4 years ago

I can take a look tomorrow.

097115 commented 4 years ago

@zmwangx Wow, that would be great!

jarun commented 4 years ago

Reopening the issue in that case.

zmwangx commented 4 years ago

Okay, looked at the origin of the URL handler code, 06d77cddec34b9dcc554155ae2abb01cbd9d2c92 by @jarun. It was written to specifically deny stdin to the handler, and written in kind of a peculiar way too (could have just used Popen with stdin=subprocess.DEVNULL without opening a pipe and immediately closing it by piping nothing into it). I'm not sure why deny stdin to the handler; @jarun can you remember or think of any reason?

I think we can enable stdin for the handler if we can't come up with an objection (will give this another thought with a clearer mind tomorrow). Meanwhile, there's a /dev/tty trick you can use right now that allows you to exhaust stdin (fd 0), then "reopen" it for interactivity @097115. Try something like this:

#!/usr/bin/env python3

import argparse
import contextlib
import re
import socket
import sys
import urllib.parse
import webbrowser

@contextlib.contextmanager
def redirect_stdin(fp):
    saved_stdin = sys.stdin
    sys.stdin = fp
    yield
    sys.stdin = saved_stdin

def resolve_domain(url):
    try:
        netloc = urllib.parse.urlparse(url).netloc
        host = re.match(r"^(.*@)?(?P<host>.*?)(:.*)?$", netloc).group("host")
        return socket.gethostbyname(host)
    except Exception:
        return None

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("urls", nargs="+")
    args = parser.parse_args()
    # Exhaust stdin.
    sys.stdin.read()
    with open("/dev/tty", "r") as tty:
        with redirect_stdin(tty):
            for url in args.urls:
                ip = resolve_domain(url)
                yn = input(f"{url} resolves to {ip if ip else 'unknown'}, open? [yN] ")
                if yn.strip().lower().startswith("y"):
                    webbrowser.open(url)

if __name__ == "__main__":
    main()

Sample session:

$ googler --url-handler=./interactive.py --exact -n 3 googler

 1.  jarun/googler: Google from the terminal - GitHub
     https://github.com/jarun/googler
     googler is a power tool to Google (web, news, videos and site search) from the command-line. It shows the title,
     URL and abstract for each result, which can be ...

 2.  Googler - Wiktionary
     https://en.wiktionary.org/wiki/Googler
     NounEdit. Googler (plural Googlers). A full-time Google corporation employee. A regular or habitual user of the
     Google search engine.

 3.  GOOGLER | 1 Definitions of Googler - YourDictionary
     https://www.yourdictionary.com/googler
     Googler definitions. Filters (0). (1) A person who is an employee of Google. See Xoogler. 0. 0. Words near
     googler in the Dictionary. google product search ...

googler (? for help) o 1-3
https://github.com/jarun/googler resolves to 192.30.255.112, open? [yN] y
https://en.wiktionary.org/wiki/Googler resolves to 198.35.26.96, open? [yN] n
https://www.yourdictionary.com/googler resolves to 99.84.238.60, open? [yN] n
097115 commented 4 years ago

@zmwangx

This -- some sort of a versatile plugin system -- definitely looks like quite a solution to my question, thank you!

(Don't know, if I should close this now, so I just leave it to @jarun, probably).

jarun commented 4 years ago

can you remember or think of any reason?

The only reason could be there was no use case for an interactive url handler and I wanted to be conservative.

Please feel free to extend by all means.