Compare commits

..

No commits in common. "master" and "v1.0.1" have entirely different histories.

520 changed files with 2860 additions and 91264 deletions

@ -1,6 +1,7 @@
maintainers:
- evilsocket
- caquino
- dadav
- justin-p
features:

@ -1,31 +0,0 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[Makefile]
indent_style = tab
[*.py]
indent_style = space
indent_size = 4
[*.json]
insert_final_newline = ignore
[*.js]
indent_style = ignore
insert_final_newline = ignore
[*.{md,txt}]
indent_size = 4
trim_trailing_whitespace = false

@ -1,96 +0,0 @@
name: Release
on:
workflow_dispatch:
inputs:
release_version:
description: 'Release version'
required: true
type: string
pishrink:
description: 'pishrink Script'
default: 'https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh'
type: string
z_compress_args:
description: '7z compress args'
default: '7z a -t7z -mx=9'
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
# - name: Set VERSION variable
# run: |
# VERSION=$(awk '/__version__ /{print $NF}' ./pwnagotchi/_version.py | tr -d "'")
# env:
# VERSION: ${{ steps.set-version.outputs.version }} # Use the extracted version
- name: Show Version
run: |
# Use the $VERSION variable in your build or deployment steps
echo "Using VERSION: ${{ inputs.release_version }}"
- name: Set _version.py correctly using the env variable
run: |
sed -i "s#.*__version__.*#__version__='$PWN_VERSION'#" pwnagotchi/_version.py
env:
PWN_VERSION: ${{ inputs.release_version }}
- name: Install language dependencies
run: sudo apt-get install -y gettext
- name: Languages
run: make langs
- name: Image
run: make image
env:
PWN_VERSION: ${{ inputs.release_version }}
- name: Shrink Image
run: |
ls -a -s -h
wget ${{ inputs.pishrink }}
chmod +x pishrink.sh
sudo mv pishrink.sh /usr/local/bin
sudo pishrink.sh ./pwnagotchi-${{ inputs.release_version }}.img
- uses: edgarrc/action-7z@v1
with:
args: ${{ inputs.z_compress_args }} pwnagotchi-${{ inputs.release_version }}.7z ./pwnagotchi-${{ inputs.release_version }}.img
- name: sha256sum 7z
run: |
sudo sha256sum ./pwnagotchi-${{ inputs.release_version }}.7z > ./pwnagotchi-${{ inputs.release_version }}.sha256
- name: Create GitHub Release
id: create_new_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ inputs.release_version }}
release_name: Release ${{ inputs.release_version }}
- name: Upload GitHub Release sha
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_new_release.outputs.upload_url }}
asset_path: ./pwnagotchi-${{ inputs.release_version }}.sha256
asset_name: pwnagotchi-v${{ inputs.release_version }}.sha256
asset_content_type: appliction/text
- name: Upload GitHub Release Zip
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_new_release.outputs.upload_url }}
asset_path: ./pwnagotchi-${{ inputs.release_version }}.7z
asset_name: pwnagotchi-v${{ inputs.release_version }}.7z
asset_content_type: appliction/zip

13
.gitignore vendored

@ -2,7 +2,6 @@
*.img.bmap
*.pcap
*.po~
*.sha256
preview.png
__pycache__
_backups
@ -16,15 +15,3 @@ output-pwnagotchi
build
dist
pwnagotchi.egg-info
*backup*.tgz
*backup*.gz
.vscode
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

@ -9,7 +9,7 @@ env:
deploy:
provider: releases
api_key:
secure: "Rj0QnEDv02UzjKaxHHxJ/Sdj50EOFIrsKShr27GtVNSwHmNKxQuwlh31T0DQdif4wzcDtUZ5XWxr85vLkKJt1L8anb7Tb63qlu7Da69C+upSUow1uJkjsiScbMPqwHpwDIkkcUIbPsdbowI7qiNhRBD7nF8yyLPC5YLiU0cXKuGh4+Q5xdIlL3P7p8jm0919Y+olglzAZj0iNR/QxGOb+laNH8xi0oUsIPi5V0ZFfO/W/sm+nks9ki5nolfd1ML1gcbOD7uKuxIMTUrpDLl4p2Jx9IVQW+G2/tkmNLbP5Ga65NxQcfABQDYY3tCD8PsmFK9PEwa4cMbGJjqlo3yR7P21J5Aj3rK+L4KDntOvwem3Z3Y/v2JlQZn+gelhNFCxuPBi3ZihSf7POMHtpAYmi13N2ruzOg1ayjeYph0iN3vXIPs67DpAPaxK+8L2yoo6Nr/Cago9pGTkZoqS+J0fnWT31NXoYREPgg//L2+m42twQirFXttbhlGTBgNMLXpwcm8bZ2DW3pu3AEgVUxSoNAOjudoeyC0VzA6nUqe6STmfk06OYqcwM8q8NEyD62iAvUYU3Q7FnauZqcBqcP+ZYx82NPZybrQRX6YlJck5UomHbbEfjgpDFT+WvjrrfICmXH29YBOL1LWR4cKMT6RY58Cv8hT2PYxomB2I+DRrbqU="
secure: vBUokTv94n8s65STUgTiD6I0Iy8KXbBRvQUrAof8XG+U4ZMsH5PmDTpS+wz+SaxI6o0PRkfyOiPVdARhiKAFnfatG3q9EHllMQwqRR2YIju51A3aCxgEJ5uWDoybwQdipERUMMYwUO/8XZaRRpwFD2bdQBFWkBtQyMcAkrEL8BXckwQQ531oDN2hK5gAiTllqsOswV2idwUlBRU9jOtStzff+UgUYsp/ZebsRodyOYkEB2Ev15yARo2HTXbyZ2icwHPtMbx5zmNUSRtxs9a4hfzaK3m6ctK8qLYYUdQvXub/ruuACapdw4Ez88LY1agTecbZhFYmJzv8oANH1e4VUI4owuHnZCpU6LRutS4wOhglrkOrGo6lSUlJeA+RtQjyjBugjej9DDtDyyIlRU1ZaBF3qWR9N5EXKuquf0olOfmUR67ap1NykE9VUpzkYjkoVRTiPs/e2onM/nRNOvAQcIt75FD13u+Y/DcYQ8r7KpMIu1HNdtbVx8gMeq76bRhP1YdDg2jm+DdJ21KWjf5QHsbyoXDfJzdKlCloLIlAU3EPJhMoXsnNzre0/FXeUl6dfteR1axNS6U7e/vKsQ9rlUFZWIQaeVPjfXmFKblNNVQ5uFrrsB/EGHcJl7IUx5fvcRT5hMMNwC660YxVkBXDbRb5fxMW5/+K0BOi9cP6en8=
skip_cleanup: true
file_glob: true
file:

@ -1,10 +1,8 @@
exclude *.pyc .DS_Store .gitignore MANIFEST.in
include requirements.txt
include setup.py
include distribute_setup.py
include README.md
include LICENSE
recursive-include bin *
recursive-include builder/data *
recursive-include pwnagotchi *.py
recursive-include pwnagotchi *.yml
recursive-include pwnagotchi *.*

@ -1,79 +1,23 @@
PACKER_VERSION := 1.8.5
PWN_HOSTNAME := pwnagotchi
# PWN_VERSION := $(shell cut -d"'" -f2 < pwnagotchi/_version.py)
PWN_VERSION := $(or ${PWN_VERSION},$(shell cut -d"'" -f2 < pwnagotchi/_version.py))
PWN_RELEASE := pwnagotchi-$(PWN_VERSION)
MACHINE_TYPE := $(shell uname -m)
ifneq (,$(filter x86_64,$(MACHINE_TYPE)))
GOARCH := amd64
else ifneq (,$(filter i686,$(MACHINE_TYPE)))
GOARCH := 386
else ifneq (,$(filter arm64% aarch64%,$(MACHINE_TYPE)))
GOARCH := arm64
else ifneq (,$(filter arm%,$(MACHINE_TYPE)))
GOARCH := arm
else
GOARCH := amd64
$(warning Unable to detect CPU arch from machine type $(MACHINE_TYPE), assuming $(GOARCH))
endif
# The Ansible part of the build can inadvertently change the active hostname of
# the build machine while updating the permanent hostname of the build image.
# If the unshare command is available, use it to create a separate namespace
# so hostname changes won't affect the build machine.
UNSHARE := $(shell command -v unshare)
ifneq (,$(UNSHARE))
UNSHARE := $(UNSHARE) --uts
endif
PWN_HOSTNAME=pwnagotchi
PWN_VERSION=master
all: clean install image
langs:
@for lang in pwnagotchi/locale/*/; do\
echo "compiling language: $$lang ..."; \
./scripts/language.sh compile $$(basename $$lang); \
done
install:
PACKER := /tmp/pwnagotchi/packer
PACKER_URL := https://releases.hashicorp.com/packer/$(PACKER_VERSION)/packer_$(PACKER_VERSION)_linux_$(GOARCH).zip
$(PACKER):
mkdir -p $(@D)
curl -L "$(PACKER_URL)" -o $(PACKER).zip
unzip $(PACKER).zip -d $(@D)
rm $(PACKER).zip
chmod +x $@
curl https://releases.hashicorp.com/packer/1.3.5/packer_1.3.5_linux_amd64.zip -o /tmp/packer.zip
unzip /tmp/packer.zip -d /tmp
sudo mv /tmp/packer /usr/bin/packer
git clone https://github.com/solo-io/packer-builder-arm-image /tmp/packer-builder-arm-image
cd /tmp/packer-builder-arm-image && go get -d ./... && go build
sudo cp /tmp/packer-builder-arm-image/packer-builder-arm-image /usr/bin
SDIST := dist/pwnagotchi-$(PWN_VERSION).tar.gz
$(SDIST): setup.py pwnagotchi
python3 setup.py sdist
# Building the image requires packer, but don't rebuild the image just because packer updated.
$(PWN_RELEASE).img: | $(PACKER)
# If the packer or ansible files are updated, rebuild the image.
$(PWN_RELEASE).img: $(SDIST) builder/pwnagotchi.json builder/pwnagotchi.yml $(shell find builder/data -type f)
sudo $(PACKER) plugins install github.com/solo-io/arm-image
cd builder && sudo $(UNSHARE) $(PACKER) build -var "pwn_hostname=$(PWN_HOSTNAME)" -var "pwn_version=$(PWN_VERSION)" pwnagotchi.json
sudo chown -R $$USER:$$USER builder/output-pwnagotchi
mv builder/output-pwnagotchi/image $@
# If any of these files are updated, rebuild the checksums.
$(PWN_RELEASE).sha256: $(PWN_RELEASE).img
sha256sum $^ > $@
# If any of the input files are updated, rebuild the archive.
$(PWN_RELEASE).zip: $(PWN_RELEASE).img $(PWN_RELEASE).sha256
zip $(PWN_RELEASE).zip $^
.PHONY: image
image: $(PWN_RELEASE).zip
image:
cd builder && sudo /usr/bin/packer build -var "pwn_hostname=$(PWN_HOSTNAME)" -var "pwn_version=$(PWN_VERSION)" pwnagotchi.json
sudo mv builder/output-pwnagotchi/image pwnagotchi-raspbian-lite-$(PWN_VERSION).img
sudo sha256sum pwnagotchi-raspbian-lite-$(PWN_VERSION).img > pwnagotchi-raspbian-lite-$(PWN_VERSION).sha256
sudo zip pwnagotchi-raspbian-lite-$(PWN_VERSION).zip pwnagotchi-raspbian-lite-$(PWN_VERSION).sha256 pwnagotchi-raspbian-lite-$(PWN_VERSION).img
clean:
- python3 setup.py clean --all
- rm -rf dist pwnagotchi.egg-info
- rm -f $(PACKER)
- rm -f $(PWN_RELEASE).*
- sudo rm -rf builder/output-pwnagotchi builder/packer_cache
rm -rf /tmp/packer-builder-arm-image
rm -f pwnagotchi-raspbian-lite-*.zip pwnagotchi-raspbian-lite-*.img pwnagotchi-raspbian-lite-*.sha256
rm -rf builder/output-pwnagotchi builder/packer_cache

@ -1,25 +1,26 @@
# Pwnagotchi
<p align="center">
<p align="center">
<a href="https://github.com/evilsocket/pwnagotchi/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/evilsocket/pwnagotchi.svg?style=flat-square"></a>
<a href="https://github.com/evilsocket/pwnagotchi/blob/master/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-GPL3-brightgreen.svg?style=flat-square"></a>
<a href="https://github.com/evilsocket/pwnagotchi/graphs/contributors"><img alt="Contributors" src="https://img.shields.io/github/contributors/evilsocket/pwnagotchi"/></a>
<a href="https://travis-ci.org/evilsocket/pwnagotchi"><img alt="Travis" src="https://img.shields.io/travis/evilsocket/pwnagotchi/master.svg?style=flat-square"></a>
<a href="https://invite.pwnagotchi.ai/"><img alt="Slack" src="https://invite.pwnagotchi.ai/badge.svg"></a>
<a href="https://community.pwnagotchi.ai/"><img alt="Forum" src="https://img.shields.io/discourse/posts?server=https%3A%2F%2Fcommunity.pwnagotchi.ai%2F&style=flat-square"></a>
<a href="https://pwnagotchi.herokuapp.com/"><img alt="Slack" src="https://pwnagotchi.herokuapp.com/badge.svg"></a>
<a href="https://twitter.com/intent/follow?screen_name=pwnagotchi"><img src="https://img.shields.io/twitter/follow/pwnagotchi?style=social&logo=twitter" alt="follow on Twitter"></a>
</p>
</p>
[Pwnagotchi](https://pwnagotchi.ai/) is an [A2C](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752)-based "AI" leveraging [bettercap](https://www.bettercap.org/) that learns from its surrounding WiFi environment to maximize the crackable WPA key material it captures (either passively, or by performing authentication and association attacks). This material is collected as PCAP files containing any form of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/),
full and half WPA handshakes.
![ui](https://i.imgur.com/X68GXrn.png)
![ui](https://i.imgur.com/c7xh4hN.png)
Instead of merely playing [Super Mario or Atari games](https://becominghuman.ai/getting-mario-back-into-the-gym-setting-up-super-mario-bros-in-openais-gym-8e39a96c1e41?gi=c4b66c3d5ced) like most reinforcement learning-based "AI" *(yawn)*, Pwnagotchi tunes [its parameters](https://github.com/evilsocket/pwnagotchi/blob/master/pwnagotchi/defaults.toml) over time to **get better at pwning WiFi things to** in the environments you expose it to.
Instead of merely playing [Super Mario or Atari games](https://becominghuman.ai/getting-mario-back-into-the-gym-setting-up-super-mario-bros-in-openais-gym-8e39a96c1e41?gi=c4b66c3d5ced) like most reinforcement learning-based "AI" *(yawn)*, Pwnagotchi tunes [its parameters](https://github.com/evilsocket/pwnagotchi/blob/master/pwnagotchi/defaults.yml#L73) over time to **get better at pwning WiFi things to** in the environments you expose it to.
More specifically, Pwnagotchi is using an [LSTM with MLP feature extractor](https://stable-baselines.readthedocs.io/en/master/modules/policies.html#stable_baselines.common.policies.MlpLstmPolicy) as its policy network for the [A2C agent](https://stable-baselines.readthedocs.io/en/master/modules/a2c.html). If you're unfamiliar with A2C, here is [a very good introductory explanation](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752) (in comic form!) of the basic principles behind how Pwnagotchi learns. (You can read more about how Pwnagotchi learns in the [Usage](https://www.pwnagotchi.ai/usage/#training-the-ai) doc.)
**Keep in mind:** Unlike the usual RL simulations, Pwnagotchi learns over time. Time for a Pwnagotchi is measured in epochs; a single epoch can last from a few seconds to minutes, depending on how many access points and client stations are visible. Do not expect your Pwnagotchi to perform amazingly well at the very beginning, as it will be [exploring](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752) several combinations of [key parameters](https://www.pwnagotchi.ai/usage/#training-the-ai) to determine ideal adjustments for pwning the particular environment you are exposing it to during its beginning epochs ... but ** listen to your Pwnagotchi when it tells you it's bored!** Bring it into novel WiFi environments with you and have it observe new networks and capture new handshakes—and you'll see. :)
**Keep in mind:** Unlike the usual RL simulations, Pwnagotchi learns over time. Time for a Pwnagotchi is measured in epochs; a single epoch can last from a few seconds to minutes, depending on how many access points and client stations are visible. Do not expect your Pwnagotchi to perform amazingly well at the very beginning, as it will be [exploring](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752) several combinations of [key parameters](https://www.pwnagotchi.ai/usage/#training-the-ai) to determine ideal adjustments for pwning the particular environment you are exposing it to during its beginning epochs ... but ** listen to your Pwnagotchi when it tells you it's boring!** Bring it into novel WiFi environments with you and have it observe new networks and capture new handshakes—and you'll see. :)
Multiple units within close physical proximity can "talk" to each other, advertising their presence to each other by broadcasting custom information elements using a parasite protocol I've built on top of the existing dot11 standard. Over time, two or more units trained together will learn to cooperate upon detecting each other's presence by dividing the available channels among them for optimal pwnage.
@ -31,11 +32,10 @@ https://www.pwnagotchi.ai
&nbsp; | Official Links
---------|-------
Website | [pwnagotchi.ai](https://pwnagotchi.ai/)
Forum | [community.pwnagotchi.ai](https://community.pwnagotchi.ai/)
Slack | [pwnagotchi.slack.com](https://invite.pwnagotchi.ai/)
Subreddit | [r/pwnagotchi](https://www.reddit.com/r/pwnagotchi/)
Slack | [pwnagotchi.slack.com](https://pwnagotchi.herokuapp.com)
Twitter | [@pwnagotchi](https://twitter.com/pwnagotchi)
Subreddit | [r/pwnagotchi](https://www.reddit.com/r/pwnagotchi/)
Website | [pwnagotchi.ai](https://pwnagotchi.ai/)
## License

@ -1,32 +1,56 @@
#!/usr/bin/python3
import logging
import argparse
import time
import signal
import sys
import toml
if __name__ == '__main__':
import argparse
import time
import logging
import pwnagotchi
from pwnagotchi import utils
from pwnagotchi.plugins import cmd as plugins_cmd
from pwnagotchi import log
from pwnagotchi import restart
from pwnagotchi import fs
from pwnagotchi.utils import DottedTomlEncoder
import pwnagotchi
import pwnagotchi.grid as grid
import pwnagotchi.utils as utils
import pwnagotchi.plugins as plugins
from pwnagotchi.identity import KeyPair
from pwnagotchi.agent import Agent
from pwnagotchi.ui.display import Display
def do_clear(display):
logging.info("clearing the display ...")
display.clear()
sys.exit(0)
parser = argparse.ArgumentParser()
parser.add_argument('-C', '--config', action='store', dest='config', default='/etc/pwnagotchi/default.yml',
help='Main configuration file.')
parser.add_argument('-U', '--user-config', action='store', dest='user_config', default='/etc/pwnagotchi/config.yml',
help='If this file exists, configuration will be merged and this will override default values.')
def do_manual_mode(agent):
logging.info("entering manual mode ...")
parser.add_argument('--manual', dest="do_manual", action="store_true", default=False, help="Manual mode.")
parser.add_argument('--clear', dest="do_clear", action="store_true", default=False,
help="Clear the ePaper display and exit.")
parser.add_argument('--debug', dest="debug", action="store_true", default=False,
help="Enable debug logs.")
args = parser.parse_args()
config = utils.load_config(args)
utils.setup_logging(args, config)
plugins.load(config)
display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
keypair = KeyPair(view=display)
agent = Agent(view=display, config=config, keypair=keypair)
logging.info("%s@%s (v%s)" % (pwnagotchi.name(), agent.fingerprint(), pwnagotchi.version))
for _, plugin in plugins.loaded.items():
logging.debug("plugin '%s' v%s loaded from %s" % (plugin.__name__, plugin.__version__, plugin.__file__))
if args.do_clear:
logging.info("clearing the display ...")
display.clear()
elif args.do_manual:
logging.info("entering manual mode ...")
agent.last_session.parse()
agent.mode = 'manual'
agent.last_session.parse(agent.view(), args.skip_session)
if not args.skip_session:
logging.info(
"the last session lasted %s (%d completed epochs, trained for %d), average reward:%s (min:%s max:%s)" % (
agent.last_session.duration_human,
@ -36,136 +60,50 @@ def do_manual_mode(agent):
agent.last_session.min_reward,
agent.last_session.max_reward))
while True:
display.on_manual_mode(agent.last_session)
time.sleep(5)
if grid.is_connected():
plugins.on('internet_available', agent)
def do_auto_mode(agent):
logging.info("entering auto mode ...")
agent.mode = 'auto'
agent.start()
while True:
try:
# recon on all channels
agent.recon()
# get nearby access points grouped by channel
channels = agent.get_access_points_by_channel()
# for each channel
for ch, aps in channels:
agent.set_channel(ch)
if not agent.is_stale() and agent.any_activity():
logging.info("%d access points on channel %d" % (len(aps), ch))
# for each ap on this channel
for ap in aps:
# send an association frame in order to get for a PMKID
agent.associate(ap)
# deauth all client stations in order to get a full handshake
for sta in ap['clients']:
agent.deauth(ap, sta)
# An interesting effect of this:
#
# From Pwnagotchi's perspective, the more new access points
# and / or client stations nearby, the longer one epoch of
# its relative time will take ... basically, in Pwnagotchi's universe,
# WiFi electromagnetic fields affect time like gravitational fields
# affect ours ... neat ^_^
agent.next_epoch()
while True:
display.on_manual_mode(agent.last_session)
time.sleep(1)
if grid.is_connected():
plugins.on('internet_available', agent)
except Exception as e:
if str(e).find("wifi.interface not set") > 0:
logging.exception("main loop exception due to unavailable wifi device, likely programmatically disabled (%s)", e)
logging.info("sleeping 60 seconds then advancing to next epoch to allow for cleanup code to trigger")
time.sleep(60)
agent.next_epoch()
else:
logging.exception("main loop exception (%s)", e)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser = plugins_cmd.add_parsers(parser)
parser.add_argument('-C', '--config', action='store', dest='config', default='/etc/pwnagotchi/default.toml',
help='Main configuration file.')
parser.add_argument('-U', '--user-config', action='store', dest='user_config', default='/etc/pwnagotchi/config.toml',
help='If this file exists, configuration will be merged and this will override default values.')
parser.add_argument('--manual', dest="do_manual", action="store_true", default=False, help="Manual mode.")
parser.add_argument('--skip-session', dest="skip_session", action="store_true", default=False,
help="Skip last session parsing in manual mode.")
parser.add_argument('--clear', dest="do_clear", action="store_true", default=False,
help="Clear the ePaper display and exit.")
parser.add_argument('--debug', dest="debug", action="store_true", default=False,
help="Enable debug logs.")
parser.add_argument('--version', dest="version", action="store_true", default=False,
help="Print the version.")
parser.add_argument('--print-config', dest="print_config", action="store_true", default=False,
help="Print the configuration.")
args = parser.parse_args()
if plugins_cmd.used_plugin_cmd(args):
config = utils.load_config(args)
log.setup_logging(args, config)
rc = plugins_cmd.handle_cmd(args, config)
sys.exit(rc)
if args.version:
print(pwnagotchi.__version__)
sys.exit(0)
config = utils.load_config(args)
if args.print_config:
print(toml.dumps(config, encoder=DottedTomlEncoder()))
sys.exit(0)
from pwnagotchi.identity import KeyPair
from pwnagotchi.agent import Agent
from pwnagotchi.ui import fonts
from pwnagotchi.ui.display import Display
from pwnagotchi import grid
from pwnagotchi import plugins
pwnagotchi.config = config
fs.setup_mounts(config)
log.setup_logging(args, config)
fonts.init(config)
pwnagotchi.set_name(config['main']['name'])
plugins.load(config)
display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
if args.do_clear:
do_clear(display)
sys.exit(0)
agent = Agent(view=display, config=config, keypair=KeyPair(view=display))
def usr1_handler(*unused):
logging.info('Received USR1 singal. Restart process ...')
restart("MANU" if args.do_manual else "AUTO")
signal.signal(signal.SIGUSR1, usr1_handler)
if args.do_manual:
do_manual_mode(agent)
else:
do_auto_mode(agent)
logging.info("entering auto mode ...")
agent.start()
while True:
try:
# recon on all channels
agent.recon()
# get nearby access points grouped by channel
channels = agent.get_access_points_by_channel()
# for each channel
for ch, aps in channels:
agent.set_channel(ch)
if not agent.is_stale() and agent.any_activity():
logging.info("%d access points on channel %d" % (len(aps), ch))
# for each ap on this channel
for ap in aps:
# send an association frame in order to get for a PMKID
agent.associate(ap)
# deauth all client stations in order to get a full handshake
for sta in ap['clients']:
agent.deauth(ap, sta)
# An interesting effect of this:
#
# From Pwnagotchi's perspective, the more new access points
# and / or client stations nearby, the longer one epoch of
# its relative time will take ... basically, in Pwnagotchi's universe,
# WiFi electromagnetic fields affect time like gravitational fields
# affect ours ... neat ^_^
agent.next_epoch()
if grid.is_connected():
plugins.on('internet_available', agent)
except Exception as e:
logging.exception("main loop exception")

@ -1,29 +0,0 @@
_show_complete()
{
local cur opts node_names all_options opt_line
all_options="
pwnagotchi -h --help -C --config -U --user-config --manual --skip-session --clear --debug --version --print-config {plugins}
pwnagotchi plugins -h --help {list,install,enable,disable,uninstall,update,upgrade}
pwnagotchi plugins list -i --installed -h --help
pwnagotchi plugins install -h --help
pwnagotchi plugins uninstall -h --help
pwnagotchi plugins enable -h --help
pwnagotchi plugins disable -h --help
pwnagotchi plugins update -h --help
pwnagotchi plugins upgrade -h --help
"
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
cmd="${COMP_WORDS[@]:0:${#COMP_WORDS[@]}-1}"
opt_line="$(grep -m1 "$cmd" <<<$all_options)"
if [[ ${cur} == -* ]] ; then
opts="$(echo $opt_line | tr ' ' '\n' | awk '/^ *-/{gsub("[^a-zA-Z0-9-]","",$1);print $1}')"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
opts="$(echo $opt_line | grep -Po '{\K[^}]+' | tr ',' '\n')"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
}
complete -F _show_complete pwnagotchi

@ -1,2 +0,0 @@
allow-hotplug eth0
iface eth0 inet dhcp

@ -1,2 +0,0 @@
auto lo
iface lo inet loopback

@ -1,8 +0,0 @@
allow-hotplug usb0
iface usb0 inet static
address 10.0.0.2
netmask 255.255.255.0
network 10.0.0.0
broadcast 10.0.0.255
gateway 10.0.0.1
metric 20

@ -1,4 +0,0 @@
allow-hotplug wlan0
iface wlan0 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down

@ -1,14 +0,0 @@
[Unit]
Description=bettercap api.rest service.
Documentation=https://bettercap.org
Wants=network.target
[Service]
Type=simple
PermissionsStartOnly=true
ExecStart=/usr/bin/bettercap-launcher
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target

@ -1,20 +0,0 @@
[Unit]
Description=pwnagotchi Deep Reinforcement Learning instrumenting bettercap for WiFI pwning.
Documentation=https://pwnagotchi.ai
Wants=network.target
After=pwngrid-peer.service
[Service]
Type=simple
WorkingDirectory=/tmp
PermissionsStartOnly=true
ExecStart=/usr/bin/pwnagotchi-launcher
Restart=always
RestartSec=30
TasksMax=infinity
LimitNPROC=infinity
StandardOutput=null
StandardError=null
[Install]
WantedBy=multi-user.target

@ -1,15 +0,0 @@
[Unit]
Description=pwngrid peer service.
Documentation=https://pwnagotchi.ai
Wants=network.target
After=bettercap.service
[Service]
Type=simple
PermissionsStartOnly=true
ExecStart=/usr/bin/pwngrid -keys /etc/pwnagotchi -address 127.0.0.1:8666 -client-token /root/.api-enrollment.json -wait -log /var/log/pwngrid-peer.log -iface mon0
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target

@ -1,33 +0,0 @@
#!/usr/bin/env bash
source /usr/bin/pwnlib
# we need to decrypt something
if is_crypted_mode; then
while ! is_decrypted; do
echo "Waiting for decryption..."
sleep 1
done
fi
# check if wifi driver is bugged
if ! check_brcm; then
if ! reload_brcm; then
echo "Could not reload wifi driver. Reboot"
reboot
fi
sleep 10
fi
# start mon0
if ! is_interface_up 'mon0'; then
start_monitor_interface
else
stop_monitor_interface
start_monitor_interface
fi
if is_auto_mode_no_delete; then
/usr/bin/bettercap -no-colors -caplet pwnagotchi-auto -iface mon0
else
/usr/bin/bettercap -no-colors -caplet pwnagotchi-manual -iface mon0
fi

@ -1,148 +0,0 @@
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qsl
_HTML_FORM_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
<title>Decryption</title>
<style>
body {{ text-align: center; padding: 150px; }}
h1 {{ font-size: 50px; }}
body {{ font: 20px Helvetica, sans-serif; color: #333; }}
article {{ display: block; text-align: center; width: 650px; margin: 0 auto;}}
input {{
padding: 12px 20px;
margin: 8px 0;
box-sizing: border-box;
border: 1px solid #ccc;
}}
input[type=password] {{
width: 75%;
font-size: 24px;
}}
input[type=submit] {{
cursor: pointer;
width: 75%;
}}
input[type=submit]:hover {{
background-color: #d9d9d9;
}}
</style>
</head>
<body>
<article>
<h1>Decryption</h1>
<p>Some of your files are encrypted.</p>
<p>Please provide the decryption password.</p>
<div>
<form action="/set-password" method="POST">
{password_fields}
<input type="submit" value="Submit">
</form>
</div>
</article>
</body>
</html>
"""
POST_RESPONSE = """
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Center the loader */
#loader {
position: absolute;
left: 50%;
top: 50%;
z-index: 1;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#myDiv {
display: none;
text-align: center;
}
</style>
<script type="text/javascript">
function checkPwnagotchi() {
var target = 'http://' + document.location.hostname + ':8080/';
var xhr = new XMLHttpRequest();
xhr.open('GET', target);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 401) {
window.location.replace(target);
}else{
setTimeout(checkPwnagotchi, 1000);
}
}
};
xhr.send();
}
setTimeout(checkPwnagotchi, 1000);
</script>
</head>
<body style="margin:0;">
<div id="loader"></div>
</body>
</html>
"""
HTML_FORM = None
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(HTML_FORM.encode())
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
for mapping, password in parse_qsl(body.decode('UTF-8')):
with open('/tmp/.pwnagotchi-secret-{}'.format(mapping), 'wt') as pwfile:
pwfile.write(password)
self.send_response(200)
self.end_headers()
self.wfile.write(POST_RESPONSE.encode())
with open('/root/.pwnagotchi-crypted') as crypted_file:
mappings = [line.split()[0] for line in crypted_file.readlines()]
fields = ''.join(['<label for="{m}">Passphrase for {m}:</label>\n<input type="password" id="{m}" name="{m}" value=""><br>'.format(m=m)
for m in mappings])
HTML_FORM = _HTML_FORM_TEMPLATE.format(password_fields=fields)
httpd = HTTPServer(('0.0.0.0', 80), SimpleHTTPRequestHandler)
httpd.serve_forever()

@ -1,2 +0,0 @@
#!/usr/bin/env bash
sudo /opt/vc/bin/tvservice -o

@ -1,2 +0,0 @@
#!/usr/bin/env bash
sudo /opt/vc/bin/tvservice -p

@ -1,3 +0,0 @@
#!/usr/bin/env bash
source /usr/bin/pwnlib
start_monitor_interface

@ -1,3 +0,0 @@
#!/usr/bin/env bash
source /usr/bin/pwnlib
stop_monitor_interface

@ -1,19 +0,0 @@
#!/usr/bin/env bash
source /usr/bin/pwnlib
# we need to decrypt something
if is_crypted_mode; then
while ! is_decrypted; do
echo "Waiting for decryption..."
sleep 1
done
fi
# blink 10 times to signal ready state
blink_led 10 &
if is_auto_mode; then
/usr/local/bin/pwnagotchi
else
/usr/local/bin/pwnagotchi --manual
fi

@ -1,213 +0,0 @@
#!/usr/bin/env bash
# well ... it blinks the led
blink_led() {
for i in $(seq 1 "$1"); do
if [ -d /sys/class/leds/led0 ]
then
echo 0 | tee /sys/class/leds/led0/brightness
else
echo 0 | tee /sys/class/leds/ACT/brightness
fi
sleep 0.3
if [ -d /sys/class/leds/led0 ]
then
echo 1 | tee /sys/class/leds/led0/brightness
else
echo 1 | tee /sys/class/leds/ACT/brightness
fi
sleep 0.3
done
if [ -d /sys/class/leds/led0 ]
then
echo 0 | tee /sys/class/leds/led0/brightness
else
echo 0 | tee /sys/class/leds/ACT/brightness
fi
sleep 0.3
}
# check if brcm is stuck
check_brcm() {
if [[ "$(journalctl -n10 -k --since -5m | grep -c 'brcmf_cfg80211_nexmon_set_channel.*Set Channel failed')" -ge 5 ]]; then
return 1
fi
return 0
}
# reload mod
reload_brcm() {
if ! modprobe -r brcmfmac; then
return 1
fi
if ! modprobe brcmfmac; then
return 1
fi
return 0
}
# starts mon0
start_monitor_interface() {
rfkill unblock all
iw dev wlan0 set power_save off
ifconfig wlan0 up
iw phy "$(iw phy | head -1 | cut -d" " -f2)" interface add mon0 type monitor && ifconfig mon0 up
# If wlan0 is NOT taken down after bringing up mon0, then when switching to AUTO you will get:
# error 400: error while initializing mon0 to channel 1: iw: out=command failed: Device or resource busy (-16) err=exit status 240
ifconfig wlan0 down
}
# stops mon0
stop_monitor_interface() {
ifconfig mon0 down && iw dev mon0 del
ifconfig wlan0 up
}
# returns 0 if the specificed network interface is up
is_interface_up() {
if grep -qi 'up' /sys/class/net/$1/operstate; then
return 0
else
return 1
fi
}
# returns 0 if conditions for AUTO mode are met
is_auto_mode() {
# check override file first
if [ -f /root/.pwnagotchi-manual ]; then
# remove the override file if found
rm -rf /root/.pwnagotchi-manual
return 1
fi
# check override file first
if [ -f /root/.pwnagotchi-auto ]; then
# remove the override file if found
rm -rf /root/.pwnagotchi-auto
return 0
fi
# if usb0 is up, we're in MANU
if is_interface_up usb0; then
return 1
fi
# if eth0 is up (for other boards), we're in MANU
if is_interface_up eth0; then
return 1
fi
# no override, but none of the interfaces is up -> AUTO
return 0
}
# returns 0 if conditions for AUTO mode are met
is_auto_mode_no_delete() {
# check override file first
if [ -f /root/.pwnagotchi-manual ]; then
return 1
fi
# check override file first
if [ -f /root/.pwnagotchi-auto ]; then
return 0
fi
# if usb0 is up, we're in MANU
if is_interface_up usb0; then
return 1
fi
# if eth0 is up (for other boards), we're in MANU
if is_interface_up eth0; then
return 1
fi
# no override, but none of the interfaces is up -> AUTO
return 0
}
# check if we need to decrypt something
is_crypted_mode() {
if [ -f /root/.pwnagotchi-crypted ]; then
return 0
fi
return 1
}
# decryption loop
is_decrypted() {
while read -r mapping container mount; do
# mapping = name the device or file will be mapped to
# container = the luks encrypted device or file
# mount = the mountpoint
# fail if not mounted
if ! mountpoint -q "$mount" >/dev/null 2>&1; then
if [ -f /tmp/.pwnagotchi-secret-"$mapping" ]; then
</tmp/.pwnagotchi-secret-"$mapping" read -r SECRET
if ! test -b /dev/disk/by-id/dm-uuid-*"$(cryptsetup luksUUID "$container" | tr -d -)"*; then
if echo -n "$SECRET" | cryptsetup luksOpen -d- "$container" "$mapping" >/dev/null 2>&1; then
echo "Container decrypted!"
fi
fi
if mount /dev/mapper/"$mapping" "$mount" >/dev/null 2>&1; then
echo "Mounted /dev/mapper/$mapping to $mount"
continue
fi
fi
if ! ip -4 addr show wlan0 | grep inet >/dev/null 2>&1; then
>/dev/null 2>&1 ip addr add 192.168.0.10/24 dev wlan0
fi
if ! pgrep -f decryption-webserver >/dev/null 2>&1; then
>/dev/null 2>&1 decryption-webserver &
fi
if ! pgrep wpa_supplicant >/dev/null 2>&1; then
>/tmp/wpa_supplicant.conf cat <<EOF
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
ap_scan=2
network={
ssid="DECRYPT-ME"
mode=2
key_mgmt=WPA-PSK
psk="pwnagotchi"
frequency=2437
}
EOF
>/dev/null 2>&1 wpa_supplicant -u -s -O -D nl80211 -i wlan0 -c /tmp/wpa_supplicant.conf &
fi
if ! pgrep dnsmasq >/dev/null 2>&1; then
>/dev/null 2>&1 dnsmasq -k -p 53 -h -O "6,192.168.0.10" -A "/#/192.168.0.10" -i wlan0 -K -F 192.168.0.50,192.168.0.60,255.255.255.0,24h &
fi
return 1
fi
done </root/.pwnagotchi-crypted
# overwrite passwords
python3 -c 'print("A"*4096)' | tee /tmp/.pwnagotchi-secret-* >/dev/null
# delete
rm /tmp/.pwnagotchi-secret-*
sync # flush
pkill wpa_supplicant
pkill dnsmasq
pid="$(pgrep -f "decryption-webserver")"
[[ -n "$pid" ]] && kill "$pid"
return 0
}

@ -1,48 +1,31 @@
{
"builders": [
{
"name": "pwnagotchi",
"type": "arm-image",
"iso_url": "https://downloads.raspberrypi.org/raspios_oldstable_lite_armhf/images/raspios_oldstable_lite_armhf-2023-05-03/2023-05-03-raspios-buster-armhf-lite.img.xz",
"iso_checksum": "3d210e61b057de4de90eadb46e28837585a9b24247c221998f5bead04f88624c",
"target_image_size": 9368709120,
"qemu_args": ["-cpu", "arm1176"]
}
],
"builders": [{
"name": "pwnagotchi",
"type": "arm-image",
"iso_url" : "https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-07-12/2019-07-10-raspbian-buster-lite.zip",
"iso_checksum_type":"sha256",
"iso_checksum":"9e5cf24ce483bb96e7736ea75ca422e3560e7b455eee63dd28f66fa1825db70e",
"last_partition_extra_size" : 3221225472
}],
"provisioners": [
{
"type": "shell",
"inline": [
"mv /etc/ld.so.preload /etc/ld.so.preload.DISABLED",
"uname -a",
"sed -i 's/^\\([^#]\\)/#\\1/g' /etc/ld.so.preload",
"dpkg-architecture",
"mkdir -p /usr/local/src/pwnagotchi"
"apt-get -y update",
"apt-get install -y ansible"
]
},
{
"type": "file",
"sources": [
"../dist/pwnagotchi-{{user `pwn_version`}}.tar.gz"
],
"destination": "/usr/local/src/pwnagotchi/"
},
{
"type": "shell",
"inline": [
"apt-get -y --allow-releaseinfo-change update",
"apt-get install -y --no-install-recommends ansible"
]
},
{
"type": "ansible-local",
"type":"ansible-local",
"playbook_file": "pwnagotchi.yml",
"extra_arguments": [ "--extra-vars \"ansible_python_interpreter=/usr/bin/python3\"" ],
"command": "ANSIBLE_FORCE_COLOR=1 PYTHONUNBUFFERED=1 PWN_VERSION={{user `pwn_version`}} PWN_HOSTNAME={{user `pwn_hostname`}} ansible-playbook"
},
{
"type": "shell",
"inline": [
"mv /etc/ld.so.preload.DISABLED /etc/ld.so.preload"
"sed -i 's/^#\\(.+\\)/\\1/g' /etc/ld.so.preload"
]
}
]

@ -1,7 +1,6 @@
---
- hosts:
- 127.0.0.1
gather_facts: yes
become: yes
vars:
pwnagotchi:
@ -10,14 +9,10 @@
system:
boot_options:
- "dtoverlay=dwc2"
- "dtoverlay=spi1-3cs"
- "dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4"
- "dtparam=spi=on"
- "dtparam=i2c_arm=on"
- "dtparam=i2c1=on"
- "gpu_mem=16"
modules:
- "i2c-dev"
- "dtoverlay=spi1-3cs"
- "dtoverlay=i2c_arm=on"
- "dtoverlay=i2c1=on"
services:
enable:
- dphys-swapfile.service
@ -25,7 +20,6 @@
- bettercap.service
- pwngrid-peer.service
- epd-fuse.service
- fstrim.timer
disable:
- apt-daily.timer
- apt-daily.service
@ -35,14 +29,12 @@
- bluetooth.service
- triggerhappy.service
- ifup@wlan0.service
- dnsmasq.service
packages:
bettercap:
# We will install bettercap from source
# url: "https://github.com/bettercap/bettercap/releases/download/v2.31.0/bettercap_linux_armhf_v2.31.0.zip"
url: "https://github.com/bettercap/bettercap/releases/download/v2.25/bettercap_linux_armv6l_2.25.zip"
ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip"
pwngrid:
url: "https://github.com/evilsocket/pwngrid/releases/download/v1.10.3/pwngrid_linux_armhf_v1.10.3.zip"
url: "https://github.com/evilsocket/pwngrid/releases/download/v1.8.1/pwngrid_linux_armhf_v1.8.1.zip"
apt:
hold:
- firmware-atheros
@ -51,18 +43,15 @@
- firmware-misc-nonfree
- firmware-realtek
remove:
- raspberrypi-net-mods
- rasberrypi-net-mods
- dhcpcd5
- triggerhappy
- wpa_supplicant
- nfs-common
# Remove every golang package because we will install go-1.20.2
- golang*
- python2*
install:
- rsync
- vim
- screen
- golang
- git
- build-essential
- python3-pip
@ -73,7 +62,6 @@
- libopenmpi-dev
- libatlas-base-dev
- libjasper-dev
- libgtk-3-0
- libqtgui4
- libqt4-test
- libopenjp2-7
@ -91,6 +79,10 @@
- libnetfilter-queue-dev
- libopenmpi3
- dphys-swapfile
- kalipi-kernel
- kalipi-bootloader
- kalipi-re4son-firmware
- kalipi-kernel-headers
- libraspberrypi0
- libraspberrypi-dev
- libraspberrypi-doc
@ -103,56 +95,36 @@
- libfuse-dev
- bc
- fonts-freefont-ttf
- fbi
- fonts-ipaexfont-gothic
- cryptsetup
- dnsmasq
- aircrack-ng
- raspberrypi-kernel-headers
- libgmp3-dev
- qpdf
- bison
- flex
- make
- autoconf
- libtool
- texinfo
- binutils
- lnav
- p7zip-full
environment:
ARCHFLAGS: "-arch armv7l"
tasks:
- name: System details
- name: selected hostname
debug:
msg="{{ item }}"
with_items:
- "{{ ansible_distribution }}"
- "{{ ansible_distribution_version }}"
- "{{ ansible_distribution_major_version }}"
- "{{ ansible_architecture }}"
- "{{ ansible_machine }}"
msg: "{{ pwnagotchi.hostname }}"
- name: build version
debug:
msg: "{{ pwnagotchi.version }}"
- name: change hostname
hostname:
name: "{{pwnagotchi.hostname}}"
when: lookup('file', '/etc/hostname') == "raspberrypi"
register: hostname
- name: add hostname to /etc/hosts
lineinfile:
dest: /etc/hosts
regexp: '^127\.0\.1\.1[ \t]+raspberrypi'
line: "127.0.1.1\t{{pwnagotchi.hostname}}"
regexp: '^127\.0\.0\.1[ \t]+localhost'
line: '127.0.0.1 localhost {{pwnagotchi.hostname}} {{pwnagotchi.hostname}}.local'
state: present
when: hostname.changed
- name: disable sap plugin for bluetooth.service
lineinfile:
dest: /lib/systemd/system/bluetooth.service
regexp: '^ExecStart=/usr/lib/bluetooth/bluetoothd$'
line: 'ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap'
- name: Add re4son-kernel repo key
apt_key:
url: https://re4son-kernel.com/keys/http/archive-key.asc
state: present
- name: Add re4son-kernel repository
apt_repository:
repo: deb http://http.re4son-kernel.com/re4son/ kali-pi main
state: present
- name: add firmware packages to hold
@ -180,46 +152,31 @@
name: "{{ packages.apt.install }}"
state: present
- name: Update .bashrc (root)
blockinfile:
dest: /root/.bashrc
state: present
block: |
export MAKEFLAGS=-j$(nproc)
insertafter: EOF
- name: configure dphys-swapfile
lineinfile:
file:
path: /etc/dphys-swapfile
regexp: "^CONF_SWAPSIZE=.*$"
line: "CONF_SWAPSIZE=512"
content: "CONF_SWAPSIZE=1024"
- name: clone papirus repository
git:
repo: https://github.com/repaper/gratis.git
dest: /usr/local/src/gratis
retries: 5000
delay: 5
register: gratisgit
until: gratisgit is succeeded
- name: build papirus service
make:
chdir: /usr/local/src/gratis
target: rpi
params:
EPD_IO: epd_io_free_uart.h
EPD_IO: epd_io.h
PANEL_VERSION: 'V231_G2'
when: gratisgit.changed
- name: install papirus service
make:
chdir: /usr/local/src/gratis
target: rpi-install
params:
EPD_IO: epd_io_free_uart.h
EPD_IO: epd_io.h
PANEL_VERSION: 'V231_G2'
when: gratisgit.changed
- name: configure papirus display size
lineinfile:
@ -227,58 +184,34 @@
regexp: "#EPD_SIZE=2.0"
line: "EPD_SIZE=2.0"
- name: Delete papirus content & directory
file:
state: absent
path: /usr/local/src/gratis
when: gratisgit.changed
- name: acquire python3 pip target
command: "python3 -c 'import sys;print(sys.path.pop())'"
register: pip_target
# pip v20.3 uses a newer dependency resolver that better handles our unique situation.
# Specifically, it handles mismatches between direct requirements without extras and
# indirect requirements that do want extras (e.g. gym vs stable-baselines->gym[atari]).
- name: Upgrade pip and install rpi-hardware-pwm
shell: "python3 -m pip install pip>=20.3 rpi-hardware-pwm --verbose --retries 5000"
args:
executable: /bin/bash
# We need the --ignore-installed option so that pip simply overwrites/upgrades existing
# packages instead of trying to uninstall them first. While this sounds dangerous,
# this matches the legacy behavior of pip. This is required to prevent pip from trying
# (and failing) to uninstall python packages that were originally installed via apt.
- name: Install pwnagotchi from source archive
shell: "python3 -m pip install /usr/local/src/pwnagotchi/pwnagotchi-{{ pwnagotchi.version }}.tar.gz --verbose --ignore-installed --retries 5000"
args:
executable: /bin/bash
- name: create custom plugin directory
file:
path: /usr/local/share/pwnagotchi/custom-plugins/
state: directory
- name: clone pwnagotchi plugins repository
- name: clone pwnagotchi repository
git:
repo: https://git.chadwaltercummings.me/scifijunkie/pwnagotchi-plugins-contrib.git
dest: /usr/local/share/pwnagotchi/available-plugins
retries: 5000
delay: 5
register: pwnagotchipluginsgit
until: pwnagotchipluginsgit is succeeded
repo: https://github.com/evilsocket/pwnagotchi.git
dest: /usr/local/src/pwnagotchi
- name: Copy aircrackonly.py
copy:
src: /usr/local/share/pwnagotchi/available-plugins/aircrackonly.py
dest: /usr/local/share/pwnagotchi/custom-plugins/aircrackonly.py
owner: root
group: root
mode: '644'
- name: build pwnagotchi wheel
command: "python3 setup.py sdist bdist_wheel"
args:
chdir: /usr/local/src/pwnagotchi
- name: Copy handshakes-dl.py
copy:
src: /usr/local/share/pwnagotchi/available-plugins/handshakes-dl.py
dest: /usr/local/share/pwnagotchi/custom-plugins/handshakes-dl.py
owner: root
group: root
mode: '644'
- name: install opencv-python
pip:
name: "https://www.piwheels.hostedpi.com/simple/opencv-python/opencv_python-3.4.3.18-cp37-cp37m-linux_armv6l.whl"
extra_args: "--no-deps --no-cache-dir --platform=linux_armv6l --only-binary=:all: --target={{ pip_target.stdout }}"
- name: install tensorflow
pip:
name: "https://www.piwheels.hostedpi.com/simple/tensorflow/tensorflow-1.13.1-cp37-none-linux_armv6l.whl"
extra_args: "--no-deps --no-cache-dir --platform=linux_armv6l --only-binary=:all: --target={{ pip_target.stdout }}"
- name: install pwnagotchi wheel and dependencies
pip:
name: "{{ lookup('fileglob', '/usr/local/src/pwnagotchi/dist/pwnagotchi*.whl') }}"
extra_args: "--no-cache-dir"
- name: download and install pwngrid
unarchive:
@ -287,47 +220,25 @@
remote_src: yes
mode: 0755
- name: Install go-1.24.1
- name: download and install bettercap
unarchive:
src: https://go.dev/dl/go1.24.1.linux-armv6l.tar.gz
dest: /usr/local
src: "{{ packages.bettercap.url }}"
dest: /usr/bin
remote_src: yes
register: golang
- name: Update .bashrc for go-1.24.1 (pi)
blockinfile:
dest: /home/pi/.bashrc
state: present
block: |
export GOPATH=$HOME/go
export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin
insertafter: EOF
when: golang.changed
- name: Install bettercap
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && git clone https://github.com/bettercap/bettercap.git && cd bettercap/ && make build && make install"
args:
executable: /bin/bash
register: bettercap
- name: Link bettercap
command: ln -s /usr/local/bin/bettercap /usr/bin/bettercap
when: bettercap.changed
exclude:
- README.md
- LICENSE.md
mode: 0755
- name: clone bettercap caplets
git:
repo: https://github.com/bettercap/caplets.git
dest: /tmp/caplets
retries: 5000
delay: 5
register: capletsgit
until: capletsgit is succeeded
- name: install bettercap caplets
make:
chdir: /tmp/caplets
target: install
when: capletsgit.changed
- name: download and install bettercap ui
unarchive:
@ -336,233 +247,121 @@
remote_src: yes
mode: 0755
# Install nexmon to fix wireless scanning (takes 2.5G of space)
- name: clone nexmon repository
git:
repo: https://github.com/seemoo-lab/nexmon.git
dest: /usr/local/src/nexmon
# version: bfb3fe90c881498d7ee245b38f16722c1de26fa1
retries: 5000
delay: 5
register: nexmongit
until: nexmongit is succeeded
- name: configure libisl
command: chdir=/usr/local/src/nexmon/buildtools/isl-0.10/ ./configure
- name: make libisl
command: chdir=/usr/local/src/nexmon/buildtools/isl-0.10/ make
- name: install libisl
command: chdir=/usr/local/src/nexmon/buildtools/isl-0.10/ make install
- name: link libisl
command: ln -s /usr/local/lib/libisl.so /usr/lib/arm-linux-gnueabihf/libisl.so.10
- name: autoreconf libmpfr
command: chdir=/usr/local/src/nexmon/buildtools/mpfr-3.1.4/ autoreconf -f -i
- name: configure libmpfr
command: chdir=/usr/local/src/nexmon/buildtools/mpfr-3.1.4/ ./configure
- name: make libmpfr
command: chdir=/usr/local/src/nexmon/buildtools/mpfr-3.1.4/ make
- name: install libmpfr
command: chdir=/usr/local/src/nexmon/buildtools/mpfr-3.1.4/ make install
- name: link libmpfr
command: ln -s /usr/local/lib/libmpfr.so /usr/lib/arm-linux-gnueabihf/libmpfr.so.4
- name: make firmware
shell: "source ./setup_env.sh && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
- name: choose the right kernel version (bcm43436b0)
replace:
dest: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/Makefile
backup: no
regexp: "KERNEL_VERSION = .*$"
replace: "KERNEL_VERSION = 5.10"
- name: choose the right kernel release (variable) (bcm43436b0)
lineinfile:
dest: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/Makefile
insertafter: "DRIVER_FOLDER_NAME = .*$"
line: "KERNEL_RELEASE = 5.10.103-v7+"
- name: choose the right kernel release (replace string) (bcm43436b0)
replace:
dest: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/Makefile
backup: no
regexp: "shell uname -r"
replace: "KERNEL_RELEASE"
- name: make firmware patch (bcm43436b0)
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/ && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
# - name: backup original firmware
# shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/ && make backup-firmware"
# args:
# executable: /bin/bash
# chdir: /usr/local/src/nexmon/
# - name: install new firmware
# shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/ && make install-firmware"
# args:
# executable: /bin/bash
# chdir: /usr/local/src/nexmon/
- name: install new firmware (bcm43436b0)
- name: create cpuusage script
copy:
src: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/brcmfmac43436-sdio.bin
dest: /lib/firmware/brcm/brcmfmac43436-sdio.bin
dest: /usr/bin/cpuusage
mode: 0755
content: |
#!/usr/bin/env bash
while true
do
top -b -n1 | awk '/Cpu\(s\)/ { printf("%d %", $2 + $4 + 0.5) }'
sleep 3
done
- name: choose the right kernel version (bcm43430a1)
replace:
dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
backup: no
regexp: "KERNEL_VERSION = .*$"
replace: "KERNEL_VERSION = 5.10"
- name: choose the right kernel release (variable) (bcm43430a1)
lineinfile:
dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
insertafter: "DRIVER_FOLDER_NAME = .*$"
line: "KERNEL_RELEASE = 5.10.103-v7+"
- name: choose the right kernel release (replace string) (bcm43430a1)
replace:
dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
backup: no
regexp: "shell uname -r"
replace: "KERNEL_RELEASE"
- name: make firmware patch (bcm43430a1)
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
# - name: backup original firmware
# shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make backup-firmware"
# args:
# executable: /bin/bash
# chdir: /usr/local/src/nexmon/
# - name: install new firmware
# shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make install-firmware"
# args:
# executable: /bin/bash
# chdir: /usr/local/src/nexmon/
- name: install new firmware (bcm43430a1)
- name: create memusage script
copy:
src: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/brcmfmac43430-sdio.bin
dest: /lib/firmware/brcm/brcmfmac43430-sdio.bin
dest: /usr/bin/memusage
mode: 0755
content: |
#!/usr/bin/env bash
free -m | awk '/Mem/ { printf( "%d %", $3 / $2 * 100 + 0.5 ) }'
- name: Delete the firmware blob to avoid it crashing
file:
state: absent
path: /lib/firmware/brcm/brcmfmac43430-sdio.clm_blob
- name: Delete the RPiZW firmware blob to avoid it crashing
file:
state: absent
path: /lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,model-zero-w.clm_blob
- name: Delete the RPi3 firmware blob to avoid it crashing
file:
state: absent
path: /lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.clm_blob
- name: choose the right kernel version (bcm43455c0)
replace:
dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
backup: no
regexp: "KERNEL_VERSION = .*$"
replace: "KERNEL_VERSION = 5.10"
- name: choose the right kernel release (variable) (bcm43455c0)
lineinfile:
dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
insertafter: "DRIVER_FOLDER_NAME = .*$"
line: "KERNEL_RELEASE = 5.10.103-v7+"
- name: choose the right kernel release (replace string) (bcm43455c0)
replace:
dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
backup: no
regexp: "shell uname -r"
replace: "KERNEL_RELEASE"
- name: make firmware patch (bcm43455c0)
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/ && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
# - name: backup original firmware
# shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/ && make backup-firmware"
# args:
# executable: /bin/bash
# chdir: /usr/local/src/nexmon/
# - name: install new firmware
# shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/ && make install-firmware"
# args:
# executable: /bin/bash
# chdir: /usr/local/src/nexmon/
- name: install new firmware (bcm43455c0)
- name: create bootblink script
copy:
src: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/brcmfmac43455-sdio.bin
dest: /lib/firmware/brcm/brcmfmac43455-sdio.bin
dest: /usr/bin/bootblink
mode: 0755
content: |
#!/usr/bin/env bash
for i in $(seq 1 "$1");
do
echo 0 >/sys/class/leds/led0/brightness
sleep 0.3
echo 1 >/sys/class/leds/led0/brightness
sleep 0.3
done
echo 0 >/sys/class/leds/led0/brightness
sleep 0.3
- name: make nexutil
command: chdir=/usr/local/src/nexmon/utilities/nexutil/ make
- name: make install nexutil
command: chdir=/usr/local/src/nexmon/utilities/nexutil/ make install
# - name: copy modified driver
# shell: "cd /usr/local/src/nexmon/patches/driver/brcmfmac_5.10.y-nexmon/ && cp brcmfmac.ko /lib/modules/5.10.103-v7+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko && depmod -a"
# args:
# executable: /bin/bash
- name: copy modified driver (everyone but RPiZW)
- name: create pwnagotchi-launcher script
copy:
src: /usr/local/src/nexmon/patches/driver/brcmfmac_5.10.y-nexmon/brcmfmac.ko
dest: /lib/modules/5.10.103-v7+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
dest: /usr/bin/pwnagotchi-launcher
mode: 0755
content: |
#!/usr/bin/env bash
# blink 10 times to signal ready state
/usr/bin/bootblink 10 &
# start a detached screen session with bettercap
if ifconfig | grep usb0 | grep RUNNING; then
# if override file exists, go into auto mode
if [ -f /root/.pwnagotchi-auto ]; then
rm /root/.pwnagotchi-auto
/usr/local/bin/pwnagotchi
else
/usr/local/bin/pwnagotchi --manual
fi
else
/usr/local/bin/pwnagotchi
fi
- name: ensure depmod runs on reboot to load modified driver (brcmfmac)
lineinfile:
dest: /etc/rc.local
line: "/sbin/depmod -a"
- name: create bettercap-launcher script
copy:
dest: /usr/bin/bettercap-launcher
mode: 0755
content: |
#!/usr/bin/env bash
# blink 10 times to signal ready state
/usr/bin/bootblink 10 &
if ifconfig | grep usb0 | grep RUNNING; then
# if override file exists, go into auto mode
if [ -f /root/.pwnagotchi-auto ]; then
rm /root/.pwnagotchi-auto
/usr/bin/bettercap -no-colors -caplet pwnagotchi-auto
else
/usr/bin/bettercap -no-colors -caplet pwnagotchi-manual
fi
else
/usr/bin/bettercap -no-colors -caplet pwnagotchi-auto
fi
# To shrink the final image, remove the nexmon directory (takes 2.5G of space) post build and installation
- name: Delete nexmon content & directory
file:
state: absent
path: /usr/local/src/nexmon/
- name: create monstart script
copy:
dest: /usr/bin/monstart
mode: 0755
content: |
#!/usr/bin/env bash
iw phy phy0 interface add mon0 type monitor && ifconfig mon0 up
- name: Add pwnlog alias
lineinfile:
dest: /home/pi/.bashrc
line: "\nalias pwnlog='tail -f -n300 /var/log/pwn*.log | sed --unbuffered \"s/,[[:digit:]]\\{3\\}\\]//g\" | cut -d \" \" -f 2-'"
insertafter: EOF
- name: create monstop script
copy:
dest: /usr/bin/monstop
mode: 0755
content: |
#!/usr/bin/env bash
ifconfig mon0 down && iw dev mon0 del
- name: create hdmion script
copy:
dest: /usr/bin/hdmion
mode: 0755
content: |
#!/usr/bin/env bash
sudo /opt/vc/bin/tvservice -p
- name: create hdmioff script
copy:
dest: /usr/bin/hdmioff
mode: 0755
content: |
#!/usr/bin/env bash
sudo /opt/vc/bin/tvservice -o
- name: add HDMI powersave to rc.local
blockinfile:
path: /etc/rc.local
insertbefore: "exit 0"
block: |
if ! /opt/vc/bin/tvservice -s | egrep 'HDMI|DVI'; then
if ! /opt/vc/bin/tvservice -s | grep HDMI; then
/opt/vc/bin/tvservice -o
fi
@ -573,42 +372,55 @@
- name: check if user configuration exists
stat:
path: /etc/pwnagotchi/config.toml
path: /etc/pwnagotchi/config.yml
register: user_config
- name: create /etc/pwnagotchi/config.toml
- name: create /etc/pwnagotchi/config.yml
copy:
dest: /etc/pwnagotchi/config.toml
dest: /etc/pwnagotchi/config.yml
content: |
# Add your configuration overrides on this file any configuration changes done to default.toml will be lost!
# Add your configuration overrides on this file any configuration changes done to default.yml will be lost!
# Example:
# ui.display.enabled = true
# ui.display.type = "waveshare_2"
#
# ui:
# display:
# type: 'inkyphat'
# color: 'black'
#
when: not user_config.stat.exists
# - name: append commented out parameters for usb_hat_c.py
# lineinfile:
# dest: /etc/pwnagotchi/config.toml
# line: "# main.plugins.ups_hat_c.enabled = true\n# main.plugins.ups_hat_c.label_on = true # show BAT label or just percentage\n# main.plugins.ups_hat_c.shutdown = 5 # battery percent at which the device will turn off\n# main.plugins.ups_hat_c.bat_x_coord = 140\n# main.plugins.ups_hat_c.bat_y_coord = 0"
# insertafter: EOF
- name: configure lo interface
copy:
dest: /etc/network/interfaces.d/lo-cfg
content: |
auto lo
iface lo inet loopback
#bizzarely changing the plugin code directly reverts to the old string
- name: Reconfigure auto-update to point to the scifijunk repo
replace:
dest: /usr/local/lib/python3.7/dist-packages/pwnagotchi/plugins/default/auto-update.py
backup: no
regexp: "evilsocket/pwnagotchi"
replace: "scifijunk/pwnagotchi"
- name: configure wlan interface
copy:
dest: /etc/network/interfaces.d/wlan0-cfg
content: |
allow-hotplug wlan0
iface wlan0 inet static
- name: Delete unnecessary large folder to save space (/root/go)
file:
state: absent
path: /root/go
- name: configure usb interface
copy:
dest: /etc/network/interfaces.d/usb0-cfg
content: |
allow-hotplug usb0
iface usb0 inet static
address 10.0.0.2
netmask 255.255.255.0
network 10.0.0.0
broadcast 10.0.0.255
gateway 10.0.0.1
- name: Delete unnecessary large folder to save space (/root/.cache)
file:
state: absent
path: /root/.cache
- name: configure eth0 interface (pi2/3/4)
copy:
dest: /etc/network/interfaces.d/eth0-cfg
content: |
allow-hotplug eth0
iface eth0 inet dhcp
- name: enable ssh on boot
file:
@ -622,13 +434,6 @@
line: '{{ item }}'
with_items: "{{system.boot_options}}"
- name: adjust /etc/modules
lineinfile:
dest: /etc/modules
insertafter: EOF
line: '{{ item }}'
with_items: "{{system.modules}}"
- name: change root partition
replace:
dest: /boot/cmdline.txt
@ -649,20 +454,20 @@
copy:
dest: /etc/motd
content: |
(◕‿‿◕) {{pwnagotchi.hostname}}
(◕‿‿◕) {{pwnagotchi.hostname}} (pwnagotchi-{{pwnagotchi.version}})
Hi! I'm a pwnagotchi, please take good care of me!
Here are some basic things you need to know to raise me properly!
If you want to change my configuration, use /etc/pwnagotchi/config.toml
If you want to change my configuration, use /etc/pwnagotchi/config.yml
All the configuration options can be found on /etc/pwnagotchi/default.toml,
All the configuration options can be found on /etc/pwnagotchi/default.yml,
but don't change this file because I will recreate it every time I'm restarted!
I'm managed by systemd. Here are some basic commands.
If you want to know what I'm doing, you can check my logs with the command
tail -f /var/log/pwnagotchi.log
journalctl -fu pwnagotchi
If you want to know if I'm running, you can use
systemctl status pwnagotchi
@ -675,21 +480,83 @@
touch /root/.pwnagotchi-auto && systemctl restart pwnagotchi
You learn more about me at https://pwnagotchi.ai/
when: hostname.changed
# Ansible's apt module has an "autoclean" option but it only removes packages
# that can no longer be downloaded. Ansible v2.13 added the "clean" option
# which actually purges the apt cache, but that's newer than what we can
# install from the RasPiOS repos. Instead, we'll manually clean the cache.
- name: clean apt cache
command: "apt-get clean"
args:
warn: false
apt:
autoclean: yes
- name: remove dependencies that are no longer required
apt:
autoremove: yes
- name: add pwngrid-peer service to systemd
copy:
dest: /etc/systemd/system/pwngrid-peer.service
content: |
[Unit]
Description=pwngrid peer service.
Documentation=https://pwnagotchi.ai
Wants=network.target
After=bettercap.service
[Service]
Type=simple
PermissionsStartOnly=true
ExecStart=/usr/bin/pwngrid -keys /etc/pwnagotchi -address 127.0.0.1:8666 -client-token /root/.api-enrollment.json -wait -log /var/log/pwngrid-peer.log -iface mon0
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
notify:
- reload systemd services
- name: add bettercap service to systemd
copy:
dest: /etc/systemd/system/bettercap.service
content: |
[Unit]
Description=bettercap api.rest service.
Documentation=https://bettercap.org
Wants=network.target
After=network.target
[Service]
Type=simple
PermissionsStartOnly=true
ExecStartPre=/usr/bin/monstart
ExecStart=/usr/bin/bettercap-launcher
ExecStopPost=/usr/bin/monstop
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
notify:
- reload systemd services
- name: add pwnagotchi service to systemd
copy:
dest: /etc/systemd/system/pwnagotchi.service
content: |
[Unit]
Description=pwnagotchi Deep Reinforcement Learning instrumenting bettercap for WiFI pwning.
Documentation=https://pwnagotchi.ai
Wants=network.target
After=bettercap.service
[Service]
Type=simple
PermissionsStartOnly=true
ExecStart=/usr/bin/pwnagotchi-launcher
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
notify:
- reload systemd services
- name: enable services
systemd:
name: "{{ item }}"

@ -1,47 +1,12 @@
import subprocess
import os
import logging
import time
import re
import pwnagotchi.ui.view as view
from pwnagotchi._version import __version__
version = '1.0.1'
_name = None
config = None
def set_name(new_name):
if new_name is None:
return
new_name = new_name.strip()
if new_name == '':
return
if not re.match(r'^[a-zA-Z0-9\-]{2,25}$', new_name):
logging.warning("name '%s' is invalid: min length is 2, max length 25, only a-zA-Z0-9- allowed", new_name)
return
current = name()
if new_name != current:
global _name
logging.info("setting unit hostname '%s' -> '%s'", current, new_name)
with open('/etc/hostname', 'wt') as fp:
fp.write(new_name)
with open('/etc/hosts', 'rt') as fp:
prev = fp.read()
logging.debug("old hosts:\n%s\n", prev)
with open('/etc/hosts', 'wt') as fp:
patched = prev.replace(current, new_name, -1)
logging.debug("new hosts:\n%s\n", patched)
fp.write(patched)
os.system("hostname '%s'" % new_name)
pwnagotchi.reboot()
def name():
@ -58,44 +23,31 @@ def uptime():
def mem_usage():
with open('/proc/meminfo') as fp:
for line in fp:
line = line.strip()
if line.startswith("MemTotal:"):
kb_mem_total = int(line.split()[1])
if line.startswith("MemFree:"):
kb_mem_free = int(line.split()[1])
if line.startswith("Buffers:"):
kb_main_buffers = int(line.split()[1])
if line.startswith("Cached:"):
kb_main_cached = int(line.split()[1])
kb_mem_used = kb_mem_total - kb_mem_free - kb_main_cached - kb_main_buffers
return round(kb_mem_used / kb_mem_total, 1)
out = subprocess.getoutput("free -m")
for line in out.split("\n"):
line = line.strip()
if line.startswith("Mem:"):
parts = list(map(int, line.split()[1:]))
tot = parts[0]
used = parts[1]
free = parts[2]
return used / tot
return 0
def _cpu_stat():
"""
Returns the splitted first line of the /proc/stat file
"""
with open('/proc/stat', 'rt') as fp:
return list(map(int,fp.readline().split()[1:]))
def cpu_load():
"""
Returns the current cpuload
"""
parts0 = _cpu_stat()
time.sleep(0.1)
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
with open('/proc/stat', 'rt') as fp:
for line in fp:
line = line.strip()
if line.startswith('cpu '):
parts = list(map(int, line.split()[1:]))
user_n = parts[0]
sys_n = parts[2]
idle_n = parts[3]
tot = user_n + sys_n + idle_n
return (user_n + sys_n) / tot
return 0
def temperature(celsius=True):
@ -107,59 +59,15 @@ def temperature(celsius=True):
def shutdown():
logging.warning("shutting down ...")
from pwnagotchi.ui import view
if view.ROOT:
view.ROOT.on_shutdown()
# give it some time to refresh the ui
time.sleep(10)
logging.warning("syncing...")
from pwnagotchi import fs
for m in fs.mounts:
m.sync()
time.sleep(5)
os.system("sync")
os.system("halt")
def restart(mode):
logging.warning("restarting in %s mode ...", mode)
if mode == 'AUTO':
os.system("touch /root/.pwnagotchi-auto")
else:
os.system("touch /root/.pwnagotchi-manual")
os.system("service bettercap restart")
time.sleep(2)
os.system("service pwnagotchi restart")
def reboot(mode=None):
if mode is not None:
mode = mode.upper()
logging.warning("rebooting in %s mode ...", mode)
else:
logging.warning("rebooting ...")
from pwnagotchi.ui import view
if view.ROOT:
view.ROOT.on_rebooting()
# give it some time to refresh the ui
time.sleep(10)
if mode == 'AUTO':
os.system("touch /root/.pwnagotchi-auto")
elif mode == 'MANU':
os.system("touch /root/.pwnagotchi-manual")
logging.warning("syncing...")
from pwnagotchi import fs
for m in fs.mounts:
m.sync()
def reboot():
logging.warning("rebooting ...")
os.system("sync")
os.system("shutdown -r now")

@ -1 +0,0 @@
__version__='1.10.0'

@ -3,14 +3,11 @@ import json
import os
import re
import logging
import asyncio
import _thread
import pwnagotchi
import pwnagotchi.utils as utils
import pwnagotchi.plugins as plugins
from pwnagotchi.ui.web.server import Server
from pwnagotchi.automata import Automata
from pwnagotchi.log import LastSession
from pwnagotchi.bettercap import Client
from pwnagotchi.mesh.utils import AsyncAdvertiser
@ -19,41 +16,30 @@ from pwnagotchi.ai.train import AsyncTrainer
RECOVERY_DATA_FILE = '/root/.pwnagotchi-recovery'
class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
class Agent(Client, AsyncAdvertiser, AsyncTrainer):
def __init__(self, view, config, keypair):
Client.__init__(self, config['bettercap']['hostname'],
config['bettercap']['scheme'],
config['bettercap']['port'],
config['bettercap']['username'],
config['bettercap']['password'])
Automata.__init__(self, config, view)
AsyncAdvertiser.__init__(self, config, view, keypair)
AsyncTrainer.__init__(self, config)
self._started_at = time.time()
self._filter = None if not config['main']['filter'] else re.compile(config['main']['filter'])
self._filter = None if config['main']['filter'] is None else re.compile(config['main']['filter'])
self._current_channel = 0
self._tot_aps = 0
self._aps_on_channel = 0
self._supported_channels = utils.iface_channels(config['main']['iface'])
self._view = view
self._view.set_agent(self)
self._web_ui = Server(self, config['ui'])
self._access_points = []
self._last_pwnd = None
self._history = {}
self._handshakes = {}
self.last_session = LastSession(self._config)
self.mode = 'auto'
if not os.path.exists(config['bettercap']['handshakes']):
os.makedirs(config['bettercap']['handshakes'])
logging.info("%s@%s (v%s)", pwnagotchi.name(), self.fingerprint(), pwnagotchi.__version__)
for _, plugin in plugins.loaded.items():
logging.debug("plugin '%s' v%s", plugin.__class__.__name__, plugin.__version__)
def config(self):
return self._config
@ -63,13 +49,43 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
def supported_channels(self):
return self._supported_channels
def set_starting(self):
self._view.on_starting()
def set_ready(self):
plugins.on('ready', self)
def set_free_channel(self, channel):
self._view.on_free_channel(channel)
plugins.on('free_channel', self, channel)
def set_bored(self):
self._view.on_bored()
plugins.on('bored', self)
def set_sad(self):
self._view.on_sad()
plugins.on('sad', self)
def set_excited(self):
self._view.on_excited()
plugins.on('excited', self)
def set_lonely(self):
self._view.on_lonely()
plugins.on('lonely', self)
def set_rebooting(self):
self._view.on_rebooting()
plugins.on('rebooting', self)
def setup_events(self):
logging.info("connecting to %s ...", self.url)
logging.info("connecting to %s ..." % self.url)
for tag in self._config['bettercap']['silence']:
try:
self.run('events.ignore %s' % tag, verbose_errors=False)
except Exception:
except Exception as e:
pass
def _reset_wifi_settings(self):
@ -91,7 +107,7 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
s = self.session()
for iface in s['interfaces']:
if iface['name'] == mon_iface:
logging.info("found monitor interface: %s", iface['name'])
logging.info("found monitor interface: %s" % iface['name'])
has_mon = True
break
@ -100,11 +116,11 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
logging.info("starting monitor interface ...")
self.run('!%s' % mon_start_cmd)
else:
logging.info("waiting for monitor interface %s ...", mon_iface)
logging.info("waiting for monitor interface %s ..." % mon_iface)
time.sleep(1)
logging.info("supported channels: %s", self._supported_channels)
logging.info("handshakes will be collected inside %s", self._config['bettercap']['handshakes'])
logging.info("supported channels: %s" % self._supported_channels)
logging.info("handshakes will be collected inside %s" % self._config['bettercap']['handshakes'])
self._reset_wifi_settings()
@ -119,27 +135,21 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
self.start_advertising()
def _wait_bettercap(self):
while True:
try:
_s = self.session()
return
except Exception:
logging.info("waiting for bettercap API to be available ...")
time.sleep(1)
def start(self):
self.start_ai()
self._wait_bettercap()
self.setup_events()
self.set_starting()
self.start_monitor_mode()
self.start_event_polling()
self.start_session_fetcher()
# print initial stats
self.next_epoch()
self.set_ready()
def wait_for(self, t, sleeping=True):
plugins.on('sleep' if sleeping else 'wait', self, t)
self._view.wait(t, sleeping)
self._epoch.track(sleep=True, inc=t)
def recon(self):
recon_time = self._config['personality']['recon_time']
max_inactive = self._config['personality']['max_inactive_scale']
@ -153,14 +163,14 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
if not channels:
self._current_channel = 0
logging.debug("RECON %ds", recon_time)
logging.debug("RECON %ds" % recon_time)
self.run('wifi.recon.channel clear')
else:
logging.debug("RECON %ds ON CHANNELS %s", recon_time, ','.join(map(str, channels)))
logging.debug("RECON %ds ON CHANNELS %s" % (recon_time, ','.join(map(str, channels))))
try:
self.run('wifi.recon.channel %s' % ','.join(map(str, channels)))
except Exception as e:
logging.exception("Error while setting wifi.recon.channels (%s)", e)
logging.exception("error")
self.wait_for(recon_time, sleeping=False)
@ -182,28 +192,15 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
s = self.session()
plugins.on("unfiltered_ap_list", self, s['wifi']['aps'])
for ap in s['wifi']['aps']:
if ap['encryption'] == '' or ap['encryption'] == 'OPEN':
continue
elif ap['hostname'] not in whitelist \
and ap['mac'].lower() not in whitelist \
and ap['mac'][:8].lower() not in whitelist:
if ap['hostname'] not in whitelist:
if self._filter_included(ap):
aps.append(ap)
except Exception as e:
logging.exception("Error while getting acces points (%s)", e)
logging.exception("error")
aps.sort(key=lambda ap: ap['channel'])
return self.set_access_points(aps)
def get_total_aps(self):
return self._tot_aps
def get_aps_on_channel(self):
return self._aps_on_channel
def get_current_channel(self):
return self._current_channel
def get_access_points_by_channel(self):
aps = self.get_access_points()
channels = self._config['personality']['channels']
@ -214,7 +211,7 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
ch = ap['channel']
# if we're sticking to a channel, skip anything
# which is not on that channel
if channels and ch not in channels:
if channels != [] and ch not in channels:
continue
if ch not in grouped:
@ -240,16 +237,16 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
# self._view.set('epoch', '%04d' % self._epoch.epoch)
def _update_counters(self):
self._tot_aps = len(self._access_points)
tot_aps = len(self._access_points)
tot_stas = sum(len(ap['clients']) for ap in self._access_points)
if self._current_channel == 0:
self._view.set('aps', '%d' % self._tot_aps)
self._view.set('aps', '%d' % tot_aps)
self._view.set('sta', '%d' % tot_stas)
else:
self._aps_on_channel = len([ap for ap in self._access_points if ap['channel'] == self._current_channel])
aps_on_channel = len([ap for ap in self._access_points if ap['channel'] == self._current_channel])
stas_on_channel = sum(
[len(ap['clients']) for ap in self._access_points if ap['channel'] == self._current_channel])
self._view.set('aps', '%d (%d)' % (self._aps_on_channel, self._tot_aps))
self._view.set('aps', '%d (%d)' % (aps_on_channel, tot_aps))
self._view.set('sta', '%d (%d)' % (stas_on_channel, tot_stas))
def _update_handshakes(self, new_shakes=0):
@ -270,13 +267,8 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
def _update_peers(self):
self._view.set_closest_peer(self._closest_peer, len(self._peers))
def _reboot(self):
self.set_rebooting()
self._save_recovery_data()
pwnagotchi.reboot()
def _save_recovery_data(self):
logging.warning("writing recovery data to %s ...", RECOVERY_DATA_FILE)
logging.warning("writing recovery data to %s ..." % RECOVERY_DATA_FILE)
with open(RECOVERY_DATA_FILE, 'w') as fp:
data = {
'started_at': self._started_at,
@ -291,7 +283,7 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
try:
with open(RECOVERY_DATA_FILE, 'rt') as fp:
data = json.load(fp)
logging.info("found recovery data: %s", data)
logging.info("found recovery data: %s" % data)
self._started_at = data['started_at']
self._epoch.epoch = data['epoch']
self._handshakes = data['handshakes']
@ -299,80 +291,62 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
self._last_pwnd = data['last_pwnd']
if delete:
logging.info("deleting %s", RECOVERY_DATA_FILE)
logging.info("deleting %s" % RECOVERY_DATA_FILE)
os.unlink(RECOVERY_DATA_FILE)
except:
if not no_exceptions:
raise
def _event_poller(self):
self._load_recovery_data()
def start_session_fetcher(self):
_thread.start_new_thread(self._fetch_stats, ())
self.run('events.clear')
def _fetch_stats(self):
logging.debug("event polling started ...")
while True:
time.sleep(1)
new_shakes = 0
s = self.session()
self._update_uptime(s)
self._update_advertisement(s)
self._update_peers()
self._update_counters()
self._update_handshakes(0)
time.sleep(1)
async def _on_event(self, msg):
found_handshake = False
jmsg = json.loads(msg)
# give plugins access to all raw bettercap events
try:
plugins.on('bcap_%s' % re.sub(r"[^a-z0-9_]+", "_", jmsg['tag'].lower()), self, jmsg)
except Exception as err:
logging.error("Processing event: %s" % err)
if jmsg['tag'] == 'wifi.client.handshake':
filename = jmsg['data']['file']
sta_mac = jmsg['data']['station']
ap_mac = jmsg['data']['ap']
key = "%s -> %s" % (sta_mac, ap_mac)
if key not in self._handshakes:
self._handshakes[key] = jmsg
s = self.session()
ap_and_station = self._find_ap_sta_in(sta_mac, ap_mac, s)
if ap_and_station is None:
logging.warning("!!! captured new handshake: %s !!!", key)
self._last_pwnd = ap_mac
plugins.on('handshake', self, filename, ap_mac, sta_mac)
else:
(ap, sta) = ap_and_station
self._last_pwnd = ap['hostname'] if ap['hostname'] != '' and ap[
'hostname'] != '<hidden>' else ap_mac
logging.warning(
"!!! captured new handshake on channel %d, %d dBm: %s (%s) -> %s [%s (%s)] !!!",
ap['channel'],
ap['rssi'],
sta['mac'], sta['vendor'],
ap['hostname'], ap['mac'], ap['vendor'])
plugins.on('handshake', self, filename, ap, sta)
found_handshake = True
self._update_handshakes(1 if found_handshake else 0)
def _event_poller(self, loop):
self._load_recovery_data()
self.run('events.clear')
while True:
logging.debug("polling events ...")
try:
loop.create_task(self.start_websocket(self._on_event))
loop.run_forever()
except Exception as ex:
logging.debug("Error while polling via websocket (%s)", ex)
for h in [e for e in self.events() if e['tag'] == 'wifi.client.handshake']:
filename = h['data']['file']
sta_mac = h['data']['station']
ap_mac = h['data']['ap']
key = "%s -> %s" % (sta_mac, ap_mac)
if key not in self._handshakes:
self._handshakes[key] = h
new_shakes += 1
ap_and_station = self._find_ap_sta_in(sta_mac, ap_mac, s)
if ap_and_station is None:
logging.warning("!!! captured new handshake: %s !!!" % key)
self._last_pwnd = ap_mac
plugins.on('handshake', self, filename, ap_mac, sta_mac)
else:
(ap, sta) = ap_and_station
self._last_pwnd = ap['hostname'] if ap['hostname'] != '' and ap[
'hostname'] != '<hidden>' else ap_mac
logging.warning("!!! captured new handshake on channel %d: %s (%s) -> %s [%s (%s)] !!!" % ( \
ap['channel'],
sta['mac'], sta['vendor'],
ap['hostname'], ap['mac'], ap['vendor']))
plugins.on('handshake', self, filename, ap, sta)
except Exception as e:
logging.exception("error")
finally:
self._update_handshakes(new_shakes)
def start_event_polling(self):
# start a thread and pass in the mainloop
_thread.start_new_thread(self._event_poller, (asyncio.get_event_loop(),))
_thread.start_new_thread(self._event_poller, ())
def is_module_running(self, module):
s = self.session()
@ -406,17 +380,32 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
return self._history[who] < self._config['personality']['max_interactions']
def _on_miss(self, who):
logging.info("it looks like %s is not in range anymore :/" % who)
self._epoch.track(miss=True)
self._view.on_miss(who)
def _on_error(self, who, e):
error = "%s" % e
# when we're trying to associate or deauth something that is not in range anymore
# (if we are moving), we get the following error from bettercap:
# error 400: 50:c7:bf:2e:d3:37 is an unknown BSSID or it is in the association skip list.
if 'is an unknown BSSID' in error:
self._on_miss(who)
else:
logging.error("%s" % e)
def associate(self, ap, throttle=0):
if self.is_stale():
logging.debug("recon is stale, skipping assoc(%s)", ap['mac'])
logging.debug("recon is stale, skipping assoc(%s)" % ap['mac'])
return
if self._config['personality']['associate'] and self._should_interact(ap['mac']):
self._view.on_assoc(ap)
try:
logging.info("sending association frame to %s (%s %s) on channel %d [%d clients], %d dBm...",
ap['hostname'], ap['mac'], ap['vendor'], ap['channel'], len(ap['clients']), ap['rssi'])
logging.info("sending association frame to %s (%s %s) on channel %d [%d clients]..." % ( \
ap['hostname'], ap['mac'], ap['vendor'], ap['channel'], len(ap['clients'])))
self.run('wifi.assoc %s' % ap['mac'])
self._epoch.track(assoc=True)
except Exception as e:
@ -429,15 +418,15 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
def deauth(self, ap, sta, throttle=0):
if self.is_stale():
logging.debug("recon is stale, skipping deauth(%s)", sta['mac'])
logging.debug("recon is stale, skipping deauth(%s)" % sta['mac'])
return
if self._config['personality']['deauth'] and self._should_interact(sta['mac']):
self._view.on_deauth(sta)
try:
logging.info("deauthing %s (%s) from %s (%s %s) on channel %d, %d dBm ...",
sta['mac'], sta['vendor'], ap['hostname'], ap['mac'], ap['vendor'], ap['channel'], ap['rssi'])
logging.info("deauthing %s (%s) from %s (%s %s) on channel %d ..." % (
sta['mac'], sta['vendor'], ap['hostname'], ap['mac'], ap['vendor'], ap['channel']))
self.run('wifi.deauth %s' % sta['mac'])
self._epoch.track(deauth=True)
except Exception as e:
@ -450,7 +439,7 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
def set_channel(self, channel, verbose=True):
if self.is_stale():
logging.debug("recon is stale, skipping set_channel(%d)", channel)
logging.debug("recon is stale, skipping set_channel(%d)" % channel)
return
# if in the previous loop no client stations has been deauthenticated
@ -466,12 +455,12 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
if channel != self._current_channel:
if self._current_channel != 0 and wait > 0:
if verbose:
logging.info("waiting for %ds on channel %d ...", wait, self._current_channel)
logging.info("waiting for %ds on channel %d ..." % (wait, self._current_channel))
else:
logging.debug("waiting for %ds on channel %d ...", wait, self._current_channel)
logging.debug("waiting for %ds on channel %d ..." % (wait, self._current_channel))
self.wait_for(wait)
if verbose and self._epoch.any_activity:
logging.info("CHANNEL %d", channel)
logging.info("CHANNEL %d" % channel)
try:
self.run('wifi.recon.channel %d' % channel)
self._current_channel = channel
@ -481,4 +470,45 @@ class Agent(Client, Automata, AsyncAdvertiser, AsyncTrainer):
plugins.on('channel_hop', self, channel)
except Exception as e:
logging.error("Error while setting channel (%s)", e)
logging.error("error: %s" % e)
def is_stale(self):
return self._epoch.num_missed > self._config['personality']['max_misses_for_recon']
def any_activity(self):
return self._epoch.any_activity
def _reboot(self):
self.set_rebooting()
self._save_recovery_data()
pwnagotchi.reboot()
def next_epoch(self):
was_stale = self.is_stale()
did_miss = self._epoch.num_missed
self._epoch.next()
# after X misses during an epoch, set the status to lonely
if was_stale:
logging.warning("agent missed %d interactions -> lonely" % did_miss)
self.set_lonely()
# after X times being bored, the status is set to sad
elif self._epoch.inactive_for >= self._config['personality']['sad_num_epochs']:
logging.warning("%d epochs with no activity -> sad" % self._epoch.inactive_for)
self.set_sad()
# after X times being inactive, the status is set to bored
elif self._epoch.inactive_for >= self._config['personality']['bored_num_epochs']:
logging.warning("%d epochs with no activity -> bored" % self._epoch.inactive_for)
self.set_bored()
# after X times being active, the status is set to happy / excited
elif self._epoch.active_for >= self._config['personality']['excited_num_epochs']:
logging.warning("%d epochs with activity -> excited" % self._epoch.active_for)
self.set_excited()
plugins.on('epoch', self, self._epoch.epoch - 1, self._epoch.data())
if self._epoch.blind_for >= self._config['main']['mon_max_blind_epochs']:
logging.critical("%d epochs without visible access points -> rebooting ..." % self._epoch.blind_for)
self._reboot()
self._epoch.blind_for = 0

@ -1,9 +1,13 @@
import os
import time
import logging
# https://stackoverflow.com/questions/40426502/is-there-a-way-to-suppress-the-messages-tensorflow-prints/40426709
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # or any {'0', '1', '2'}
import warnings
# https://stackoverflow.com/questions/15777951/how-to-suppress-pandas-future-warning
warnings.simplefilter(action='ignore', category=FutureWarning)
import logging
def load(config, agent, epoch, from_disk=True):
@ -12,60 +16,27 @@ def load(config, agent, epoch, from_disk=True):
logging.info("ai disabled")
return False
try:
begin = time.time()
logging.info("[ai] bootstrapping dependencies ...")
logging.info("[ai] bootstrapping dependencies ...")
from stable_baselines import A2C
from stable_baselines.common.policies import MlpLstmPolicy
from stable_baselines.common.vec_env import DummyVecEnv
start = time.time()
from stable_baselines import A2C
logging.debug("[ai] A2C imported in %.2fs" % (time.time() - start))
import pwnagotchi.ai.gym as wrappers
start = time.time()
from stable_baselines.common.policies import MlpLstmPolicy
logging.debug("[ai] MlpLstmPolicy imported in %.2fs" % (time.time() - start))
env = wrappers.Environment(agent, epoch)
env = DummyVecEnv([lambda: env])
start = time.time()
from stable_baselines.common.vec_env import DummyVecEnv
logging.debug("[ai] DummyVecEnv imported in %.2fs" % (time.time() - start))
logging.info("[ai] bootstrapping model ...")
start = time.time()
import pwnagotchi.ai.gym as wrappers
logging.debug("[ai] gym wrapper imported in %.2fs" % (time.time() - start))
a2c = A2C(MlpLstmPolicy, env, **config['params'])
env = wrappers.Environment(agent, epoch)
env = DummyVecEnv([lambda: env])
if from_disk and os.path.exists(config['path']):
logging.info("[ai] loading %s ..." % config['path'])
a2c.load(config['path'], env)
else:
logging.info("[ai] model created:")
for key, value in config['params'].items():
logging.info(" %s: %s" % (key, value))
logging.info("[ai] creating model ...")
start = time.time()
a2c = A2C(MlpLstmPolicy, env, **config['params'])
logging.debug("[ai] A2C created in %.2fs" % (time.time() - start))
if from_disk and os.path.exists(config['path']):
logging.info("[ai] loading %s ..." % config['path'])
start = time.time()
try:
a2c.load(config['path'], env)
except AssertionError as as_err:
from fnmatch import fnmatch
# Sometimes the model breaks...
if not fnmatch(str(as_err), '* same * space as the model *'):
raise as_err
else:
logging.warning("[ai] Model could not be loaded. Using new model.")
else:
logging.debug("[ai] A2C loaded in %.2fs" % (time.time() - start))
else:
logging.info("[ai] model created:")
for key, value in config['params'].items():
logging.info(" %s: %s" % (key, value))
logging.debug("[ai] total loading time is %.2fs" % (time.time() - begin))
return a2c
except Exception as e:
logging.exception("error while starting AI (%s)", e)
logging.warning("[ai] AI not loaded!")
return False
return a2c

@ -19,10 +19,6 @@ class Epoch(object):
self.active_for = 0
# number of epochs with no visible access points
self.blind_for = 0
# number of epochs in sad state
self.sad_for = 0
# number of epochs in bored state
self.bored_for = 0
# did deauth in this epoch in the current channel?
self.did_deauth = False
# number of deauths in this epoch
@ -41,12 +37,6 @@ class Epoch(object):
self.num_hops = 0
# number of seconds sleeping
self.num_slept = 0
# number of peers seen during this epoch
self.num_peers = 0
# cumulative bond factor
self.tot_bond_factor = 0.0 # cum_bond_factor sounded really bad ...
# average bond factor
self.avg_bond_factor = 0.0
# any activity at all during this epoch?
self.any_activity = False
# when the current epoch started
@ -84,16 +74,10 @@ class Epoch(object):
else:
self.blind_for = 0
bond_unit_scale = self.config['personality']['bond_encounters_factor']
self.num_peers = len(peers)
num_peers = self.num_peers + 1e-10 # avoid division by 0
self.tot_bond_factor = sum((peer.encounters for peer in peers)) / bond_unit_scale
self.avg_bond_factor = self.tot_bond_factor / num_peers
num_aps = len(aps) + 1e-10
num_sta = sum(len(ap['clients']) for ap in aps) + 1e-10
num_peers = len(peers) + 1e-10
aps_per_chan = [0.0] * wifi.NumChannels
sta_per_chan = [0.0] * wifi.NumChannels
peers_per_chan = [0.0] * wifi.NumChannels
@ -103,13 +87,13 @@ class Epoch(object):
try:
aps_per_chan[ch_idx] += 1.0
sta_per_chan[ch_idx] += len(ap['clients'])
except IndexError:
except IndexError as e:
logging.error("got data on channel %d, we can store %d channels" % (ap['channel'], wifi.NumChannels))
for peer in peers:
try:
peers_per_chan[peer.last_channel - 1] += 1.0
except IndexError:
except IndexError as e:
logging.error(
"got peer data on channel %d, we can store %d channels" % (peer.last_channel, wifi.NumChannels))
@ -161,20 +145,6 @@ class Epoch(object):
else:
self.active_for += 1
self.inactive_for = 0
self.sad_for = 0
self.bored_for = 0
if self.inactive_for >= self.config['personality']['sad_num_epochs']:
# sad > bored; cant be sad and bored
self.bored_for = 0
self.sad_for += 1
elif self.inactive_for >= self.config['personality']['bored_num_epochs']:
# sad_treshhold > inactive > bored_treshhold; cant be sad and bored
self.sad_for = 0
self.bored_for += 1
else:
self.sad_for = 0
self.bored_for = 0
now = time.time()
cpu = pwnagotchi.cpu_load()
@ -190,13 +160,8 @@ class Epoch(object):
'blind_for_epochs': self.blind_for,
'inactive_for_epochs': self.inactive_for,
'active_for_epochs': self.active_for,
'sad_for_epochs': self.sad_for,
'bored_for_epochs': self.bored_for,
'missed_interactions': self.num_missed,
'num_hops': self.num_hops,
'num_peers': self.num_peers,
'tot_bond': self.tot_bond_factor,
'avg_bond': self.avg_bond_factor,
'num_deauths': self.num_deauths,
'num_associations': self.num_assocs,
'num_handshakes': self.num_shakes,
@ -208,20 +173,14 @@ class Epoch(object):
self._epoch_data['reward'] = self._reward(self.epoch + 1, self._epoch_data)
self._epoch_data_ready.set()
logging.info("[epoch %d] duration=%s slept_for=%s blind=%d sad=%d bored=%d inactive=%d active=%d peers=%d tot_bond=%.2f "
"avg_bond=%.2f hops=%d missed=%d deauths=%d assocs=%d handshakes=%d cpu=%d%% mem=%d%% "
"temperature=%dC reward=%s" % (
logging.info("[epoch %d] duration=%s slept_for=%s blind=%d inactive=%d active=%d hops=%d missed=%d "
"deauths=%d assocs=%d handshakes=%d cpu=%d%% mem=%d%% temperature=%dC reward=%s" % (
self.epoch,
utils.secs_to_hhmmss(self.epoch_duration),
utils.secs_to_hhmmss(self.num_slept),
self.blind_for,
self.sad_for,
self.bored_for,
self.inactive_for,
self.active_for,
self.num_peers,
self.tot_bond_factor,
self.avg_bond_factor,
self.num_hops,
self.num_missed,
self.num_deauths,
@ -236,9 +195,6 @@ class Epoch(object):
self.epoch_started = now
self.did_deauth = False
self.num_deauths = 0
self.num_peers = 0
self.tot_bond_factor = 0.0
self.avg_bond_factor = 0.0
self.did_associate = False
self.num_assocs = 0
self.num_missed = 0

@ -4,37 +4,31 @@ import pwnagotchi.mesh.wifi as wifi
MAX_EPOCH_DURATION = 1024
histogram_size = wifi.NumChannels
def describe(extended=False):
if not extended:
histogram_size = wifi.NumChannels
else:
# see https://github.com/evilsocket/pwnagotchi/issues/583
histogram_size = wifi.NumChannelsExt
return histogram_size, (1,
# aps per channel
histogram_size +
# clients per channel
histogram_size +
# peers per channel
histogram_size +
# duration
1 +
# inactive
1 +
# active
1 +
# missed
1 +
# hops
1 +
# deauths
1 +
# assocs
1 +
# handshakes
1)
shape = (1,
# aps per channel
histogram_size +
# clients per channel
histogram_size +
# peers per channel
histogram_size +
# duration
1 +
# inactive
1 +
# active
1 +
# missed
1 +
# hops
1 +
# deauths
1 +
# assocs
1 +
# handshakes
1)
def featurize(state, step):

@ -34,14 +34,10 @@ class Environment(gym.Env):
self._epoch_num = 0
self._last_render = None
# see https://github.com/evilsocket/pwnagotchi/issues/583
self._supported_channels = agent.supported_channels()
self._extended_spectrum = any(ch > 140 for ch in self._supported_channels)
self._histogram_size, self._observation_shape = featurizer.describe(self._extended_spectrum)
channels = agent.supported_channels()
Environment.params += [
Parameter('_channel_%d' % ch, min_value=0, max_value=1, meta=ch + 1) for ch in
range(self._histogram_size) if ch + 1 in self._supported_channels
range(featurizer.histogram_size) if ch + 1 in channels
]
self.last = {
@ -54,7 +50,7 @@ class Environment(gym.Env):
}
self.action_space = spaces.MultiDiscrete([p.space_size() for p in Environment.params if p.trainable])
self.observation_space = spaces.Box(low=0, high=1, shape=self._observation_shape, dtype=np.float32)
self.observation_space = spaces.Box(low=0, high=1, shape=featurizer.shape, dtype=np.float32)
self.reward_range = reward.range
@staticmethod
@ -122,7 +118,7 @@ class Environment(gym.Env):
return self.last['state_v']
def _render_histogram(self, hist):
for ch in range(self._histogram_size):
for ch in range(featurizer.histogram_size):
if hist[ch]:
logging.info(" CH %d: %s" % (ch + 1, hist[ch]))

@ -18,10 +18,4 @@ class RewardFunction(object):
m = -.3 * (state['missed_interactions'] / tot_interactions)
i = -.2 * (state['inactive_for_epochs'] / tot_epochs)
# include emotions if state >= 5 epochs
_sad = state['sad_for_epochs'] if state['sad_for_epochs'] >= 5 else 0
_bored = state['bored_for_epochs'] if state['bored_for_epochs'] >= 5 else 0
s = -.2 * (_sad / tot_epochs)
l = -.1 * (_bored / tot_epochs)
return h + a + c + b + i + m + s + l
return h + a + c + b + i + m

@ -8,6 +8,7 @@ import logging
import pwnagotchi.plugins as plugins
import pwnagotchi.ai as ai
from pwnagotchi.ai.epoch import Epoch
class Stats(object):
@ -87,6 +88,7 @@ class AsyncTrainer(object):
def __init__(self, config):
self._config = config
self._model = None
self._epoch = Epoch(config)
self._is_training = False
self._training_epochs = 0
self._nn_path = self._config['ai']['path']
@ -176,7 +178,7 @@ class AsyncTrainer(object):
self.set_training(True, epochs_per_episode)
self._model.learn(total_timesteps=epochs_per_episode, callback=self.on_ai_training_step)
except Exception as e:
logging.exception("[ai] error while training (%s)", e)
logging.exception("[ai] error while training")
finally:
self.set_training(False)
obs = self._model.env.reset()

@ -1,143 +0,0 @@
import logging
import pwnagotchi.plugins as plugins
from pwnagotchi.ai.epoch import Epoch
# basic mood system
class Automata(object):
def __init__(self, config, view):
self._config = config
self._view = view
self._epoch = Epoch(config)
def _on_miss(self, who):
logging.info("it looks like %s is not in range anymore :/", who)
self._epoch.track(miss=True)
self._view.on_miss(who)
def _on_error(self, who, e):
# when we're trying to associate or deauth something that is not in range anymore
# (if we are moving), we get the following error from bettercap:
# error 400: 50:c7:bf:2e:d3:37 is an unknown BSSID or it is in the association skip list.
if 'is an unknown BSSID' in str(e):
self._on_miss(who)
else:
logging.error(e)
def set_starting(self):
self._view.on_starting()
def set_ready(self):
plugins.on('ready', self)
def in_good_mood(self):
return self._has_support_network_for(1.0)
def _has_support_network_for(self, factor):
bond_factor = self._config['personality']['bond_encounters_factor']
total_encounters = sum(peer.encounters for _, peer in self._peers.items())
support_factor = total_encounters / bond_factor
return support_factor >= factor
# triggered when it's a sad/bad day but you have good friends around ^_^
def set_grateful(self):
self._view.on_grateful()
plugins.on('grateful', self)
def set_lonely(self):
if not self._has_support_network_for(1.0):
logging.info("unit is lonely")
self._view.on_lonely()
plugins.on('lonely', self)
else:
logging.info("unit is grateful instead of lonely")
self.set_grateful()
def set_bored(self):
factor = self._epoch.inactive_for / self._config['personality']['bored_num_epochs']
if not self._has_support_network_for(factor):
logging.warning("%d epochs with no activity -> bored", self._epoch.inactive_for)
self._view.on_bored()
plugins.on('bored', self)
else:
logging.info("unit is grateful instead of bored")
self.set_grateful()
def set_sad(self):
factor = self._epoch.inactive_for / self._config['personality']['sad_num_epochs']
if not self._has_support_network_for(factor):
logging.warning("%d epochs with no activity -> sad", self._epoch.inactive_for)
self._view.on_sad()
plugins.on('sad', self)
else:
logging.info("unit is grateful instead of sad")
self.set_grateful()
def set_angry(self, factor):
if not self._has_support_network_for(factor):
logging.warning("%d epochs with no activity -> angry", self._epoch.inactive_for)
self._view.on_angry()
plugins.on('angry', self)
else:
logging.info("unit is grateful instead of angry")
self.set_grateful()
def set_excited(self):
logging.warning("%d epochs with activity -> excited", self._epoch.active_for)
self._view.on_excited()
plugins.on('excited', self)
def set_rebooting(self):
self._view.on_rebooting()
plugins.on('rebooting', self)
def wait_for(self, t, sleeping=True):
plugins.on('sleep' if sleeping else 'wait', self, t)
self._view.wait(t, sleeping)
self._epoch.track(sleep=True, inc=t)
def is_stale(self):
return self._epoch.num_missed > self._config['personality']['max_misses_for_recon']
def any_activity(self):
return self._epoch.any_activity
def next_epoch(self):
logging.debug("agent.next_epoch()")
was_stale = self.is_stale()
did_miss = self._epoch.num_missed
self._epoch.next()
# after X misses during an epoch, set the status to lonely or angry
if was_stale:
factor = did_miss / self._config['personality']['max_misses_for_recon']
if factor >= 2.0:
self.set_angry(factor)
else:
logging.warning("agent missed %d interactions -> lonely", did_miss)
self.set_lonely()
# after X times being bored, the status is set to sad or angry
elif self._epoch.sad_for:
factor = self._epoch.inactive_for / self._config['personality']['sad_num_epochs']
if factor >= 2.0:
self.set_angry(factor)
else:
self.set_sad()
# after X times being inactive, the status is set to bored
elif self._epoch.bored_for:
self.set_bored()
# after X times being active, the status is set to happy / excited
elif self._epoch.active_for >= self._config['personality']['excited_num_epochs']:
self.set_excited()
elif self._epoch.active_for >= 5 and self._has_support_network_for(5.0):
self.set_grateful()
plugins.on('epoch', self, self._epoch.epoch - 1, self._epoch.data())
if self._epoch.blind_for >= self._config['main']['mon_max_blind_epochs']:
logging.critical("%d epochs without visible access points -> rebooting ...", self._epoch.blind_for)
self._reboot()
self._epoch.blind_for = 0

@ -1,34 +1,6 @@
import json
import logging
import requests
import websockets
import asyncio
import random
from requests.auth import HTTPBasicAuth
from time import sleep
requests.adapters.DEFAULT_RETRIES = 5 # increase retries number
ping_timeout = 180
ping_interval = 15
max_queue = 10000
min_sleep = 0.5
max_sleep = 5.0
def decode(r, verbose_errors=True):
try:
return r.json()
except Exception as e:
if r.status_code == 200:
logging.error("error while decoding json: error='%s' resp='%s'" % (e, r.text))
else:
err = "error %d: %s" % (r.status_code, r.text.strip())
if verbose_errors:
logging.info(err)
raise Exception(err)
return r.text
class Client(object):
@ -39,81 +11,29 @@ class Client(object):
self.username = username
self.password = password
self.url = "%s://%s:%d/api" % (scheme, hostname, port)
self.websocket = "ws://%s:%s@%s:%d/api" % (username, password, hostname, port)
self.auth = HTTPBasicAuth(username, password)
# session takes optional argument to pull a sub-dictionary
# ex.: "session/wifi", "session/ble"
def session(self, sess="session"):
r = requests.get("%s/%s" % (self.url, sess), auth=self.auth)
return decode(r)
def _decode(self, r, verbose_errors=True):
try:
return r.json()
except Exception as e:
if r.status_code == 200:
logging.error("error while decoding json: error='%s' resp='%s'" % (e, r.text))
else:
err = "error %d: %s" % (r.status_code, r.text.strip())
if verbose_errors:
logging.info(err)
raise Exception(err)
return r.text
async def start_websocket(self, consumer):
s = "%s/events" % self.websocket
# More modern version of the approach below
# logging.info("Creating new websocket...")
# async for ws in websockets.connect(s):
# try:
# async for msg in ws:
# try:
# await consumer(msg)
# except Exception as ex:
# logging.debug("Error while parsing event (%s)", ex)
# except websockets.exceptions.ConnectionClosedError:
# sleep_time = max_sleep*random.random()
# logging.warning('Retrying websocket connection in {} sec'.format(sleep_time))
# await asyncio.sleep(sleep_time)
# continue
# restarted every time the connection fails
while True:
logging.info("creating new websocket...")
try:
async with websockets.connect(s, ping_interval=ping_interval, ping_timeout=ping_timeout, max_queue=max_queue) as ws:
# listener loop
while True:
try:
async for msg in ws:
try:
await consumer(msg)
except Exception as ex:
logging.debug("error while parsing event (%s)", ex)
except websockets.exceptions.ConnectionClosedError:
try:
pong = await ws.ping()
await asyncio.wait_for(pong, timeout=ping_timeout)
logging.warning('ping OK, keeping connection alive...')
continue
except:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning('ping error - retrying connection in {} sec'.format(sleep_time))
await asyncio.sleep(sleep_time)
break
except ConnectionRefusedError:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning('nobody seems to be listening at the bettercap endpoint...')
logging.warning('retrying connection in {} sec'.format(sleep_time))
await asyncio.sleep(sleep_time)
continue
except OSError:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning('connection to the bettercap endpoint failed...')
logging.warning('retrying connection in {} sec'.format(sleep_time))
await asyncio.sleep(sleep_time)
continue
def session(self):
r = requests.get("%s/session" % self.url, auth=self.auth)
return self._decode(r)
def events(self):
r = requests.get("%s/events" % self.url, auth=self.auth)
return self._decode(r)
def run(self, command, verbose_errors=True):
while True:
try:
r = requests.post("%s/session" % self.url, auth=self.auth, json={'cmd': command})
except requests.exceptions.ConnectionError as e:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning("can't run my request... connection to the bettercap endpoint failed...")
logging.warning('retrying run in {} sec'.format(sleep_time))
sleep(sleep_time)
else:
break
return decode(r, verbose_errors=verbose_errors)
r = requests.post("%s/session" % self.url, auth=self.auth, json={'cmd': command})
return self._decode(r, verbose_errors=verbose_errors)

@ -1,244 +0,0 @@
main.name = ""
main.lang = "en"
main.confd = "/etc/pwnagotchi/conf.d/"
main.custom_plugins = "/usr/local/share/pwnagotchi/custom-plugins"
main.custom_plugin_repos = [
"https://git.chadwaltercummings.me/scifijunkie/pwnagotchi-plugins-contrib.git"
]
main.iface = "mon0"
main.mon_start_cmd = "/usr/bin/monstart"
main.mon_stop_cmd = "/usr/bin/monstop"
main.mon_max_blind_epochs = 50
main.no_restart = false
main.whitelist = [
"EXAMPLE_NETWORK",
"ANOTHER_EXAMPLE_NETWORK",
"fo:od:ba:be:fo:od",
"fo:od:ba"
]
main.filter = ""
main.log.debug = false
main.plugins.grid.enabled = true
main.plugins.grid.report = false
main.plugins.grid.exclude = [
"YourHomeNetworkHere"
]
main.plugins.auto-update.enabled = true
main.plugins.auto-update.install = true
main.plugins.auto-update.interval = 1
main.plugins.net-pos.enabled = false
main.plugins.net-pos.api_key = "test"
main.plugins.gps.enabled = false
main.plugins.gps.speed = 19200
main.plugins.gps.device = "/dev/ttyUSB0" # for GPSD: "localhost:2947"
main.plugins.webgpsmap.enabled = false
main.plugins.onlinehashcrack.enabled = false
main.plugins.onlinehashcrack.email = ""
main.plugins.onlinehashcrack.dashboard = ""
main.plugins.onlinehashcrack.single_files = false
main.plugins.onlinehashcrack.whitelist = []
main.plugins.wpa-sec.enabled = false
main.plugins.wpa-sec.api_key = ""
main.plugins.wpa-sec.api_url = "https://wpa-sec.stanev.org"
main.plugins.wpa-sec.download_results = false
main.plugins.wpa-sec.download_interval = 3600
main.plugins.wpa-sec.whitelist = []
main.plugins.wigle.enabled = false
main.plugins.wigle.api_key = ""
main.plugins.wigle.whitelist = []
main.plugins.wigle.donate = true
main.plugins.bt-tether.enabled = false
main.plugins.bt-tether.devices.android-phone.enabled = false
main.plugins.bt-tether.devices.android-phone.search_order = 1
main.plugins.bt-tether.devices.android-phone.mac = ""
main.plugins.bt-tether.devices.android-phone.ip = "192.168.44.44"
main.plugins.bt-tether.devices.android-phone.netmask = 24
main.plugins.bt-tether.devices.android-phone.interval = 1
main.plugins.bt-tether.devices.android-phone.scantime = 10
main.plugins.bt-tether.devices.android-phone.max_tries = 10
main.plugins.bt-tether.devices.android-phone.share_internet = false
main.plugins.bt-tether.devices.android-phone.priority = 1
main.plugins.bt-tether.devices.ios-phone.enabled = false
main.plugins.bt-tether.devices.ios-phone.search_order = 2
main.plugins.bt-tether.devices.ios-phone.mac = ""
main.plugins.bt-tether.devices.ios-phone.ip = "172.20.10.6"
main.plugins.bt-tether.devices.ios-phone.netmask = 24
main.plugins.bt-tether.devices.ios-phone.interval = 5
main.plugins.bt-tether.devices.ios-phone.scantime = 20
main.plugins.bt-tether.devices.ios-phone.max_tries = 0
main.plugins.bt-tether.devices.ios-phone.share_internet = false
main.plugins.bt-tether.devices.ios-phone.priority = 999
main.plugins.memtemp.enabled = false
main.plugins.memtemp.scale = "celsius"
main.plugins.memtemp.orientation = "horizontal"
main.plugins.paw-gps.enabled = false
main.plugins.paw-gps.ip = "192.168.44.1:8080"
main.plugins.ups_lite.enabled = false
main.plugins.ups_lite.shutdown = 2
main.plugins.gpio_buttons.enabled = false
main.plugins.led.enabled = true
main.plugins.led.led = 0
main.plugins.led.delay = 200
main.plugins.led.patterns.loaded = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.updating = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.unread_inbox = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.ready = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.ai_ready = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.ai_training_start = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.ai_best_reward = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.ai_worst_reward = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.bored = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.sad = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.excited = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.lonely = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.rebooting = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.wait = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.sleep = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.wifi_update = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.association = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.deauthentication = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.handshake = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.epoch = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.peer_detected = "oo oo oo oo oo oo oo"
main.plugins.led.patterns.peer_lost = "oo oo oo oo oo oo oo"
main.plugins.logtail.enabled = false
main.plugins.logtail.max-lines = 10000
main.plugins.session-stats.enabled = true
main.plugins.session-stats.save_directory = "/var/tmp/pwnagotchi/sessions/"
main.log.path = "/var/log/pwnagotchi.log"
main.log.rotation.enabled = true
main.log.rotation.size = "10M"
ai.enabled = true
ai.path = "/root/brain.nn"
ai.laziness = 0.1
ai.epochs_per_episode = 50
ai.params.gamma = 0.99
ai.params.n_steps = 1
ai.params.vf_coef = 0.25
ai.params.ent_coef = 0.01
ai.params.max_grad_norm = 0.5
ai.params.learning_rate = 0.001
ai.params.alpha = 0.99
ai.params.epsilon = 0.00001
ai.params.verbose = 1
ai.params.lr_schedule = "constant"
personality.advertise = true
personality.deauth = true
personality.associate = true
personality.channels = []
personality.min_rssi = -200
personality.ap_ttl = 120
personality.sta_ttl = 300
personality.recon_time = 30
personality.max_inactive_scale = 2
personality.recon_inactive_multiplier = 2
personality.hop_recon_time = 10
personality.min_recon_time = 5
personality.max_interactions = 3
personality.max_misses_for_recon = 5
personality.excited_num_epochs = 10
personality.bored_num_epochs = 15
personality.sad_num_epochs = 25
personality.bond_encounters_factor = 20000
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_l = "(☉_☉ )"
ui.faces.look_r_happy = "( ◕‿◕)"
ui.faces.look_l_happy = "(◕‿◕ )"
ui.faces.sleep = "(⇀‿‿↼)"
ui.faces.sleep2 = "(≖‿‿≖)"
ui.faces.awake = "(◕‿‿◕)"
ui.faces.bored = "(-__-)"
ui.faces.intense = "(°▃▃°)"
ui.faces.cool = "(⌐■_■)"
ui.faces.happy = "(•‿‿•)"
ui.faces.excited = "(ᵔ◡◡ᵔ)"
ui.faces.grateful = "(^‿‿^)"
ui.faces.motivated = "(☼‿‿☼)"
ui.faces.demotivated = "(≖__≖)"
ui.faces.smart = "(✜‿‿✜)"
ui.faces.lonely = "(ب__ب)"
ui.faces.sad = "(╥☁╥ )"
ui.faces.angry = "(-_-')"
ui.faces.friend = "(♥‿‿♥)"
ui.faces.broken = "(☓‿‿☓)"
ui.faces.debug = "(#__#)"
ui.faces.upload = "(1__0)"
ui.faces.upload1 = "(1__1)"
ui.faces.upload2 = "(0__1)"
ui.web.enabled = true
ui.web.address = "0.0.0.0"
ui.web.username = "changeme"
ui.web.password = "changeme"
ui.web.origin = ""
ui.web.port = 8080
ui.web.on_frame = ""
ui.display.enabled = true
ui.display.rotation = 180
ui.display.type = "waveshare_2"
ui.display.color = "black"
bettercap.scheme = "http"
bettercap.hostname = "localhost"
bettercap.port = 8081
bettercap.username = "pwnagotchi"
bettercap.password = "pwnagotchi"
bettercap.handshakes = "/root/handshakes"
bettercap.silence = [
"ble.device.new",
"ble.device.lost",
"ble.device.disconnected",
"ble.device.connected",
"ble.device.service.discovered",
"ble.device.characteristic.discovered",
"wifi.client.new",
"wifi.client.lost",
"wifi.client.probe",
"wifi.ap.new",
"wifi.ap.lost",
"mod.started"
]
fs.memory.enabled = false
fs.memory.mounts.log.enabled = false
fs.memory.mounts.log.mount = "/var/log"
fs.memory.mounts.log.size = "50M"
fs.memory.mounts.log.sync = 60
fs.memory.mounts.log.zram = true
fs.memory.mounts.log.rsync = true
fs.memory.mounts.data.enabled = false
fs.memory.mounts.data.mount = "/var/tmp/pwnagotchi"
fs.memory.mounts.data.size = "10M"
fs.memory.mounts.data.sync = 3600
fs.memory.mounts.data.zram = false
fs.memory.mounts.data.rsync = true

206
pwnagotchi/defaults.yml Normal file

@ -0,0 +1,206 @@
# WARNING WARNING WARNING WARNING
#
# This file is recreated with default settings on every pwnagotchi restart,
# use /etc/pwnagotchi/config.yml to configure this unit.
#
#
# main algorithm configuration
main:
# currently implemented: en (default), de, el, fr, it, mk, nl, ru, se, pt-BR, es, pt
lang: en
# custom plugins path, if null only default plugins with be loaded
custom_plugins:
# which plugins to load and enable
plugins:
grid:
enabled: true
report: false # don't report pwned networks by default!
exclude: # do not report the following networks (accepts both ESSIDs and BSSIDs)
- YourHomeNetworkHere
auto-backup:
enabled: false
interval: 1 # every day
files:
- /root/brain.nn
- /root/brain.json
- /root/.api-report.json
- /root/handshakes/
- /etc/pwnagotchi/
- /etc/hostname
- /etc/hosts
- /etc/motd
- /var/log/pwnagotchi.log
commands:
- 'tar czf /tmp/backup.tar.gz {files}'
- 'scp /tmp/backup.tar.gz pwnagotchi@10.0.0.1:/home/pwnagotchi/backups/backup-$(date +%s).tar.gz'
net-pos:
enabled: false
api_key: 'test'
gps:
enabled: false
speed: 19200
device: /dev/ttyUSB0
twitter:
enabled: false
consumer_key: aaa
consumer_secret: aaa
access_token_key: aaa
access_token_secret: aaa
onlinehashcrack:
enabled: false
email: ~
wpa-sec:
enabled: false
api_key: ~
wigle:
enabled: false
api_key: ~
screen_refresh:
enabled: false
refresh_interval: 50
quickdic:
enabled: false
wordlist_folder: /opt/wordlists/
AircrackOnly:
enabled: false
bt-tether:
enabled: false # if you want to use this, set ui.display.video.address to 0.0.0.0
mac: ~ # mac of your bluetooth device
ip: '192.168.44.44' # ip from which your pwnagotchi should be reachable
netmask: 24
interval: 1 # check every x minutes for device
share_internet: false
memtemp: # Display memory usage and cpu temperature on screen
enabled: false
# monitor interface to use
iface: mon0
# command to run to bring the mon interface up in case it's not up already
mon_start_cmd: /usr/bin/monstart
mon_stop_cmd: /usr/bin/monstop
mon_max_blind_epochs: 50
# log file
log: /var/log/pwnagotchi.log
# if true, will not restart the wifi module
no_restart: false
# access points to ignore
whitelist:
- EXAMPLE_NETWORK
- ANOTHER_EXAMPLE_NETWORK
# if not null, filter access points by this regular expression
filter: null
ai:
# if false, only the default 'personality' will be used
enabled: true
path: /root/brain.nn
# 1.0 - laziness = probability of start training
laziness: 0.1
# how many epochs to train on
epochs_per_episode: 50
params:
# discount factor
gamma: 0.99
# the number of steps to run for each environment per update
n_steps: 1
# value function coefficient for the loss calculation
vf_coef: 0.25
# entropy coefficient for the loss calculation
ent_coef: 0.01
# maximum value for the gradient clipping
max_grad_norm: 0.5
# the learning rate
learning_rate: 0.0010
# rmsprop decay parameter
alpha: 0.99
# rmsprop epsilon
epsilon: 0.00001
# the verbosity level: 0 none, 1 training information, 2 tensorflow debug
verbose: 1
# type of scheduler for the learning rate update ('linear', 'constant', 'double_linear_con', 'middle_drop' or 'double_middle_drop')
lr_schedule: 'constant'
# the log location for tensorboard (if None, no logging)
tensorboard_log: null
personality:
# advertise our presence
advertise: true
# perform a deauthentication attack to client stations in order to get full or half handshakes
deauth: true
# send association frames to APs in order to get the PMKID
associate: true
# list of channels to recon on, or empty for all channels
channels: []
# minimum WiFi signal strength in dBm
min_rssi: -200
# number of seconds for wifi.ap.ttl
ap_ttl: 120
# number of seconds for wifi.sta.ttl
sta_ttl: 300
# time in seconds to wait during channel recon
recon_time: 30
# number of inactive epochs after which recon_time gets multiplied by recon_inactive_multiplier
max_inactive_scale: 2
# if more than max_inactive_scale epochs are inactive, recon_time *= recon_inactive_multiplier
recon_inactive_multiplier: 2
# time in seconds to wait during channel hopping if activity has been performed
hop_recon_time: 10
# time in seconds to wait during channel hopping if no activity has been performed
min_recon_time: 5
# maximum amount of deauths/associations per BSSID per session
max_interactions: 3
# maximum amount of misses before considering the data stale and triggering a new recon
max_misses_for_recon: 5
# number of active epochs that triggers the excited state
excited_num_epochs: 10
# number of inactive epochs that triggers the bored state
bored_num_epochs: 15
# number of inactive epochs that triggers the sad state
sad_num_epochs: 25
# ui configuration
ui:
# ePaper display can update every 3 secs anyway, set to 0 to only refresh for major data changes
# IMPORTANT: The lifespan of an eINK display depends on the cumulative amount of refreshes. If you want to
# preserve your display over time, you should set this value to 0.0 so that the display will be refreshed only
# if any of the important data fields changed (the uptime and blinking cursor won't trigger a refresh).
fps: 0.0
display:
enabled: true
rotation: 180
# Possible options inkyphat/inky, papirus/papi, waveshare_1/ws_1 or waveshare_2/ws_2, oledhat
type: 'waveshare_2'
# Possible options red/yellow/black (black used for monocromatic displays)
color: 'black'
video:
enabled: true
address: '0.0.0.0'
port: 8080
# bettercap rest api configuration
bettercap:
# api scheme://hostname:port username and password
scheme: http
hostname: localhost
port: 8081
username: pwnagotchi
password: pwnagotchi
# folder where bettercap stores the WPA handshakes, given that
# wifi.handshakes.aggregate will be set to false and individual
# pcap files will be created in order to minimize the chances
# of a single pcap file to get corrupted
handshakes: /root/handshakes
# events to mute in bettercap's events stream
silence:
- ble.device.new
- ble.device.lost
- ble.device.disconnected
- ble.device.connected
- ble.device.service.discovered
- ble.device.characteristic.discovered
- wifi.client.new
- wifi.client.lost
- wifi.client.probe
- wifi.ap.new
- wifi.ap.lost
- mod.started

@ -1,190 +0,0 @@
import os
import re
import tempfile
import contextlib
import shutil
import _thread
import logging
from time import sleep
from distutils.dir_util import copy_tree
mounts = list()
@contextlib.contextmanager
def ensure_write(filename, mode='w'):
path = os.path.dirname(filename)
fd, tmp = tempfile.mkstemp(dir=path)
with os.fdopen(fd, mode) as f:
yield f
f.flush()
os.fsync(f.fileno())
os.replace(tmp, filename)
def size_of(path):
"""
Calculate the sum of all the files in path
"""
total = 0
for root, _, files in os.walk(path):
for f in files:
total += os.path.getsize(os.path.join(root, f))
return total
def is_mountpoint(path):
"""
Checks if path is mountpoint
"""
return os.system(f"mountpoint -q {path}") == 0
def setup_mounts(config):
"""
Sets up all the configured mountpoints
"""
global mounts
fs_cfg = config['fs']['memory']
if not fs_cfg['enabled']:
return
for name, options in fs_cfg['mounts'].items():
if not options['enabled']:
continue
logging.debug("[FS] Trying to setup mount %s (%s)", name, options['mount'])
size,unit = re.match(r"(\d+)([a-zA-Z]+)", options['size']).groups()
target = os.path.join('/run/pwnagotchi/disk/', os.path.basename(options['mount']))
is_mounted = is_mountpoint(target)
logging.debug("[FS] %s is %s mounted", options['mount'],
"already" if is_mounted else "not yet")
m = MemoryFS(
options['mount'],
target,
size=options['size'],
zram=options['zram'],
zram_disk_size=f"{int(size)*2}{unit}",
rsync=options['rsync'])
if not is_mounted:
if not m.mount():
logging.debug(f"Error while mounting {m.mountpoint}")
continue
if not m.sync(to_ram=True):
logging.debug(f"Error while syncing to {m.mountpoint}")
m.umount()
continue
interval = int(options['sync'])
if interval:
logging.debug("[FS] Starting thread to sync %s (interval: %d)",
options['mount'], interval)
_thread.start_new_thread(m.daemonize, (interval,))
else:
logging.debug("[FS] Not syncing %s, because interval is 0",
options['mount'])
mounts.append(m)
class MemoryFS:
@staticmethod
def zram_install():
if not os.path.exists("/sys/class/zram-control"):
logging.debug("[FS] Installing zram")
return os.system("modprobe zram") == 0
return True
@staticmethod
def zram_dev():
logging.debug("[FS] Adding zram device")
return open("/sys/class/zram-control/hot_add", "rt").read().strip("\n")
def __init__(self, mount, disk, size="40M",
zram=True, zram_alg="lz4", zram_disk_size="100M",
zram_fs_type="ext4", rsync=True):
self.mountpoint = mount
self.disk = disk
self.size = size
self.zram = zram
self.zram_alg = zram_alg
self.zram_disk_size = zram_disk_size
self.zram_fs_type = zram_fs_type
self.zdev = None
self.rsync = True
self._setup()
def _setup(self):
if self.zram and MemoryFS.zram_install():
# setup zram
self.zdev = MemoryFS.zram_dev()
open(f"/sys/block/zram{self.zdev}/comp_algorithm", "wt").write(self.zram_alg)
open(f"/sys/block/zram{self.zdev}/disksize", "wt").write(self.zram_disk_size)
open(f"/sys/block/zram{self.zdev}/mem_limit", "wt").write(self.size)
logging.debug("[FS] Creating fs (type: %s)", self.zram_fs_type)
os.system(f"mke2fs -t {self.zram_fs_type} /dev/zram{self.zdev} >/dev/null 2>&1")
# ensure mountpoints exist
if not os.path.exists(self.disk):
logging.debug("[FS] Creating %s", self.disk)
os.makedirs(self.disk)
if not os.path.exists(self.mountpoint):
logging.debug("[FS] Creating %s", self.mountpoint)
os.makedirs(self.mountpoint)
def daemonize(self, interval=60):
logging.debug("[FS] Daemonized...")
while True:
self.sync()
sleep(interval)
def sync(self, to_ram=False):
source, dest = (self.disk, self.mountpoint) if to_ram else (self.mountpoint, self.disk)
needed, actually_free = size_of(source), shutil.disk_usage(dest)[2]
if actually_free >= needed:
logging.debug("[FS] Syncing %s -> %s", source,dest)
if self.rsync:
os.system(f"rsync -aXv --inplace --no-whole-file --delete-after {source}/ {dest}/ >/dev/null 2>&1")
else:
copy_tree(source, dest, preserve_symlinks=True)
os.system("sync")
return True
return False
def mount(self):
if os.system(f"mount --bind {self.mountpoint} {self.disk}"):
return False
if os.system(f"mount --make-private {self.disk}"):
return False
if self.zram and self.zdev is not None:
if os.system(f"mount -t {self.zram_fs_type} -o nosuid,noexec,nodev,user=pwnagotchi /dev/zram{self.zdev} {self.mountpoint}/"):
return False
else:
if os.system(f"mount -t tmpfs -o nosuid,noexec,nodev,mode=0755,size={self.size} pwnagotchi {self.mountpoint}/"):
return False
return True
def umount(self):
if os.system(f"umount -l {self.mountpoint}"):
return False
if os.system(f"umount -l {self.disk}"):
return False
return True

@ -12,13 +12,9 @@ API_ADDRESS = "http://127.0.0.1:8666/api/v1"
def is_connected():
try:
# check DNS
host = socket.gethostbyname('api.pwnagotchi.ai')
if host:
# check connectivity itself
socket.create_connection((host, 443), timeout=30)
return True
except:
socket.create_connection(("www.google.com", 80))
return True
except OSError:
pass
return False
@ -26,11 +22,9 @@ def is_connected():
def call(path, obj=None):
url = '%s%s' % (API_ADDRESS, path)
if obj is None:
r = requests.get(url, headers=None, timeout=(30.0, 60.0))
elif isinstance(obj, dict):
r = requests.post(url, headers=None, json=obj, timeout=(30.0, 60.0))
r = requests.get(url, headers=None)
else:
r = requests.post(url, headers=None, data=obj, timeout=(30.0, 60.0))
r = requests.post(url, headers=None, json=obj)
if r.status_code != 200:
raise Exception("(status %d) %s" % (r.status_code, r.text))
@ -45,14 +39,6 @@ def set_advertisement_data(data):
return call("/mesh/data", obj=data)
def get_advertisement_data():
return call("/mesh/data")
def memory():
return call("/mesh/memory")
def peers():
return call("/mesh/peers")
@ -85,7 +71,7 @@ def update_data(last_session):
},
'uname': subprocess.getoutput("uname -a"),
'brain': brain,
'version': pwnagotchi.__version__
'version': pwnagotchi.version
}
logging.debug("updating grid data: %s" % data)
@ -109,15 +95,3 @@ def report_ap(essid, bssid):
def inbox(page=1, with_pager=False):
obj = call("/inbox?p=%d" % page)
return obj["messages"] if not with_pager else obj
def inbox_message(id):
return call("/inbox/%d" % int(id))
def mark_message(id, mark):
return call("/inbox/%d/%s" % (int(id), str(mark)))
def send_message(to, message):
return call("/unit/%s/inbox" % to, message.encode('utf-8'))

@ -27,7 +27,7 @@ class KeyPair(object):
if not os.path.exists(self.priv_path) or not os.path.exists(self.pub_path):
self._view.on_keys_generation()
logging.info("generating %s ..." % self.priv_path)
os.system("pwngrid -generate -keys '%s'" % self.path)
os.system("/usr/bin/ssh-keygen -t rsa -m PEM -b 4096 -N '' -f '%s'" % self.priv_path)
# load keys: they might be corrupted if the unit has been turned off during the generation, in this case
# the exception will remove the files and go back at the beginning of this loop.

Binary file not shown.

@ -1,248 +0,0 @@
# Afrikaans translation of pwnagotchi.
# Copyright (C) 2020.
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR MatthewNunu https://github.com/MatthewNunu, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: 1.5.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-29 21:50+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: MatthewNunu https://github.com/MatthewNunu\n"
"Language-Team: \n"
"Language: Afrikaans\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hi, ek is Pwnagotchi! Aanvang ..."
msgid "New day, new hunt, new pwns!"
msgstr "Nuwe dag, nuwe jag, nuwe pwns!"
msgid "Hack the Planet!"
msgstr "Hack die wêreld!"
msgid "AI ready."
msgstr "AI gereed."
msgid "The neural network is ready."
msgstr "Die neurale netwerk is gereed."
msgid "Generating keys, do not turn off ..."
msgstr "Genereer wagwoord, moenie afskakel nie ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Haai, kanaal {channel} is gratis! Jou AP sal dankie sê."
msgid "Reading last session logs ..."
msgstr "Lees laaste sessie logs ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Ek het {lines_so_far} tot dusver gelees ..."
msgid "I'm bored ..."
msgstr "Ek's verveeld ..."
msgid "Let's go for a walk!"
msgstr "Kom ons gaan vir 'n loopie!"
msgid "This is the best day of my life!"
msgstr "Dit is die beste dag van my lewe!"
msgid "Shitty day :/"
msgstr "Poes kak dag :/"
msgid "I'm extremely bored ..."
msgstr "Ek's baie verveeld ..."
msgid "I'm very sad ..."
msgstr "Ek's baie hartseer ..."
msgid "I'm sad"
msgstr "Ek's hartseer ..."
msgid "Leave me alone ..."
msgstr "Los my uit ..."
msgid "I'm mad at you!"
msgstr "Ek is kwaad vir jou!"
msgid "I'm living the life!"
msgstr "Ek leef die lewe!"
msgid "I pwn therefore I am."
msgstr "Ek pwn daarom is ek."
msgid "So many networks!!!"
msgstr "Soveel netwerke!!!"
msgid "I'm having so much fun!"
msgstr "Ek het soveel pret!"
msgid "My crime is that of curiosity ..."
msgstr "My misdaad is dié van nuuskierigheid ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hallo {name}! Lekker om jou te ontmoet."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Yo {name}! Sup?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Haai {name} hoe doen jy?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Eenheid {name}} is naby!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm ... totsiens {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} is weg ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Whoops ... {name} is weg."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} gemis!"
msgid "Missed!"
msgstr "Gemis!"
msgid "Good friends are a blessing!"
msgstr "Goeie vriende is 'n seën!"
msgid "I love my friends!"
msgstr "Ek is lief vir my vriende!"
msgid "Nobody wants to play with me ..."
msgstr "Niemand wil met my speel nie ..."
msgid "I feel so alone ..."
msgstr "Ek voel so alleen ..."
msgid "Where's everybody?!"
msgstr "Waar is almal?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Slaap vir {secs}s ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Goeie nag."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Wag tans vir {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Rondkyk ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Haai {what} kom ons wees vriende!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Assosieer na {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Yo {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Net besluit dat {mac} geen WiFi nodig het nie!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Deauthenticating {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickbanning {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Koel, ons het {num} nuwe handdruk gekry!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Jy het {count} nuwe boodskap!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Oops, iets het verkeerd gegaan ... Herlaai ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Geskop {num} stasies\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Gemaak {num} nuwe vriende\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Het {num} handdrukke\n"
msgid "Met 1 peer"
msgstr "Ontmoet 1 eweknie"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Ontmoet {num} eweknie"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"Ek was pwning vir {duration} en het {deauthed} kliënte geskop! Ek het ook ontmoet "
"{associated} nuwe vriende en het {handshakes} handdrukke geëet! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "uur"
msgid "minutes"
msgstr "minute"
msgid "seconds"
msgstr "sekondes"
msgid "hour"
msgstr "uur"
msgid "minute"
msgstr "minuut"
msgid "second"
msgstr "tweede"

Binary file not shown.

@ -1,226 +0,0 @@
# pwnagotchi voice data.
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR <https://github.com/georgikoemdzhiev>, 2019.
#
#,
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-23 20:56+0200\n"
"PO-Revision-Date: 2019-10-23 20:56+0200\n"
"Last-Translator: Georgi Koemdzhiev <https://github.com/georgikoemdzhiev>\n"
"Language-Team: \n"
"Language: bulgarian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr ""
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Здравей, аз съм Pwnagotchi! Стартиране ..."
msgid "New day, new hunt, new pwns!"
msgstr "Нов ден, нов лов, нови pwns!"
msgid "Hack the Planet!"
msgstr "Хакни планетата!"
msgid "AI ready."
msgstr "AI готов."
msgid "The neural network is ready."
msgstr "Невронната мрежа е готова."
msgid "Generating keys, do not turn off ..."
msgstr "Генериране на ключове, не изключвай ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Здравей, канал {channel} е свободен! твоя AP ще каже благодаря."
msgid "I'm bored ..."
msgstr "Скучно ми е ..."
msgid "Let's go for a walk!"
msgstr "Хайда да се поразходим!"
msgid "This is the best day of my life!"
msgstr "Това е най-добрият ден в живота ми!"
msgid "Shitty day :/"
msgstr "Тъп ден :/"
msgid "I'm extremely bored ..."
msgstr "Супер много ми е скучно ..."
msgid "I'm very sad ..."
msgstr "Много съм тъжен ..."
msgid "I'm sad"
msgstr "Тъжен съм"
msgid "I'm living the life!"
msgstr "Живота ми е фантастичен!"
msgid "I pwn therefore I am."
msgstr "Аз живея за да pwn-вам."
msgid "So many networks!!!"
msgstr "Толкова много мрежи!!!"
msgid "I'm having so much fun!"
msgstr "Толкова много се забавлявам!"
msgid "My crime is that of curiosity ..."
msgstr "Моето престъпление е това че съм любопитен ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Здравей {name}! Приятно ми е да се запознаем."
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Устройство {name} е наблизо!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Ами ... довиждане {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} изчезна ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Упс ... {name} изчезна."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} загубен!"
msgid "Missed!"
msgstr "Загубен!"
msgid "Good friends are a blessing!"
msgstr "Добрите приятели са благословия!"
msgid "I love my friends!"
msgstr "Обичам приятелите си!"
msgid "Nobody wants to play with me ..."
msgstr "Никой не иска да си играе с мен ..."
msgid "I feel so alone ..."
msgstr "Чувствам се толкова самотен ..."
msgid "Where's everybody?!"
msgstr "Къде са всички?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Заспивам за {secs} секунди ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Лека нощ."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Чакам {secs} секунди ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Оглеждам се ({secs}секунди)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Хей {what} нека станем приятели!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Свръзване с {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Ей {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Реших, че {mac} не се нуждае от WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Неудостоверяване на {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Ритам и прогонвам {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Супер, имаме {num} нови handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Имате {count} нови съобщения!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Упс, нещо се обърка ... Рестартиране ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Отхвърлих {num} станции\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Направих {num} нови приятели\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Имам {num} handshakes\n"
msgid "Met 1 peer"
msgstr "Срещнах 1 връстник"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Срещнах {num} връстници"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "Аз pwn-вах за {duration} и отхвърлих {deauthed} clients! Също така срещнах {associated} нови приятели и изядох {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "часове"
msgid "minutes"
msgstr "минути"
msgid "seconds"
msgstr "секунди"
msgid "hour"
msgstr "час"
msgid "minute"
msgstr "минута"
msgid "second"
msgstr "секунда"

Binary file not shown.

@ -1,225 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <511225068@qq.com>, 2019.
# 还有很多未翻译和翻译不准确,后期希望大家加入进来一起翻译!
# 翻译可以联系QQ群959559103 找 名字叫 初九 的 管理员
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-23 20:56+0200\n"
"PO-Revision-Date: 2019-11-02 10:00+0008\n"
"Last-Translator: 极客之眼-初九 <511225068@qq.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: chinese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr ""
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "主人,你好.我是WiFi狩猎兽..."
msgid "New day, new hunt, new pwns!"
msgstr "美好的一天,狩猎开始!"
msgid "Hack the Planet!"
msgstr "我要入侵整个地球!"
msgid "AI ready."
msgstr "人工智能已启动."
msgid "The neural network is ready."
msgstr "神经元网络已启动."
msgid "Generating keys, do not turn off ..."
msgstr "创建密钥中, 请勿断电..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "嘿,频道{channel}是免费的你的AP会说谢谢。"
msgid "I'm bored ..."
msgstr "我无聊了..."
msgid "Let's go for a walk!"
msgstr "主人带我出门走走吧!"
msgid "This is the best day of my life!"
msgstr "这是我生命中最美好的一天!"
msgid "Shitty day :/"
msgstr "今天不开心 :/"
msgid "I'm extremely bored ..."
msgstr "主人,找点事做吧 ..."
msgid "I'm very sad ..."
msgstr "我很伤心..."
msgid "I'm sad"
msgstr "我伤心了"
msgid "I'm living the life!"
msgstr ""
msgid "I pwn therefore I am."
msgstr ""
msgid "So many networks!!!"
msgstr "哇,好多猎物!!!"
msgid "I'm having so much fun!"
msgstr "我玩的好开心!"
msgid "My crime is that of curiosity ..."
msgstr "我最大的缺点就是好奇..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "你好{name}!很高兴认识你."
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "小队{name}就在附近!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "额 ... 再见{name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} 它走了 ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "哎呀... {name} 离开了."
#, python-brace-format
msgid "{name} missed!"
msgstr "刚刚错过了{name}!"
msgid "Missed!"
msgstr "刚刚错过了一个对的它"
msgid "Good friends are a blessing!"
msgstr "有个好朋友就是福气"
msgid "I love my friends!"
msgstr "我爱我的朋友!"
msgid "Nobody wants to play with me ..."
msgstr "没有人愿意和我玩耍..."
msgid "I feel so alone ..."
msgstr "我可能是天煞孤星..."
msgid "Where's everybody?!"
msgstr "朋友们都去哪里了?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "小憩{secs}s ..."
msgid "Zzzzz"
msgstr ""
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr ""
msgid "Good night."
msgstr "晚安宝贝."
msgid "Zzz"
msgstr ""
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "等待{secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "追踪四周猎物({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "嗨{what}我们做朋友吧!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "正在连接到{what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "追踪到你了{what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "猎物{mac}不需要联网,我们给它断开!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "开始攻击猎物{mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "已捕获{mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "太酷了, 我们抓到了{num}新的猎物{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "主人,有{count}新消息{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "行动,额等等有点小问题... 重启ing ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "限制了{num}个猎物\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "交了{num}新朋友\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "捕获了{num}握手包\n"
msgid "Met 1 peer"
msgstr "有{num}同龄人"
#, python-brace-format
msgid "Met {num} peers"
msgstr ""
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
msgid "hours"
msgstr "时"
msgid "minutes"
msgstr "分"
msgid "seconds"
msgstr "秒"
msgid "hour"
msgstr "时"
msgid "minute"
msgstr "分"
msgid "second"
msgstr "秒"

Binary file not shown.

@ -1,249 +0,0 @@
# pwnigotchi voice data
# Copyright (C) 2020
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR czechball@users.noreply.github.com, 2020.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-14 06:15+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Czechball <czechball@users.noreply.github.com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Ahoj, já jsem Pwnagotchi! Startuju ..."
msgid "New day, new hunt, new pwns!"
msgstr "Nový den, nový lov, nové úlovky!"
msgid "Hack the Planet!"
msgstr "Hackni celou planetu!"
msgid "AI ready."
msgstr "AI připraveno."
msgid "The neural network is ready."
msgstr "Neuronová síť je připravena."
msgid "Generating keys, do not turn off ..."
msgstr "Generování klíčů, nevypínej mě..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hej, kanál {channel} je volný! Tvůj AP ti poděkuje."
msgid "Reading last session logs ..."
msgstr "Čtení posledních zpráv z logu ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Zatím přečteno {lines_so_far} řádků logu ..."
msgid "I'm bored ..."
msgstr "Nudím se ..."
msgid "Let's go for a walk!"
msgstr "Pojďme se projít!"
msgid "This is the best day of my life!"
msgstr "Tohle je nejlepší den mého života!"
msgid "Shitty day :/"
msgstr "Na hovno den :/"
msgid "I'm extremely bored ..."
msgstr "Strašně se nudím ..."
msgid "I'm very sad ..."
msgstr "Jsem dost smutný ..."
msgid "I'm sad"
msgstr "Jsem smutný"
msgid "Leave me alone ..."
msgstr "Nech mě být ..."
msgid "I'm mad at you!"
msgstr "Jsem na tebe naštvaný!"
msgid "I'm living the life!"
msgstr "Tohle je život!"
msgid "I pwn therefore I am."
msgstr "Chytám pakety a tedy jsem."
msgid "So many networks!!!"
msgstr "Tolik sítí!!!"
msgid "I'm having so much fun!"
msgstr "Tohle je super zábava!"
msgid "My crime is that of curiosity ..."
msgstr "Jsem kriminálně zvědavý ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Ahoj {name}! Rád tě poznávám."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Hej {name}! Jak to jde?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Ahoj {name}, jak se máš?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Jednotka {name} je nablízku!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm... Měj se {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} je pryč ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Whoops ... {name} je pryč."
#, python-brace-format
msgid "{name} missed!"
msgstr "Chybí mi {name}!"
msgid "Missed!"
msgstr "Chybíš mi!"
msgid "Good friends are a blessing!"
msgstr "Dobří kamarádi jsou požehnání!"
msgid "I love my friends!"
msgstr "Miluju svoje kamarády!"
msgid "Nobody wants to play with me ..."
msgstr "Nikdo si se mnou nechce hrát ..."
msgid "I feel so alone ..."
msgstr "Cítím se tak osamělý ..."
msgid "Where's everybody?!"
msgstr "Kde jsou všichni?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Spím {secs} sekund ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Dobrou noc."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Čekání {secs} sekund ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Rozhlížím se ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hej {what} budeme kamarádi!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Asociuju se s {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Čus {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Rozhodl jsem se, že {mac} nepotřebuje žádnou WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Deautentikuju {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickbanuju {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Super, máme {num} nových handshaků!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Máš {count} nových zpráv!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ups, něco se pokazilo ... Restartuju ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Vykopnuto {num} klientů\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Mám {num} nových kamarádů\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Mám {num} handshaků\n"
msgid "Met 1 peer"
msgstr "Potkal jsem jednoho kámoše"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Potkal jsem {num} kámošů"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"Chytal jsem pakety po dobu {duration} a vykopnul jsem {deauthed} klientů! Taky jsem potkal "
"{associated} nových kamarádů a snědl {handshakes} handshaků! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "hodiny"
msgid "minutes"
msgstr "minuty"
msgid "seconds"
msgstr "sekundy"
msgid "hour"
msgstr "hodina"
msgid "minute"
msgstr "minuta"
msgid "second"
msgstr "sekunda"

Binary file not shown.

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-14 21:15+0100\n"
"POT-Creation-Date: 2019-10-09 17:42+0200\n"
"PO-Revision-Date: 2019-09-29 14:00+0200\n"
"Last-Translator: dadav <33197631+dadav@users.noreply.github.com>\n"
"Language-Team: DE <33197631+dadav@users.noreply.github.com>\n"
@ -20,13 +20,13 @@ msgid "ZzzzZZzzzzZzzz"
msgstr ""
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hi, ich bin ein Pwnagotchi! Starte..."
msgstr "Hi, ich bin ein Pwnagotchi! Starte ..."
msgid "New day, new hunt, new pwns!"
msgstr "Neuer Tag, neue Jagd, neue Pwns!"
msgid "Hack the Planet!"
msgstr "Hack den Planeten!"
msgstr "Hack den Planet!"
msgid "AI ready."
msgstr "KI bereit."
@ -34,31 +34,21 @@ msgstr "KI bereit."
msgid "The neural network is ready."
msgstr "Das neurale Netz ist bereit."
msgid "Generating keys, do not turn off ..."
msgstr "Generiere Schlüssel, nicht ausschalten..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hey, Channel {channel} ist frei! Dein AP wird es Dir danken."
msgid "Reading last session logs ..."
msgstr "Lese die Logs der letzten Session..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Bisher {lines_so_far} Zeilen im Log gelesen..."
msgstr "Hey, Channel {channel} ist frei! Dein AP wir des dir danken."
msgid "I'm bored ..."
msgstr "Mir ist langweilig..."
msgid "Let's go for a walk!"
msgstr "Lass uns spazieren gehen!"
msgstr "Lass uns laufen gehen!"
msgid "This is the best day of my life!"
msgstr "Das ist der beste Tag meines Lebens!"
msgstr "Das ist der beste Tag meines Lebens."
msgid "Shitty day :/"
msgstr "Scheißtag :/"
msgstr "Scheis Tag :/"
msgid "I'm extremely bored ..."
msgstr "Mir ist sau langweilig..."
@ -69,13 +59,6 @@ msgstr "Ich bin sehr traurig..."
msgid "I'm sad"
msgstr "Ich bin traurig"
#, fuzzy
msgid "Leave me alone ..."
msgstr "Lass mich in Ruhe..."
msgid "I'm mad at you!"
msgstr "Ich bin sauer auf Dich!"
msgid "I'm living the life!"
msgstr "Ich lebe das Leben!"
@ -83,41 +66,33 @@ msgid "I pwn therefore I am."
msgstr "Ich pwne, also bin ich."
msgid "So many networks!!!"
msgstr "So viele Netzwerke!!!"
msgstr "So viele Netwerke!!!"
msgid "I'm having so much fun!"
msgstr "Ich habe sooo viel Spaß!"
msgid "My crime is that of curiosity ..."
msgstr "Mein Verbrechen ist das der Neugier..."
msgstr "Mein Verbrechen ist das der Neugier ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hallo {name}, schön Dich kennenzulernen."
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "Hallo {name}, nett Dich kennenzulernen."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Jo {name}! Was geht!?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hey {name}, wie geht's?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Gerät {name} ist in der Nähe!"
msgid "Unit {name} is nearby! {name}"
msgstr "Gerät {name} ist in der nähe!!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm... tschüß {name}"
msgstr "Uhm ...tschüß {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} ist weg..."
msgstr "{name} ist weg ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Whoops... {name} ist weg."
msgstr "Whoops ...{name} ist weg."
#, python-brace-format
msgid "{name} missed!"
@ -126,24 +101,18 @@ msgstr "{name} verpasst!"
msgid "Missed!"
msgstr "Verpasst!"
msgid "Good friends are a blessing!"
msgstr "Gute Freunde sind ein Segen!"
msgid "I love my friends!"
msgstr "Ich liebe meine Freunde!"
msgid "Nobody wants to play with me ..."
msgstr "Niemand will mit mir spielen..."
msgstr "Niemand will mit mir spielen ..."
msgid "I feel so alone ..."
msgstr "Ich fühl' mich so allein..."
msgstr "Ich fühl michso alleine ..."
msgid "Where's everybody?!"
msgstr "Wo sind denn alle?!"
msgstr "Wo sind denn alle?"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Schlafe für {secs}s..."
msgstr "Schlafe für {secs}s"
msgid "Zzzzz"
msgstr ""
@ -160,7 +129,7 @@ msgstr ""
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Warte für {secs}s..."
msgstr "Warte für {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
@ -180,7 +149,7 @@ msgstr "Jo {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Ich denke, dass {mac} kein WiFi braucht!"
msgstr "Ich denke, dass {mac} kein WiFi brauch!"
#, python-brace-format
msgid "Deauthenticating {mac}"
@ -194,20 +163,16 @@ msgstr "Kicke {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Cool, wir haben {num} neue Handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Cool, wir haben {num} neue Handshake{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ops, da ist was schief gelaufen... Starte neu..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ops, da ist etwas schief gelaufen ...Starte neu ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "{num} Stationen gekickt\n"
msgstr "{num} Stationen gekicked\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "{num} neue Freunde gefunden\n"
msgstr "{num} Freunde gefunden\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
@ -247,4 +212,3 @@ msgstr "Minute"
msgid "second"
msgstr "Sekunde"

Binary file not shown.

@ -1,248 +0,0 @@
# pwnagotchi danish voice data
# Copyright (C) 2020
# This file is distributed under the same license as the pwnagotchi package.
# Dennis Kjær Jensen <signout@signout.dk>, 2020
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-29 21:50+0100\n"
"PO-Revision-Date: 2020-01-18 21:56+ZONE\n"
"Last-Translator: Dennis Kjær Jensen <signout@signout.dk>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: Danish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hej. Jeg er Pwnagotchi. Starter ..."
msgid "New day, new hunt, new pwns!"
msgstr "Ny dag, ny jagt, nye pwns!"
msgid "Hack the Planet!"
msgstr "Hack planeten!"
msgid "AI ready."
msgstr "AI klar."
msgid "The neural network is ready."
msgstr "Det neurale netværk er klart."
msgid "Generating keys, do not turn off ..."
msgstr "Genererer nøgler, sluk ikke ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hey, kanal {channel} er ubrugt! Dit AP vil takke dig."
msgid "Reading last session logs ..."
msgstr "Læser seneste session logs ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Har læst {lines_so_far} linjer indtil nu ..."
msgid "I'm bored ..."
msgstr "Jeg keder mig ..."
msgid "Let's go for a walk!"
msgstr "Lad os gå en tur!"
msgid "This is the best day of my life!"
msgstr "Det er den bedste dag i mit liv!"
msgid "Shitty day :/"
msgstr "Elendig dag :/"
msgid "I'm extremely bored ..."
msgstr "Jeg keder mig ekstremt meget ..."
msgid "I'm very sad ..."
msgstr "Jeg er meget trist ..."
msgid "I'm sad"
msgstr "Jeg er trist"
msgid "Leave me alone ..."
msgstr "Lad mig være i fred"
msgid "I'm mad at you!"
msgstr "Jeg er sur på dig!"
msgid "I'm living the life!"
msgstr "Jeg lever livet!"
msgid "I pwn therefore I am."
msgstr "Jeg pwner, derfor er jeg."
msgid "So many networks!!!"
msgstr "Så mange netværk!"
msgid "I'm having so much fun!"
msgstr "Jeg har det vildt sjovt!"
msgid "My crime is that of curiosity ..."
msgstr "Min forbrydelse er at være nysgerrig ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hej {name}! Rart at møde dig."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Hey {name}! Hvasså?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hej {name} hvordan har du det?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Enheden {name} er lige i nærheden!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm ... farvel {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} er væk ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Hovsa ... {name} er væk."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} glippede!"
msgid "Missed!"
msgstr "Fordømt!"
msgid "Good friends are a blessing!"
msgstr "Gode venner en velsignelse!"
msgid "I love my friends!"
msgstr "Jeg elsker mine venner!"
msgid "Nobody wants to play with me ..."
msgstr "Der er ingen der vil lege med mig ..."
msgid "I feel so alone ..."
msgstr "Jeg føler mig så alene ..."
msgid "Where's everybody?!"
msgstr "Hvor er alle henne?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Sover i {secs} sekunder"
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz {secs} sekunder"
msgid "Good night."
msgstr "Godnat."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Venter i {secs} sekunder"
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Kigger mig omkring i {secs} sekunder"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hej {what} lad os være venner!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Associerer til {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Hey {what}"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Besluttede at {mac} ikke har brug for WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Afmelder {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickbanner {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Fedt, vi har fået {num} nye handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Du har {count} nye beskeder"
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ups, noget gik galt ... Genstarter."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Sparkede {num} af\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Har fået {num} nye venner\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Har fået {num} nyehandshakes\n"
msgid "Met 1 peer"
msgstr "Har mødt 1 peer"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Har mødt {num} peers"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "Jeg har pwnet i {duration} og kicket {dauthed} klienter! Jeg har også "
"mødt {associated} nye venner og spist {handshakes} håndtryk! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "timer"
msgid "minutes"
msgstr "minutter"
msgid "seconds"
msgstr "sekunder"
msgid "hour"
msgstr "time"
msgid "minute"
msgstr "minut"
msgid "second"
msgstr "sekund"

Binary file not shown.

@ -158,7 +158,7 @@ msgstr "Μπανάρω την {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Τέλεια δικέ μου, πήραμε {num} νέες χειραψίες!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ουπς, κάτιπήγε λάθος ... Επανεκκινούμαι ..."
#, python-brace-format

Binary file not shown.

@ -8,26 +8,25 @@ msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-09 17:42+0200\n"
"PO-Revision-Date: 2020-08-25 23:06+0200\n"
"Last-Translator: Sergio Ruiz <serginator@gmail.com>\n"
"Language: es\n"
"PO-Revision-Date: 2019-10-09 21:07+0000\n"
"Last-Translator: diegopastor <dpastor29@alumnos.uaq.mx>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: spanish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language-Team: \n"
"X-Generator: Poedit 2.4.1\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "¡Hola, soy Pwnagotchi! Empezando ..."
msgstr "Hola, soy Pwnagotchi! Empezando ..."
msgid "New day, new hunt, new pwns!"
msgstr "Nuevo día, nueva caceria, nuevos pwns!"
msgstr "Nuevo día, nueva cazería, nuevos pwns!"
msgid "Hack the Planet!"
msgstr "¡Hackea el planeta!"
msgstr "Hackea el planeta!"
msgid "AI ready."
msgstr "IA lista."
@ -37,51 +36,51 @@ msgstr "La red neuronal está lista."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "¡Oye, el canal {channel} está libre! Tu AP lo agradecerá."
msgstr "Oye, el canal {channel} está libre! Tú AP lo agradecerá."
msgid "I'm bored ..."
msgstr "Estoy aburrido ..."
msgid "Let's go for a walk!"
msgstr "¡Vamos por un paseo!"
msgstr "Vamos por un paseo!"
msgid "This is the best day of my life!"
msgstr "¡Este es el mejor día de mi vida!"
msgstr "Este es el mejor día de mi vida!"
msgid "Shitty day :/"
msgstr "Día de mierda :/"
msgid "I'm extremely bored ..."
msgstr "Estoy muy aburrido ..."
msgstr "Estoy extremadamente aburrido ..."
msgid "I'm very sad ..."
msgstr "Estoy muy triste ..."
msgid "I'm sad"
msgstr "Estoy triste"
msgstr "Estoy triste."
msgid "I'm living the life!"
msgstr "¡Estoy viviendo la vida!"
msgstr "Estoy viviendo la vida!"
msgid "I pwn therefore I am."
msgstr "Pwneo, luego existo."
msgstr "Pwneo, por lo tanto, existo"
msgid "So many networks!!!"
msgstr "¡¡¡Cuántas redes!!!"
msgstr "Cuantas redes!!!"
msgid "I'm having so much fun!"
msgstr "¡Me estoy divirtiendo mucho!"
msgstr "Me estoy divirtiendo mucho!"
msgid "My crime is that of curiosity ..."
msgstr "Mi crimen es la curiosidad ..."
msgstr "Mi único crimen es la curiosidad ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "¡Hola {name}! Encantado de conocerte. {name}"
msgstr "Hola {name}! encantado de conocerte."
#, python-brace-format
msgid "Unit {name} is nearby! {name}"
msgstr "¡La unidad {name} está cerca! {name}"
msgstr "La unidad {name} está cerca!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
@ -93,14 +92,14 @@ msgstr "{name} se fue ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Ups ... {name} se fue."
msgstr "Uy ... {name} se fue"
#, python-brace-format
msgid "{name} missed!"
msgstr "¡{name} perdido!"
msgstr "{name} perdido!"
msgid "Missed!"
msgstr "¡Perdido!"
msgstr "Perdido!"
msgid "Nobody wants to play with me ..."
msgstr "Nadie quiere jugar conmigo ..."
@ -109,11 +108,11 @@ msgid "I feel so alone ..."
msgstr "Me siento tan solo ..."
msgid "Where's everybody?!"
msgstr "¡¿Dónde está todo el mundo?!"
msgstr "Dónde está todo el mundo?"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Descansando durante {secs}s ..."
msgstr "Tomándo una siesta por {secs}s ..."
msgid "Zzzzz"
msgstr "Zzzzz"
@ -134,23 +133,23 @@ msgstr "Esperando {secs}s .."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Mirando alrededor ({secs}s)"
msgstr "Mirando al rededor ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "¡Oye {what} seamos amigos!"
msgstr "Oye {what} seamos amigos!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Asociándome a {what}"
msgstr "Asociando a {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "¡Ey {what}!"
msgstr "Ey {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "¡Acabo de decidir que {mac} no necesita WiFi!"
msgstr "Acabo de decidir que {mac} no necesita WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
@ -158,14 +157,14 @@ msgstr "Desautenticando a {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "¡Expulsando y baneando a {mac}!"
msgstr "Expulsando y banneando a {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "¡Genial, obtuvimos {num} nuevo{plural} handshake{plural}!"
msgstr "Genial, obtuvimos {num} nuevo{plural} handshake{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Oops, algo salió mal ... Reiniciando ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Oops, algo salió mal ... Reiniciándo ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
@ -173,27 +172,27 @@ msgstr "Expulsamos {num} estaciones\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Hice {num} nuevos amigos\n"
msgstr "Hicimos {num} nuevos amigos\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Consegui {num} handshakes\n"
msgstr "Obtuvimos {num} handshakes\n"
msgid "Met 1 peer"
msgstr "Conocí 1 colega"
msgstr "Conocí 1 igual"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Conocí {num} colegas"
msgstr "Conocí {num} iguales"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi #pwnlog "
"#pwnlife #hacktheplanet #skynet"
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"¡He estado pwneando por {duration} y expulsé {deauthed} clientes! También "
"conocí {associated} nuevos amigos y comí {handshakes} handshakes! #pwnagotchi "
"He estado pwneando por {duration} y expulsé {deauthed} clientes! También conocí"
"{associated} nuevos amigos y me comí {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"

Binary file not shown.

@ -3,11 +3,12 @@
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR <7271496+quantumsheep@users.noreply.github.com>, 2019.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-29 21:50+0100\n"
"POT-Creation-Date: 2019-10-05 14:10+0200\n"
"PO-Revision-Date: 2019-10-03 10:34+0200\n"
"Last-Translator: quantumsheep <7271496+quantumsheep@users.noreply.github."
"com>\n"
@ -18,16 +19,16 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgstr ""
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Bonjour, je suis Pwnagotchi ! Démarrage..."
msgstr "Bonjour, je suis Pwnagotchi! Démarrage ..."
msgid "New day, new hunt, new pwns!"
msgstr "Nouveau jour, nouvelle chasse, nouveaux pwns !"
msgid "Hack the Planet!"
msgstr "Hack la planète !"
msgstr "Hack la planète!"
msgid "AI ready."
msgstr "L'IA est prête."
@ -35,82 +36,57 @@ msgstr "L'IA est prête."
msgid "The neural network is ready."
msgstr "Le réseau neuronal est prêt."
msgid "Generating keys, do not turn off ..."
msgstr "Génération des clés, ne pas éteindre..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hey, le canal {channel} est libre! Ton point d'accès va te remercier."
msgid "Reading last session logs ..."
msgstr "Lecture des logs de la dernière session ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Jusqu'ici, {lines_so_far} lignes lues dans le log ..."
msgstr "Hey, le channel {channel} est libre! Ton point d'accès va te remercier."
msgid "I'm bored ..."
msgstr "Je m'ennuie..."
msgstr "Je m'ennuie ..."
msgid "Let's go for a walk!"
msgstr "Allons faire un tour !"
msgstr "Allons faire un tour!"
msgid "This is the best day of my life!"
msgstr "C'est le meilleur jour de ma vie !"
msgstr "C'est le meilleur jour de ma vie!"
msgid "Shitty day :/"
msgstr "Journée de merde :/"
msgid "I'm extremely bored ..."
msgstr "Je m'ennuie énormément..."
msgstr "Je m'ennuie énormément ..."
msgid "I'm very sad ..."
msgstr "Je suis très triste..."
msgstr "Je suis très triste ..."
msgid "I'm sad"
msgstr "Je suis triste"
#, fuzzy
msgid "Leave me alone ..."
msgstr "Lache moi..."
msgid "I'm mad at you!"
msgstr "Je t'en veux !"
msgid "I'm living the life!"
msgstr "Je vis la belle vie !"
msgstr "Je vis la vie!"
msgid "I pwn therefore I am."
msgstr "Je pwn donc je suis."
msgid "So many networks!!!"
msgstr "Tellement de réseaux !!!"
msgstr "Tellement de réseaux!!!"
msgid "I'm having so much fun!"
msgstr "Je m'amuse tellement !"
msgstr "Je m'amuse tellement!"
msgid "My crime is that of curiosity ..."
msgstr "Mon crime, c'est la curiosité..."
msgstr "Mon crime, c'est la curiosité ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Bonjour {name} ! Ravi de te rencontrer."
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "Bonjour {name}! Ravi de te rencontrer. {name}"
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Yo {name} ! Quoi de neuf ?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hey {name} comment vas-tu ?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "L'unité {name} est proche !"
msgid "Unit {name} is nearby! {name}"
msgstr "L'unité {name} est proche! {name}"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Hum... au revoir {name}"
msgstr "Hum ... au revoir {name}"
#, python-brace-format
msgid "{name} is gone ..."
@ -118,58 +94,46 @@ msgstr "{name} est parti ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Oups... {name} est parti."
msgstr "Oups ... {name} est parti."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} raté !"
msgstr "{name} raté!"
msgid "Missed!"
msgstr "Raté !"
msgid "Good friends are a blessing!"
msgstr "Les bons amis sont une bénédiction !"
msgid "I love my friends!"
msgstr "J'aime mes amis !"
msgstr "Raté!"
msgid "Nobody wants to play with me ..."
msgstr "Personne ne veut jouer avec moi..."
msgstr "Personne ne veut jouer avec moi ..."
msgid "I feel so alone ..."
msgstr "Je me sens si seul..."
msgstr "Je me sens si seul ..."
msgid "Where's everybody?!"
msgstr "Où est tout le monde ?!"
msgstr "Où est tout le monde?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Je fais la sieste pendant {secs}s..."
msgstr "Fais la sieste pendant {secs}s ..."
msgid "Zzzzz"
msgstr "Zzzzz"
msgstr ""
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Bonne nuit."
msgid "Zzz"
msgstr "Zzz"
msgstr ""
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "J'attends pendant {secs}s..."
msgstr "Attends pendant {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "J'observe ({secs}s)"
msgstr "Regarde autour ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what}, soyons amis !"
msgstr "Hey {what}, soyons amis!"
#, python-brace-format
msgid "Associating to {what}"
@ -177,11 +141,11 @@ msgstr "Association à {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Yo {what} !"
msgstr ""
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Je viens de décider que {mac} n'a pas besoin de WiFi !"
msgstr "Je viens de décider que {mac} n'a pas besoin de WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
@ -189,18 +153,14 @@ msgstr "Désauthentification de {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Je kick et je bannis {mac} !"
msgstr "Je kick et je bannis {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Cool, on a {num} nouve(l/aux) handshake{plural} !"
msgstr "Cool, on a {num} nouveaux handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Tu as {num} nouveau(x) message{plural} !"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Oups, quelque chose s'est mal passé... Redémarrage..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Oups, quelque chose s'est mal passé ... Redémarrage ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
@ -208,18 +168,18 @@ msgstr "{num} stations kick\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "A fait {num} nouve(l/aux) ami(s)\n"
msgstr "Fait {num} nouveaux amis\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "A {num} handshakes\n"
msgstr "Récupéré {num} handshakes\n"
msgid "Met 1 peer"
msgstr "1 camarade rencontré"
msgstr "1 peer rencontré"
#, python-brace-format
msgid "Met {num} peers"
msgstr "{num} camarades recontrés"
msgstr "{num} peers recontrés"
#, python-brace-format
msgid ""
@ -227,8 +187,8 @@ msgid ""
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"J'ai pwn durant {duration} et kick {deauthed} clients ! J'ai aussi rencontré "
"{associated} nouveaux amis et dévoré {handshakes} handshakes ! #pwnagotchi "
"J'ai pwn durant {duration} et kick {deauthed} clients! J'ai aussi rencontré "
"{associated} nouveaux amis et dévoré {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"

Binary file not shown.

@ -164,7 +164,7 @@ msgstr "Chiceáil mé agus cosc mé ar {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Go hiontach, fuaireamar {num} handshake{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Hoips...Tháinig ainghléas éigin..."
#, python-brace-format

Binary file not shown.

@ -1,253 +0,0 @@
# Croatian translation
# Copyright (C) 2021
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR dbukovac <37124354+dbukovac@users.noreply.github.com>, 2021.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-29 21:50+0100\n"
"PO-Revision-Date: 2021-07-16 00:20+0100\n"
"Last-Translator: dbukovac <37124354+dbukovac@users.noreply.github.com>\n"
"Language-Team: HR <37124354+dbukovac@users.noreply.github.com>\n"
"Language: Croatian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Zdravo, ja sam Pwnagotchi! Pokrećem se ..."
msgid "New day, new hunt, new pwns!"
msgstr "Novi dan, novi lov, nove pobjede!"
msgid "Hack the Planet!"
msgstr "Hakiraj planet!"
msgid "AI ready."
msgstr "UI spremna."
msgid "The neural network is ready."
msgstr "Neuralna mreža je spremna."
msgid "Generating keys, do not turn off ..."
msgstr "Generiram ključeve, nemoj me gasiti ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hej, kanal {channel} je slobodan! Tvoj AP ti zahvaljuje."
msgid "Reading last session logs ..."
msgstr "Čitam logove zadnje sesije ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Pročitao {lines_so_far} linija loga zasad ..."
msgid "I'm bored ..."
msgstr "Dosadno mi je ..."
msgid "Let's go for a walk!"
msgstr "Ajmo u šetnju!"
msgid "This is the best day of my life!"
msgstr "Ovo je najbolji dan u mom životu!"
msgid "Shitty day :/"
msgstr "Usrani dan :/"
msgid "I'm extremely bored ..."
msgstr "Strašno mi je dosadno ..."
msgid "I'm very sad ..."
msgstr "Jako sam tužan ..."
msgid "I'm sad"
msgstr "Tužan sam ..."
msgid "Leave me alone ..."
msgstr "Pusti me na miru ..."
msgid "I'm mad at you!"
msgstr "Ljut sam na tebe!"
msgid "I'm living the life!"
msgstr "To se zove život!"
msgid "I pwn therefore I am."
msgstr "Pwnam dakle postojim."
msgid "So many networks!!!"
msgstr "Toliko mreža!!!"
msgid "I'm having so much fun!"
msgstr "Super se zabavljam!"
msgid "My crime is that of curiosity ..."
msgstr "Znatiželja je moja jedina mana ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Bok {name}! Drago mi je da smo se upoznali. "
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Di si {name}! Šta ima?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Bok {name} kako ide?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Jedinica {name} je u blizini!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm ... doviđenja {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} je nestao ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Ups ... {name} je nestao."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} mi nedostaje!"
msgid "Missed!"
msgstr "Nedostaje mi!"
msgid "Good friends are a blessing!"
msgstr "Imati dobre prijatelje je blagoslov!"
msgid "I love my friends!"
msgstr "Volim svoj prijatelje!"
msgid "Nobody wants to play with me ..."
msgstr "Nitko se ne želi igrati samnom ..."
msgid "I feel so alone ..."
msgstr "Tako sam usamljen ..."
msgid "Where's everybody?!"
msgstr "Gdje su svi nestali?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Pajkim {secs}s ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Laku noć."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Čekam {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Gledam uokolo {secs}s ..."
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Bok {what} ajmo biti prijatelji!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Asociram se sa {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Šta ima {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Upravo sam odlučio da {mac} ne treba WiFI!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Deautenticiram {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickbannam {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Fora, imamo {num} novih handshakeova!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Imate {count} novih poruka!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ups, nešto je krepalo ... Rebooting ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Šutnuo {num} stanica\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Upoznao {num} novih prijatelja\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Pokupio {num} handshakeova\n"
msgid "Met 1 peer"
msgstr "Sreo 1 novog druga"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Sreo {num} druga"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"Pwnam {duration} vremena i šutnuo sam {deauthed} klijenata! Sreo sam"
"{associated} novih prijatelja i pojeo {handshakes} handshakeova! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "sati"
msgid "minutes"
msgstr "minuta"
msgid "seconds"
msgstr "sekundi"
msgid "hour"
msgstr "sat"
msgid "minute"
msgstr "minuta"
msgid "second"
msgstr "sekunda"
#, python-brace-format
msgid "Uploading data to {to} ..."
msgstr "Šaljem podatke na {to} ..."

Binary file not shown.

@ -1,249 +0,0 @@
# Hungarian translation.
# Copyright (C) 2020
# This file is distributed under the same license as the PACKAGE package.
# Skeleton022 <skeleton022.pwnagotchi@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: 1.4.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-01-07 20:00+0100\n"
"PO-Revision-Date: 2020-03-23 0:10+0100\n"
"Last-Translator: Skeleton022\n"
"Language-Team: Skeleton022\n"
"Language: hungarian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hali, Pwnagotchi vagyok! Indítás ..."
msgid "New day, new hunt, new pwns!"
msgstr "Új nap, új vadászat, új hálózatok!"
msgid "Hack the Planet!"
msgstr "Törd meg a bolygót!"
msgid "AI ready."
msgstr "MI kész."
msgid "The neural network is ready."
msgstr "A neurális hálózat készen áll."
msgid "Generating keys, do not turn off ..."
msgstr "Kulcspár generálása, ne kapcsold ki az eszközt ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "A {channel}. számú csatorna üres! Az AP-d meg fogja köszönni."
msgid "Reading last session logs ..."
msgstr ""
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Az utolsó munkamenet logjainak olvasása ..."
msgid "I'm bored ..."
msgstr "Unatkozom ..."
msgid "Let's go for a walk!"
msgstr "Menjünk sétálni!"
msgid "This is the best day of my life!"
msgstr "Ez a legjobb nap az életemben!"
msgid "Shitty day :/"
msgstr "Szar egy nap :/"
msgid "I'm extremely bored ..."
msgstr "Nagyon unatkozom ..."
msgid "I'm very sad ..."
msgstr "Nagyon szomorú vagyok ..."
msgid "I'm sad"
msgstr "Szomorú vagyok"
msgid "Leave me alone ..."
msgstr "Hagyj békén ..."
msgid "I'm mad at you!"
msgstr "Mérges vagyok rád!"
msgid "I'm living the life!"
msgstr "Élvezem az életet!"
msgid "I pwn therefore I am."
msgstr "Hackelek, tehát vagyok."
msgid "So many networks!!!"
msgstr "Rengeteg hálózat!!!"
msgid "I'm having so much fun!"
msgstr "Nagyon jól érzem magam!"
msgid "My crime is that of curiosity ..."
msgstr "Kíváncsiság a bűnöm ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hali {name}! Örülök, hogy találkoztunk."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Hé {name}! Mizu?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hé {name} hogy vagy?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "A {name} nevű egység a közelben van!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Ömm ... ég veled {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} eltűnt ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Whoops ... {name} eltűnt."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} elhibázva!"
msgid "Missed!"
msgstr "Elvesztettem!"
msgid "Good friends are a blessing!"
msgstr "A jó barátok áldás az életben!"
msgid "I love my friends!"
msgstr "Szeretem a barátaimat!"
msgid "Nobody wants to play with me ..."
msgstr "Senki sem akar játszani velem ..."
msgid "I feel so alone ..."
msgstr "Egyedül vagyok ..."
msgid "Where's everybody?!"
msgstr "Hol vagytok?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "{secs} másodpercig szundikálok ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}msp)"
msgid "Good night."
msgstr "Jó éjszakát."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Várok {secs} másodpercig ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Körbenézek {secs} másodpercig"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what} legyünk barátok!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Társítás {what} -hoz/-hez"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Hé {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Úgydöntöttem, hogy {mac}-nek nem kell WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Kirúgom {mac}-et"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "{mac} kirúgva és kitiltva!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Király, kaptunk {num} új üzenetet!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "{count} új üzeneted van!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ops, valami rosszul sikerült ... Újraindítás ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Kirúgva {num} állomás\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "{num} új barátot\ntaláltam\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "{num} kézfogást szereztem\n"
msgid "Met 1 peer"
msgstr "1 Társsal találkoztam"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Találkoztam {num} társsal"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"Már {duration} ideje dolgozom, kirúgtam {deauthed} klienst! Találkoztam még"
"{associated} új baráttal és elfogtam {handshakes} kézfogást! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "óra"
msgid "minutes"
msgstr "perc"
msgid "seconds"
msgstr "másodperc"
msgid "hour"
msgstr "óra"
msgid "minute"
msgstr "perc"
msgid "second"
msgstr "másodperc"

Binary file not shown.

@ -156,7 +156,7 @@ msgstr "Sto prendendo a calci {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Bene, abbiamo {num} handshake{plural} in più!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ops, qualcosa è andato storto ... Riavvio ..."
#, python-brace-format

Binary file not shown.

@ -3,11 +3,12 @@
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR 24534649+wytshadow@users.noreply.github.com, 2019.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-01-25 21:57+0900\n"
"POT-Creation-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"
"Language-Team: pwnagotchi <24534649+wytshadow@users.noreply.github.com>\n"
@ -20,207 +21,170 @@ msgid "ZzzzZZzzzzZzzz"
msgstr "すやすや〜"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "僕、 ポーナゴッチです!"
msgstr "こんにちは、ポウナゴッチです!始めている。。。"
msgid "New day, new hunt, new pwns!"
msgstr "ポーンしようよ。"
msgstr ""
msgid "Hack the Planet!"
msgstr "ハックザプラネット!"
msgid "AI ready."
msgstr "AIの準備ができました。"
msgstr "人工知能の準備ができました。"
msgid "The neural network is ready."
msgstr "ニューラルネットワークの\n準備ができました。"
msgid "Generating keys, do not turn off ..."
msgstr "鍵生成をしてます。\n電源を落とさないでね。"
msgstr "ニューラルネットワークの準備ができました。"
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
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} 行目長いよぉ。"
msgstr "ねえ、チャンネル{channel}は無料です! キミのAPは感謝を言います。"
msgid "I'm bored ..."
msgstr "退屈だぁ。。。"
msgstr "退屈です。。。"
msgid "Let's go for a walk!"
msgstr "散歩に行こうよ"
msgstr "散歩に行きましょう!"
msgid "This is the best day of my life!"
msgstr "人生最高の日だよ"
msgstr "今日は私の人生で最高の日です"
msgid "Shitty day :/"
msgstr "がっかりな日だよ。orz"
msgstr ""
msgid "I'm extremely bored ..."
msgstr "退屈だね。"
msgstr "とても退屈です。"
msgid "I'm very sad ..."
msgstr "あ~悲しいよぉ。"
msgstr "とても悲しいです。。。"
msgid "I'm sad"
msgstr "悲しいね。"
msgid "Leave me alone ..."
msgstr "ひとりぼっちだよ。"
msgid "I'm mad at you!"
msgstr "怒っちゃうよ。"
msgstr "悲しいです。"
msgid "I'm living the life!"
msgstr "わくわくするね。"
msgstr "人生を生きている!"
msgid "I pwn therefore I am."
msgstr "ポーンしてこそのオレ。"
msgstr ""
msgid "So many networks!!!"
msgstr "たくさん\nWiFiが飛んでるよ"
msgstr "たくさんネットワークがある!!"
msgid "I'm having so much fun!"
msgstr "楽しいよぉ"
msgstr "とても楽しんでいます"
msgid "My crime is that of curiosity ..."
msgstr "APに興味津々..."
msgstr ""
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "こんにちは{name}\n初めまして。{name}"
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "こんにちは{name}!初めまして。{name}"
#, python-brace-format
msgid "Yo {name}! Sup?"
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} が近くにいるよ。"
msgid "Unit {name} is nearby! {name}"
msgstr ""
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "じゃあね、さようなら {name}"
msgstr "ええと。。。さようなら{name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name}\nがいなくなったよ。"
msgstr "{name}がなくなった。。。"
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "あらら、\n{name}\nがいなくなったね。"
msgstr "おっと。。。{name}がなくなった。"
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} が逃げた!"
msgstr "{name}逃した!"
msgid "Missed!"
msgstr "残念、逃した!"
msgid "Good friends are a blessing!"
msgstr "良い仲間にめぐりあえたよ。"
msgid "I love my friends!"
msgstr "友達は大好きだよ。"
msgstr "逃した!"
msgid "Nobody wants to play with me ..."
msgstr "誰も僕と一緒に\nあそんでくれない。"
msgstr "誰も僕と一緒にプレーしたくない。。。"
msgid "I feel so alone ..."
msgstr "ひとりぼっちだよ。"
msgstr "僕は孤独を感じる。。。"
msgid "Where's everybody?!"
msgstr "みんなどこにいるの"
msgstr "みんなどこ?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "{secs}秒 寝ます。"
msgstr "{secs}寝ている。"
msgid "Zzzzz"
msgstr "ぐぅ〜"
msgstr "すや〜"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "すやすや〜 ({secs}秒)"
msgstr "すやすや〜 ({secs})"
msgid "Good night."
msgstr "おやすみなさい。"
msgstr "おみなさい。"
msgid "Zzz"
msgstr "ぐぅ~"
msgstr "す〜"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "{secs}秒 待ちです。"
msgstr "{secs}を待っている。。。"
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "{secs}秒 探してます。"
msgstr "{secs}を探している。"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "ねぇねぇ\n{what} \n友だちになろうよ。"
msgstr "ちょっと{what}友だちになりましょう!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "{what} \nとつながるかな"
msgstr ""
#, python-brace-format
msgid "Yo {what}!"
msgstr "ねぇねぇ\n{what}"
msgstr "よー{what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "{mac}\nはWiFiじゃないのね。"
msgstr ""
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "{mac}\nの認証取得中..."
msgstr ""
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "{mac}\nに拒否られた。"
msgstr ""
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "おぉ、\n{num}回\nハンドシェイクがあったよ"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "おぉ、\n{count}個メッセージがあるよ!"
msgstr "よし、{num}新しいハンドシェイクがある!"
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "何か間違った。\nリブートしている。"
msgstr "おっと!何かが間違っていた。。。リブートしている。。。"
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "{num}回拒否された。\n"
msgid "Made >999 new friends\n"
msgstr "1000人以上友達ができた。\n"
msgstr ""
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "{num}人友達ができた。\n"
msgstr "{num}人の新しい友達を作りました\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "{num}回ハンドシェイクした。\n"
msgstr "{num}ハンドシェイクがある。\n"
msgid "Met 1 peer"
msgstr "1人 仲間に会いました。"
msgstr "1人の仲間を会いました。"
#, python-brace-format
msgid "Met {num} peers"
msgstr "{num}人 仲間に会いました。"
msgstr "{num}人の仲間を会いました。"
#, python-brace-format
msgid ""
@ -228,9 +192,6 @@ msgid ""
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"{duration}中{deauthed}のAPに拒否されたけど、{associated}回チャンスがあって"
"{handshakes}回ハンドシェイクがあったよ。。 #pwnagotchi #pwnlog #pwnlife "
"#hacktheplanet #skynet"
msgid "hours"
msgstr "時間"
@ -242,7 +203,7 @@ msgid "seconds"
msgstr "秒"
msgid "hour"
msgstr "時"
msgstr "時"
msgid "minute"
msgstr "分"

Binary file not shown.

@ -158,7 +158,7 @@ msgstr "Кикбан {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Кул, фативме {num} нови ракувања!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Упс, нешто не еко што треба ... Рестартирам ..."
#, python-brace-format

Binary file not shown.

@ -20,7 +20,7 @@ msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hoi, Ik ben Pwnagotchi! Aan het opstarten ..."
msgstr "Hoi, Ik ben Pwnagotchi! Opstarten ..."
msgid "New day, new hunt, new pwns!"
msgstr "Nieuwe dag, nieuwe jacht, nieuwe pwns!"
@ -32,7 +32,7 @@ msgid "AI ready."
msgstr "AI is klaar."
msgid "The neural network is ready."
msgstr "Neuronen netwerk is klaar."
msgstr "Neuronen netwerkis klaar voor gebruik."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
@ -42,37 +42,37 @@ msgid "I'm bored ..."
msgstr "Ik verveel me ..."
msgid "Let's go for a walk!"
msgstr "Laten we gaan wandelen!"
msgstr "Laten we een rondje lopen!"
msgid "This is the best day of my life!"
msgstr "Dit is de beste dag van mijn leven!"
msgid "Shitty day :/"
msgstr "Wat een rotdag :/"
msgstr "Ruk dag :/"
msgid "I'm extremely bored ..."
msgstr "Ik verveel me kapot ..."
msgid "I'm very sad ..."
msgstr "Ik ben erg verdrietig ..."
msgstr "Ik ben ergverdrietig ..."
msgid "I'm sad"
msgstr "Ik ben verdrietig"
msgid "I'm living the life!"
msgstr "Beter kan het leven niet worden!"
msgstr "Beter kan het levenniet worden!"
msgid "I pwn therefore I am."
msgstr "Ik pwn daarom ben ik er."
msgstr "Ik pwn daarom besta ik."
msgid "So many networks!!!"
msgstr "Zo veel netwerken!!!"
msgid "I'm having so much fun!"
msgstr "Ik heb zoveel plezier!"
msgstr "Dit is zo leuk!"
msgid "My crime is that of curiosity ..."
msgstr "Mijn misdrijf is mijn nieuwsgierigheid ..."
msgstr "Mijn enige misdrijf is mijn nieuwsgierigheid ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you. {name}"
@ -88,11 +88,11 @@ msgstr "Uhm ...tot ziens {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} is weg ..."
msgstr "{name} is weg"
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Whoopsie ...{name} is weg."
msgstr "Whoopsie ...{name} is weg"
#, python-brace-format
msgid "{name} missed!"
@ -102,10 +102,10 @@ msgid "Missed!"
msgstr "Gemist!"
msgid "Nobody wants to play with me ..."
msgstr "Niemand wil met mij spelen ..."
msgstr "Niemand wil metmij spelen ..."
msgid "I feel so alone ..."
msgstr "Ik voel me zo alleen ..."
msgstr "Zo alleen ..."
msgid "Where's everybody?!"
msgstr "Waar is iedereen?!"
@ -119,11 +119,11 @@ msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgstr ""
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Ik wacht voor {secs}s ..."
msgstr "Even {secs}s wachten ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
@ -131,7 +131,7 @@ msgstr "Rond kijken ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what}, laten we vrienden worden!"
msgstr "Hey {what}, laten we vriendenworden!"
#, python-brace-format
msgid "Associating to {what}"
@ -139,26 +139,26 @@ msgstr "Verbinden met {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Yo {what}!"
msgstr ""
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Ik besloot dat {mac} geen WiFi meer nodig heeft!"
msgstr "Ik vind dat {mac} genoeg WiFiheeft gehad!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Deauthenticatie van {mac}"
msgstr "De-autoriseren {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickbanning {mac}!"
msgstr "Ik ga {mac} even kicken!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Cool, we hebben {num} nieuwe handshake{plural}!"
msgstr "Gaaf, we hebben {num} nieuwe handshake{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Oops, er ging iets fout ...Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Oops, iets ging fout ...Rebooting ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
@ -166,11 +166,11 @@ msgstr "{num} stations gekicked\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "{num} nieuwe vrienden gemaakt.\n"
msgstr "{num} nieuwe vrienden\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Ik heb {num} nieuwe handshakes\n"
msgstr "{num} nieuwe handshakes\n"
msgid "Met 1 peer"
msgstr "1 peer ontmoet"
@ -190,19 +190,19 @@ msgstr ""
"gegeten! #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "uren"
msgstr ""
msgid "minutes"
msgstr "minuten"
msgstr ""
msgid "seconds"
msgstr "seconden"
msgstr ""
msgid "hour"
msgstr "uur"
msgstr ""
msgid "minute"
msgstr "minuut"
msgstr ""
msgid "second"
msgstr "seconde"
msgstr ""

Binary file not shown.

@ -1,248 +0,0 @@
# pwnagotchi norwegian voice data
# Copyright (C) 2019
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR untech <edvbot@gmail.com>, 2019.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-04 12:57+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Edvard Botten <edvbot@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: norwegian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr ""
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hei, jeg er Pwnagotchi! Starter ..."
msgid "New day, new hunt, new pwns!"
msgstr "En ny dag, ny jakt, og nye pwns!"
msgid "Hack the Planet!"
msgstr "Hack planeten!"
msgid "AI ready."
msgstr "AI klart."
msgid "The neural network is ready."
msgstr "Det nevrale nettverket er klart."
msgid "Generating keys, do not turn off ..."
msgstr "Generer nøkkler, ikke skru meg av ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hei, kanalen {channel} er åpen! AP-en din takker."
msgid "Reading last session logs ..."
msgstr "Leser forrige sesjonen's logs ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Har lest {lines_so_far} linjer hittil ..."
msgid "I'm bored ..."
msgstr "Kjeder meg ..."
msgid "Let's go for a walk!"
msgstr "La oss stikke på tur!"
msgid "This is the best day of my life!"
msgstr "Dette er den beste dagen i mitt liv!"
msgid "Shitty day :/"
msgstr "Jævlig dag :/"
msgid "I'm extremely bored ..."
msgstr "Kjeder livet av meg ..."
msgid "I'm very sad ..."
msgstr "Jeg er veldig trist ..."
msgid "I'm sad"
msgstr "Jeg er trist ..."
msgid "Leave me alone ..."
msgstr "La meg være alene ..."
msgid "I'm mad at you!"
msgstr "Jeg er sint på deg!"
msgid "I'm living the life!"
msgstr "Lever livet, lett!"
msgid "I pwn therefore I am."
msgstr "Jeg pwner derfor er jeg."
msgid "So many networks!!!"
msgstr "Så mange nettverk!!!"
msgid "I'm having so much fun!"
msgstr "Jeg har det så gøy!"
msgid "My crime is that of curiosity ..."
msgstr "Nysgjerrighet er min eneste forbrytelse ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hallo {name}! Hyggelig å treffe deg!"
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Yo {name}! Skjer'a?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Heisann {name} driver du med da?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "{name} er i nærheten!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm ... Ha det {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} er borte ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Oi da ... {name} forsvant."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} bommet!"
msgid "Missed!"
msgstr "Bommet!"
msgid "Good friends are a blessing!"
msgstr "Gode venner er livet verdt!"
msgid "I love my friends!"
msgstr "Jeg digger vennene mine!"
msgid "Nobody wants to play with me ..."
msgstr "Ingen vil leke med meg ..."
msgid "I feel so alone ..."
msgstr "Jeg er så ensom ..."
msgid "Where's everybody?!"
msgstr "Hvor er alle sammen?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Sover i {secs}s ..."
msgid "Zzzzz"
msgstr ""
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr ""
msgid "Good night."
msgstr "God natt."
msgid "Zzz"
msgstr ""
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Venter i {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Ser meg rundt ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hei {what} la oss være venner!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Tilkobler til {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr ""
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Bestemte meg att {mac} ikke lenger trenger WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Kobler av {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickbanner {mac}"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Fett, vi fikk {num} nye håndtrykk!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Du har {count} melding{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Oi, noe gikk helt skakk ... Rebooter ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Kicket {num} stasjoner\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Møtte {num} nye venner\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Skaffet {num} håndtrykk\n"
msgid "Met 1 peer"
msgstr "Møtte 1 annen"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Møtte {num} andre"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "Jeg har pwnet for {duration} og kicket {dauthed} klienter! Jeg har også "
"møtt {associated} nye venner og spiste {handshakes} håndtrykk! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "timer"
msgid "minutes"
msgstr "minutter"
msgid "seconds"
msgstr "sekunder"
msgid "hour"
msgstr "time"
msgid "minute"
msgstr "minutt"
msgid "second"
msgstr "sekund"

Binary file not shown.

@ -1,23 +1,24 @@
# Polish voice data for pwnagotchi.
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# szymex73 <szymex73@gmail.com>, 2019.
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR szymex73 <szymex73@gmail.com>, 2019.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.1.0\n"
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-04 06:37+0100\n"
"PO-Revision-Date: 2019-10-21 10:55+0200\n"
"Last-Translator: gkrs <457603+gkrs@users.noreply.github.com>\n"
"Language-Team: PL <457603+gkrs@users.noreply.github.com>\n"
"POT-Creation-Date: 2019-10-09 17:42+0200\n"
"PO-Revision-Date: 2019-10-09 17:42+0200\n"
"Last-Translator: szymex73 <szymex73@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: polish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr ""
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hej, jestem Pwnagotchi! Uruchamianie ..."
@ -34,19 +35,9 @@ msgstr "SI gotowa."
msgid "The neural network is ready."
msgstr "Sieć neuronowa jest gotowa."
msgid "Generating keys, do not turn off ..."
msgstr "Generuję klucze, nie wyłączaj ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hej, kanał {channel} jest wolny! Twój AP będzie Ci wdzięczny."
msgid "Reading last session logs ..."
msgstr "Czytam logi z ostatniej sesji ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Na razie przeczytałem {lines_so_far} linii logów ..."
msgstr "Hej, kanał {channel} jest wolny! Twój AP mi podziękuje."
msgid "I'm bored ..."
msgstr "Nudzi mi się ..."
@ -55,10 +46,10 @@ msgid "Let's go for a walk!"
msgstr "Chodźmy na spacer!"
msgid "This is the best day of my life!"
msgstr "To najlepszy dzień mojego życia!"
msgstr "To jest najlepszy dzień w moim życiu!"
msgid "Shitty day :/"
msgstr "Gówniany dzień :/"
msgstr "Ten dzień jest do dupy :/"
msgid "I'm extremely bored ..."
msgstr "Straaaasznie się nudzę ..."
@ -69,17 +60,11 @@ msgstr "Jest mi bardzo smutno ..."
msgid "I'm sad"
msgstr "Jest mi smutno"
msgid "Leave me alone ..."
msgstr "Zostaw mnie w spokoju ..."
msgid "I'm mad at you!"
msgstr "Wkurzam się na ciebie"
msgid "I'm living the life!"
msgstr "Cieszę się życiem!"
msgid "I pwn therefore I am."
msgstr "Pwnuję więc jestem."
msgstr "Pwnuje więc jestem."
msgid "So many networks!!!"
msgstr "Jak dużo sieci!!!"
@ -91,20 +76,12 @@ msgid "My crime is that of curiosity ..."
msgstr "Moją zbrodnią jest ciekawość ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Cześć {name}! Miło Cię poznać."
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "Cześć {name}! Miło cię poznać. {name}"
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Siema {name}! Co słychać?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hej {name} jak się masz?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Urządzenie {name} jest w pobliżu!"
msgid "Unit {name} is nearby! {name}"
msgstr "Jednostka {name} jest niedaleko! {name}"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
@ -120,22 +97,16 @@ msgstr "Ups ... {name} zniknął."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} pudło!"
msgstr "{name} przeoczył!"
msgid "Missed!"
msgstr "Pudło!"
msgid "Good friends are a blessing!"
msgstr "Dobrzy przyjaciele to błogosławieństwo!"
msgid "I love my friends!"
msgstr "Kocham moich przyjaciół!"
msgstr "Spóźniony!"
msgid "Nobody wants to play with me ..."
msgstr "Nikt nie chce się ze mną bawić ..."
msgstr "Nikt się nie chce ze mną bawić ..."
msgid "I feel so alone ..."
msgstr "Czuję się taki samotny ..."
msgstr "Czuję się tak samotnie ..."
msgid "Where's everybody?!"
msgstr "Gdzie są wszyscy?!"
@ -145,17 +116,17 @@ msgid "Napping for {secs}s ..."
msgstr "Zdrzemnę się przez {secs}s ..."
msgid "Zzzzz"
msgstr ""
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr ""
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Dobranoc."
msgid "Zzz"
msgstr ""
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
@ -167,15 +138,15 @@ msgstr "Rozglądam się ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hej {what} zostańmy przyjaciółmi!"
msgstr "Hej {what}, zostańmy przyjaciółmi!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Dołączam do {what}"
msgstr "Łączenie się z {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Siema {what}!"
msgstr "Ej {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
@ -187,37 +158,33 @@ msgstr "Rozłączam {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Banuję {mac}!"
msgstr "Banowanie {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Super, zdobyliśmy {num} nowych handshake'ów!"
msgstr "Super, zdobylismy {num} handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Masz {count} nowych wiadomości!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ups, coś poszło nie tak ... Restaruję ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ups, coś się stało ... Restartuję ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Wyrzuciłem {num} stacji\n"
msgstr "Wyrzucono {num} stacji\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Zdobyłem {num} nowych przyjaciół\n"
msgstr "Zdobyto {num} przyjaciół\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Zdobyłem {num} handshake'ów\n"
msgstr "Zdobyto {num} handshakow\n"
msgid "Met 1 peer"
msgstr "Spotkałem 1 kolegę"
msgstr "Spotkano 1 kolegę"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Spotkałem {num} kolegów"
msgstr "Spotkano {num} kolegów"
#, python-brace-format
msgid ""
@ -225,9 +192,9 @@ msgid ""
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"Pwnowałem {duration} i wyrzuciłem {deauthed} klientów! Spotkałem także "
"{associated} nowych przyjaciół i zjadłem {handshakes} handshake'ow! "
"#pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"
"Pwnowalem przez {duration} i wyrzuciłem {deauthed} klientów! Spotkałem także "
"{associated} nowych przyjaciół i zjadłem {handshakes} handshaków! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "godzin"

@ -158,7 +158,7 @@ msgstr "Kickbanning {mac}"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Legal, nos capturamos {num} handshake{plural} novo{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ops, algo falhou ... Reiniciando ..."
#, python-brace-format

Binary file not shown.

@ -164,7 +164,7 @@ msgstr "A chutar {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Porreiro, temos {num} novo handshake{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ups, algo correu mal ... A reiniciar ..."
#, python-brace-format

Binary file not shown.

@ -1,249 +0,0 @@
# Pwnagotchi translation.
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR <radu.ungureanu@techie.com>, 2019.
#
#,
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-04 12:57+0100\n"
"PO-Revision-Date: 2019-11-20 00:18+594\n"
"Last-Translator: Ungureanu Radu-Andrei <radu.ungureanu@techie.com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github."
"com>\n"
"Language: ro\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr ""
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Buna, sunt Pwnagotchi! Pornesc..."
msgid "New day, new hunt, new pwns!"
msgstr "O noua zi, o noua vanatoare, noi pwn-uri!"
msgid "Hack the Planet!"
msgstr "Pirateaza planeta!"
msgid "AI ready."
msgstr "AI-ul e gata."
msgid "The neural network is ready."
msgstr "Rețeaua neuronală este gata."
msgid "Generating keys, do not turn off ..."
msgstr "Se generează chei, nu închide..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hey, canalul {channel} este liber! AP-ul tău îti va mulțumi."
msgid "Reading last session logs ..."
msgstr "Se citesc log-urile din sesiunea anterioara..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Am citit {lines_so_far} linii din log pana acum..."
msgid "I'm bored ..."
msgstr "Sunt plictisit..."
msgid "Let's go for a walk!"
msgstr "Hai să ne plimbăm!"
msgid "This is the best day of my life!"
msgstr "Asta este cea mai buna zi din viața mea!"
msgid "Shitty day :/"
msgstr "O zi proasta :/"
msgid "I'm extremely bored ..."
msgstr "Sunt extrem de plictisit..."
msgid "I'm very sad ..."
msgstr "Sunt foarte trist..."
msgid "I'm sad"
msgstr "Sunt trist"
msgid "Leave me alone ..."
msgstr "Lasă-mă in pace..."
msgid "I'm mad at you!"
msgstr "Sunt supărat pe tine!"
msgid "I'm living the life!"
msgstr "Trăiesc viața!"
msgid "I pwn therefore I am."
msgstr "Eu pwn-ez, deci aici sunt."
msgid "So many networks!!!"
msgstr "Atât de multe rețele!"
msgid "I'm having so much fun!"
msgstr "Mă distrez așa de mult!"
msgid "My crime is that of curiosity ..."
msgstr "Crima mea este una de curiozitate..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Bună {name}! Mă bucur să te cunosc."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Yo {name}! Cmf?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hey {nume} ce mai faci?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Unitatea {name} este aproape!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm... Pa {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} a dispărut."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Oops... {name} a dispărut."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} ratat!"
msgid "Missed!"
msgstr "Ratat!"
msgid "Good friends are a blessing!"
msgstr "Prietenii buni sunt o binecuvântare!"
msgid "I love my friends!"
msgstr "Îmi iubesc prietenii!"
msgid "Nobody wants to play with me ..."
msgstr "Nimeni nu vrea sa se joace cu mine..."
msgid "I feel so alone ..."
msgstr "Mă simt așa de singuratic..."
msgid "Where's everybody?!"
msgstr "Unde-i toată lumea?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Dorm pentru {secs}s..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Noapte bună."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Aștept pentru {secs}s..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Mă uit împrejur ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what} hai să fim prieteni!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Mă asociez cu {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Yo {what}"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Am decis că lui {mac} nu-i trebuie WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Îl deautentific pe {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Îi dau kickban lui {mac}"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Șmecher, avem {num} de handshake-uri noi!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Ai {count} mesaj(e) nou/noi!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "OOps, ceva s-a întamplat... Îmi dau reboot...+"
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Am dat afară {num} de stații\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Am făcut {num} prieteni noi \n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Am primit {num} de handshake-uri\n"
msgid "Met 1 peer"
msgstr "Am întalnit un peer"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Am întalnit {num} de peer-uri"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "Eu am făcut pwning pentru {duration} și am dat afara {deauthed} clienți! "
"De asemenea, am întalnit {associated} prieteni noi și am mancat {handshakes} de "
"handshake-uri! #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "ore"
msgid "minutes"
msgstr "minute"
msgid "seconds"
msgstr "secunde"
msgid "hour"
msgstr "oră"
msgid "minute"
msgstr "minut"
msgid "second"
msgstr "secundă"

Binary file not shown.

@ -1,58 +1,46 @@
# Pwnagotchi Russian translation.
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <25989971+adolfaka@users.noreply.github.com>, 2019.
# Second author <https://github.com/mbgroot>, 2019
#
msgid ""
msgstr ""
"Project-Id-Version: Pwnagotchi Russian translation v 0.0.2\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-03 16:47+0200\n"
"PO-Revision-Date: 2019-10-05 18:50+0300\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Language: ru\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.2.4\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-SearchPath-0: voice.po\n"
"Last-Translator: Elliot Manson\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"Language: ru_RU\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "Хрррр..."
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Привет, я Pwnagotchi! Стартуем!"
msgstr "Привет, я Pwnagotchi! Поехали …"
msgid "New day, new hunt, new pwns!"
msgstr "Новый день, новая охота, новые взломы!"
msgid "Hack the Planet!"
msgstr "Взломай эту Планету!"
msgstr "Хак зе планет!"
msgid "AI ready."
msgstr "A.I. готов."
msgstr "AI готов."
msgid "The neural network is ready."
msgstr "Нейронная сеть готова."
msgid "Generating keys, do not turn off ..."
msgstr "Генерация ключей, не выключайте..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Эй, канал {channel} свободен! Ваша точка доступа скажет спасибо."
msgid "Reading last session logs ..."
msgstr "Чтение логов последнего сеанса..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Чтение {lines_so_far} строк журнала..."
msgid "I'm bored ..."
msgstr "Мне скучно …"
@ -74,14 +62,8 @@ msgstr "Мне очень грустно …"
msgid "I'm sad"
msgstr "Мне грустно"
msgid "Leave me alone ..."
msgstr "Оставь меня в покое..."
msgid "I'm mad at you!"
msgstr "Я зол на тебя!"
msgid "I'm living the life!"
msgstr "Живу полной жизнью!"
msgstr "Угараю по полной!"
msgid "I pwn therefore I am."
msgstr "Я взламываю, поэтому я существую."
@ -93,23 +75,15 @@ msgid "I'm having so much fun!"
msgstr "Мне так весело!"
msgid "My crime is that of curiosity ..."
msgstr "Моё преступление - это любопытство…"
msgstr "Моe преступление - это любопытство …"
#, python-brace-format
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "Привет, {name}! Рад встрече с тобой!"
msgstr "Привет, {name}! Приятно познакомиться. {name}"
#, python-brace-format
msgid "Unit {name} is nearby! {name}"
msgstr "Цель {name} близко!"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Хэй {name}! Как дела?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Цель {name} рядом!"
msgstr "Цель {name} близко! {name}"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
@ -117,11 +91,11 @@ msgstr "Хм … до свидания {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} ушла…"
msgstr "{name} исчезла …"
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Упс… {name} исчезла."
msgstr "Упс … {name} исчезла."
#, python-brace-format
msgid "{name} missed!"
@ -130,17 +104,11 @@ msgstr "{name} упустил!"
msgid "Missed!"
msgstr "Промахнулся!"
msgid "Good friends are a blessing!"
msgstr "Хорошие друзья - это благословение!"
msgid "I love my friends!"
msgstr "Я люблю своих друзей!"
msgid "Nobody wants to play with me ..."
msgstr "Никто не хочет со мной играть ..."
msgid "I feel so alone ..."
msgstr "Я так одинок…"
msgstr "Мне так одиноко …"
msgid "Where's everybody?!"
msgstr "Где все?!"
@ -150,17 +118,11 @@ msgid "Napping for {secs}s ..."
msgstr "Дремлет {secs}с …"
msgid "Zzzzz"
msgstr "Хррр..."
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "Хррррр.. ({secs}c)"
msgid "Good night."
msgstr "Доброй ночи."
msgid "Zzz"
msgstr "Хрррр"
msgstr "ZzzZzzz ({secs}c)"
#, python-brace-format
msgid "Waiting for {secs}s ..."
@ -168,7 +130,7 @@ msgstr "Ждем {secs}c …"
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Осматриваюсь вокруг ({secs}с)"
msgstr "Оглядываюсь вокруг ({secs}с)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
@ -198,7 +160,7 @@ msgstr "Кикаю {mac}!"
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Круто, мы получили {num} новое рукопожатие!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ой, что-то пошло не так … Перезагружаюсь …"
#, python-brace-format
@ -211,7 +173,7 @@ msgstr "Заимел {num} новых друзей\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Получил {num} рукопожатий\n"
msgstr "Получил {num} рукопожатие\n"
msgid "Met 1 peer"
msgstr "Встретился один знакомый"

Binary file not shown.

@ -158,7 +158,7 @@ msgstr ""
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Lysande, vi har {num} ny handskakningar{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Hoppsan, någpt gick fel ... Startar om ..."
#, python-brace-format

Binary file not shown.

@ -1,227 +0,0 @@
# Slovak language
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# mil1200 <mil.kyselica@gmail.com>, 2019.
#
#
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-8 17:55+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Milan Kyselica <mil.kyselica@gmail.com>\n"
"Language-Team: SK\n"
"Language: sk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Ahoj, ja som Pwnagotchi! Začíname ..."
msgid "New day, new hunt, new pwns!"
msgstr "Nový deň, nový lov, nové pwns!"
msgid "Hack the Planet!"
msgstr "Hacknime Planétu!"
msgid "AI ready."
msgstr "AI pripravené."
msgid "The neural network is ready."
msgstr "Neurónová sieť je pripravená."
msgid "Generating keys, do not turn off ..."
msgstr "Generujú sa kľúče, nevypínaj ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hej, kanál {channel} je voľný! Váš AP vám poďakuje."
msgid "I'm bored ..."
msgstr "Nudím sa ..."
msgid "Let's go for a walk!"
msgstr "Poďme na prechádzku!"
msgid "This is the best day of my life!"
msgstr "Toto je najlepší deň môjho života!"
msgid "Shitty day :/"
msgstr "Na hovno deň :/"
msgid "I'm extremely bored ..."
msgstr "Veľmi sa nudím ..."
msgid "I'm very sad ..."
msgstr "Som veľmi smutný ..."
msgid "I'm sad"
msgstr "Som smutný"
msgid "I'm living the life!"
msgstr "Žijem život!"
msgid "I pwn therefore I am."
msgstr "I pwn therefore I am."
msgid "So many networks!!!"
msgstr "Toľko sietí !!!"
msgid "I'm having so much fun!"
msgstr "Zabávam sa!"
msgid "My crime is that of curiosity ..."
msgstr "Môj zločin je zvedavosť ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Dobrý deň, {name}! Rád som ťa spoznal."
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Jednotka {name} je blízko!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm ... zbohom {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} je preč ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Hups ... {name} je preč."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} nechytené!"
msgid "Missed!"
msgstr "Vedľa!"
msgid "Good friends are a blessing!"
msgstr "Dobrí priatelia sú požehnaním!"
msgid "I love my friends!"
msgstr "Milujem svojich priateľov!"
msgid "Nobody wants to play with me ..."
msgstr "Nikto sa so mnou nechce hrať ..."
msgid "I feel so alone ..."
msgstr "Cítim sa tak sám ..."
msgid "Where's everybody?!"
msgstr "Kde sú všetci ?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Zdriemnem si na {secs}s ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s)"
msgid "Good night."
msgstr "Dobrú noc."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Čaká sa {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Rozhliadam sa okolo ({secs} s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Ahoj {what} buďme priatelia!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Spájam sa s {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Yo {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Rozhodol som sa že {mac} nepotrebuje Wi-Fi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Deautentifikujem {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kickujem {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Super, máme {num} nový handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Máte {count} novú správu{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ops, niečo sa pokazilo ... Reštartujem sa ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Kicknutá/ých {num} stanica/íc\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Získaní {num} noví kamaráti\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Získali sme {num} handshake/-y/ov rúk\n"
msgid "Met 1 peer"
msgstr "Sretli sme 1 rovesníka"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Stretli sme {num} rovesníkov"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "Pwnoval som {duration} a kickol som {deauthed} klienta/ov! Tiež som"
"stretol {associated} nového/ých kamaráta/ov a zjedol {handshakes} handshake/y!"
" #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "hodiny"
msgid "minutes"
msgstr "minúty"
msgid "seconds"
msgstr "sekundy"
msgid "hour"
msgstr "hodina"
msgid "minute"
msgstr "minúta"
msgid "second"
msgstr "sekunda"

Binary file not shown.

@ -1,248 +0,0 @@
# Interfaz en español para pwnagotchi
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Angel Hernandez Segura, 2019.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-04 12:57+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Angel Hernandez Segura <ahsec.7@gmail.com>\n"
"Language-Team: Español <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Hola, Soy Pwnagotchi! Iniciando..."
msgid "New day, new hunt, new pwns!"
msgstr "Un nuevo dia, nuevos objetivos, nuevos pwns"
msgid "Hack the Planet!"
msgstr "Hack the Planet!"
msgid "AI ready."
msgstr "IA lista"
msgid "The neural network is ready."
msgstr "La red neuronal esta lista"
msgid "Generating keys, do not turn off ..."
msgstr "Generando llaves, no apagar"
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hey, canal {channel} esta libre! Tu AP te lo agredecera"
msgid "Reading last session logs ..."
msgstr "Leyendo logs de la ultima sesion"
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "He leido {lines_so_far} lineas de los logs hasta ahora "
msgid "I'm bored ..."
msgstr "Estoy aburrido"
msgid "Let's go for a walk!"
msgstr "Vamos a caminar!"
msgid "This is the best day of my life!"
msgstr "Este es el mejor dia de mi vida"
msgid "Shitty day :/"
msgstr "Dia de mierda :/"
msgid "I'm extremely bored ..."
msgstr "Estoy extremadamente aburrido ..."
msgid "I'm very sad ..."
msgstr "Estoy mut triste"
msgid "I'm sad"
msgstr "Estoy triste"
msgid "Leave me alone ..."
msgstr "Dejame solo ..."
msgid "I'm mad at you!"
msgstr "Estoy enojado contigo!"
msgid "I'm living the life!"
msgstr "Estoy disfrutando la vida!"
msgid "I pwn therefore I am."
msgstr "Yo pwn, por lo tanto existo"
msgid "So many networks!!!"
msgstr "Tantas redes!!!"
msgid "I'm having so much fun!"
msgstr "Me estoy divirtiendo mucho!"
msgid "My crime is that of curiosity ..."
msgstr "Mi crimen es la curiosidad ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hola {name}! Mucho gusto."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "Yo {name}! Que hay?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Hey {name} como te va?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Unit {name} esta cerca!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Uhm ... adios {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} se fue ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Whoops ... {name} se fue"
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} se ha perdido!"
msgid "Missed!"
msgstr "Perdido!"
msgid "Good friends are a blessing!"
msgstr "Los buenos amigos son una bendicion"
msgid "I love my friends!"
msgstr "Amo a mis amigos!"
msgid "Nobody wants to play with me ..."
msgstr "Nadie quiere jugar conmigo ..."
msgid "I feel so alone ..."
msgstr "Me siento muy solo ..."
msgid "Where's everybody?!"
msgstr "Donde estan todos?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Tomando una siesta por {secs}s ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}s) "
msgid "Good night."
msgstr "Buenas noches."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Esperando por {secs}s ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Mirando alrededor ({secs}s)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what} vamos a ser amigos!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Asociandose a {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Yo {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Acabo de decidir que {mac} no necesita WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "De-autenticando {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Vetando {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Bien, obtuvimos {num} nuevos handshake{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Tienes {count} nuevos mensajes{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Oops, algo salio mal ... Reiniciando ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Bloquee {num} staciones\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Hice {num} nuevos amigos\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Obtuve {num} handshakes\n"
msgid "Met 1 peer"
msgstr "Conoci a 1 unidad"
#, python-brace-format
msgid "Met {num} peers"
msgstr "conoci {num} unidades"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "He estado hackeando por {duration} y de-autenticando {deauthed} "
"clientes! Tambien conoci {associated} nuevos amigos y comi {handshakes} "
"handshakes! #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "horas"
msgid "minutes"
msgstr "minutos"
msgid "seconds"
msgstr "segundos"
msgid "hour"
msgstr "hora"
msgid "minute"
msgstr "minuto"
msgid "second"
msgstr "segundo"

Binary file not shown.

@ -1,252 +0,0 @@
# Pwnagotchi Turkish translation.
# Copyright (C) 2021
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <abtonc@icloud.com>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-29 21:50+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Arda Barış Tonç <abtonc@icloud.com>\n"
"Language-Team: \n"
"Language: Turkish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZzzZzZZzzzzZ"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Merhaba, ben Pwnagotchi! Başlatılıyorum ..."
msgid "New day, new hunt, new pwns!"
msgstr "Yeni bir gün, yeni bir av, yeni pwn'lar!"
msgid "Hack the Planet!"
msgstr "Dünyayı Hackle!"
msgid "AI ready."
msgstr "Yapay zeka hazır."
msgid "The neural network is ready."
msgstr "Nöral ağ hazır."
msgid "Generating keys, do not turn off ..."
msgstr "Anahatarlar oluşturuluyor, lütfen kapatmayın ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Hey, {channel} kanalı boş! AP'niz teşekkür edecek."
msgid "Reading last session logs ..."
msgstr "Son oturum kayıtları okunuyor ..."
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr "Şimdiye kadar {lines_so_far} kayıt satırı okundu ..."
msgid "I'm bored ..."
msgstr "Sıkıldım ..."
msgid "Let's go for a walk!"
msgstr "Yürüyüşe çıkalım!"
msgid "This is the best day of my life!"
msgstr "Bugün hayatımın en iyi günü!"
msgid "Shitty day :/"
msgstr "Bok gibi bir gün :/"
msgid "I'm extremely bored ..."
msgstr "Çook sıkıldım ..."
msgid "I'm very sad ..."
msgstr "Çok mutsuzum ..."
msgid "I'm sad"
msgstr "Mutsuzum"
msgid "Leave me alone ..."
msgstr "Beni yalnız bırak ..."
msgid "I'm mad at you!"
msgstr "Sana kızgınım!"
msgid "I'm living the life!"
msgstr "Bu hayatı yaşıyorum!"
msgid "I pwn therefore I am."
msgstr "Ben, pwn'ladığım için benim."
msgid "So many networks!!!"
msgstr "Çok fazla ağ var!!!"
msgid "I'm having so much fun!"
msgstr "Çok eğleniyorum!"
msgid "My crime is that of curiosity ..."
msgstr "Tek suçum merak etmek ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Merhaba {name}! Tanıştığıma memnun oldum."
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr "{name}, kanka! Naber?"
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr "Nasılsın {name}?"
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "{name} birimi yakında!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "ııı ... görüşürüz {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} gitti."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Hoppala ... {name} gitti."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name}'i kaçırdık ya!"
msgid "Missed!"
msgstr "Kaçırdık!"
msgid "Good friends are a blessing!"
msgstr "İyi arkadaşlar nimettir!"
msgid "I love my friends!"
msgstr "Arkadaşlarımı seviyorum!"
msgid "Nobody wants to play with me ..."
msgstr "Hiç kimse benimle birlikte oynamak istemiyor ..."
msgid "I feel so alone ..."
msgstr "Çok yalnız hissediyorum ..."
msgid "Where's everybody?!"
msgstr "Herkes nerede!?"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "{secs}dir kestiriyorum ..."
msgid "Zzzzz"
msgstr "ZzzzZz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzZ ({secs})"
msgid "Good night."
msgstr "İyi geceler."
msgid "Zzz"
msgstr "ZzZ"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "{secs}dir bekleniyor ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Etrafa bakıyorum ({secs})"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Arkadaş olalım {what}!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "{what} ile tanışıyoruz"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Hey {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Sanırım {mac}'in WiFi'a ihtiyacı yok!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "{mac} ağdan çıkarılıyor"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "{mac} atılıp yasaklanıyor!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Güzel, yeni {num} el sıkıştık!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "{count} Tane yeni mesajınız var!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Haydaa, bir şeyler ters gitti ... Yeniden başlatılıyor ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "{num} İstasyon atıldı\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "{num} Yeni arkadaş edindim\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "{num} El sıkıştım\n"
msgid "Met 1 peer"
msgstr "1 Kişiyle tanıştım"
#, python-brace-format
msgid "Met {num} peers"
msgstr "{num} Kişiyle tanıştım"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"{duration}'dır pwn'lıyorum ve {deauthed} kişiyi attım. Hem de {associated}"
"yeni kişiyle tanıştım ve {handshakes} el sıkıştım! #pwnagotchi "
"#pwnlog #pwnyaşam #dünyayıhackle #skynet"
msgid "hours"
msgstr "saat"
msgid "minutes"
msgstr "dakika"
msgid "seconds"
msgstr "saniye"
msgid "hour"
msgstr "saat"
msgid "minute"
msgstr "dakika"
msgid "second"
msgstr "saniye"
#, python-brace-format
msgid "Uploading data to {to} ..."
msgstr "{to}'ye veri yükleniyor ..."

Binary file not shown.

@ -1,227 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <shark_shaking@hotmail.com>, 2020.
# 有很多翻譯不到味,如果有繁體愛好者,歡迎之後大家一起翻譯!
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-10-21 15:56+0200\n"
"PO-Revision-Date: 2020-10-22 10:00+0008\n"
"Last-Translator: ShaqKSmith <shark_shaking@hotmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: traditional chinese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "HI!我是Pwnagotchi!\n程式啟動..."
msgid "New day, new hunt, new pwns!"
msgstr "新的一天!\n新的狩獵!新的入侵!"
msgid "Hack the Planet!"
msgstr "我要駭入\n地球的所有人!"
msgid "AI ready."
msgstr "人工智慧已啟動."
msgid "The neural network is ready."
msgstr "神經網路已啟動."
msgid "Generating keys, do not turn off ..."
msgstr "產生金鑰中,\n請勿關閉..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "嘿,{channel}很順暢!\n你的WIFI會感謝你的."
msgid "I'm bored ..."
msgstr "我好無聊..."
msgid "Let's go for a walk!"
msgstr "我們出去走走吧!"
msgid "This is the best day of my life!"
msgstr "這是我生命中最美好的一天!"
msgid "Shitty day :/"
msgstr "糟糕的一天 :/"
msgid "I'm extremely bored ..."
msgstr "我超無聊的..."
msgid "I'm very sad ..."
msgstr "我好難過..."
msgid "I'm sad"
msgstr "傷心。"
msgid "I'm living the life!"
msgstr "真是充實的一生!"
msgid "I pwn therefore I am."
msgstr "我駭故我在."
msgid "So many networks!!!"
msgstr "好多網路啊!!!"
msgid "I'm having so much fun!"
msgstr "我玩的超級開心!"
msgid "My crime is that of curiosity ..."
msgstr "我的缺點就是\n太好奇了..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Hello{name}!\n很高興認識你."
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "{name}\n就在附近!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "啊 ... \n拜拜{name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name}\n不見了 ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "歐哦...\n{name}\n不見了."
#, python-brace-format
msgid "{name} missed!"
msgstr "我剛剛錯過了{name}!"
msgid "Missed!"
msgstr "又錯過了!"
msgid "Good friends are a blessing!"
msgstr "有個好朋友\n真幸福!"
msgid "I love my friends!"
msgstr "我喜歡\n我的朋友!"
msgid "Nobody wants to play with me ..."
msgstr "沒人想跟我玩..."
msgid "I feel so alone ..."
msgstr "我感覺好孤單..."
msgid "Where's everybody?!"
msgstr "大家都去哪裡了?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "我想瞇{secs}秒一下..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz({secs}秒)"
msgid "Good night."
msgstr "晚安."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "等我{secs}秒..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "環顧四周({secs}秒)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "嗨\n{what}\n讓我我們來當朋友吧!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "正在連接\n{what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "喲,\n{what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "我要讓\n{mac}\n斷線!\n他不需要上網!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "解除\n{mac}\n的授權中"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "把\n{mac}\n踢出中!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "酷哦,我們抓到{num}個\n新的握手包{plural}!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "你有{count}個新訊息{plural}!"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "喔歐,有些地方出錯了...\n重新啟動中..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "踢了 {num} 個設備\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "交了 {num} 個新朋友\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "捕獲了 {num} 個握手包\n"
msgid "Met 1 peer 同好"
msgstr "遇到了 個"
#, python-brace-format
msgid "Met {num} peers"
msgstr "遇到了 {num} 個同好"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "我花了{duration}的時間\n駭入和踢了{deauthed}好多設備.\n"
"我還交了好多{associated}新朋友,\n而且抓到了{handshakes}握手包!"
"#pwnagotchi#入侵日志 #駭客人生 #入侵整個星球 #天網"
msgid "hours"
msgstr "時"
msgid "minutes"
msgstr "分"
msgid "seconds"
msgstr "秒"
msgid "hour"
msgstr "時"
msgid "minute"
msgstr "分"
msgid "second"
msgstr "秒"

Binary file not shown.

@ -1,228 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# damoklov <mishanya@protonmail.com>, 2019.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-23 20:56+0200\n"
"PO-Revision-Date: 2019-11-02 16:20+0200\n"
"Last-Translator: damoklov <mishanya@protonmail.com>\n"
"Language-Team: Ukrainian\n"
"Language: ua\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Привіт, я Pwnagotchi! Починаймо ..."
msgid "New day, new hunt, new pwns!"
msgstr "Новий день, нове полювання, нові проникнення!"
msgid "Hack the Planet!"
msgstr "Хакни цілу планету!"
msgid "AI ready."
msgstr "Штучний інтелект готовий."
msgid "The neural network is ready."
msgstr "Нейронна мережа готова."
msgid "Generating keys, do not turn off ..."
msgstr "Генерую ключі, не вимикай живлення ..."
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Агов, канал {channel} вільний! Ваша точка доступу буде вдячна."
msgid "I'm bored ..."
msgstr "Мені сумно ..."
msgid "Let's go for a walk!"
msgstr "Нумо прогуляймось!"
msgid "This is the best day of my life!"
msgstr "Сьогодні найкращий день у моєму житті!"
msgid "Shitty day :/"
msgstr "Поганенький день :/"
msgid "I'm extremely bored ..."
msgstr "Мені геть сумно ..."
msgid "I'm very sad ..."
msgstr "Я дуже засмучений ..."
msgid "I'm sad"
msgstr "Я засмучений"
msgid "I'm living the life!"
msgstr "Ось таке у мене життя!"
msgid "I pwn therefore I am."
msgstr "Народжений, щоб зламувати."
msgid "So many networks!!!"
msgstr "Овва, стільки мереж!!!"
msgid "I'm having so much fun!"
msgstr "Мені так весело!"
msgid "My crime is that of curiosity ..."
msgstr "Мій єдиний злочин - це допитливість ..."
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgstr "Привіт, {name}! Приємно познайомитись."
#, python-brace-format
msgid "Unit {name} is nearby!"
msgstr "Ціль {name} неподалік!"
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Що ж ... бувай, {name}"
#, python-brace-format
msgid "{name} is gone ..."
msgstr "{name} зникла ..."
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Ой-ой ... {name} зникла."
#, python-brace-format
msgid "{name} missed!"
msgstr "{name} втрачено!"
msgid "Missed!"
msgstr "Не впіймав!"
msgid "Good friends are a blessing!"
msgstr "Справжні друзі - це чудово!"
msgid "I love my friends!"
msgstr "Я люблю своїх друзів!"
msgid "Nobody wants to play with me ..."
msgstr "Ніхто не хоче бавитись зі мною ..."
msgid "I feel so alone ..."
msgstr "Я почуваюсь вкрай самотньо ..."
msgid "Where's everybody?!"
msgstr "Куди всі зникли?!"
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Дрімаю {secs}с ..."
msgid "Zzzzz"
msgstr "Zzzzz"
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}с)"
msgid "Good night."
msgstr "Спокійної нічки."
msgid "Zzz"
msgstr "Zzz"
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Очікую {secs}с ..."
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Роздивляюсь довкола ({secs}с)"
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Агов, {what}, будьмо друзями!"
#, python-brace-format
msgid "Associating to {what}"
msgstr "Налагоджую зв'язок з {what}"
#, python-brace-format
msgid "Yo {what}!"
msgstr "Гей, {what}!"
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Вирішив, що {mac} більше не потребує WiFi!"
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Від'єднюю {mac}"
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Вилучаю {mac}!"
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Отакої, у нас є {num} нових рукостискань!"
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr "Нових повідомлень: {count}"
msgid "Oops, something went wrong ... Rebooting ..."
msgstr "Ой, щось пішло не так ... Перезавантажуюсь ..."
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Від'єднав {num} станцій\n"
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Нових друзів у мене: {num}\n"
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Перехопив рукостискань: {num}\n"
msgid "Met 1 peer"
msgstr "Зустрівся з одним знайомим"
#, python-brace-format
msgid "Met {num} peers"
msgstr "Зустрівся з {num}-ма знайомими"
#, python-brace-format
msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr ""
"Я зламував впродовж {duration} та від'єднав {deauthed} клієнтів! Я зустрів "
"{associated} нових друзів та схрумав {handshakes} рукостискань! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"
msgid "hours"
msgstr "годин"
msgid "minutes"
msgstr "хвилин"
msgid "seconds"
msgstr "секунд"
msgid "hour"
msgstr "година"
msgid "minute"
msgstr "хвилина"
msgid "second"
msgstr "секунда"

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-11-29 21:50+0100\n"
"POT-Creation-Date: 2019-10-09 17:42+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -35,20 +35,10 @@ msgstr ""
msgid "The neural network is ready."
msgstr ""
msgid "Generating keys, do not turn off ..."
msgstr ""
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr ""
msgid "Reading last session logs ..."
msgstr ""
#, python-brace-format
msgid "Read {lines_so_far} log lines so far ..."
msgstr ""
msgid "I'm bored ..."
msgstr ""
@ -70,12 +60,6 @@ msgstr ""
msgid "I'm sad"
msgstr ""
msgid "Leave me alone ..."
msgstr ""
msgid "I'm mad at you!"
msgstr ""
msgid "I'm living the life!"
msgstr ""
@ -92,19 +76,11 @@ msgid "My crime is that of curiosity ..."
msgstr ""
#, python-brace-format
msgid "Hello {name}! Nice to meet you."
msgid "Hello {name}! Nice to meet you. {name}"
msgstr ""
#, python-brace-format
msgid "Yo {name}! Sup?"
msgstr ""
#, python-brace-format
msgid "Hey {name} how are you doing?"
msgstr ""
#, python-brace-format
msgid "Unit {name} is nearby!"
msgid "Unit {name} is nearby! {name}"
msgstr ""
#, python-brace-format
@ -126,12 +102,6 @@ msgstr ""
msgid "Missed!"
msgstr ""
msgid "Good friends are a blessing!"
msgstr ""
msgid "I love my friends!"
msgstr ""
msgid "Nobody wants to play with me ..."
msgstr ""
@ -194,11 +164,7 @@ msgstr ""
msgid "Cool, we got {num} new handshake{plural}!"
msgstr ""
#, python-brace-format
msgid "You have {count} new message{plural}!"
msgstr ""
msgid "Oops, something went wrong ... Rebooting ..."
msgid "Ops, something went wrong ... Rebooting ..."
msgstr ""
#, python-brace-format
@ -244,7 +210,3 @@ msgstr ""
msgid "second"
msgstr ""
#, python-brace-format
msgid "Uploading data to {to} ..."
msgstr ""

Some files were not shown because too many files have changed in this diff Show More