Giter Site home page Giter Site logo

roku-dev-cli's Introduction

Overview

roku-dev-cli is a command-line tool for loading builds onto a dev-enabled Roku device.

Features:

  • build zipping, installation, and logging
  • project analysis
  • network proxying

Installation

roku-dev-cli can be installed from the pypi repository using pip.

pip3 install roku-dev-cli

Usage

roku-cli --help

Usage: Loading a Build

To load a build on the Roku, first make sure the device is on the same network and is in developer mode (how to enter developer mode).

In your terminal, go to the base directory of your Roku project where the manifest file exists. Then run the following command:

roku <IP_ADDRESS>

This will zip up the current directory and send it to the device. If the app is successfully installed the tool will output the application's log to your console as it executes. Hitting Ctrl-C will safely exit the tool without stopping the application.

The script will do some basic checking of the project making sure all the component files are valid XML.

Usage: Loading a build from an existing zip file

If you already have a zip file you want to load, you can use the zip_file flag instead of zipping the current directory:

roku --zip-file <ZIP_FILE_PATH> <IP_ADDRESS>

This will install the zip file and start logging the application output.

Usage: Channel Analysis

There are two reporting tools available.

One tool provides a graph of nodes and texture memory over time, which is written to a file and viewable in a browser.

roku -n <IP_ADDRESS>

The other parses any logrendezvous output from the telnet port and writes it to a file. This will create three lists:

  • rendezvous by frequency (highest to lowest)
  • rendezvous by longest duration (highest to lowest)
  • rendezvous neighboring other rendezvous lines, which may show an opportunity to use queueFields to mitigate multiple rendezvous
roku --report-rendezvous <IP_ADDRESS>

Before running this tool, make sure the device is printing out rendezvous logs. You can do this by telnetting into port 8080 on the device and running the following command:

> logrendezvous on

Usage: Network Proxying

The tool has some support for mitmproxy, which allows you to view and control network traffic running through the box.

The Roku OS currently does not support HTTP proxy forwarding, so users must first route traffic through a computer.

Step 0: Install mitmproxy

On mac, run the following command:

brew install mitmproxy

Step 1: Setup routing

On Linux:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -i wlan1 -p tcp --dport 443 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i wlan1 -p tcp --dport 80 -j REDIRECT --to-port 8080

Replace wlan1 with the wifi interface the Roku device is connected to.

On Mac:

Enable port forwarding:

sudo sysctl -w net.inet.ip.forwarding=1

Update pf config. It should look something like this...

...
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
# Port forwarding for mitmproxy
rdr pass on bridge100 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass on bridge100 inet proto tcp from any to any port 443 -> 127.0.0.1 port 8080
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
...

Notice that the forwarding rules were inserted between some other existing rules, if you append them to the end of the file you will get some warnings.

Finally run the following commands. The first will check file syntax while the second one will restart the service loading the new rules.

sudo pfctl -v -n -f /etc/pf.conf
sudo pfctl -ef /etc/pf.conf

Step 2: Start the proxy

Finally start the tool with the --proxy flag. This will add mitmproxy's certificate to your build and replace certificate instances to use it instead.

roku --proxy <IP_ADDRESS>

At this point the application should be running through your proxy.

TODO: document use of mitmdump scripts

Developing

Running from source

To switch to a local source version:

pip install -e /path/to/your/local/repos/roku-dev-cli

To switch to the published version:

pip uninstall roku-dev-cli && pip install roku-dev-cli

Testing

Where relevant, please add unit tests and make sure they are passing before submitting a pull request.

pytest

Publishing to PyPi

  1. If necessary, create a personal account at pypi.org and ask to be added as a maintainer of https://pypi.org/project/roku-dev-cli/.

  2. If necessary, edit ~/.pypirc to include your pypi.org credentials. For example:

    [distutils]
    index-servers =
      pypi
    
    [pypi]
    username: <your-pypi-username>
  3. Merge your pull request, including updating version.py.

  4. If necessary, install twine and wheel:

    pip3 install twine wheel
  5. Publish to the default public pypi repo, you will be prompted to enter your pypi.org password:

    python3 setup.py sdist
    python3 setup.py bdist_wheel --universal
    twine upload dist/*

roku-dev-cli's People

Contributors

jwfearn avatar mbbill avatar sjbarag avatar strattonbrazil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

roku-dev-cli's Issues

Mitmproxy not working

I have run the cli, deployed an app, and have opened the mitmweb. It says "connected", but I don't see any traffic, and the channel can't successfully make network requests. I get this error:

127.0.0.1:60659: Transparent mode failure: RuntimeError('Insufficient privileges to access pfctl. See https://mitmproxy.org/docs/latest/howto-transparent/#macos for details.')
127.0.0.1:60660: Transparent mode failure: RuntimeError('Insufficient privileges to access pfctl. See https://mitmproxy.org/docs/latest/howto-transparent/#macos for details.')
127.0.0.1:60659: mitmproxy has crashed!
Traceback (most recent call last):
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/server.py", line 279, in server_event
    for command in layer_commands:
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 144, in handle_event
    command = command_generator.send(send)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 257, in handle_event
    yield from super().handle_event(event)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 129, in handle_event
    yield from self.__continue(event)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 220, in __continue
    yield from self.__process(command_generator, event.reply)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 183, in __process
    command = command_generator.send(send)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 271, in _handle_event
    yield from self._ask()
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 285, in _ask
    yield from self.layer.handle_event(e)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 144, in handle_event
    command = command_generator.send(send)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layers/http/__init__.py", line 740, in _handle_event
    yield from self.event_to_child(handler, event)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layers/http/__init__.py", line 761, in event_to_child
    yield from self.event_to_child(stream, command.event)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layers/http/__init__.py", line 749, in event_to_child
    for command in child.handle_event(event):
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layer.py", line 144, in handle_event
    command = command_generator.send(send)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layers/http/__init__.py", line 136, in _handle_event
    yield from self.client_state(event)
  File "/usr/local/Cellar/mitmproxy/7.0.2/libexec/lib/python3.9/site-packages/mitmproxy/proxy/layers/http/__init__.py", line 162, in state_wait_for_request_headers
    assert self.conte
```xt.server.address
AssertionError  

Logs don't tail after "Brightscript Debugger>" appears in console output

After experiencing a crash (or legitimately using the BrightScript debugger via telnet ip.add.re.ss 8085), the first few installed builds don't result in logs getting printed. It appears that connecting to a Roku over telnet (like this CLI does) always returns a few lines of history.

Any way to make this not happen? I wind up ^Cing the script after it installs and just running telnet directly, so something like roku --install-only ip.add.re.ss && telnet ip.add.re.ss 8085 would be lovely. Or even just letting the logs continue to flow after detecting Brightscript Debugger>?

Allow `mitmweb` UI instead of `mitmdump`

mitmdump is really nice, but the output with roku --proxy is currently very chatty. It'd be neat to at least have the MITM proxy UI available so that interactive changes can be made!

Let's consider a --proxy-ui argument that defaults to dump or something. Or perhaps just --use-mitmweb? ๐Ÿคทโ€โ™‚๏ธ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.