Module lib.shell.shellcore
Class defining a minimalist shell, directly executable on the board. We modify directories, list, delete, move files, edit files … The commands are : - cd : change directory - pwd : current directory - cat : display the content of file - cls : clear screen - mkdir : create directory - mv : move file - rmdir : remove directory - cp : copy file - rm : remove file - ls : list file - ll : list file long - date : get the system date or synchronize with Ntp - setdate : set date and time - uptime : the amount of time system is running - find : find a file - run : execute python script - download : transfer files from device to computer (only available with camflasher) - upload : transfer files from computer to device (only available with camflasher) - edit : edit a text file - exit : exit of shell - gc : garbage collection - grep : grep text in many files - mount : mount sd card - umount : umount sd card - temperature : device temperature - meminfo : memory informations - flashinfo : flash informations - sysinfo : system informations - deepsleep : deepsleep of board - ping : ping host - reboot : reboot board - help : list all command available - man : manual of one command - df : display free disk space - ip2host : convert ip address in hostname - host2ip : convert hostname in ip address - eval : evaluation python string - exec : execute python string - dump : display hexadecimal dump of the content of file
Expand source code
# Distributed under Pycameresp License
# Copyright (c) 2023 Remi BERTHOLET
# pylint:disable=too-many-lines
# pylint:disable=consider-using-f-string
# pylint:disable=unspecified-encoding
""" Class defining a minimalist shell, directly executable on the board.
We modify directories, list, delete, move files, edit files ...
The commands are :
- cd : change directory
- pwd : current directory
- cat : display the content of file
- cls : clear screen
- mkdir : create directory
- mv : move file
- rmdir : remove directory
- cp : copy file
- rm : remove file
- ls : list file
- ll : list file long
- date : get the system date or synchronize with Ntp
- setdate : set date and time
- uptime : the amount of time system is running
- find : find a file
- run : execute python script
- download : transfer files from device to computer (only available with camflasher)
- upload : transfer files from computer to device (only available with camflasher)
- edit : edit a text file
- exit : exit of shell
- gc : garbage collection
- grep : grep text in many files
- mount : mount sd card
- umount : umount sd card
- temperature : device temperature
- meminfo : memory informations
- flashinfo : flash informations
- sysinfo : system informations
- deepsleep : deepsleep of board
- ping : ping host
- reboot : reboot board
- help : list all command available
- man : manual of one command
- df : display free disk space
- ip2host : convert ip address in hostname
- host2ip : convert hostname in ip address
- eval : evaluation python string
- exec : execute python string
- dump : display hexadecimal dump of the content of file
"""
# pylint:disable=wrong-import-position
import sys
sys.path.append("lib")
sys.path.append("simul")
import io
import os
import uos
import machine
from tools import useful,logger,sdcard,filesystem,exchange,info,strings,terminal,watchdog,lang,date
from tools.console import Console
shell_commands = None
def get_screen_size():
""" Return the screen size and check if output redirected """
# pylint:disable=global-variable-not-assigned
if Console.is_redirected() is False:
height, width = terminal.get_screen_size()
else:
height, width = terminal.MAXINT, 80
return height, width
def cd(directory = "/"):
""" Change directory """
try:
uos.chdir(filesystem.normpath(directory))
except:
if directory != ".":
Console.print("No such file or directory '%s'"%directory)
def pwd():
""" Display the current directory """
Console.print("%s"%uos.getcwd())
def mkdir(directory, recursive=False, quiet=False):
""" Make directory """
try:
if quiet is False:
Console.print("mkdir '%s'"%directory)
filesystem.makedir(filesystem.normpath(directory), recursive)
except:
Console.print("Cannot mkdir '%s'"%directory)
def removedir(directory, force=False, quiet=False, simulate=False, ignore_error=False):
""" Remove directory """
try:
if filesystem.exists(directory+"/.DS_Store"):
rmfile(directory+"/.DS_Store", quiet, force, simulate)
if (filesystem.ismicropython() or force) and simulate is False:
uos.rmdir(directory)
if quiet is False:
Console.print("rmdir '%s'"%(directory))
except:
if ignore_error is False:
Console.print("rmdir '%s' not removed"%(directory))
def rmdir(directory, recursive=False, force=False, quiet=False, simulate=False, ignore_error=False):
""" Remove directory """
directory = filesystem.normpath(directory)
if recursive is False:
removedir(directory, force=force, quiet=quiet, simulate=simulate, ignore_error=ignore_error)
else:
directories = [directory]
d = directory
while 1:
parts = filesystem.split(d)
if parts[1] == "" or parts[0] == "":
break
directories.append(parts[0])
d = parts[0]
if "/" in directories:
directories.remove("/")
if sdcard.SdCard.get_mountpoint() in directories:
directories.remove(sdcard.SdCard.get_mountpoint())
for d in directories:
if filesystem.exists(d) and d != ".":
removedir(d, force=force, quiet=quiet, simulate=simulate, ignore_error=ignore_error)
def mv(source, destination):
""" Move or rename file """
try:
uos.rename(filesystem.normpath(source),filesystem.normpath(destination))
except:
Console.print("Cannot mv '%s'->'%s'"%(source,destination))
def copyfile(src,dst,quiet):
""" Copy file """
dst = dst.replace("//","/")
dst = dst.replace("//","/")
dstdir, dstfile = filesystem.split(dst)
try:
if not filesystem.exists(dstdir):
if dstdir != "." and dstdir != "":
mkdir(dstdir, recursive=True, quiet=quiet)
src_file = open(src, 'rb')
dst_file = open(dst, 'wb')
if quiet is False:
Console.print("cp '%s' -> '%s'"%(src,dst))
while True:
buf = src_file.read(256)
if len(buf) > 0:
dst_file.write(buf)
if len(buf) < 256:
break
src_file.close()
dst_file.close()
except:
Console.print("Cannot cp '%s' -> '%s'"%(src, dst))
def cp(source, destination, recursive=False, quiet=False):
""" Copy file command """
source = filesystem.normpath(source)
destination = filesystem.normpath(destination)
if filesystem.isfile(source):
copyfile(source,destination,quiet)
else:
if filesystem.isdir(source):
path = source
pattern = "*"
else:
path, pattern = filesystem.split(source)
_, filenames = filesystem.scandir(path, pattern, recursive)
for src in filenames:
dst = destination + "/" + src[len(path):]
copyfile(src,dst,quiet)
def rmfile(filename, quiet=False, force=False, simulate=False):
""" Remove file """
try:
if (filesystem.ismicropython() or force) and simulate is False:
uos.remove(filesystem.normpath(filename))
if quiet is False:
Console.print("rm '%s'"%(filename))
except:
Console.print("rm '%s' not removed"%(filename))
def rm(file, recursive=False, quiet=False, force=False, simulate=False):
""" Remove file command """
file = filesystem.normpath(file)
filenames = []
directories = []
if filesystem.isfile(file):
path = file
rmfile(file, force=force, quiet=quiet, simulate=simulate)
else:
if filesystem.isdir(file):
if recursive:
directories.append(file)
path = file
pattern = "*"
else:
path = None
pattern = None
else:
path, pattern = filesystem.split(file)
if path is None:
Console.print("Cannot rm '%s'"%file)
else:
dirs, filenames = filesystem.scandir(path, pattern, recursive)
directories += dirs
for filename in filenames:
rmfile(filename, force=force, quiet=quiet, simulate=simulate)
if recursive:
directories.sort()
directories.reverse()
for directory in directories:
rmdir(directory, recursive=recursive, force=force, quiet=quiet, simulate=simulate, ignore_error=True)
class LsDisplayer:
""" Ls displayer class """
def __init__(self, path, showdir, long):
""" Constructor """
self.height, self.width = get_screen_size()
self.count = 1
self.long = long
self.path = path
self.showdir = showdir
def purge_path(self, path):
""" Purge the path for the display """
path = path.encode("utf8")
path = filesystem.normpath(path)
prefix = filesystem.prefix([path, self.path.encode("utf8")])
return path[len(prefix):].lstrip(b"/")
def show(self, path):
""" Show the information of a file or directory """
fileinfo = filesystem.fileinfo(path)
file_date = fileinfo[8]
size = fileinfo[6]
# If directory
if fileinfo[0] & 0x4000 == 0x4000:
if self.showdir:
if self.long:
message = b"%s %s [%s]"%(date.date_to_bytes(file_date),b" "*7,self.purge_path(path))
else:
message = b"[%s]"%self.purge_path(path)
self.count = print_part(message, self.width, self.height, self.count)
else:
if self.long:
fileinfo = filesystem.fileinfo(path)
file_date = fileinfo[8]
size = fileinfo[6]
message = b"%s %s %s"%(date.date_to_bytes(file_date),strings.size_to_bytes(size),self.purge_path(path))
else:
message = self.purge_path(path)
self.count = print_part(message, self.width, self.height, self.count)
def show_dir(self, state):
""" Indicates if the directory must show """
self.showdir = state
def ls(file="", recursive=False, long=False):
""" List files command """
searchfile(file, recursive, LsDisplayer(uos.getcwd(), True, long))
def ll(file="", recursive=False):
""" List files long command """
searchfile(file, recursive, LsDisplayer(uos.getcwd(), True, True))
def searchfile(file, recursive, obj = None):
""" Search file """
file = filesystem.normpath(file)
p = filesystem.abspath(uos.getcwd(), file)
filenames = []
try:
if file == "":
_,filenames = filesystem.scandir(uos.getcwd(), "*", recursive, obj)
elif filesystem.isfile(p):
if obj is not None:
obj.show_dir(False)
obj.show(p)
filenames = [p]
elif filesystem.isdir(p):
_, filenames = filesystem.scandir(p, "*", recursive, obj)
else:
path, pattern = filesystem.split(p)
if obj is not None:
obj.show_dir(False)
_, filenames = filesystem.scandir(path, pattern, recursive, obj)
except Exception as err:
Console.print(err)
if len(filenames) == 0 and file != "" and file != ".":
Console.print("%s : No such file or directory"%file)
return filenames
def find(file):
""" Find a file in directories """
filenames = searchfile(file, True)
for filename in filenames:
Console.print(filename)
def print_part(message, width, height, count):
""" Print a part of text """
# pylint:disable=global-variable-not-assigned
if isinstance(message , bytes):
message = message.decode("utf8")
if count is not None and count >= height:
Console.print(message,end="")
if Console.is_redirected() is False:
key = terminal.getch()
else:
key = " "
count = 1
if key in ["x","X","q","Q","\x1B"]:
return None
Console.print("\n", end="")
else:
if count is None:
count = 1
else:
count += 1
Console.print(message)
return count
def grep(file, text, recursive=False, ignorecase=False, regexp=False):
""" Grep command """
from re import search
file = filesystem.normpath(file)
def __search(text, content, ignorecase, regexp):
if ignorecase:
content = content.lower()
text = text.lower()
if regexp:
if search(text, content):
return True
else:
if content.find(text) != -1:
return True
return False
def __grep(text, filename, ignorecase, regexp, width, height, count):
lineNumber = 1
with open(filename,"r", encoding="latin-1") as f:
while 1:
line = f.readline()
if line:
if __search(text, line, ignorecase, regexp):
line = line.replace("\t"," ")
message = "%s:%d:%s"%(filename, lineNumber, line)
message = message.rstrip()[:width]
count = print_part(message, width, height, count)
if count is None:
Console.print("")
return None
lineNumber += 1
else:
break
return count
if filesystem.isfile(file):
filenames = [file]
else:
path, pattern = filesystem.split(file)
_, filenames = filesystem.scandir(path, pattern, recursive)
height, width = get_screen_size()
count = 1
for filename in filenames:
count = __grep(text, filename, ignorecase, regexp, width, height, count)
if count is None:
break
def ping(host):
""" Ping host """
try:
from server.ping import ping as ping_
ping_(host, count=4, timeout=1)
except:
Console.print("Not available")
def ip2host(ip_address):
""" Convert ip to hostname """
try:
import wifi
_, _, _, dns = wifi.Station.get_info()
from server.dnsclient import resolve_hostname
Console.print(resolve_hostname(dns, ip_address))
except:
Console.print("Not available")
def host2ip(hostname):
""" Convert hostname to ip """
try:
import wifi
_, _, _, dns = wifi.Station.get_info()
from server.dnsclient import resolve_ip_address
Console.print(resolve_ip_address(dns, hostname))
except:
Console.print("Not available")
def mountsd(mountpoint="/sd"):
""" Mount command """
try:
sdcard.SdCard.mount(mountpoint)
Console.print("Sd mounted on '%s'"%mountpoint)
except:
Console.print("Cannot mount sd on '%s'"%mountpoint)
def umountsd(mountpoint="/sd"):
""" Umount command """
try:
sdcard.SdCard.umount(mountpoint)
Console.print("Sd umounted from '%s'"%mountpoint)
except:
Console.print("Cannot umount sd from '%s'"%mountpoint)
def date_time(update=False, offsetUTC=+1, noDst=False):
""" Get or set date """
try:
from server.timesetting import set_date
if update:
if noDst:
dst = False
else:
dst = True
set_date(offsetUTC, dst)
del sys.modules["server.timesetting"]
except:
pass
Console.print(date.date_to_string())
def setdate(datetime=""):
""" Set date and time """
import re
file_date=re.compile("[/: ]")
failed = False
try:
spls = file_date.split(datetime)
lst = []
if len(spls) > 1:
for spl in spls:
if len(spl) > 0:
try:
r = spl.lstrip("0")
if len(r) == 0:
lst.append(0)
else:
lst.append(eval(r))
except:
failed = True
break
if len(lst) == 6:
# pylint: disable=unbalanced-tuple-unpacking
year,month,day,hour,minute,second = lst
machine.RTC().datetime((year, month, day, 0, hour, minute, second, 0))
else:
failed = True
else:
failed = True
except Exception as err:
failed = True
logger.syslog(err)
if failed is True:
Console.print('Expected format "YYYY/MM/DD hh:mm:ss"')
def formatsd(fstype="FAT"):
""" Format sd card """
if fstype in ["FAT","LFS"]:
if sdcard.SdCard.is_mounted() is False:
res = input("All data will be lost on Sd card ? proceed with format (y/n) :")
if res in ["y","Y"]:
if sdcard.SdCard.formatsd() is True:
Console.print("Formatting terminated")
else:
Console.print("Formatting failed")
else:
Console.print("Sd card is mounted, a reboot required")
else:
Console.print("Filesystem supported : FAT or LFS")
def reboot():
""" Reboot command """
try:
from tools import system
system.reboot("Reboot device with command")
except:
machine.deepsleep(1000)
def deepsleep(seconds=60):
""" Deep sleep command """
machine.deepsleep(int(seconds)*1000)
def ligthsleep(seconds=60):
""" Light sleep command """
machine.lightsleep(int(seconds)*1000)
edit_class = None
def edit(file, no_color=False, read_only=False):
""" Edit command """
# pylint:disable=global-variable-not-assigned
global edit_class
if Console.is_redirected() is False:
if edit_class is None:
try:
from shell.editor import Editor
except:
from editor import Editor
edit_class = Editor
edit_class(file, no_color=no_color, read_only=read_only)
def cat(file):
""" Cat command """
try:
f = open(file, "r")
height, width = get_screen_size()
count = 1
while 1:
line = f.readline()
if not line:
break
message = line.replace("\t"," ").rstrip()[:width]
count = print_part(message, width, height, count)
if count is None:
break
f.close()
except:
Console.print("Cannot cat '%s'"%(file))
def df(mountpoint = None):
""" Display free disk space """
Console.print(strings.tostrings(info.flashinfo(mountpoint=mountpoint)))
def gc():
""" Garbage collector command """
from gc import collect
collect()
def uptime():
""" Tell how long the system has been running """
Console.print(strings.tostrings(info.uptime()))
def man(command):
""" Man command """
Console.print(man_one(command))
def man_one(command_name):
""" Manual of one command """
try:
command_name, command_function, command_params, command_flags = get_command(command_name)
text = " " + command_name + " "
for param in command_params:
text += param + " "
text += "\n"
for flag,flagName,val in command_flags:
text += " %s : %s\n"%(flag,flagName)
result = text[:-1]
except:
result = "Unknown command '%s'"%command_name
return result
# pylint: disable=redefined-builtin
def help():
""" Help command """
height, width = get_screen_size()
count = 1
cmds = list(shell_commands.keys())
cmds.sort()
for command in cmds:
lines = man_one(command)
lines = "-"*30+"\n" + lines
for line in lines.split("\n"):
count = print_part(line, width, height, count)
if count is None:
return
def eval_(string):
""" Evaluate content of string """
Console.print(eval(string))
def exec_(string):
""" Execute content of string """
exec(string)
shell_exited = False
def exit():
""" Exit shell command """
global shell_exited
shell_exited = True
def dump_(filename):
""" dump file content """
height, width = get_screen_size()
if Console.is_redirected() is False:
width = (width - 12)//4
else:
width = 16
offset = 0
file = open(filename, "rb")
data = b' '
count = 1
while True:
line = io.BytesIO()
line.write(b'%08X ' % offset)
data = file.read(width)
if len(data) <= 0:
break
strings.dump_line (data, line, width)
offset += width
count = print_part(line.getvalue(), width, height, count)
if count is None:
break
def cls():
""" clear screen """
Console.print("\x1B[2J\x1B[0;0f", end="")
def check_cam_flasher():
""" Check if the terminal is CamFlasher """
# pylint:disable=global-variable-not-assigned
if Console.is_redirected() is False:
# Request terminal device attribut
sys.stdout.write(b"\x1B[0c")
# Wait terminal device attribut response
response = terminal.getch(duration=1000)
# If CamFlasher detected
if response == "\x1B[?3;2c":
return True
return False
def upload(file="", recursive=False):
""" Upload file from computer to device """
if check_cam_flasher():
Console.print("Upload to device start")
try:
command = exchange.UploadCommand(uos.getcwd())
command.write(file, recursive, sys.stdin.buffer, sys.stdout.buffer)
result = True
while result:
file_reader = exchange.FileReader()
result = file_reader.read(uos.getcwd(), sys.stdin.buffer, sys.stdout.buffer)
watchdog.WatchDog.feed()
Console.print("Upload end")
except Exception as err:
logger.syslog(err, display=False)
Console.print("Upload failed")
else:
Console.print("CamFlasher application required for this command")
class Exporter:
""" Exporter file to camflasher """
def __init__(self):
""" Constructor """
def send_file(self, path):
""" Send the file """
result = True
fileinfo = filesystem.fileinfo(path)
# If a file
if fileinfo[0] & 0x4000 != 0x4000:
file_write = exchange.FileWriter()
if filesystem.exists(path):
sys.stdout.buffer.write("࿊".encode("utf8"))
result = file_write.write(path, sys.stdin.buffer, sys.stdout.buffer)
watchdog.WatchDog.feed()
return result
def show(self, path):
""" Show the information of a file or directory """
for _ in range(3):
# If the send successful exit, else retry three time
if self.send_file(path) is True:
break
def show_dir(self, state):
""" Indicates if the directory must show """
def download(file="", recursive=False):
""" Download file from device to computer """
if check_cam_flasher():
Console.print("Download from device start")
try:
searchfile(file, recursive, Exporter())
Console.print ("Download end")
except Exception as err:
logger.syslog(err, display=False)
Console.print("Download failed")
else:
Console.print("CamFlasher application required for this command")
def temperature():
""" Get the internal temperature """
celcius, farenheit = info.temperature()
Console.print("%.2f°C, %d°F"%(celcius, farenheit))
def meminfo():
""" Get memory informations """
Console.print(strings.tostrings(b"%s : %s"%(lang.memory_label, info.meminfo())))
def flashinfo(mountpoint=None):
""" Get flash informations """
Console.print(strings.tostrings(b"%s : %s"%(lang.flash_info, info.flashinfo(mountpoint=mountpoint))))
def sysinfo():
""" Get system informations """
Console.print(strings.tostrings(info.sysinfo()))
def vtcolors():
""" Show all VT100 colors """
res = b'\x1B[4m4 bits colors\x1B[m\n'
for i in range(16):
if i % 8 == 0:
res += b"\n "
if i < 9:
forecolor = 15
else:
forecolor = 0
res += b"\x1B[38;5;%dm\x1B[48;5;%dm %2d \x1B[0m"%(forecolor, i,i)
res += b'\n\n\x1B[4m8 bits colors\x1B[m\n'
j = 0
for i in range(16,256):
if j % 12== 0:
res += b"\n "
backcolor = i
if j % 36 < 36//2:
forecolor = 15
else:
forecolor = 0
res += b"\x1B[38;5;%dm\x1B[48;5;%dm %3d \x1B[0m"%(forecolor,backcolor,i)
j += 1
res += b'\n\n\x1B[4mModifiers\x1B[m\n\n'
for i,j in [(0,"reset/normal"),(1,b"bold"),(3,b"italic"),(4,b"underline"),(7,b"reverse")]:
res += b" %d : \x1B[%dm%s\x1B[0m\n"%(i,i,j)
res += b'\n\x1B[4mExamples\x1B[m\n\n'
res += b' >>> print("\\033[\033[1m1\033[m;\033[7m7\033[mmBold reverse\\033[0m")\n'
res += b" \033[1;7mBold reverse\033[0m"
res += b"\n\n"
res += b' >>> print("\033[38;5;15m\033[48;5;1m\\033[48;5;1m\033[m\033[38;5;13m\\033[38;5;13m\033[mHello\\033[m")\n'
res += b" \033[48;5;1m\033[38;5;13mHello\033[m\n"
Console.print(res.decode("utf8"))
def get_command(command_name):
""" Get a command callback according to the command name """
try:
# pylint:disable=global-variable-not-assigned
global shell_commands
command = shell_commands[command_name]
command_function = command[0]
command_params = []
command_flags = []
for item in command[1:]:
if type(item) == type(""):
command_params.append(item)
if type(item) == type((0,)):
command_flags.append(item)
except Exception as err:
# pylint: disable=raise-missing-from
raise RuntimeError("Command not found '%s'"%command_name)
return command_name, command_function, command_params, command_flags
def exec_command(args):
""" Execute command """
# pylint:disable=global-variable-not-assigned
command_name = ""
command_function = None
command_params = []
command_flags = []
output_redirection = None
output_filename = None
try:
if len(args) >= 1:
paramsCount = 0
flags = {}
for arg in args:
arg = arg.strip()
if len(arg) > 0:
if command_name == "":
command_name, command_function, command_params, command_flags = get_command(arg)
else:
if len(arg) >= 2 and arg[:2] == "--":
for commandFlag in command_flags:
if arg.strip()[2:] == commandFlag[1].strip():
flags[commandFlag[1]] = commandFlag[2]
break
else:
raise RuntimeError("Illegal option '%s'"%arg)
elif arg[0] == "-":
for commandFlag in command_flags:
if arg.strip() == commandFlag[0].strip():
flags[commandFlag[1]] = commandFlag[2]
break
else:
raise RuntimeError("Illegal option '%s'"%arg)
elif arg[0] == ">":
output_redirection = True
else:
if output_redirection is None:
if paramsCount >= len(command_params):
raise RuntimeError("Too many parameters on '%s'"%command_name)
else:
flags[command_params[paramsCount]] = arg
paramsCount += 1
elif output_redirection is True:
output_filename = arg
except Exception as err:
Console.print(err)
return
Console.close()
try:
if command_name.strip() != "":
if output_filename is not None:
try:
Console.open(output_filename)
except:
pass
command_function(**flags)
except TypeError as err:
logger.syslog(err, display=False)
Console.print("Missing parameters for '%s'"%command_name)
except KeyboardInterrupt as err:
logger.syslog(err)
Console.print(" [Canceled]")
except Exception as err:
logger.syslog(err)
finally:
Console.close()
def parse_command_line(commandLine):
""" Parse command line """
commands = []
args = []
quote = None
arg = ""
for char in commandLine:
if char == '"' or char == "'":
if quote is not None:
if quote == char:
args.append(arg)
arg = ""
quote = None
else:
arg += char
else:
quote = char
elif char == " ":
if quote is not None:
arg += char
else:
args.append(arg)
arg = ""
elif char == ";":
if quote is not None:
arg += char
else:
if len(arg) > 0:
args.append(arg)
commands.append(args)
arg = ""
args = []
else:
arg += char
if len(arg) > 0:
args.append(arg)
if len(args) > 0:
commands.append(args)
for command in commands:
exec_command(command)
def shell_sh(path=None, throw=False):
""" Start the shell """
global shell_exited, shell_commands
current_dir = uos.getcwd()
create_shell_commands()
if path is not None:
uos.chdir(path)
shell_exited = False
while shell_exited is False:
try:
commandLine = ""
commandLine = input("%s=> "%os.getcwd())
watchdog.WatchDog.feed()
except EOFError:
Console.print("")
break
except KeyboardInterrupt:
Console.print("Ctr-C detected, use 'exit' to restart server or 'quit' to get python prompt")
if commandLine.strip() == "quit":
if throw is True:
raise KeyboardInterrupt()
else:
break
parse_command_line(commandLine)
shell_commands = None
uos.chdir(current_dir)
def create_shell_commands():
""" Return the shell commands """
global shell_commands
shell_commands = \
{
"cd" :[cd ,"directory" ],
"pwd" :[pwd ],
"cat" :[cat ,"file" ],
"cls" :[cls ],
"mkdir" :[mkdir ,"directory", ("-r","recursive",True)],
"mv" :[mv ,"source","destination" ],
"rmdir" :[rmdir ,"directory", ("-r","recursive",True),("-f","force",True),("-q","quiet",True),("-s","simulate",True)],
"cp" :[cp ,"source","destination", ("-r","recursive",True),("-q","quiet",True)],
"rm" :[rm ,"file", ("-r","recursive",True),("-f","force",True),("-s","simulate",True)],
"ls" :[ls ,"file", ("-r","recursive",True),("-l","long",True)],
"ll" :[ll ,"file", ("-r","recursive",True)],
"date" :[date_time ,"offsetUTC" , ("-u","update",True), ("-n","noDst",True)],
"setdate" :[setdate ,"datetime" ],
"uptime" :[uptime ],
"find" :[find ,"file" ],
"run" :[useful.run ,"filename" ],
"download" :[download ,"file", ("-r","recursive",True)],
"upload" :[upload ,"file", ("-r","recursive",True)],
"edit" :[edit ,"file", ("-n","no_color",True),("-r","read_only",True)],
"exit" :[exit ],
"gc" :[gc ],
"grep" :[grep ,"text","file", ("-r","recursive",True),("-i","ignorecase",True),("-e","regexp",True)],
"mount" :[mountsd ,"mountpoint" ],
"umount" :[umountsd ,"mountpoint" ],
"temperature":[temperature ],
"meminfo" :[meminfo ],
"flashinfo" :[flashinfo ],
"sysinfo" :[sysinfo ],
"deepsleep" :[deepsleep ,"seconds" ],
"lightsleep" :[ligthsleep ,"seconds" ],
"ping" :[ping ,"host" ],
"reboot" :[reboot ],
"help" :[help ],
"man" :[man ,"command" ],
"memdump" :[info.memdump ],
"df" :[df ,"mountpoint" ],
"ip2host" :[ip2host ,"ip_address" ],
"host2ip" :[host2ip ,"hostname" ],
"eval" :[eval_ ,"string" ],
"exec" :[exec_ ,"string" ],
"dump" :[dump_ ,"filename" ],
"formatsd" :[formatsd ,"fstype" ],
"vtcolors" :[vtcolors ],
}
if __name__ == "__main__":
sh(sys.argv[1])
Functions
def cat(file)-
Cat command
Expand source code
def cat(file): """ Cat command """ try: f = open(file, "r") height, width = get_screen_size() count = 1 while 1: line = f.readline() if not line: break message = line.replace("\t"," ").rstrip()[:width] count = print_part(message, width, height, count) if count is None: break f.close() except: Console.print("Cannot cat '%s'"%(file)) def cd(directory='/')-
Change directory
Expand source code
def cd(directory = "/"): """ Change directory """ try: uos.chdir(filesystem.normpath(directory)) except: if directory != ".": Console.print("No such file or directory '%s'"%directory) def check_cam_flasher()-
Check if the terminal is CamFlasher
Expand source code
def check_cam_flasher(): """ Check if the terminal is CamFlasher """ # pylint:disable=global-variable-not-assigned if Console.is_redirected() is False: # Request terminal device attribut sys.stdout.write(b"\x1B[0c") # Wait terminal device attribut response response = terminal.getch(duration=1000) # If CamFlasher detected if response == "\x1B[?3;2c": return True return False def cls()-
clear screen
Expand source code
def cls(): """ clear screen """ Console.print("\x1B[2J\x1B[0;0f", end="") def copyfile(src, dst, quiet)-
Copy file
Expand source code
def copyfile(src,dst,quiet): """ Copy file """ dst = dst.replace("//","/") dst = dst.replace("//","/") dstdir, dstfile = filesystem.split(dst) try: if not filesystem.exists(dstdir): if dstdir != "." and dstdir != "": mkdir(dstdir, recursive=True, quiet=quiet) src_file = open(src, 'rb') dst_file = open(dst, 'wb') if quiet is False: Console.print("cp '%s' -> '%s'"%(src,dst)) while True: buf = src_file.read(256) if len(buf) > 0: dst_file.write(buf) if len(buf) < 256: break src_file.close() dst_file.close() except: Console.print("Cannot cp '%s' -> '%s'"%(src, dst)) def cp(source, destination, recursive=False, quiet=False)-
Copy file command
Expand source code
def cp(source, destination, recursive=False, quiet=False): """ Copy file command """ source = filesystem.normpath(source) destination = filesystem.normpath(destination) if filesystem.isfile(source): copyfile(source,destination,quiet) else: if filesystem.isdir(source): path = source pattern = "*" else: path, pattern = filesystem.split(source) _, filenames = filesystem.scandir(path, pattern, recursive) for src in filenames: dst = destination + "/" + src[len(path):] copyfile(src,dst,quiet) def create_shell_commands()-
Return the shell commands
Expand source code
def create_shell_commands(): """ Return the shell commands """ global shell_commands shell_commands = \ { "cd" :[cd ,"directory" ], "pwd" :[pwd ], "cat" :[cat ,"file" ], "cls" :[cls ], "mkdir" :[mkdir ,"directory", ("-r","recursive",True)], "mv" :[mv ,"source","destination" ], "rmdir" :[rmdir ,"directory", ("-r","recursive",True),("-f","force",True),("-q","quiet",True),("-s","simulate",True)], "cp" :[cp ,"source","destination", ("-r","recursive",True),("-q","quiet",True)], "rm" :[rm ,"file", ("-r","recursive",True),("-f","force",True),("-s","simulate",True)], "ls" :[ls ,"file", ("-r","recursive",True),("-l","long",True)], "ll" :[ll ,"file", ("-r","recursive",True)], "date" :[date_time ,"offsetUTC" , ("-u","update",True), ("-n","noDst",True)], "setdate" :[setdate ,"datetime" ], "uptime" :[uptime ], "find" :[find ,"file" ], "run" :[useful.run ,"filename" ], "download" :[download ,"file", ("-r","recursive",True)], "upload" :[upload ,"file", ("-r","recursive",True)], "edit" :[edit ,"file", ("-n","no_color",True),("-r","read_only",True)], "exit" :[exit ], "gc" :[gc ], "grep" :[grep ,"text","file", ("-r","recursive",True),("-i","ignorecase",True),("-e","regexp",True)], "mount" :[mountsd ,"mountpoint" ], "umount" :[umountsd ,"mountpoint" ], "temperature":[temperature ], "meminfo" :[meminfo ], "flashinfo" :[flashinfo ], "sysinfo" :[sysinfo ], "deepsleep" :[deepsleep ,"seconds" ], "lightsleep" :[ligthsleep ,"seconds" ], "ping" :[ping ,"host" ], "reboot" :[reboot ], "help" :[help ], "man" :[man ,"command" ], "memdump" :[info.memdump ], "df" :[df ,"mountpoint" ], "ip2host" :[ip2host ,"ip_address" ], "host2ip" :[host2ip ,"hostname" ], "eval" :[eval_ ,"string" ], "exec" :[exec_ ,"string" ], "dump" :[dump_ ,"filename" ], "formatsd" :[formatsd ,"fstype" ], "vtcolors" :[vtcolors ], } def date_time(update=False, offsetUTC=1, noDst=False)-
Get or set date
Expand source code
def date_time(update=False, offsetUTC=+1, noDst=False): """ Get or set date """ try: from server.timesetting import set_date if update: if noDst: dst = False else: dst = True set_date(offsetUTC, dst) del sys.modules["server.timesetting"] except: pass Console.print(date.date_to_string()) def deepsleep(seconds=60)-
Deep sleep command
Expand source code
def deepsleep(seconds=60): """ Deep sleep command """ machine.deepsleep(int(seconds)*1000) def df(mountpoint=None)-
Display free disk space
Expand source code
def df(mountpoint = None): """ Display free disk space """ Console.print(strings.tostrings(info.flashinfo(mountpoint=mountpoint))) def download(file='', recursive=False)-
Download file from device to computer
Expand source code
def download(file="", recursive=False): """ Download file from device to computer """ if check_cam_flasher(): Console.print("Download from device start") try: searchfile(file, recursive, Exporter()) Console.print ("Download end") except Exception as err: logger.syslog(err, display=False) Console.print("Download failed") else: Console.print("CamFlasher application required for this command") def dump_(filename)-
dump file content
Expand source code
def dump_(filename): """ dump file content """ height, width = get_screen_size() if Console.is_redirected() is False: width = (width - 12)//4 else: width = 16 offset = 0 file = open(filename, "rb") data = b' ' count = 1 while True: line = io.BytesIO() line.write(b'%08X ' % offset) data = file.read(width) if len(data) <= 0: break strings.dump_line (data, line, width) offset += width count = print_part(line.getvalue(), width, height, count) if count is None: break def edit(file, no_color=False, read_only=False)-
Edit command
Expand source code
def edit(file, no_color=False, read_only=False): """ Edit command """ # pylint:disable=global-variable-not-assigned global edit_class if Console.is_redirected() is False: if edit_class is None: try: from shell.editor import Editor except: from editor import Editor edit_class = Editor edit_class(file, no_color=no_color, read_only=read_only) def eval_(string)-
Evaluate content of string
Expand source code
def eval_(string): """ Evaluate content of string """ Console.print(eval(string)) def exec_(string)-
Execute content of string
Expand source code
def exec_(string): """ Execute content of string """ exec(string) def exec_command(args)-
Execute command
Expand source code
def exec_command(args): """ Execute command """ # pylint:disable=global-variable-not-assigned command_name = "" command_function = None command_params = [] command_flags = [] output_redirection = None output_filename = None try: if len(args) >= 1: paramsCount = 0 flags = {} for arg in args: arg = arg.strip() if len(arg) > 0: if command_name == "": command_name, command_function, command_params, command_flags = get_command(arg) else: if len(arg) >= 2 and arg[:2] == "--": for commandFlag in command_flags: if arg.strip()[2:] == commandFlag[1].strip(): flags[commandFlag[1]] = commandFlag[2] break else: raise RuntimeError("Illegal option '%s'"%arg) elif arg[0] == "-": for commandFlag in command_flags: if arg.strip() == commandFlag[0].strip(): flags[commandFlag[1]] = commandFlag[2] break else: raise RuntimeError("Illegal option '%s'"%arg) elif arg[0] == ">": output_redirection = True else: if output_redirection is None: if paramsCount >= len(command_params): raise RuntimeError("Too many parameters on '%s'"%command_name) else: flags[command_params[paramsCount]] = arg paramsCount += 1 elif output_redirection is True: output_filename = arg except Exception as err: Console.print(err) return Console.close() try: if command_name.strip() != "": if output_filename is not None: try: Console.open(output_filename) except: pass command_function(**flags) except TypeError as err: logger.syslog(err, display=False) Console.print("Missing parameters for '%s'"%command_name) except KeyboardInterrupt as err: logger.syslog(err) Console.print(" [Canceled]") except Exception as err: logger.syslog(err) finally: Console.close() def exit()-
Exit shell command
Expand source code
def exit(): """ Exit shell command """ global shell_exited shell_exited = True def find(file)-
Find a file in directories
Expand source code
def find(file): """ Find a file in directories """ filenames = searchfile(file, True) for filename in filenames: Console.print(filename) def flashinfo(mountpoint=None)-
Get flash informations
Expand source code
def flashinfo(mountpoint=None): """ Get flash informations """ Console.print(strings.tostrings(b"%s : %s"%(lang.flash_info, info.flashinfo(mountpoint=mountpoint)))) def formatsd(fstype='FAT')-
Format sd card
Expand source code
def formatsd(fstype="FAT"): """ Format sd card """ if fstype in ["FAT","LFS"]: if sdcard.SdCard.is_mounted() is False: res = input("All data will be lost on Sd card ? proceed with format (y/n) :") if res in ["y","Y"]: if sdcard.SdCard.formatsd() is True: Console.print("Formatting terminated") else: Console.print("Formatting failed") else: Console.print("Sd card is mounted, a reboot required") else: Console.print("Filesystem supported : FAT or LFS") def gc()-
Garbage collector command
Expand source code
def gc(): """ Garbage collector command """ from gc import collect collect() def get_command(command_name)-
Get a command callback according to the command name
Expand source code
def get_command(command_name): """ Get a command callback according to the command name """ try: # pylint:disable=global-variable-not-assigned global shell_commands command = shell_commands[command_name] command_function = command[0] command_params = [] command_flags = [] for item in command[1:]: if type(item) == type(""): command_params.append(item) if type(item) == type((0,)): command_flags.append(item) except Exception as err: # pylint: disable=raise-missing-from raise RuntimeError("Command not found '%s'"%command_name) return command_name, command_function, command_params, command_flags def get_screen_size()-
Return the screen size and check if output redirected
Expand source code
def get_screen_size(): """ Return the screen size and check if output redirected """ # pylint:disable=global-variable-not-assigned if Console.is_redirected() is False: height, width = terminal.get_screen_size() else: height, width = terminal.MAXINT, 80 return height, width def grep(file, text, recursive=False, ignorecase=False, regexp=False)-
Grep command
Expand source code
def grep(file, text, recursive=False, ignorecase=False, regexp=False): """ Grep command """ from re import search file = filesystem.normpath(file) def __search(text, content, ignorecase, regexp): if ignorecase: content = content.lower() text = text.lower() if regexp: if search(text, content): return True else: if content.find(text) != -1: return True return False def __grep(text, filename, ignorecase, regexp, width, height, count): lineNumber = 1 with open(filename,"r", encoding="latin-1") as f: while 1: line = f.readline() if line: if __search(text, line, ignorecase, regexp): line = line.replace("\t"," ") message = "%s:%d:%s"%(filename, lineNumber, line) message = message.rstrip()[:width] count = print_part(message, width, height, count) if count is None: Console.print("") return None lineNumber += 1 else: break return count if filesystem.isfile(file): filenames = [file] else: path, pattern = filesystem.split(file) _, filenames = filesystem.scandir(path, pattern, recursive) height, width = get_screen_size() count = 1 for filename in filenames: count = __grep(text, filename, ignorecase, regexp, width, height, count) if count is None: break def help()-
Help command
Expand source code
def help(): """ Help command """ height, width = get_screen_size() count = 1 cmds = list(shell_commands.keys()) cmds.sort() for command in cmds: lines = man_one(command) lines = "-"*30+"\n" + lines for line in lines.split("\n"): count = print_part(line, width, height, count) if count is None: return def host2ip(hostname)-
Convert hostname to ip
Expand source code
def host2ip(hostname): """ Convert hostname to ip """ try: import wifi _, _, _, dns = wifi.Station.get_info() from server.dnsclient import resolve_ip_address Console.print(resolve_ip_address(dns, hostname)) except: Console.print("Not available") def ip2host(ip_address)-
Convert ip to hostname
Expand source code
def ip2host(ip_address): """ Convert ip to hostname """ try: import wifi _, _, _, dns = wifi.Station.get_info() from server.dnsclient import resolve_hostname Console.print(resolve_hostname(dns, ip_address)) except: Console.print("Not available") def ligthsleep(seconds=60)-
Light sleep command
Expand source code
def ligthsleep(seconds=60): """ Light sleep command """ machine.lightsleep(int(seconds)*1000) def ll(file='', recursive=False)-
List files long command
Expand source code
def ll(file="", recursive=False): """ List files long command """ searchfile(file, recursive, LsDisplayer(uos.getcwd(), True, True)) def ls(file='', recursive=False, long=False)-
List files command
Expand source code
def ls(file="", recursive=False, long=False): """ List files command """ searchfile(file, recursive, LsDisplayer(uos.getcwd(), True, long)) def man(command)-
Man command
Expand source code
def man(command): """ Man command """ Console.print(man_one(command)) def man_one(command_name)-
Manual of one command
Expand source code
def man_one(command_name): """ Manual of one command """ try: command_name, command_function, command_params, command_flags = get_command(command_name) text = " " + command_name + " " for param in command_params: text += param + " " text += "\n" for flag,flagName,val in command_flags: text += " %s : %s\n"%(flag,flagName) result = text[:-1] except: result = "Unknown command '%s'"%command_name return result def meminfo()-
Get memory informations
Expand source code
def meminfo(): """ Get memory informations """ Console.print(strings.tostrings(b"%s : %s"%(lang.memory_label, info.meminfo()))) def mkdir(directory, recursive=False, quiet=False)-
Make directory
Expand source code
def mkdir(directory, recursive=False, quiet=False): """ Make directory """ try: if quiet is False: Console.print("mkdir '%s'"%directory) filesystem.makedir(filesystem.normpath(directory), recursive) except: Console.print("Cannot mkdir '%s'"%directory) def mountsd(mountpoint='/sd')-
Mount command
Expand source code
def mountsd(mountpoint="/sd"): """ Mount command """ try: sdcard.SdCard.mount(mountpoint) Console.print("Sd mounted on '%s'"%mountpoint) except: Console.print("Cannot mount sd on '%s'"%mountpoint) def mv(source, destination)-
Move or rename file
Expand source code
def mv(source, destination): """ Move or rename file """ try: uos.rename(filesystem.normpath(source),filesystem.normpath(destination)) except: Console.print("Cannot mv '%s'->'%s'"%(source,destination)) def parse_command_line(commandLine)-
Parse command line
Expand source code
def parse_command_line(commandLine): """ Parse command line """ commands = [] args = [] quote = None arg = "" for char in commandLine: if char == '"' or char == "'": if quote is not None: if quote == char: args.append(arg) arg = "" quote = None else: arg += char else: quote = char elif char == " ": if quote is not None: arg += char else: args.append(arg) arg = "" elif char == ";": if quote is not None: arg += char else: if len(arg) > 0: args.append(arg) commands.append(args) arg = "" args = [] else: arg += char if len(arg) > 0: args.append(arg) if len(args) > 0: commands.append(args) for command in commands: exec_command(command) def ping(host)-
Ping host
Expand source code
def ping(host): """ Ping host """ try: from server.ping import ping as ping_ ping_(host, count=4, timeout=1) except: Console.print("Not available") def print_part(message, width, height, count)-
Print a part of text
Expand source code
def print_part(message, width, height, count): """ Print a part of text """ # pylint:disable=global-variable-not-assigned if isinstance(message , bytes): message = message.decode("utf8") if count is not None and count >= height: Console.print(message,end="") if Console.is_redirected() is False: key = terminal.getch() else: key = " " count = 1 if key in ["x","X","q","Q","\x1B"]: return None Console.print("\n", end="") else: if count is None: count = 1 else: count += 1 Console.print(message) return count def pwd()-
Display the current directory
Expand source code
def pwd(): """ Display the current directory """ Console.print("%s"%uos.getcwd()) def reboot()-
Reboot command
Expand source code
def reboot(): """ Reboot command """ try: from tools import system system.reboot("Reboot device with command") except: machine.deepsleep(1000) def removedir(directory, force=False, quiet=False, simulate=False, ignore_error=False)-
Remove directory
Expand source code
def removedir(directory, force=False, quiet=False, simulate=False, ignore_error=False): """ Remove directory """ try: if filesystem.exists(directory+"/.DS_Store"): rmfile(directory+"/.DS_Store", quiet, force, simulate) if (filesystem.ismicropython() or force) and simulate is False: uos.rmdir(directory) if quiet is False: Console.print("rmdir '%s'"%(directory)) except: if ignore_error is False: Console.print("rmdir '%s' not removed"%(directory)) def rm(file, recursive=False, quiet=False, force=False, simulate=False)-
Remove file command
Expand source code
def rm(file, recursive=False, quiet=False, force=False, simulate=False): """ Remove file command """ file = filesystem.normpath(file) filenames = [] directories = [] if filesystem.isfile(file): path = file rmfile(file, force=force, quiet=quiet, simulate=simulate) else: if filesystem.isdir(file): if recursive: directories.append(file) path = file pattern = "*" else: path = None pattern = None else: path, pattern = filesystem.split(file) if path is None: Console.print("Cannot rm '%s'"%file) else: dirs, filenames = filesystem.scandir(path, pattern, recursive) directories += dirs for filename in filenames: rmfile(filename, force=force, quiet=quiet, simulate=simulate) if recursive: directories.sort() directories.reverse() for directory in directories: rmdir(directory, recursive=recursive, force=force, quiet=quiet, simulate=simulate, ignore_error=True) def rmdir(directory, recursive=False, force=False, quiet=False, simulate=False, ignore_error=False)-
Remove directory
Expand source code
def rmdir(directory, recursive=False, force=False, quiet=False, simulate=False, ignore_error=False): """ Remove directory """ directory = filesystem.normpath(directory) if recursive is False: removedir(directory, force=force, quiet=quiet, simulate=simulate, ignore_error=ignore_error) else: directories = [directory] d = directory while 1: parts = filesystem.split(d) if parts[1] == "" or parts[0] == "": break directories.append(parts[0]) d = parts[0] if "/" in directories: directories.remove("/") if sdcard.SdCard.get_mountpoint() in directories: directories.remove(sdcard.SdCard.get_mountpoint()) for d in directories: if filesystem.exists(d) and d != ".": removedir(d, force=force, quiet=quiet, simulate=simulate, ignore_error=ignore_error) def rmfile(filename, quiet=False, force=False, simulate=False)-
Remove file
Expand source code
def rmfile(filename, quiet=False, force=False, simulate=False): """ Remove file """ try: if (filesystem.ismicropython() or force) and simulate is False: uos.remove(filesystem.normpath(filename)) if quiet is False: Console.print("rm '%s'"%(filename)) except: Console.print("rm '%s' not removed"%(filename)) def searchfile(file, recursive, obj=None)-
Search file
Expand source code
def searchfile(file, recursive, obj = None): """ Search file """ file = filesystem.normpath(file) p = filesystem.abspath(uos.getcwd(), file) filenames = [] try: if file == "": _,filenames = filesystem.scandir(uos.getcwd(), "*", recursive, obj) elif filesystem.isfile(p): if obj is not None: obj.show_dir(False) obj.show(p) filenames = [p] elif filesystem.isdir(p): _, filenames = filesystem.scandir(p, "*", recursive, obj) else: path, pattern = filesystem.split(p) if obj is not None: obj.show_dir(False) _, filenames = filesystem.scandir(path, pattern, recursive, obj) except Exception as err: Console.print(err) if len(filenames) == 0 and file != "" and file != ".": Console.print("%s : No such file or directory"%file) return filenames def setdate(datetime='')-
Set date and time
Expand source code
def setdate(datetime=""): """ Set date and time """ import re file_date=re.compile("[/: ]") failed = False try: spls = file_date.split(datetime) lst = [] if len(spls) > 1: for spl in spls: if len(spl) > 0: try: r = spl.lstrip("0") if len(r) == 0: lst.append(0) else: lst.append(eval(r)) except: failed = True break if len(lst) == 6: # pylint: disable=unbalanced-tuple-unpacking year,month,day,hour,minute,second = lst machine.RTC().datetime((year, month, day, 0, hour, minute, second, 0)) else: failed = True else: failed = True except Exception as err: failed = True logger.syslog(err) if failed is True: Console.print('Expected format "YYYY/MM/DD hh:mm:ss"') def shell_sh(path=None, throw=False)-
Start the shell
Expand source code
def shell_sh(path=None, throw=False): """ Start the shell """ global shell_exited, shell_commands current_dir = uos.getcwd() create_shell_commands() if path is not None: uos.chdir(path) shell_exited = False while shell_exited is False: try: commandLine = "" commandLine = input("%s=> "%os.getcwd()) watchdog.WatchDog.feed() except EOFError: Console.print("") break except KeyboardInterrupt: Console.print("Ctr-C detected, use 'exit' to restart server or 'quit' to get python prompt") if commandLine.strip() == "quit": if throw is True: raise KeyboardInterrupt() else: break parse_command_line(commandLine) shell_commands = None uos.chdir(current_dir) def sysinfo()-
Get system informations
Expand source code
def sysinfo(): """ Get system informations """ Console.print(strings.tostrings(info.sysinfo())) def temperature()-
Get the internal temperature
Expand source code
def temperature(): """ Get the internal temperature """ celcius, farenheit = info.temperature() Console.print("%.2f°C, %d°F"%(celcius, farenheit)) def umountsd(mountpoint='/sd')-
Umount command
Expand source code
def umountsd(mountpoint="/sd"): """ Umount command """ try: sdcard.SdCard.umount(mountpoint) Console.print("Sd umounted from '%s'"%mountpoint) except: Console.print("Cannot umount sd from '%s'"%mountpoint) def upload(file='', recursive=False)-
Upload file from computer to device
Expand source code
def upload(file="", recursive=False): """ Upload file from computer to device """ if check_cam_flasher(): Console.print("Upload to device start") try: command = exchange.UploadCommand(uos.getcwd()) command.write(file, recursive, sys.stdin.buffer, sys.stdout.buffer) result = True while result: file_reader = exchange.FileReader() result = file_reader.read(uos.getcwd(), sys.stdin.buffer, sys.stdout.buffer) watchdog.WatchDog.feed() Console.print("Upload end") except Exception as err: logger.syslog(err, display=False) Console.print("Upload failed") else: Console.print("CamFlasher application required for this command") def uptime()-
Tell how long the system has been running
Expand source code
def uptime(): """ Tell how long the system has been running """ Console.print(strings.tostrings(info.uptime())) def vtcolors()-
Show all VT100 colors
Expand source code
def vtcolors(): """ Show all VT100 colors """ res = b'\x1B[4m4 bits colors\x1B[m\n' for i in range(16): if i % 8 == 0: res += b"\n " if i < 9: forecolor = 15 else: forecolor = 0 res += b"\x1B[38;5;%dm\x1B[48;5;%dm %2d \x1B[0m"%(forecolor, i,i) res += b'\n\n\x1B[4m8 bits colors\x1B[m\n' j = 0 for i in range(16,256): if j % 12== 0: res += b"\n " backcolor = i if j % 36 < 36//2: forecolor = 15 else: forecolor = 0 res += b"\x1B[38;5;%dm\x1B[48;5;%dm %3d \x1B[0m"%(forecolor,backcolor,i) j += 1 res += b'\n\n\x1B[4mModifiers\x1B[m\n\n' for i,j in [(0,"reset/normal"),(1,b"bold"),(3,b"italic"),(4,b"underline"),(7,b"reverse")]: res += b" %d : \x1B[%dm%s\x1B[0m\n"%(i,i,j) res += b'\n\x1B[4mExamples\x1B[m\n\n' res += b' >>> print("\\033[\033[1m1\033[m;\033[7m7\033[mmBold reverse\\033[0m")\n' res += b" \033[1;7mBold reverse\033[0m" res += b"\n\n" res += b' >>> print("\033[38;5;15m\033[48;5;1m\\033[48;5;1m\033[m\033[38;5;13m\\033[38;5;13m\033[mHello\\033[m")\n' res += b" \033[48;5;1m\033[38;5;13mHello\033[m\n" Console.print(res.decode("utf8"))
Classes
class Exporter-
Exporter file to camflasher
Constructor
Expand source code
class Exporter: """ Exporter file to camflasher """ def __init__(self): """ Constructor """ def send_file(self, path): """ Send the file """ result = True fileinfo = filesystem.fileinfo(path) # If a file if fileinfo[0] & 0x4000 != 0x4000: file_write = exchange.FileWriter() if filesystem.exists(path): sys.stdout.buffer.write("࿊".encode("utf8")) result = file_write.write(path, sys.stdin.buffer, sys.stdout.buffer) watchdog.WatchDog.feed() return result def show(self, path): """ Show the information of a file or directory """ for _ in range(3): # If the send successful exit, else retry three time if self.send_file(path) is True: break def show_dir(self, state): """ Indicates if the directory must show """Methods
def send_file(self, path)-
Send the file
Expand source code
def send_file(self, path): """ Send the file """ result = True fileinfo = filesystem.fileinfo(path) # If a file if fileinfo[0] & 0x4000 != 0x4000: file_write = exchange.FileWriter() if filesystem.exists(path): sys.stdout.buffer.write("࿊".encode("utf8")) result = file_write.write(path, sys.stdin.buffer, sys.stdout.buffer) watchdog.WatchDog.feed() return result def show(self, path)-
Show the information of a file or directory
Expand source code
def show(self, path): """ Show the information of a file or directory """ for _ in range(3): # If the send successful exit, else retry three time if self.send_file(path) is True: break def show_dir(self, state)-
Indicates if the directory must show
Expand source code
def show_dir(self, state): """ Indicates if the directory must show """
class LsDisplayer (path, showdir, long)-
Ls displayer class
Constructor
Expand source code
class LsDisplayer: """ Ls displayer class """ def __init__(self, path, showdir, long): """ Constructor """ self.height, self.width = get_screen_size() self.count = 1 self.long = long self.path = path self.showdir = showdir def purge_path(self, path): """ Purge the path for the display """ path = path.encode("utf8") path = filesystem.normpath(path) prefix = filesystem.prefix([path, self.path.encode("utf8")]) return path[len(prefix):].lstrip(b"/") def show(self, path): """ Show the information of a file or directory """ fileinfo = filesystem.fileinfo(path) file_date = fileinfo[8] size = fileinfo[6] # If directory if fileinfo[0] & 0x4000 == 0x4000: if self.showdir: if self.long: message = b"%s %s [%s]"%(date.date_to_bytes(file_date),b" "*7,self.purge_path(path)) else: message = b"[%s]"%self.purge_path(path) self.count = print_part(message, self.width, self.height, self.count) else: if self.long: fileinfo = filesystem.fileinfo(path) file_date = fileinfo[8] size = fileinfo[6] message = b"%s %s %s"%(date.date_to_bytes(file_date),strings.size_to_bytes(size),self.purge_path(path)) else: message = self.purge_path(path) self.count = print_part(message, self.width, self.height, self.count) def show_dir(self, state): """ Indicates if the directory must show """ self.showdir = stateMethods
def purge_path(self, path)-
Purge the path for the display
Expand source code
def purge_path(self, path): """ Purge the path for the display """ path = path.encode("utf8") path = filesystem.normpath(path) prefix = filesystem.prefix([path, self.path.encode("utf8")]) return path[len(prefix):].lstrip(b"/") def show(self, path)-
Show the information of a file or directory
Expand source code
def show(self, path): """ Show the information of a file or directory """ fileinfo = filesystem.fileinfo(path) file_date = fileinfo[8] size = fileinfo[6] # If directory if fileinfo[0] & 0x4000 == 0x4000: if self.showdir: if self.long: message = b"%s %s [%s]"%(date.date_to_bytes(file_date),b" "*7,self.purge_path(path)) else: message = b"[%s]"%self.purge_path(path) self.count = print_part(message, self.width, self.height, self.count) else: if self.long: fileinfo = filesystem.fileinfo(path) file_date = fileinfo[8] size = fileinfo[6] message = b"%s %s %s"%(date.date_to_bytes(file_date),strings.size_to_bytes(size),self.purge_path(path)) else: message = self.purge_path(path) self.count = print_part(message, self.width, self.height, self.count) def show_dir(self, state)-
Indicates if the directory must show
Expand source code
def show_dir(self, state): """ Indicates if the directory must show """ self.showdir = state