commit
1360c734ff
.gitignore
bin
builder
pwnagotchi
requirements.txt
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ dist
|
|||||||
pwnagotchi.egg-info
|
pwnagotchi.egg-info
|
||||||
*backup*.tgz
|
*backup*.tgz
|
||||||
*backup*.gz
|
*backup*.gz
|
||||||
|
.vscode
|
||||||
|
@ -14,9 +14,11 @@ from pwnagotchi import plugins
|
|||||||
from pwnagotchi import log
|
from pwnagotchi import log
|
||||||
from pwnagotchi.identity import KeyPair
|
from pwnagotchi.identity import KeyPair
|
||||||
from pwnagotchi.agent import Agent
|
from pwnagotchi.agent import Agent
|
||||||
|
from pwnagotchi.ui import fonts
|
||||||
from pwnagotchi.ui.display import Display
|
from pwnagotchi.ui.display import Display
|
||||||
from pwnagotchi import restart
|
from pwnagotchi import restart
|
||||||
from pwnagotchi import fs
|
from pwnagotchi import fs
|
||||||
|
from pwnagotchi.utils import DottedTomlEncoder
|
||||||
|
|
||||||
|
|
||||||
def do_clear(display):
|
def do_clear(display):
|
||||||
@ -122,11 +124,13 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
config = utils.load_config(args)
|
config = utils.load_config(args)
|
||||||
if args.print_config:
|
if args.print_config:
|
||||||
print(toml.dumps(config))
|
print(toml.dumps(config, encoder=DottedTomlEncoder()))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
pwnagotchi.config = config
|
||||||
fs.setup_mounts(config)
|
fs.setup_mounts(config)
|
||||||
log.setup_logging(args, config)
|
log.setup_logging(args, config)
|
||||||
|
fonts.init(config)
|
||||||
|
|
||||||
pwnagotchi.set_name(config['main']['name'])
|
pwnagotchi.set_name(config['main']['name'])
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@
|
|||||||
- python3-flask
|
- python3-flask
|
||||||
- python3-flask-cors
|
- python3-flask-cors
|
||||||
- python3-flaskext.wtf
|
- python3-flaskext.wtf
|
||||||
|
- fonts-ipaexfont-gothic
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: change hostname
|
- name: change hostname
|
||||||
|
@ -10,6 +10,7 @@ from pwnagotchi import fs
|
|||||||
from pwnagotchi._version import __version__
|
from pwnagotchi._version import __version__
|
||||||
|
|
||||||
_name = None
|
_name = None
|
||||||
|
config = None
|
||||||
|
|
||||||
|
|
||||||
def set_name(new_name):
|
def set_name(new_name):
|
||||||
@ -66,8 +67,6 @@ def mem_usage():
|
|||||||
kb_mem_total = int(line.split()[1])
|
kb_mem_total = int(line.split()[1])
|
||||||
if line.startswith("MemFree:"):
|
if line.startswith("MemFree:"):
|
||||||
kb_mem_free = int(line.split()[1])
|
kb_mem_free = int(line.split()[1])
|
||||||
if line.startswith("MemAvailable:"):
|
|
||||||
kb_mem_available = int(line.split()[1])
|
|
||||||
if line.startswith("Buffers:"):
|
if line.startswith("Buffers:"):
|
||||||
kb_main_buffers = int(line.split()[1])
|
kb_main_buffers = int(line.split()[1])
|
||||||
if line.startswith("Cached:"):
|
if line.startswith("Cached:"):
|
||||||
@ -78,18 +77,27 @@ def mem_usage():
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def cpu_load():
|
def _cpu_stat():
|
||||||
|
"""
|
||||||
|
Returns the splitted first line of the /proc/stat file
|
||||||
|
"""
|
||||||
with open('/proc/stat', 'rt') as fp:
|
with open('/proc/stat', 'rt') as fp:
|
||||||
for line in fp:
|
return list(map(int,fp.readline().split()[1:]))
|
||||||
line = line.strip()
|
|
||||||
if line.startswith('cpu '):
|
|
||||||
parts = list(map(int, line.split()[1:]))
|
def cpu_load():
|
||||||
user_n = parts[0]
|
"""
|
||||||
sys_n = parts[2]
|
Returns the current cpuload
|
||||||
idle_n = parts[3]
|
"""
|
||||||
tot = user_n + sys_n + idle_n
|
parts0 = _cpu_stat()
|
||||||
return (user_n + sys_n) / tot
|
time.sleep(0.1)
|
||||||
return 0
|
parts1 = _cpu_stat()
|
||||||
|
parts_diff = [p1 - p0 for (p0, p1) in zip(parts0, parts1)]
|
||||||
|
user, nice, sys, idle, iowait, irq, softirq, steal, _guest, _guest_nice = parts_diff
|
||||||
|
idle_sum = idle + iowait
|
||||||
|
non_idle_sum = user + nice + sys + irq + softirq + steal
|
||||||
|
total = idle_sum + non_idle_sum
|
||||||
|
return non_idle_sum / total
|
||||||
|
|
||||||
|
|
||||||
def temperature(celsius=True):
|
def temperature(celsius=True):
|
||||||
|
@ -148,6 +148,8 @@ personality.sad_num_epochs = 25
|
|||||||
personality.bond_encounters_factor = 20000
|
personality.bond_encounters_factor = 20000
|
||||||
|
|
||||||
ui.fps = 0.0
|
ui.fps = 0.0
|
||||||
|
ui.font.name = "DejaVuSansMono" # for japanese: fonts-japanese-gothic
|
||||||
|
ui.font.size_offset = 0 # will be added to the font size
|
||||||
|
|
||||||
ui.faces.look_r = "( ⚆_⚆)"
|
ui.faces.look_r = "( ⚆_⚆)"
|
||||||
ui.faces.look_l = "(☉_☉ )"
|
ui.faces.look_l = "(☉_☉ )"
|
||||||
|
Binary file not shown.
@ -3,12 +3,11 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# FIRST AUTHOR 24534649+wytshadow@users.noreply.github.com, 2019.
|
# FIRST AUTHOR 24534649+wytshadow@users.noreply.github.com, 2019.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-16 15:05+0200\n"
|
"POT-Creation-Date: 2020-01-25 21:57+0900\n"
|
||||||
"PO-Revision-Date: 2019-10-16 15:05+0200\n"
|
"PO-Revision-Date: 2019-10-16 15:05+0200\n"
|
||||||
"Last-Translator: wytshadow <24534649+wytshadow@users.noreply.github.com>\n"
|
"Last-Translator: wytshadow <24534649+wytshadow@users.noreply.github.com>\n"
|
||||||
"Language-Team: pwnagotchi <24534649+wytshadow@users.noreply.github.com>\n"
|
"Language-Team: pwnagotchi <24534649+wytshadow@users.noreply.github.com>\n"
|
||||||
@ -21,170 +20,207 @@ msgid "ZzzzZZzzzzZzzz"
|
|||||||
msgstr "すやすや〜"
|
msgstr "すやすや〜"
|
||||||
|
|
||||||
msgid "Hi, I'm Pwnagotchi! Starting ..."
|
msgid "Hi, I'm Pwnagotchi! Starting ..."
|
||||||
msgstr "こんにちは、ポウナゴッチです!始めている。。。"
|
msgstr "僕、 ポーナゴッチです!"
|
||||||
|
|
||||||
msgid "New day, new hunt, new pwns!"
|
msgid "New day, new hunt, new pwns!"
|
||||||
msgstr ""
|
msgstr "ポーンしようよ。"
|
||||||
|
|
||||||
msgid "Hack the Planet!"
|
msgid "Hack the Planet!"
|
||||||
msgstr "ハックザプラネット!"
|
msgstr "ハックザプラネット!"
|
||||||
|
|
||||||
msgid "AI ready."
|
msgid "AI ready."
|
||||||
msgstr "人工知能の準備ができました。"
|
msgstr "AIの準備ができました。"
|
||||||
|
|
||||||
msgid "The neural network is ready."
|
msgid "The neural network is ready."
|
||||||
msgstr "ニューラルネットワークの準備ができました。"
|
msgstr "ニューラルネットワークの\n準備ができました。"
|
||||||
|
|
||||||
|
msgid "Generating keys, do not turn off ..."
|
||||||
|
msgstr "鍵生成をしてます。\n電源を落とさないでね。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
||||||
msgstr "ねえ、チャンネル{channel}は無料です! キミのAPは感謝を言います。"
|
msgstr "チャンネル\n {channel} \nはfreeだよ。ありがとうね。"
|
||||||
|
|
||||||
|
msgid "Reading last session logs ..."
|
||||||
|
msgstr "session log を読んでます。"
|
||||||
|
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Read {lines_so_far} log lines so far ..."
|
||||||
|
msgstr "{lines_so_far} 行目長いよぉ。"
|
||||||
|
|
||||||
msgid "I'm bored ..."
|
msgid "I'm bored ..."
|
||||||
msgstr "退屈です。。。"
|
msgstr "退屈だぁ。。。"
|
||||||
|
|
||||||
msgid "Let's go for a walk!"
|
msgid "Let's go for a walk!"
|
||||||
msgstr "散歩に行きましょう!"
|
msgstr "散歩に行こうよ!"
|
||||||
|
|
||||||
msgid "This is the best day of my life!"
|
msgid "This is the best day of my life!"
|
||||||
msgstr "今日は私の人生で最高の日です!"
|
msgstr "人生最高の日だよ!"
|
||||||
|
|
||||||
msgid "Shitty day :/"
|
msgid "Shitty day :/"
|
||||||
msgstr ""
|
msgstr "がっかりな日だよ。orz"
|
||||||
|
|
||||||
msgid "I'm extremely bored ..."
|
msgid "I'm extremely bored ..."
|
||||||
msgstr "とても退屈です。"
|
msgstr "退屈だね。"
|
||||||
|
|
||||||
msgid "I'm very sad ..."
|
msgid "I'm very sad ..."
|
||||||
msgstr "とても悲しいです。。。"
|
msgstr "あ~悲しいよぉ。"
|
||||||
|
|
||||||
msgid "I'm sad"
|
msgid "I'm sad"
|
||||||
msgstr "悲しいです。"
|
msgstr "悲しいね。"
|
||||||
|
|
||||||
|
msgid "Leave me alone ..."
|
||||||
|
msgstr "ひとりぼっちだよ。"
|
||||||
|
|
||||||
|
msgid "I'm mad at you!"
|
||||||
|
msgstr "怒っちゃうよ。"
|
||||||
|
|
||||||
msgid "I'm living the life!"
|
msgid "I'm living the life!"
|
||||||
msgstr "人生を生きている!"
|
msgstr "わくわくするね。"
|
||||||
|
|
||||||
msgid "I pwn therefore I am."
|
msgid "I pwn therefore I am."
|
||||||
msgstr ""
|
msgstr "ポーンしてこそのオレ。"
|
||||||
|
|
||||||
msgid "So many networks!!!"
|
msgid "So many networks!!!"
|
||||||
msgstr "たくさんネットワークがある!!!"
|
msgstr "たくさん\nWiFiが飛んでるよ!"
|
||||||
|
|
||||||
msgid "I'm having so much fun!"
|
msgid "I'm having so much fun!"
|
||||||
msgstr "とても楽しんでいます!"
|
msgstr "楽しいよぉ!"
|
||||||
|
|
||||||
msgid "My crime is that of curiosity ..."
|
msgid "My crime is that of curiosity ..."
|
||||||
msgstr ""
|
msgstr "APに興味津々..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hello {name}! Nice to meet you. {name}"
|
msgid "Hello {name}! Nice to meet you."
|
||||||
msgstr "こんにちは{name}!初めまして。{name}"
|
msgstr "こんにちは{name}!\n初めまして。{name}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unit {name} is nearby! {name}"
|
msgid "Yo {name}! Sup?"
|
||||||
msgstr ""
|
msgstr "ねぇねぇ、\n{name} どうしたの?"
|
||||||
|
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Hey {name} how are you doing?"
|
||||||
|
msgstr "{name} こんにちは"
|
||||||
|
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Unit {name} is nearby!"
|
||||||
|
msgstr "{name} が近くにいるよ。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Uhm ... goodbye {name}"
|
msgid "Uhm ... goodbye {name}"
|
||||||
msgstr "ええと。。。さようなら{name}"
|
msgstr "じゃあね、さようなら {name}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{name} is gone ..."
|
msgid "{name} is gone ..."
|
||||||
msgstr "{name}がなくなった。。。"
|
msgstr "{name}\nがいなくなったよ。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Whoops ... {name} is gone."
|
msgid "Whoops ... {name} is gone."
|
||||||
msgstr "おっと。。。{name}がなくなった。"
|
msgstr "あらら、\n{name}\nがいなくなったね。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{name} missed!"
|
msgid "{name} missed!"
|
||||||
msgstr "{name}逃した!"
|
msgstr "{name} が逃げた!"
|
||||||
|
|
||||||
msgid "Missed!"
|
msgid "Missed!"
|
||||||
msgstr "逃した!"
|
msgstr "残念、逃した!"
|
||||||
|
|
||||||
|
msgid "Good friends are a blessing!"
|
||||||
|
msgstr "良い仲間にめぐりあえたよ。"
|
||||||
|
|
||||||
|
msgid "I love my friends!"
|
||||||
|
msgstr "友達は大好きだよ。"
|
||||||
|
|
||||||
msgid "Nobody wants to play with me ..."
|
msgid "Nobody wants to play with me ..."
|
||||||
msgstr "誰も僕と一緒にプレーしたくない。。。"
|
msgstr "誰も僕と一緒に\nあそんでくれない。"
|
||||||
|
|
||||||
msgid "I feel so alone ..."
|
msgid "I feel so alone ..."
|
||||||
msgstr "僕は孤独を感じる。。。"
|
msgstr "ひとりぼっちだよ。"
|
||||||
|
|
||||||
msgid "Where's everybody?!"
|
msgid "Where's everybody?!"
|
||||||
msgstr "みんなどこ?!"
|
msgstr "みんなどこにいるの?!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Napping for {secs}s ..."
|
msgid "Napping for {secs}s ..."
|
||||||
msgstr "{secs}寝ている。"
|
msgstr "{secs}秒 寝ます。"
|
||||||
|
|
||||||
msgid "Zzzzz"
|
msgid "Zzzzz"
|
||||||
msgstr "すや〜"
|
msgstr "ぐぅ〜"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "ZzzZzzz ({secs}s)"
|
msgid "ZzzZzzz ({secs}s)"
|
||||||
msgstr "すやすや〜 ({secs})"
|
msgstr "すやすや〜 ({secs}秒)"
|
||||||
|
|
||||||
msgid "Good night."
|
msgid "Good night."
|
||||||
msgstr "お休みなさい。"
|
msgstr "おやすみなさい。"
|
||||||
|
|
||||||
msgid "Zzz"
|
msgid "Zzz"
|
||||||
msgstr "す〜"
|
msgstr "ぐぅ~"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Waiting for {secs}s ..."
|
msgid "Waiting for {secs}s ..."
|
||||||
msgstr "{secs}を待っている。。。"
|
msgstr "{secs}秒 待ちです。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Looking around ({secs}s)"
|
msgid "Looking around ({secs}s)"
|
||||||
msgstr "{secs}を探している。"
|
msgstr "{secs}秒 探してます。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey {what} let's be friends!"
|
msgid "Hey {what} let's be friends!"
|
||||||
msgstr "ちょっと{what}友だちになりましょう!"
|
msgstr "ねぇねぇ\n{what} \n友だちになろうよ。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Associating to {what}"
|
msgid "Associating to {what}"
|
||||||
msgstr ""
|
msgstr "{what} \nとつながるかな?"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Yo {what}!"
|
msgid "Yo {what}!"
|
||||||
msgstr "よー{what}!"
|
msgstr "ねぇねぇ\n{what}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Just decided that {mac} needs no WiFi!"
|
msgid "Just decided that {mac} needs no WiFi!"
|
||||||
msgstr ""
|
msgstr "{mac}\nはWiFiじゃないのね。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Deauthenticating {mac}"
|
msgid "Deauthenticating {mac}"
|
||||||
msgstr ""
|
msgstr "{mac}\nの認証取得中..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kickbanning {mac}!"
|
msgid "Kickbanning {mac}!"
|
||||||
msgstr ""
|
msgstr "{mac}\nに拒否られた。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cool, we got {num} new handshake{plural}!"
|
msgid "Cool, we got {num} new handshake{plural}!"
|
||||||
msgstr "よし、{num}新しいハンドシェイクがある!"
|
msgstr "おぉ、\n{num}回\nハンドシェイクがあったよ!"
|
||||||
|
|
||||||
msgid "Oops, something went wrong ... Rebooting ..."
|
#, python-brace-format
|
||||||
msgstr "おっと!何かが間違っていた。。。リブートしている。。。"
|
msgid "You have {count} new message{plural}!"
|
||||||
|
msgstr "おぉ、\n{count}個メッセージがあるよ!"
|
||||||
|
|
||||||
|
msgid "Ops, something went wrong ... Rebooting ..."
|
||||||
|
msgstr "何か間違った。\nリブートしている。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kicked {num} stations\n"
|
msgid "Kicked {num} stations\n"
|
||||||
msgstr ""
|
msgstr "{num}回拒否された。\n"
|
||||||
|
|
||||||
|
msgid "Made >999 new friends\n"
|
||||||
|
msgstr "1000人以上友達ができた。\n"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Made {num} new friends\n"
|
msgid "Made {num} new friends\n"
|
||||||
msgstr "{num}人の新しい友達を作りました\n"
|
msgstr "{num}人友達ができた。\n"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Got {num} handshakes\n"
|
msgid "Got {num} handshakes\n"
|
||||||
msgstr "{num}ハンドシェイクがある。\n"
|
msgstr "{num}回ハンドシェイクした。\n"
|
||||||
|
|
||||||
msgid "Met 1 peer"
|
msgid "Met 1 peer"
|
||||||
msgstr "1人の仲間を会いました。"
|
msgstr "1人 仲間に会いました。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Met {num} peers"
|
msgid "Met {num} peers"
|
||||||
msgstr "{num}人の仲間を会いました。"
|
msgstr "{num}人 仲間に会いました。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -192,6 +228,9 @@ msgid ""
|
|||||||
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
|
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
|
||||||
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"{duration}中{deauted}のAPに拒否されたけど、{associated}回チャンスがあって"
|
||||||
|
"{handshakes}回ハンドシェイクがあったよ。。 #pownagotchi #pwnlog #pwnlife "
|
||||||
|
"#hacktheplanet #skynet"
|
||||||
|
|
||||||
msgid "hours"
|
msgid "hours"
|
||||||
msgstr "時間"
|
msgstr "時間"
|
||||||
@ -203,7 +242,7 @@ msgid "seconds"
|
|||||||
msgstr "秒"
|
msgstr "秒"
|
||||||
|
|
||||||
msgid "hour"
|
msgid "hour"
|
||||||
msgstr "時間"
|
msgstr "時"
|
||||||
|
|
||||||
msgid "minute"
|
msgid "minute"
|
||||||
msgstr "分"
|
msgstr "分"
|
||||||
|
@ -4,7 +4,10 @@ import _thread
|
|||||||
import threading
|
import threading
|
||||||
import importlib, importlib.util
|
import importlib, importlib.util
|
||||||
import logging
|
import logging
|
||||||
|
import pwnagotchi
|
||||||
from pwnagotchi.ui import view
|
from pwnagotchi.ui import view
|
||||||
|
from pwnagotchi.utils import save_config
|
||||||
|
|
||||||
|
|
||||||
default_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "default")
|
default_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "default")
|
||||||
loaded = {}
|
loaded = {}
|
||||||
@ -37,10 +40,16 @@ def toggle_plugin(name, enable=True):
|
|||||||
returns True if changed, otherwise False
|
returns True if changed, otherwise False
|
||||||
"""
|
"""
|
||||||
global loaded, database
|
global loaded, database
|
||||||
|
|
||||||
|
if pwnagotchi.config:
|
||||||
|
pwnagotchi.config['main']['plugins'][name]['enabled'] = enable
|
||||||
|
save_config(pwnagotchi.config, '/etc/pwnagotchi/config.toml')
|
||||||
|
|
||||||
if not enable and name in loaded:
|
if not enable and name in loaded:
|
||||||
if getattr(loaded[name], 'on_unload', None):
|
if getattr(loaded[name], 'on_unload', None):
|
||||||
loaded[name].on_unload(view.ROOT)
|
loaded[name].on_unload(view.ROOT)
|
||||||
del loaded[name]
|
del loaded[name]
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if enable and name in database and name not in loaded:
|
if enable and name in database and name not in loaded:
|
||||||
|
@ -2,8 +2,8 @@ import logging
|
|||||||
import json
|
import json
|
||||||
import toml
|
import toml
|
||||||
import _thread
|
import _thread
|
||||||
import pwnagotchi.plugins as plugins
|
from pwnagotchi import restart, plugins
|
||||||
from pwnagotchi import restart
|
from pwnagotchi.utils import save_config
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from flask import render_template_string
|
from flask import render_template_string
|
||||||
|
|
||||||
@ -499,13 +499,10 @@ class WebConfig(plugins.Plugin):
|
|||||||
elif request.method == "POST":
|
elif request.method == "POST":
|
||||||
if path == "save-config":
|
if path == "save-config":
|
||||||
try:
|
try:
|
||||||
parsed_toml = toml.loads(request.get_json())
|
save_config(request.get_json(), '/etc/pwnagotchi/config.toml') # test
|
||||||
with open('/etc/pwnagotchi/config.toml') as config_file:
|
|
||||||
toml.dump(parsed_toml, config_file)
|
|
||||||
|
|
||||||
_thread.start_new_thread(restart, (self.mode,))
|
_thread.start_new_thread(restart, (self.mode,))
|
||||||
return "success"
|
return "success"
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logging.error(ex)
|
logging.error(ex)
|
||||||
return "config error"
|
return "config error", 500
|
||||||
abort(404)
|
abort(404)
|
||||||
|
@ -1,18 +1,38 @@
|
|||||||
from PIL import ImageFont
|
from PIL import ImageFont
|
||||||
|
|
||||||
PATH = '/usr/share/fonts/truetype/dejavu/DejaVuSansMono'
|
# should not be changed
|
||||||
|
FONT_NAME = 'DejaVuSansMono'
|
||||||
|
|
||||||
Bold = ImageFont.truetype("%s-Bold.ttf" % PATH, 10)
|
# can be changed
|
||||||
BoldSmall = ImageFont.truetype("%s-Bold.ttf" % PATH, 8)
|
STATUS_FONT_NAME = None
|
||||||
BoldBig = ImageFont.truetype("%s-Bold.ttf" % PATH, 25)
|
SIZE_OFFSET = 0
|
||||||
Medium = ImageFont.truetype("%s.ttf" % PATH, 10)
|
|
||||||
Small = ImageFont.truetype("%s.ttf" % PATH, 9)
|
Bold = None
|
||||||
Huge = ImageFont.truetype("%s-Bold.ttf" % PATH, 25)
|
BoldSmall = None
|
||||||
|
BoldBig = None
|
||||||
|
Medium = None
|
||||||
|
Small = None
|
||||||
|
Huge = None
|
||||||
|
|
||||||
|
|
||||||
def setup(bold, bold_small, medium, huge):
|
def init(config):
|
||||||
global PATH, Bold, BoldSmall, Medium, Huge
|
global STATUS_FONT_NAME, SIZE_OFFSET
|
||||||
Bold = ImageFont.truetype("%s-Bold.ttf" % PATH, bold)
|
STATUS_FONT_NAME = config['ui']['font']['name']
|
||||||
BoldSmall = ImageFont.truetype("%s-Bold.ttf" % PATH, bold_small)
|
SIZE_OFFSET = config['ui']['font']['size_offset']
|
||||||
Medium = ImageFont.truetype("%s.ttf" % PATH, medium)
|
setup(10, 8, 10, 25, 25, 9)
|
||||||
Huge = ImageFont.truetype("%s-Bold.ttf" % PATH, huge)
|
|
||||||
|
|
||||||
|
def status_font(old_font):
|
||||||
|
global STATUS_FONT_NAME, SIZE_OFFSET
|
||||||
|
return ImageFont.truetype(STATUS_FONT_NAME, size=old_font.size + SIZE_OFFSET)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bold, bold_small, medium, huge, bold_big, small):
|
||||||
|
global Bold, BoldSmall, Medium, Huge, BoldBig, Small, FONT_NAME
|
||||||
|
|
||||||
|
Small = ImageFont.truetype(FONT_NAME, small)
|
||||||
|
Medium = ImageFont.truetype(FONT_NAME, medium)
|
||||||
|
BoldSmall = ImageFont.truetype("%s-Bold" % FONT_NAME, bold_small)
|
||||||
|
Bold = ImageFont.truetype("%s-Bold" % FONT_NAME, bold)
|
||||||
|
BoldBig = ImageFont.truetype("%s-Bold" % FONT_NAME, bold_big)
|
||||||
|
Huge = ImageFont.truetype("%s-Bold" % FONT_NAME, huge)
|
||||||
|
@ -22,7 +22,7 @@ class DisplayImpl(object):
|
|||||||
# status is special :D
|
# status is special :D
|
||||||
'status': {
|
'status': {
|
||||||
'pos': (0, 0),
|
'pos': (0, 0),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ class DFRobot(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 250
|
self._layout['width'] = 250
|
||||||
self._layout['height'] = 122
|
self._layout['height'] = 122
|
||||||
self._layout['face'] = (0, 40)
|
self._layout['face'] = (0, 40)
|
||||||
@ -25,7 +25,7 @@ class DFRobot(DisplayImpl):
|
|||||||
self._layout['mode'] = (225, 109)
|
self._layout['mode'] = (225, 109)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (125, 20),
|
'pos': (125, 20),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
@ -40,4 +40,4 @@ class DFRobot(DisplayImpl):
|
|||||||
self._display.display(buf)
|
self._display.display(buf)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._display.Clear(0xFF)
|
self._display.Clear(0xFF)
|
||||||
|
@ -10,7 +10,7 @@ class Inky(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 8, 10, 28)
|
fonts.setup(10, 8, 10, 28, 25, 9)
|
||||||
self._layout['width'] = 212
|
self._layout['width'] = 212
|
||||||
self._layout['height'] = 104
|
self._layout['height'] = 104
|
||||||
self._layout['face'] = (0, 37)
|
self._layout['face'] = (0, 37)
|
||||||
@ -26,7 +26,7 @@ class Inky(DisplayImpl):
|
|||||||
self._layout['mode'] = (187, 93)
|
self._layout['mode'] = (187, 93)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (102, 18),
|
'pos': (102, 18),
|
||||||
'font': fonts.Small,
|
'font': fonts.status_font(fonts.Small),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class LcdHat(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 240
|
self._layout['width'] = 240
|
||||||
self._layout['height'] = 240
|
self._layout['height'] = 240
|
||||||
self._layout['face'] = (0, 40)
|
self._layout['face'] = (0, 40)
|
||||||
@ -26,7 +26,7 @@ class LcdHat(DisplayImpl):
|
|||||||
self._layout['mode'] = (215, 109)
|
self._layout['mode'] = (215, 109)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (125, 20),
|
'pos': (125, 20),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ class OledHat(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(8, 8, 8, 8)
|
fonts.setup(8, 8, 8, 8, 25, 9)
|
||||||
self._layout['width'] = 128
|
self._layout['width'] = 128
|
||||||
self._layout['height'] = 64
|
self._layout['height'] = 64
|
||||||
self._layout['face'] = (0, 32)
|
self._layout['face'] = (0, 32)
|
||||||
@ -26,7 +26,7 @@ class OledHat(DisplayImpl):
|
|||||||
self._layout['mode'] = (103, 10)
|
self._layout['mode'] = (103, 10)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (30, 18),
|
'pos': (30, 18),
|
||||||
'font': fonts.Small,
|
'font': fonts.status_font(fonts.Small),
|
||||||
'max': 18
|
'max': 18
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -11,7 +11,7 @@ class Papirus(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 8, 10, 23)
|
fonts.setup(10, 8, 10, 23, 25, 9)
|
||||||
self._layout['width'] = 200
|
self._layout['width'] = 200
|
||||||
self._layout['height'] = 96
|
self._layout['height'] = 96
|
||||||
self._layout['face'] = (0, 24)
|
self._layout['face'] = (0, 24)
|
||||||
@ -27,7 +27,7 @@ class Papirus(DisplayImpl):
|
|||||||
self._layout['mode'] = (175, 86)
|
self._layout['mode'] = (175, 86)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (85, 14),
|
'pos': (85, 14),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 16
|
'max': 16
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -11,7 +11,7 @@ class Spotpear24inch(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(12, 10, 12, 70)
|
fonts.setup(12, 10, 12, 70, 25, 9)
|
||||||
self._layout['width'] = 320
|
self._layout['width'] = 320
|
||||||
self._layout['height'] = 240
|
self._layout['height'] = 240
|
||||||
self._layout['face'] = (35, 50)
|
self._layout['face'] = (35, 50)
|
||||||
@ -27,7 +27,7 @@ class Spotpear24inch(DisplayImpl):
|
|||||||
self._layout['mode'] = (280, 220)
|
self._layout['mode'] = (280, 220)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (80, 160),
|
'pos': (80, 160),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class WaveshareV1(DisplayImpl):
|
|||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
if self.config['color'] == 'black':
|
if self.config['color'] == 'black':
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 250
|
self._layout['width'] = 250
|
||||||
self._layout['height'] = 122
|
self._layout['height'] = 122
|
||||||
self._layout['face'] = (0, 40)
|
self._layout['face'] = (0, 40)
|
||||||
@ -27,11 +27,11 @@ class WaveshareV1(DisplayImpl):
|
|||||||
self._layout['mode'] = (225, 109)
|
self._layout['mode'] = (225, 109)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (125, 20),
|
'pos': (125, 20),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
fonts.setup(10, 8, 10, 25)
|
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||||
self._layout['width'] = 212
|
self._layout['width'] = 212
|
||||||
self._layout['height'] = 104
|
self._layout['height'] = 104
|
||||||
self._layout['face'] = (0, 26)
|
self._layout['face'] = (0, 26)
|
||||||
@ -47,7 +47,7 @@ class WaveshareV1(DisplayImpl):
|
|||||||
self._layout['mode'] = (187, 93)
|
self._layout['mode'] = (187, 93)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (91, 15),
|
'pos': (91, 15),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class Waveshare144lcd(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 8, 10, 18)
|
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||||
self._layout['width'] = 128
|
self._layout['width'] = 128
|
||||||
self._layout['height'] = 128
|
self._layout['height'] = 128
|
||||||
self._layout['face'] = (0, 43)
|
self._layout['face'] = (0, 43)
|
||||||
@ -26,7 +26,7 @@ class Waveshare144lcd(DisplayImpl):
|
|||||||
self._layout['mode'] = (0, 117)
|
self._layout['mode'] = (0, 117)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (65, 26),
|
'pos': (65, 26),
|
||||||
'font': fonts.Small,
|
'font': fonts.status_font(fonts.Small),
|
||||||
'max': 12
|
'max': 12
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class Waveshare154inch(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 200
|
self._layout['width'] = 200
|
||||||
self._layout['height'] = 200
|
self._layout['height'] = 200
|
||||||
self._layout['face'] = (0, 40)
|
self._layout['face'] = (0, 40)
|
||||||
@ -26,7 +26,7 @@ class Waveshare154inch(DisplayImpl):
|
|||||||
self._layout['mode'] = (170, 187)
|
self._layout['mode'] = (170, 187)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (5, 90),
|
'pos': (5, 90),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -11,7 +11,7 @@ class WaveshareV2(DisplayImpl):
|
|||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
if self.config['color'] == 'black':
|
if self.config['color'] == 'black':
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 250
|
self._layout['width'] = 250
|
||||||
self._layout['height'] = 122
|
self._layout['height'] = 122
|
||||||
self._layout['face'] = (0, 40)
|
self._layout['face'] = (0, 40)
|
||||||
@ -27,11 +27,11 @@ class WaveshareV2(DisplayImpl):
|
|||||||
self._layout['mode'] = (225, 109)
|
self._layout['mode'] = (225, 109)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (125, 20),
|
'pos': (125, 20),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
fonts.setup(10, 8, 10, 25)
|
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||||
self._layout['width'] = 212
|
self._layout['width'] = 212
|
||||||
self._layout['height'] = 104
|
self._layout['height'] = 104
|
||||||
self._layout['face'] = (0, 26)
|
self._layout['face'] = (0, 26)
|
||||||
@ -48,7 +48,7 @@ class WaveshareV2(DisplayImpl):
|
|||||||
self._layout['mode'] = (187, 93)
|
self._layout['mode'] = (187, 93)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (125, 20),
|
'pos': (125, 20),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 14
|
'max': 14
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class Waveshare213bc(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 8, 10, 25)
|
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||||
self._layout['width'] = 212
|
self._layout['width'] = 212
|
||||||
self._layout['height'] = 104
|
self._layout['height'] = 104
|
||||||
self._layout['face'] = (0, 26)
|
self._layout['face'] = (0, 26)
|
||||||
@ -26,7 +26,7 @@ class Waveshare213bc(DisplayImpl):
|
|||||||
self._layout['mode'] = (187, 93)
|
self._layout['mode'] = (187, 93)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (91, 15),
|
'pos': (91, 15),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class Waveshare213d(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 8, 10, 25)
|
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||||
self._layout['width'] = 212
|
self._layout['width'] = 212
|
||||||
self._layout['height'] = 104
|
self._layout['height'] = 104
|
||||||
self._layout['face'] = (0, 26)
|
self._layout['face'] = (0, 26)
|
||||||
@ -26,7 +26,7 @@ class Waveshare213d(DisplayImpl):
|
|||||||
self._layout['mode'] = (187, 93)
|
self._layout['mode'] = (187, 93)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (91, 15),
|
'pos': (91, 15),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 20
|
'max': 20
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class Waveshare27inch(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 264
|
self._layout['width'] = 264
|
||||||
self._layout['height'] = 176
|
self._layout['height'] = 176
|
||||||
self._layout['face'] = (66, 27)
|
self._layout['face'] = (66, 27)
|
||||||
@ -26,7 +26,7 @@ class Waveshare27inch(DisplayImpl):
|
|||||||
self._layout['mode'] = (239, 163)
|
self._layout['mode'] = (239, 163)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (38, 93),
|
'pos': (38, 93),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 40
|
'max': 40
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,7 +10,7 @@ class Waveshare29inch(DisplayImpl):
|
|||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
fonts.setup(10, 9, 10, 35)
|
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||||
self._layout['width'] = 296
|
self._layout['width'] = 296
|
||||||
self._layout['height'] = 128
|
self._layout['height'] = 128
|
||||||
self._layout['face'] = (0, 40)
|
self._layout['face'] = (0, 40)
|
||||||
@ -26,7 +26,7 @@ class Waveshare29inch(DisplayImpl):
|
|||||||
self._layout['mode'] = (268, 114)
|
self._layout['mode'] = (268, 114)
|
||||||
self._layout['status'] = {
|
self._layout['status'] = {
|
||||||
'pos': (130, 25),
|
'pos': (130, 25),
|
||||||
'font': fonts.Medium,
|
'font': fonts.status_font(fonts.Medium),
|
||||||
'max': 28
|
'max': 28
|
||||||
}
|
}
|
||||||
return self._layout
|
return self._layout
|
||||||
|
@ -10,11 +10,43 @@ import json
|
|||||||
import shutil
|
import shutil
|
||||||
import toml
|
import toml
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
import pwnagotchi
|
import pwnagotchi
|
||||||
|
from toml.encoder import TomlEncoder, _dump_str
|
||||||
from pwnagotchi.fs import ensure_write
|
from pwnagotchi.fs import ensure_write
|
||||||
|
|
||||||
|
|
||||||
|
class DottedTomlEncoder(TomlEncoder):
|
||||||
|
"""
|
||||||
|
Dumps the toml into the dotted-key format
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, _dict=dict):
|
||||||
|
super(DottedTomlEncoder, self).__init__(_dict)
|
||||||
|
|
||||||
|
def dump_sections(self, o, sup):
|
||||||
|
retstr = ""
|
||||||
|
pre = ""
|
||||||
|
|
||||||
|
if sup:
|
||||||
|
pre = sup + "."
|
||||||
|
|
||||||
|
for section, value in o.items():
|
||||||
|
section = str(section)
|
||||||
|
qsection = section
|
||||||
|
if not re.match(r'^[A-Za-z0-9_-]+$', section):
|
||||||
|
qsection = _dump_str(section)
|
||||||
|
if value is not None:
|
||||||
|
if isinstance(value, dict):
|
||||||
|
toadd, _ = self.dump_sections(value, pre + qsection)
|
||||||
|
retstr += toadd
|
||||||
|
else:
|
||||||
|
retstr += (pre + qsection + " = " +
|
||||||
|
str(self.dump_value(value)) + '\n')
|
||||||
|
return (retstr, self._dict())
|
||||||
|
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/823196/yaml-merge-in-python
|
# https://stackoverflow.com/questions/823196/yaml-merge-in-python
|
||||||
def merge_config(user, default):
|
def merge_config(user, default):
|
||||||
if isinstance(user, dict) and isinstance(default, dict):
|
if isinstance(user, dict) and isinstance(default, dict):
|
||||||
@ -44,6 +76,11 @@ def keys_to_str(data):
|
|||||||
|
|
||||||
return converted_dict
|
return converted_dict
|
||||||
|
|
||||||
|
def save_config(config, target):
|
||||||
|
with open(target, 'wt') as fp:
|
||||||
|
fp.write(toml.dumps(config, encoder=DottedTomlEncoder()))
|
||||||
|
return True
|
||||||
|
|
||||||
def load_config(args):
|
def load_config(args):
|
||||||
default_config_path = os.path.dirname(args.config)
|
default_config_path = os.path.dirname(args.config)
|
||||||
if not os.path.exists(default_config_path):
|
if not os.path.exists(default_config_path):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pycryptodome==3.9.4
|
pycryptodome==3.9.4
|
||||||
requests==2.21.0
|
requests==2.21.0
|
||||||
PyYAML==5.1
|
PyYAML==5.3.1
|
||||||
scapy==2.4.3
|
scapy==2.4.3
|
||||||
gym==0.14.0
|
gym==0.14.0
|
||||||
scipy==1.3.1
|
scipy==1.3.1
|
||||||
@ -17,7 +17,7 @@ spidev==3.4
|
|||||||
gast==0.2.2
|
gast==0.2.2
|
||||||
flask==1.0.2
|
flask==1.0.2
|
||||||
flask-cors==3.0.7
|
flask-cors==3.0.7
|
||||||
flask-wtf==0.14.2
|
flask-wtf==0.14.3
|
||||||
dbus-python==1.2.12
|
dbus-python==1.2.12
|
||||||
toml==0.10.0
|
toml==0.10.0
|
||||||
python-dateutil==2.8.1
|
python-dateutil==2.8.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user