Prepare for PyPI

pull/3/merge v0.0.1
Dave Hylands 2016-01-08 18:08:56 -08:00
rodzic 53a708c215
commit 6e6ccd7aaf
16 zmienionych plików z 582 dodań i 293 usunięć

4
.gitignore vendored 100644
Wyświetl plik

@ -0,0 +1,4 @@
build/
dist/
__pycache__/
*.egg-info/

21
LICENSE 100644
Wyświetl plik

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Dave Hylands
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

3
MANIFEST.in 100644
Wyświetl plik

@ -0,0 +1,3 @@
include LICENSE
include README.rst
include tests/test-rshell.shr

22
Makefile 100644
Wyświetl plik

@ -0,0 +1,22 @@
test:
./tests/test-rshell.sh
# Creates the source distribution tarball
sdist:
python3 setup.py sdist
# Registers this package on the pypi test server
register-test:
python3 setup.py register -r pypitest
# Creates the distribution tarball and uploads to the pypi test server
upload-test:
python3 setup.py sdist upload -r pypitest
# Creates the distribution tarball and uploads to the pypi live server
upload:
python3 setup.py sdist upload -r pypi
# Registers this package on the pypi live server
register:
python3 setup.py register -r pypi

277
README.md
Wyświetl plik

@ -1,277 +0,0 @@
rshell.py
=========
Remote MicroPytyhon shell.
This is a simple shell which runs on the host and uses MicroPython's raw-repl
to send python snippets to the pyboard in order to get filesystem information,
and to copy files to and from MicroPython's filesystem.
It also has the ability to invoke the regular REPL, so rshell can be used
as a terminal emulator as well.
Note: With rshell you can disable USB Mass Storage and still copy files into
and out of your pyboard.
When using the commands, the /flash directory, and the /sdcard directory
(if an sdcard is inserted) are considered to be on the pyboard, and all
other directories are considered to be on the host.
NOTE: rshell requires a fairly recent version of the MicroPython firmware,
specifically one which contains the ubinascii.unhexlify command which was
added May 19, 2015 (v1.4.3-28-ga3a14b9 or newer).
If your verion of the firmware isn't new enough, then you'll see an error
message something like this:
```
>./rshell.py
rshell needs MicroPython firmware with ubinascii.unhexlify
```
# Installation
rshell.py needs Python3. All of my testing was done using version 3.4.0.
rshell.py needs getch.py and pyboard.py. There is a copy of getch.py and
pyboard.py in this repository, in the same directory that rshell.py came from.
You'll also need to install pyserial. In ubuntu I did
```
sudo pip3 install pyserial
```
# Sample Session
This shows a pyboard in its default state, copying a hello.py and then entering
the repl and importing it.
```
>./rshell.py
Welcome to rshell. Use Control-D to exit.
/home/dhylands/Dropbox/micropython/upy-shell/rshell> ls -l /flash
529 May 21 17:34 README.txt
286 May 21 17:34 boot.py
34 May 21 17:34 main.py
2436 May 21 17:34 pybcdc.inf
/home/dhylands/Dropbox/micropython/upy-shell/rshell> cp hello.py /flash
/home/dhylands/Dropbox/micropython/upy-shell/rshell> ls -l /flash
529 May 21 17:34 README.txt
286 May 21 17:34 boot.py
21 May 21 17:35 hello.py
34 May 21 17:34 main.py
2436 May 21 17:34 pybcdc.inf
/home/dhylands/Dropbox/micropython/upy-shell/rshell> cat /flash/hello.py
print('Hello World')
/home/dhylands/Dropbox/micropython/upy-shell/rshell> repl
Entering REPL. Use Control-X to exit.
Micro Python v1.4.3-28-ga3a14b9 on 2015-05-21; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>>
>>> import hello
Hello World
>>>
/home/dhylands/Dropbox/micropython/upy-shell/rshell>
```
# Command Line Options
## -h, --help
Displays a lit of the valid options. You should get something like the
following displayed:
```
usage: rshell [options] [command]
Remote Shell for a MicroPython board.
positional arguments:
cmd Optional command to execute
optional arguments:
-h, --help show this help message and exit
-p PORT, --port PORT Set the serial port to use (default '/dev/ttyACM0')
-f FILENAME, --file FILENAME
Specifies a file of commands to process.
-d, --debug Enable debug features
-n, --nocolor Turn off colorized output
You can specify the default serial port using the RSHELL_PORT environment
variable.
```
## -p PORT, --port PORT
Specifies the serial port which should be used to talk to the MicroPython board.
You can set the RSHELL_PORT environment variable to specify the default port
to be used, if --port is not specified on the command line.
## -f FILENAME, --file FILENAME
Specifies a file of rshell commands to process. This allows you to create
a script which executes any valid rshell commands.
## -d, --debug
Turns on debugging. This allows you to see the script which is sent over the
raw REPL and the response received.
## -n, --nocolor
By default, rshell uses ANSI color escape codes when displaying the prompt
and ls output. This option allows colorized output to be disabled.
# File System
rshell can be connected to multiple pyboards simultaneously. If the board
module exists on the pyboard (i.e. a file named board.py somewhere in the
module search path) and it contains an attribute called name
then the pyboard will use that name. If the board module can't be imported
then the board will be named, pyboard or wipy. Names will have -1 (or some
other number) to make the board name unique.
You can access the internal flash on the first board connected using /flash
and the sd card on the first board connected can be accessed using /sd.
For all other connected pyboards, you can use /board-name/flash or
/board-name/sd (you can see the board names using the boards command).
# Commands
## args
```
args [arguments...]
```
Debug function for verifying argument parsing. This function just
prints out each argument that it receives.
## boards
```
boards
```
Lists all of the boards that rshell is currently connected to, their names,
and the connection.
## cat
```
cat FILENAME...
```
Concatinates files and sends to stdout.
## cd
```
cd DIRECTORY
```
Changes the current directory. ~ expansion is supported, and cd -
goes to the previous directory.
## connect
```
connect TYPE TYPE_PARAMS
connect serial port [baud]
connect telnet ip-address-or-name
```
Connects a pyboard to rshell. rshell can be connected to multiple pyboards
simultaneously.
## cp
```
cp SOURCE DEST
cp SOURCE... DIRECTORY
```
Copies the SOURCE file to DEST. DEST may be a filename or a
directory name. If more than one source file is specified, then
the destination should be a directory.
## echo
```
echo TEXT...
```
Display a line of text.
## edit
```
edit filename
```
If the file is on a pyboard, it copies the file to host, invokes an editor
and if any changes were made to the file, it copies it back to the pyboard.
The editor which is used defaults to vi, but can be overridem using either
the --editor command line option when rshell.py is invoked, or by using
the RSHELL_EDITOR, VISUAL or EDITOR environment variables (they are tried
in the order listed).
## filesize
```
filesize FILE
```
Prints the size of the file, in bytes. This function is primarily
testing.
## filetype
```
filetype FILE
```
Prints the type of file (dir or file). This function is primarily
for testing.
## help
```
help [COMMAND]
```
List available commands with no arguments, or detailed help when
a command is provided.
## ls
```
usage: ls [-a] [-l] FILE...
List directory contents.
positional arguments:
FILE Files or directories to list
optional arguments:
-h, --help show this help message and exit
-a, --all do not ignore hidden files
-l, --long use a long listing format
```
## mkdir
```
mkdir DIRECTORY...
```
Creates one or more directories.
## repl
```
repl [board-name] [~ line][~]
```
Enters into the regular REPL with the MicroPython board.
Use Control-X to exit REPL mode and return the shell. It may take
a second or two before the REPL exits.
If you provide a board-name then rshell will connect to that board,
otherwise it will connect to the default board (first connected board).
If you provide a tilde followed by a space (~ ) then anything after the
tilde will be entered as if you typed it on the command line.
If you want the repl to exit, end the line with the ~ character.
For example, you could use:
```
rshell.py repl ~ pyb.bootloader()~
```
and it will boot the pyboard into DFU.
## rm
```
usage: rm [-r|--recursive][-f|--force] FILE...
Removes files or directories (directories must be empty).
positional arguments:
FILE File to remove
optional arguments:
-h, --help show this help message and exit
-r, --recursive remove directories and their contents recursively
-f, --force ignore nonexistant files and arguments
```

444
README.rst 100644
Wyświetl plik

@ -0,0 +1,444 @@
rshell.py
=========
Remote MicroPytyhon shell.
This is a simple shell which runs on the host and uses MicroPython's
raw-REPL to send python snippets to the pyboard in order to get
filesystem information, and to copy files to and from MicroPython's
filesystem.
It also has the ability to invoke the regular REPL, so rshell can be
used as a terminal emulator as well.
Note: With rshell you can disable USB Mass Storage and still copy files
into and out of your pyboard.
When using the commands, the /flash directory, and the /sdcard directory
(if an sdcard is inserted) are considered to be on the pyboard, and all
other directories are considered to be on the host.
NOTE: rshell requires a fairly recent version of the MicroPython
firmware, specifically one which contains the ubinascii.unhexlify
command which was added May 19, 2015 (v1.4.3-28-ga3a14b9 or newer).
If your verion of the firmware isn't new enough, then you'll see an
error message something like this:
::
>./rshell.py
rshell needs MicroPython firmware with ubinascii.unhexlify
Installation
============
You can install rshell using the command:
::
sudo pip3 install rshell
If you use a virtualenv, then you don't need the sudo. rshell needs Python3.
All of my testing was done using version 3.4.0.
Sample Session
==============
This shows a pyboard in its default state, copying a hello.py and then
entering the repl and importing it.
::
>rshell
Welcome to rshell. Use Control-D to exit.
/home/dhylands/Dropbox/micropython/rshell> ls -l /flash
529 May 21 17:34 README.txt
286 May 21 17:34 boot.py
34 May 21 17:34 main.py
2436 May 21 17:34 pybcdc.inf
/home/dhylands/Dropbox/micropython/rshell> cp hello.py /flash
/home/dhylands/Dropbox/micropython/rshell> ls -l /flash
529 May 21 17:34 README.txt
286 May 21 17:34 boot.py
21 May 21 17:35 hello.py
34 May 21 17:34 main.py
2436 May 21 17:34 pybcdc.inf
/home/dhylands/Dropbox/micropython/rshell> cat /flash/hello.py
print('Hello World')
/home/dhylands/Dropbox/micropython/rshell> repl
Entering REPL. Use Control-X to exit.
Micro Python v1.4.3-28-ga3a14b9 on 2015-05-21; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>>
>>> import hello
Hello World
>>>
/home/dhylands/Dropbox/micropython/rshell>
Command Line Options
====================
-h, --help
----------
Displays a lit of the valid options. You should get something like the
following displayed:
::
usage: rshell [options] [command]
Remote Shell for a MicroPython board.
positional arguments:
cmd Optional command to execute
optional arguments:
-h, --help show this help message and exit
-b BAUD, --baud BAUD Set the baudrate used (default = 115200)
--buffer-size BUFFER_SIZE
Set the buffer size used for transfers (default = 512)
-p PORT, --port PORT Set the serial port to use (default '/dev/ttyACM0')
-u USER, --user USER Set username to use (default 'micro')
-w PASSWORD, --password PASSWORD
Set password to use (default 'python')
-e EDITOR, --editor EDITOR
Set the editor to use (default 'vi')
-f FILENAME, --file FILENAME
Specifies a file of commands to process.
-d, --debug Enable debug features
-n, --nocolor Turn off colorized output
--nowait Don't wait for serial port
--timing Print timing information about each command
--quiet Turns off some output (useful for testing)
You can specify the default serial port using the RSHELL_PORT environment
variable.
-b BAUD, --baud BAUD
--------------------
Sets the baud rate to use when talking to the pyboard over a serial port. If
no baud is specified, then the baudrate from the RSHELL_BAUD enviroinment
variable is used. If the RSHELL_BAUD environment variable is not defined then
the default baudrate of 115200 is used.
--buffer-size
-------------
Sets the buffer size used when transferring files betweem the host and the
pyboard. If no buffer size is specified, then the value from the
RSHELL_BUFFER_SIZE environment variable is used. If the RSHELL_BUFFER_SIZE
environment variable is not defined, then the default of 512 is used.
-d, --debug
-----------
Turns on debugging. This allows you to see the script which is sent over
the raw REPL and the response received.
-e EDITOR, --editor
-------------------
Specifies the editor to use with the edit command. If no editor is specified,
then the following environment variables will be searched: RSHELL_EDITOR,
VISUAL, and EDITOR. If none of those environment variables is set then vi will
be used.
-f FILENAME, --file FILENAME
----------------------------
Specifies a file of rshell commands to process. This allows you to
create a script which executes any valid rshell commands.
-n, --nocolor
-------------
By default, rshell uses ANSI color escape codes when displaying the
prompt and ls output. This option allows colorized output to be
disabled.
--nowait
--------
If a port is specified, then rshell will wait for the serial port to exist
before continuing. With the --nowait option, rshell will not wait for the
serial port to exist.
-p PORT, --port PORT
--------------------
Specifies the serial port which should be used to talk to the
MicroPython board. You can set the RSHELL\_PORT environment variable to
specify the default port to be used, if --port is not specified on the
command line.
--quiet
-------
This option causes the Connecting messages printed when rshell starts to be
suppressed. This is mostly useful the test scripts.
--timing
--------
If the timing option is specified then rshell will print the amount of time
that each command takes to execute.
-u USER, --user USER
--------------------
Specifies the username to use when logging into a WiPy over telent. If no
username is specified, then the username from the RSHELL_USER environment
variable is used. If the RSHELL_USER environment variable doesn't exist
then the default username 'micro' is used.
-w PASSWORD, --password PASSWORD
--------------------------------
Specified the password to use when logging into a WiPy over telnet. If no
password is specified, then the password from the RSHELL_PASSWORD environment
variable is used. If the RSHELL_PASSWORD environment variable doesn't exist
then the default password 'python' is used.
cmd
---
If a command is specified, then that command will be executed and rshell will
exit. Examples:
::
rshell cp somefile.py /flash
rshell repl ~ pyb.bootloader() ~
File System
===========
rshell can be connected to multiple pyboards simultaneously. If the
board module exists on the pyboard (i.e. a file named board.py somewhere
in the module search path) and it contains an attribute called name then
the pyboard will use that name. If the board module can't be imported
then the board will be named, pyboard or wipy. Names will have -1 (or
some other number) to make the board name unique.
You can access the internal flash on the first board connected using
/flash and the sd card on the first board connected can be accessed
using /sd.
For all other connected pyboards, you can use /board-name/flash or
/board-name/sd (you can see the board names using the boards command).
The boards command will show all of the connected pyboards, along with all of
the directories which map onto that pyboard.
Commands
========
args
----
::
args [arguments...]
Debug function for verifying argument parsing. This function just prints
out each argument that it receives.
boards
------
::
boards
Lists all of the boards that rshell is currently connected to, their
names, and the connection.
cat
---
::
cat FILENAME...
Concatinates files and sends to stdout.
cd
--
::
cd DIRECTORY
Changes the current directory. ~ expansion is supported, and cd - goes
to the previous directory.
connect
-------
::
connect TYPE TYPE_PARAMS
connect serial port [baud]
connect telnet ip-address-or-name
Connects a pyboard to rshell. rshell can be connected to multiple
pyboards simultaneously.
cp
--
::
cp SOURCE DEST
cp SOURCE... DIRECTORY
Copies the SOURCE file to DEST. DEST may be a filename or a directory
name. If more than one source file is specified, then the destination
should be a directory.
echo
----
::
echo TEXT...
Display a line of text.
edit
----
::
edit filename
If the file is on a pyboard, it copies the file to host, invokes an
editor and if any changes were made to the file, it copies it back to
the pyboard.
The editor which is used defaults to vi, but can be overridem using
either the --editor command line option when rshell.py is invoked, or by
using the RSHELL\_EDITOR, VISUAL or EDITOR environment variables (they
are tried in the order listed).
filesize
--------
::
filesize FILE
Prints the size of the file, in bytes. This function is primarily
testing.
filetype
--------
::
filetype FILE
Prints the type of file (dir or file). This function is primarily for
testing.
help
----
::
help [COMMAND]
List available commands with no arguments, or detailed help when a
command is provided.
ls
--
::
usage: ls [-a] [-l] FILE...
List directory contents.
positional arguments:
FILE Files or directories to list
optional arguments:
-h, --help show this help message and exit
-a, --all do not ignore hidden files
-l, --long use a long listing format
mkdir
-----
::
mkdir DIRECTORY...
Creates one or more directories.
repl
----
::
repl [board-name] [~ line][ ~]
Enters into the regular REPL with the MicroPython board. Use Control-X
to exit REPL mode and return the shell. It may take a second or two
before the REPL exits.
If you provide a board-name then rshell will connect to that board,
otherwise it will connect to the default board (first connected board).
If you provide a tilde followed by a space (~ ) then anything after the
tilde will be entered as if you typed it on the command line.
If you want the repl to exit, end the line with the ~ character.
For example, you could use:
::
rshell.py repl ~ pyb.bootloader()~
and it will boot the pyboard into DFU.
rm
--
::
usage: rm [-r|--recursive][-f|--force] FILE...
Removes files or directories (directories must be empty).
positional arguments:
FILE File to remove
optional arguments:
-h, --help show this help message and exit
-r, --recursive remove directories and their contents recursively
-f, --force ignore nonexistant files and arguments
shell
-----
The shell command can also be abbreviated using the exclamation point.
::
shell some-command
!some-command
This will invoke a command, and return back to rshell. Example:
::
!make deploy
will flash the pyboard.

Wyświetl plik

Wyświetl plik

@ -0,0 +1,4 @@
import rshell.main
def main():
rshell.main.main()

Wyświetl plik

@ -11,14 +11,15 @@
# from __future__ import print_function
from rshell.getch import getch
from rshell.pyboard import Pyboard
import argparse
import binascii
import calendar
import cmd
from getch import getch
import inspect
import os
import pyboard
import select
import serial
import shutil
@ -75,6 +76,7 @@ HAS_BUFFER = False
IS_UPY = False
DEBUG = False
BUFFER_SIZE = 512
QUIET = False
SIX_MONTHS = 183 * 24 * 60 * 60
@ -980,17 +982,19 @@ def connect_telnet(name, ip_address=None, user='micro', password='python'):
ip_address = socket.gethostbyname(name)
except socket.gaierror:
ip_address = name
if name == ip_address:
print('Connecting to (%s) ...' % ip_address)
else:
print('Connecting to %s (%s) ...' % (name, ip_address))
if not QUIET:
if name == ip_address:
print('Connecting to (%s) ...' % ip_address)
else:
print('Connecting to %s (%s) ...' % (name, ip_address))
dev = DeviceNet(name, ip_address, user, password)
add_device(dev)
def connect_serial(port, baud=115200, wait=False):
"""Connect to a MicroPython board via a serial port."""
print('Connecting to %s ...' % port)
if not QUIET:
print('Connecting to %s ...' % port)
try:
dev = DeviceSerial(port, baud, wait)
except DeviceError as err:
@ -1168,7 +1172,7 @@ class DeviceSerial(Device):
self.dev_name_long = '%s at %d baud' % (port, baud)
try:
pyb = pyboard.Pyboard(port, baudrate=baud)
pyb = Pyboard(port, baudrate=baud)
except serial.serialutil.SerialException as err:
raise DeviceError(str(err))
@ -1225,7 +1229,7 @@ class DeviceNet(Device):
self.dev_name_long = self.dev_name_short
try:
pyb = pyboard.Pyboard(ip_address, user=user, password=password)
pyb = Pyboard(ip_address, user=user, password=password)
except (socket.timeout, OSError):
raise DeviceError('No response from {}'.format(ip_address))
except KeyboardInterrupt:
@ -1553,9 +1557,15 @@ class Shell(cmd.Cmd):
rows = []
with DEV_LOCK:
for dev in DEVS:
rows.append((dev.name, '@ %s' % dev.dev_name_short, dev.status()))
if dev is DEFAULT_DEV:
dirs = [dir[:-1] for dir in dev.root_dirs]
else:
dirs = []
dirs += ['/{}{}'.format(dev.name, dir)[:-1] for dir in dev.root_dirs]
dirs = 'Dirs: ' + ' '.join(dirs)
rows.append((dev.name, '@ %s' % dev.dev_name_short, dev.status(), dirs))
if rows:
column_print('<< ', rows, self.print)
column_print('<<< ', rows, self.print)
else:
print('No boards connected')
@ -2170,6 +2180,13 @@ def main():
help="Print timing information about each command",
default=False
)
parser.add_argument(
"--quiet",
dest="quiet",
action="store_true",
help="Turns off some output (useful for testing)",
default=False
)
parser.add_argument(
"cmd",
nargs=argparse.REMAINDER,
@ -2185,12 +2202,16 @@ def main():
print("Password = %s" % args.password)
print("Wait = %d" % args.wait)
print("Timing = %d" % args.timing)
print("Quiet = %d" % args.quiet)
print("Buffer_size = %d" % args.buffer_size)
print("Cmd = [%s]" % ', '.join(args.cmd))
global DEBUG
DEBUG = args.debug
global QUIET
QUIET = args.quiet
global EDITOR
EDITOR = args.editor
@ -2227,5 +2248,5 @@ def main():
shell = Shell(timing=args.timing)
shell.cmdloop(cmd_line)
main()
if __name__ == "__main__":
main()

2
setup.cfg 100644
Wyświetl plik

@ -0,0 +1,2 @@
[metadata]
description-file = README.md

41
setup.py 100644
Wyświetl plik

@ -0,0 +1,41 @@
import os
from setuptools import setup
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = f.read()
setup(
name = 'rshell',
version = '0.0.1',
author = 'Dave Hylands',
author_email = 'dhylands@gmail.com',
description = ('A remote shell for working with MicroPython boards.'),
license = 'MIT',
keywords = 'micropython shell',
url = 'https://github.com/dhylands/rshell',
download_url = 'https://github.com/dhylands/rshell/tarball/v0.0.1',
packages=['rshell', 'tests'],
long_description=long_description,
classifiers=[
'Development Status :: 3 - Alpha',
'Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Embedded Systems',
'Topic :: System :: Shells',
'Topic :: Terminals :: Serial',
'Topic :: Utilities',
],
install_requires=[
'pyserial',
'pyudev >= 0.16',
],
entry_points = {
'console_scripts': ['rshell=rshell.command_line:main'],
},
)

1
tests/hello.py 100644
Wyświetl plik

@ -0,0 +1 @@
print('Hello World')

Wyświetl plik

@ -1,12 +1,15 @@
#!/bin/bash
#set -x
# set -x
LOCAL_DIR='./rshell-test'
REMOTE_DIR='/flash/rshell-test'
RSHELL="$(pwd)/rshell.py"
MAKE_ALL_BYTES="$(pwd)/make_all_bytes.py"
RSHELL_DIR=rshell
TESTS_DIR=tests
RSHELL="$(pwd)/${RSHELL_DIR}/rshell.py --quiet"
MAKE_ALL_BYTES="$(pwd)/${TESTS_DIR}/make_all_bytes.py"
cmp_results() {
local file1=$1