Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use it on Windows Chrome #19

Closed
naeloob opened this issue Feb 12, 2020 · 7 comments
Closed

How to use it on Windows Chrome #19

naeloob opened this issue Feb 12, 2020 · 7 comments
Assignees

Comments

@naeloob
Copy link
Contributor

naeloob commented Feb 12, 2020

First to thank you for this great tool.
It's Awesome!!

I managed to use it on Windows-Chrome.

That's are the changes i've done.

Change SIGPIPE

On windows there's no SIGPIPE signal.
I've seen on the python docs that they advise to catch the exception BrokenPipeError:

From https://docs.python.org/3.7/library/signal.html#note-on-sigpipe

Changes on main function of brotab_mediator.py
def main():
#signal.signal(signal.SIGPIPE, signal_pipe)
monkeypatch_socket_bind()
disable_click_echo()

global actual_port
for port in range(DEFAULT_MIN_HTTP_PORT, DEFAULT_MAX_HTTP_PORT):
    logger.info('Starting mediator on %s:%s...',
                DEFAULT_HTTP_IFACE, port)
    actual_port = port
    try:
        app.run(DEFAULT_HTTP_IFACE, port, debug=False, threaded=False)
        logger.info('Exiting mediator...')
        break
    except OSError as e:
        logger.info('Cannot bind on port %s: %s', port, e)
    except BrokenPipeError:
        signal_pipe

else:
    logger.error(
        'No TCP ports available for bind in range from %s to %s',
        DEFAULT_MIN_HTTP_PORT, DEFAULT_MAX_HTTP_PORT)

I think this way is compatible with all OS.

How to Configure for Chrome on Windows

A) Changes on brotab_mediator.json:
Path entry must have double \

Example:
"path": "D:\\Python-3.7.6.0\\Envs\\BroTab\\Scripts\\bt_mediator.EXE",

B) Create a Registry Key

From https://developer.chrome.com/extensions/nativeMessaging#native-messaging-host-location

On Windows, the manifest file can be located anywhere in the file system. The application installer must create registry key HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application or HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application, and set default value of that key to the full path to the manifest file.
For example, using the following command:
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application" /ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /for using the following .reg file:
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application]
@="C:\path\to\nmh-manifest.json"

In this case i've used :
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\brotab_mediator]
@="[PathWhereManifestFileIs]\brotab_mediator.json"

Enable Logging on Chrome

Just a quick note if you want to see what's happenning on Chrome side...

From https://www.chromium.org/for-testers/enable-logging

To enable logging, launch Chrome with these command line flags:

--enable-logging=stderr --v=1 # Linux (newer instructions for Linux: here)
--enable-logging --v=1 # Windows
--enable-logging=stderr --v=1 > log.txt 2>&1 # Windows, seems to capture more output

Hope to get time to make it work on FF.

Edit :
I cannot get any response from query command, in any of its variations.
Always returns b'[]'

2020-02-12 17:40:00,818 19656 INFO       getting browser name
2020-02-12 17:40:00,818 19656 INFO       SENDING: {'name': 'get_browser'}
2020-02-12 17:40:00,819 19656 INFO       RECEIVED: b'"chrome/chromium"'
2020-02-12 17:40:03,751 19656 INFO       query info: eyJ1cmwiOiBbIio6Ly8qLmdvb2dsZS5jb20vKiJdfQ==
2020-02-12 17:40:03,752 19656 INFO       SENDING: {'name': 'query_tabs', 'query_info': 'eyJ1cmwiOiBbIio6Ly8qLmdvb2dsZS5jb20vKiJdfQ=='}
2020-02-12 17:40:03,755 19656 INFO       RECEIVED: b'[]'
2020-02-12 17:42:04,148 19656 INFO       getting browser name
2020-02-12 17:42:04,149 19656 INFO       SENDING: {'name': 'get_browser'}
2020-02-12 17:42:04,150 19656 INFO       RECEIVED: b'"chrome/chromium"'
2020-02-12 17:42:07,076 19656 INFO       query info: eyJ1cmwiOiBbIioiXX0=
2020-02-12 17:42:07,076 19656 INFO       SENDING: {'name': 'query_tabs', 'query_info': 'eyJ1cmwiOiBbIioiXX0='}
2020-02-12 17:42:07,077 19656 INFO       RECEIVED: b'[]'
2020-02-12 17:42:50,217 19656 INFO       getting browser name
2020-02-12 17:42:50,217 19656 INFO       SENDING: {'name': 'get_browser'}
2020-02-12 17:42:50,218 19656 INFO       RECEIVED: b'"chrome/chromium"'
2020-02-12 17:43:51,644 19656 INFO       getting browser name
2020-02-12 17:43:51,645 19656 INFO       SENDING: {'name': 'get_browser'}
2020-02-12 17:43:51,647 19656 INFO       RECEIVED: b'"chrome/chromium"'
2020-02-12 17:43:54,571 19656 INFO       query info: eyJ0aXRsZSI6ICIqIn0=
2020-02-12 17:43:54,572 19656 INFO       SENDING: {'name': 'query_tabs', 'query_info': 'eyJ0aXRsZSI6ICIqIn0='}
2020-02-12 17:43:54,575 19656 INFO       RECEIVED: b'[]'

Any clue?

@naeloob
Copy link
Contributor Author

naeloob commented Feb 12, 2020

Changes to make Move work under Windows :

Changes on inout.py
A) Add encoding utf-8 on save_tabs_to_file and load_tabs_from_file. I think this change is safe for any OS.

def save_tabs_to_file(tabs, filename):
    with open(filename, 'w', encoding='utf-8') as file_:
        file_.write('\n'.join(tabs))

def load_tabs_from_file(filename):
    with open(filename, encoding='utf-8') as file_:
        Lines = [line.strip() for line in file_.readlines()]
    if os.path.exists(filename):
        os.remove(filename)
    return Lines

B)

  • Use Filename from NamedTemporaryFile and close it. I think this change is safe for any OS.
  • Use Notepad instead of nvim. It has to be a different editor for each OS.
def edit_tabs_in_editor(tabs_before):
    with NamedTemporaryFile() as file_:
        file_name=file_.name
        file_.close()
        save_tabs_to_file(tabs_before, file_name)
        try:
            #check_call([os.environ.get('EDITOR', 'nvim'), file_.name])
            check_call([os.environ.get('EDITOR', 'notepad'), file_.name])
            tabs_after = load_tabs_from_file(file_name)
            return tabs_after
        except CalledProcessError:
            return None

@balta2ar
Copy link
Owner

Thanks for the great and detailed write up! Your suggestions definitely need to be merged when I have a bit more time.

To enable logging, launch Chrome with these command line flags

That was and is a huge pain point for me. It was so inconvenient to check extension's logs in a browser given that I work mostly in command-line. I'll try that and I wish there were simple and reliable way to do the same in Firefox.

@balta2ar balta2ar self-assigned this Feb 12, 2020
@naeloob
Copy link
Contributor Author

naeloob commented Feb 12, 2020

Another change in api.py :

Just add an slash, in line

            words |= set(self._get(
                '/get_words/%s/?match_regex=%s&join_with=%s' % (tab_id, match_regex, join_with)

    def get_words(self, tab_ids, match_regex, join_with):
        words = set()
        match_regex = encode_query(match_regex)
        join_with = encode_query(join_with)

        for tab_id in tab_ids:
            prefix, _window_id, tab_id = tab_id.split('.')
            if prefix + '.' != self._prefix:
                continue

            logger.info(
                'SingleMediatorAPI: get_words: %s, match_regex: %s, join_with: %s',
                tab_id, match_regex, join_with)
            words |= set(self._get(
                '/get_words/%s/?match_regex=%s&join_with=%s' % (tab_id, match_regex, join_with)
            ).splitlines())

        if not tab_ids:
            words = set(self._get(
                '/get_words/?match_regex=%s&join_with=%s' % (match_regex, join_with)
            ).splitlines())

        return sorted(list(words))

Else Flask server makes a 308 permanent redirect to that url, that urlopen cannot handle.

@naeloob
Copy link
Contributor Author

naeloob commented Feb 12, 2020

brotab_mediator.py

Added is_port_accepting_connections() from inout.py

def is_port_accepting_connections(port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(0.100)
    result = s.connect_ex(('127.0.0.1', port))
    s.close()
    return result == 0

Changed main() in order to check the port is not open

def main():
    #signal.signal(signal.SIGPIPE, signal_pipe)
    monkeypatch_socket_bind()
    disable_click_echo()

    global actual_port
    for port in range(DEFAULT_MIN_HTTP_PORT, DEFAULT_MAX_HTTP_PORT):
        logger.info('Starting mediator on %s:%s...',
                    DEFAULT_HTTP_IFACE, port)
        if is_port_accepting_connections(port):
            continue
        actual_port = port
        try:
            app.run(DEFAULT_HTTP_IFACE, port, debug=False, threaded=False)
            logger.info('Exiting mediator...')
            break
        except OSError as e:
            logger.info('Cannot bind on port %s: %s', port, e)
        except BrokenPipeError:
            signal_pipe

    else:
        logger.error(
            'No TCP ports available for bind in range from %s to %s',
            DEFAULT_MIN_HTTP_PORT, DEFAULT_MAX_HTTP_PORT)

@naeloob
Copy link
Contributor Author

naeloob commented Feb 13, 2020

I have no results from any query, and the error message on log is :
[13864:21284:0213/004303.367:INFO:CONSOLE(224)] "TypeError: Error in invocation of tabs.query(object queryInfo, function callback): No matching signature.", source: chrome-extension://mhpeahbikehnfkfnmopaigggliclhmnc/background.js (224)

Background.js

It's posible that query methods are wrong?

BrowserTabs Class

  query(queryInfo, onSuccess) {
    throw new Error('query is not implemented');
  } 

FirefoxTabs Class

  query(queryInfo, onSuccess, onFailure) {
    this._browser.tabs.query(queryInfo)
      .then(onSuccess, onFailure);
  }

ChromeTabs

 query(queryInfo, onSuccess, onFailure) {
    this._browser.tabs.query(queryInfo)
      .then(onSuccess, onFailure);
  }

BrowserTabs has 2 parameters, but FF and Chrome have 3.

And Chrome seem a copy/paste from firefox.
Chrome query method has 2 parameters
tabs.query(object queryInfo, function callback)

Edit:
SOLVED!!
I've changed query(queryInfo, onSuccess) to just two parameters in browsertabs, ff, and chrome classes.

@naeloob
Copy link
Contributor Author

naeloob commented Feb 14, 2020

I've made a pull request in order to aggregate these things : #21

It lacks the changes on brotab_mediator.json (Path to bt_mediator.EXE entry must have double ) and the creation of the Registry Key.

@balta2ar
Copy link
Owner

It lacks the changes on brotab_mediator.json (Path to bt_mediator.EXE entry must have double ) and the creation of the Registry Key.

Added all your changes from the pull request and also implemented these two. Now Windows support should be much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants