Merge pull request #1 from evilsocket/master

kk
This commit is contained in:
Alex Muthmann 2019-10-03 13:24:22 +02:00 committed by GitHub
commit 7224975946
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 2597 additions and 1901 deletions

10
.DEREK.yml Normal file
View File

@ -0,0 +1,10 @@
maintainers:
- evilsocket
- caquino
- dadav
- justin-p
features:
- comments
- pr_description_required

View File

@ -1,23 +1,53 @@
dist: bionic dist: bionic
language: generic language: go
go:
- 1.x
env: env:
global: global:
- LANG=C - LANG=C
- LC_ALL=C - LC_ALL=C
before_cache:
- mountpoint -q $TRAVIS_BUILD_DIR/tmp/mnt && sudo umount -R $TRAVIS_BUILD_DIR/tmp/mnt deploy:
- sudo find $TRAVIS_BUILD_DIR/tmp/ -name '*.img' -delete provider: releases
api_key:
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: pwnagotchi-*.zip
on:
tags: true
repo: evilsocket/pwnagotchi
branches:
only:
- /^v[0-9]+\.[0-9]+\.[0-9]+[A-Za-z0-9]+?$/
cache: cache:
apt: true apt: true
directories: directories:
- tmp/ - qemu-4.1.0
before_script:
- sudo apt-get -y update
- sudo apt-get -y install qemu-user-static binfmt-support qemu bmap-tools
- sudo update-binfmts --display
- unset GOROOT
script:
- sudo ./scripts/create_sibling.sh -n pwnagotchi -o pwnagotchi.img
- zip -s 2g pwnagotchi.zip pwnagotchi.img
# TODO: deploy! before_script:
- test -d qemu-4.1.0 || ( wget https://download.qemu.org/qemu-4.1.0.tar.xz && tar xvJf qemu-4.1.0.tar.xz )
- cd qemu-4.1.0
- ./configure --target-list=arm-softmmu
- make -j$(nproc)
- sudo make install
- cd $TRAVIS_BUILD_DIR
- sudo apt-get -y update
- sudo apt-get -y install qemu-user-static binfmt-support bmap-tools kpartx
- sudo update-binfmts --display
script:
- sudo make clean
- sudo -E env "PATH=$PATH" make install
- sudo make image -e PWN_HOSTNAME=pwnagotchi VERSION=$TRAVIS_TAG
before_deploy:
# Set up git user name and tag this commit
- git config --local user.name "evilsocket"
- git config --local user.email "evilsocket@gmail.com"
- export TRAVIS_TAG=${TRAVIS_TAG:-$(date +'%Y%m%d%H%M%S')-$(git log --format=%h -1)}
- git tag $TRAVIS_TAG

22
Makefile Normal file
View File

@ -0,0 +1,22 @@
PWN_HOSTNAME=pwnagotchi
PWN_VERSION=master
all: install image clean
install:
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
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
cp /tmp/packer-builder-arm-image/packer-builder-arm-image /usr/bin
image:
cd builder && sudo /usr/bin/packer build pwnagotchi.json
mv builder/output-pwnagotchi/image pwnagotchi-raspbian-lite-$(PWN_VERSION).img
zip pwnagotchi-raspbian-lite-$(PWN_VERSION).zip pwnagotchi-raspbian-lite-$(PWN_VERSION).img
clean:
rm -rf /tmp/packer-builder-arm-image
rm -f pwnagotchi-raspbian-lite.img
rm -rf builder/output-pwnagotchi builder/packer_cache

View File

@ -52,6 +52,22 @@ The supported models are:
- [Pimoroni Inky pHAT](https://shop.pimoroni.com/products/inky-phat) - [Pimoroni Inky pHAT](https://shop.pimoroni.com/products/inky-phat)
- [PaPiRus eInk Screen](https://uk.pi-supply.com/products/papirus-zero-epaper-screen-phat-pi-zero) - [PaPiRus eInk Screen](https://uk.pi-supply.com/products/papirus-zero-epaper-screen-phat-pi-zero)
The only kind of displays supported are the ones listed above, but we are always happy to receive pull requests supporting new displays.
One thing to note, not all displays are created equaly, TFT displays for example work similar to an HDMI display, and they are not supported, currently all the displays supported are I2C displays.
### Color and Black & White displays
Some of the supported displays support Black & White and Coloured versions, one common question is regarding refresh speed of said displays.
Color displays have a much slower refresh rate, in some cases it can take up to 15 seconds, if slow refresh rates is something that you want to avoid we advise you to use Black & White displays
### FPS
You can configure the refresh interval of the display on config.yml, we advise to use a slow refresh to not shorten the lifetime of your display.
Another option is to change fps to 0, which will only refresh when changes are made to the screen.
### Software ### Software
- Raspbian + [nexmon patches](https://re4son-kernel.com/re4son-pi-kernel/) for monitor mode, or any Linux with a monitor mode enabled interface (if you tune config.yml). - Raspbian + [nexmon patches](https://re4son-kernel.com/re4son-pi-kernel/) for monitor mode, or any Linux with a monitor mode enabled interface (if you tune config.yml).
@ -119,6 +135,7 @@ Pwnagotchi is able to speak multiple languages!! Currently supported are:
* greek * greek
* macedonian * macedonian
* italian * italian
* french
If you want to add a language use the `language.sh` script. If you want to add for example the language **italian** you would type: If you want to add a language use the `language.sh` script. If you want to add for example the language **italian** you would type:
@ -148,6 +165,64 @@ Now you can use the `preview.py`-script to preview the changes:
# Now open http://localhost:8080 and http://localhost:8081 # Now open http://localhost:8080 and http://localhost:8081
``` ```
### Plugins
Pwnagotchi has a simple plugins system that you can use to customize your unit and its behaviour. You can place your plugins anywhere
as python files and then edit the `config.yml` file (`main.plugins` value) to point to their containing folder. Check the [plugins folder](https://github.com/evilsocket/pwnagotchi/tree/master/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/) for a list of default
plugins and all the callbacks that you can define for your own customizations.
Here's as an example the GPS plugin:
```python
__author__ = 'evilsocket@gmail.com'
__version__ = '1.0.0'
__name__ = 'gps'
__license__ = 'GPL3'
__description__ = 'Save GPS coordinates whenever an handshake is captured.'
__enabled__ = True # set to false if you just don't use GPS
import core
import json
import os
device = '/dev/ttyUSB0'
speed = 19200
running = False
def on_loaded():
core.log("GPS plugin loaded for %s" % device)
def on_ready(agent):
global running
if os.path.exists(device):
core.log("enabling GPS bettercap's module for %s" % device)
try:
agent.run('gps off')
except:
pass
agent.run('set gps.device %s' % device)
agent.run('set gps.speed %d' % speed)
agent.run('gps on')
running = True
else:
core.log("no GPS detected")
def on_handshake(agent, filename, access_point, client_station):
if running:
info = agent.session()
gps = info['gps']
gps_filename = filename.replace('.pcap', '.gps.json')
core.log("saving GPS to %s (%s)" % (gps_filename, gps))
with open(gps_filename, 'w+t') as fp:
json.dump(gps, fp)
```
### Random Info ### Random Info
- `hostname` sets the unit name. - `hostname` sets the unit name.
@ -161,7 +236,7 @@ the `PARTUUID`s for `rootfs` and `boot` partitions are the same in `/etc/fstab`.
## License ## License
`pwnagotchi` is made with ♥ by [@evilsocket](https://twitter.com/evilsocket) and it's released under the GPL3 license. `pwnagotchi` is made with ♥ by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.

33
builder/pwnagotchi.json Normal file
View File

@ -0,0 +1,33 @@
{
"variables": {
"home": "{{env `HOME`}}"
},
"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": [
"sed -i 's/^\\([^#]\\)/#\\1/g' /etc/ld.so.preload",
"apt-get -y update",
"apt-get install -y ansible"
]
},
{
"type":"ansible-local",
"playbook_file": "pwnagotchi.yml"
},
{
"type": "shell",
"inline": [
"sed -i 's/^#\\(.+\\)/\\1/g' /etc/ld.so.preload"
]
}
]
}

306
builder/pwnagotchi.yml Normal file
View File

@ -0,0 +1,306 @@
---
- hosts:
- 127.0.0.1
become: yes
vars:
pwn_hostname: "pwnagotchi"
pwn_version: "master"
tasks:
- name: selected hostname
debug:
msg: "{{ pwn_hostname }}"
- name: build version
debug:
msg: "{{ pwn_version }}"
- name: change hostname
hostname:
name: "{{pwn_hostname}}"
- name: add hostname to /etc/hosts
lineinfile:
dest: /etc/hosts
regexp: '^127\.0\.0\.1[ \t]+localhost'
line: '127.0.0.1 localhost {{pwn_hostname}} {{pwn_hostname}}.local'
state: present
- 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: update apt package cache
apt:
update_cache: yes
- name: upgrade apt distro
apt:
upgrade: dist
- name: install packages
apt:
name: "{{ packages }}"
state: present
vars:
packages:
- vim
- screen
- golang
- git
- build-essential
- python3-pip
- gawk
- libopenmpi-dev
- libatlas-base-dev
- libjasper-dev
- libqtgui4
- libqt4-test
- libopenjp2-7
- tcpdump
- lsof
- libilmbase23
- libopenexr23
- libgstreamer1.0-0
- libavcodec58
- libavformat58
- libswscale5
- libpcap-dev
- libusb-1.0-0-dev
- libnetfilter-queue-dev
- dphys-swapfile
- kalipi-kernel
- kalipi-bootloader
- kalipi-re4son-firmware
- kalipi-kernel-headers
- libraspberrypi0
- libraspberrypi-dev
- libraspberrypi-doc
- libraspberrypi-bin
- fonts-dejavu
- fonts-dejavu-core
- fonts-dejavu-extra
- name: configure dphys-swapfile
file:
path: /etc/dphys-swapfile
content: "CONF_SWAPSIZE=1024"
- name: disable unecessary services
systemd:
name: "{{services}}"
state: stopped
enabled: no
vars:
services:
- apt-daily.timer
- apt-daily.service
- apt-daily-upgrade.timer
- apt-daily-upgrade.service
- bluetooth.service
- triggerhappy.service
- name: enable dphys-swapfile service
systemd:
name: dphys-swapfile.service
state: started
enabled: yes
- name: build bettercap
command: go get -u github.com/bettercap/bettercap
environment:
GOPATH: /root/go
GOROOT: /usr/lib/go
- name: install bettercap
copy:
src: /root/go/bin/bettercap
dest: /usr/bin/bettercap
mode: 0755
- name: clone bettercap caplets
git:
repo: https://github.com/bettercap/caplets.git
dest: /tmp/caplets
- name: install bettercap caplets
make:
chdir: /tmp/caplets
target: install
- name: clone pwnagotchi repository
git:
repo: https://github.com/evilsocket/pwnagotchi.git
dest: /tmp/pwnagotchi
- name: copy pwnagotchi files to final destination
copy:
src: /tmp/pwnagotchi/sdcard/rootfs/root/pwnagotchi/
dest: /root/pwnagotchi/
mode: preserve
- name: remove pwnagotchi files from temporary repository
file:
path: /tmp/pwnagotchi
state: absent
- name: install python modules
pip:
requirements: /root/pwnagotchi/scripts/requirements.txt
- name: create cpuusage script
copy:
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: create memusage script
copy:
dest: /usr/bin/memusage
mode: 0755
content: |
#!/usr/bin/env
free -m | awk '/Mem/ { printf( "%d %", $3 / $2 * 100 + 0.5 ) }'
- 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: create monstop script
copy:
dest: /usr/bin/monstop
mode: 0755
content: |
#!/usr/bin/env bash
ifconfig mon0 down && iw dev mon0 del
- name: configure rc.local
blockinfile:
path: /etc/rc.local
insertbefore: "exit 0"
block: |
if ! /opt/vc/bin/tvservice -s | grep HDMI; then
/opt/vc/bin/tvservice -o
fi
/root/pwnagotchi/scripts/startup.sh &
- name: configure lo interface
blockinfile:
path: /etc/network/interfaces.d/lo-cfg
create: yes
block: |
auto lo
iface lo inet loopback
- name: configure wlan interface
blockinfile:
path: /etc/network/interfaces.d/wlan0-cfg
create: yes
block: |
allow-hotplug wlan0
iface wlan0 inet static
- name: configure usb interface
blockinfile:
path: /etc/network/interfaces.d/usb0-cfg
create: yes
block: |
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: configure eth0 interface (pi2/3/4)
blockinfile:
path: /etc/network/interfaces.d/eth0-cfg
create: yes
block: |
allow-hotplug eth0
iface eth0 inet dhcp
- name: enable ssh on boot
file:
path: /boot/ssh
state: touch
- name: adjust /boot/config.txt
lineinfile:
dest: /boot/config.txt
insertafter: EOF
line: '{{ item }}'
with_items:
- "dtoverlay=dwc2"
- "dtparam=spi=on"
- "dtoverlay=spi1-3cs"
- "dtoverlay=pi3-disable-bt"
- "dtparam=audio=off"
- name: change root partition
replace:
dest: /boot/cmdline.txt
backup: no
regexp: "root=PARTUUID=[a-zA-Z0-9\\-]+"
replace: "root=/dev/mmcblk0p2"
- name: configure /boot/cmdline.txt
lineinfile:
path: /boot/cmdline.txt
backrefs: True
state: present
backup: no
regexp: '(.*)$'
line: '\1 modules-load=dwc2,g_ether'
- name: configure ssh
lineinfile:
dest: /etc/ssh/sshd_config
backup: no
regexp: '#?PermitRootLogin (.*)$'
line: 'PermitRootLogin yes'
- name: configure motd
copy:
dest: /etc/motd
content: "(◕‿‿◕) {{pwn_hostname}} (pwnagotchi-{{pwn_version}})"
- name: clean apt cache
apt:
autoclean: yes
- name: remove dependencies that are no longer required
apt:
autoremove: yes
- name: remove ssh keys
file:
state: absent
path: "{{item}}"
with_items:
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_rsa_key.pub
- /etc/ssh/ssh_host_dsa_key
- /etc/ssh/ssh_host_dsa_key.pub
- /etc/ssh/ssh_host/ecdsa_key
- /etc/ssh/ssh_host/ecdsa_key.pub
- /etc/ssh/ssh_host_ed25519_key
- /etc/ssh/ssh_host_ed25519_key.pub

View File

@ -265,7 +265,6 @@ usage: $0 [OPTIONS]
-i <file> # Provide the path of an already downloaded raspbian image -i <file> # Provide the path of an already downloaded raspbian image
-o <file> # Name of the img-file (default: pwnagotchi.img) -o <file> # Name of the img-file (default: pwnagotchi.img)
-s <size> # Size which should be added to second partition (in Gigabyte) (default: 4) -s <size> # Size which should be added to second partition (in Gigabyte) (default: 4)
-S # Create a sparse image and generate bmap file (default when bmaptool is available)
-v <version> # Version of raspbian (Supported: ${SUPPORTED_RASPBIAN_VERSIONS[*]}; default: latest) -v <version> # Version of raspbian (Supported: ${SUPPORTED_RASPBIAN_VERSIONS[*]}; default: latest)
-p # Only run provisioning (assumes the image is already mounted) -p # Only run provisioning (assumes the image is already mounted)
-d # Only run dependencies checks -d # Only run dependencies checks

28
scripts/release.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/bash
# nothing to see here, just a utility i use to create new releases ^_^
VERSION_FILE=$(dirname "${BASH_SOURCE[0]}")/../sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/version.py
echo "version file is $VERSION_FILE"
CURRENT_VERSION=$(cat $VERSION_FILE | grep version | cut -d"'" -f2)
TO_UPDATE=(
$VERSION_FILE
)
echo -n "current version is $CURRENT_VERSION, select new version: "
read NEW_VERSION
echo "creating version $NEW_VERSION ...\n"
for file in "${TO_UPDATE[@]}"; do
echo "patching $file ..."
sed -i.bak "s/$CURRENT_VERSION/$NEW_VERSION/g" "$file"
rm -rf "$file.bak"
git add $file
done
git commit -m "releasing v$NEW_VERSION"
git push
git tag -a v$NEW_VERSION -m "release v$NEW_VERSION"
git push origin v$NEW_VERSION
echo
echo "All done, v$NEW_VERSION released ^_^"

View File

@ -1,111 +1,117 @@
#!/bin/bash #!/bin/bash
# Default variables # Default variables
GIT_FOLDER="/tmp/pwnagotchi" GIT_FOLDER="/tmp/pwnagotchi"
GIT_URL="https://github.com/evilsocket/pwnagotchi/" GIT_URL="https://github.com/evilsocket/pwnagotchi/"
VERSION="master" VERSION="master"
SUPPORTED_RESTART_MODES=( 'auto' 'manual' ) SUPPORTED_RESTART_MODES=( 'auto' 'manual' )
MODE="auto" MODE="auto"
BACKUPCONFIG=0 BACKUPCONFIG=0
RESTORECONFIG=0 RESTORECONFIG=0
# Functions # Functions
function usage() { function usage() {
cat <<EOF cat <<EOF
usage: $0 [OPTIONS] usage: $0 [OPTIONS]
Options: Options:
-v # Version to update to, can be a branch or commit. (default: master) -v # Version to update to, can be a branch or commit. (default: master)
-u # Url to clone from. (default: https://github.com/evilsocket/pwnagotchi) -u # Url to clone from. (default: https://github.com/evilsocket/pwnagotchi)
-m # Mode to restart to. (Supported: ${SUPPORTED_RESTART_MODES[*]}; default: auto) -m # Mode to restart to. (Supported: ${SUPPORTED_RESTART_MODES[*]}; default: auto)
-b # Backup the current pwnagotchi config. -b # Backup the current pwnagotchi config and hostname references.
-r # Restore the current pwnagotchi config. (-b will be enabled.) -r # Restore the current pwnagotchi config and hostname references. (-b will be enabled.)
-h # Shows this help. -h # Shows this help.
EOF EOF
exit 0 exit 0
} }
function test_root() { function test_root() {
if ! [ $(id -u) = 0 ]; then if ! [ $(id -u) = 0 ]; then
echo "[!] This script must be run as root." echo "[!] This script must be run as root."
exit 1 exit 1
fi fi
} }
function test_github() { function test_github() {
wget -q --spider $GIT_URL wget -q --spider $GIT_URL
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "[!] Cannot reach github. This script requires internet access, ensure connection sharing is working." echo "[!] Cannot reach github. This script requires internet access, ensure connection sharing is working."
exit 2 exit 2
fi fi
} }
echo "[+] Checking prerequisites." echo "[+] Checking prerequisites."
test_root test_root
test_github test_github
while getopts ":v:u:m:b:r:h" o; do while getopts ":v:u:m:b:r:h" o; do
case "${o}" in case "${o}" in
v) v)
VERSION="${OPTARG}" VERSION="${OPTARG}"
;; ;;
u) u)
GIT_URL="${OPTARG}" GIT_URL="${OPTARG}"
;; ;;
m) m)
if [[ "${SUPPORTED_RESTART_MODES[*]}" =~ ${OPTARG} ]]; then if [[ "${SUPPORTED_RESTART_MODES[*]}" =~ ${OPTARG} ]]; then
MODE="${OPTARG}" MODE="${OPTARG}"
else else
usage usage
fi fi
;; ;;
b) b)
BACKUPCONFIG=1 BACKUPCONFIG=1
;; ;;
r) r)
BACKUPCONFIG=1 BACKUPCONFIG=1
RESTORECONFIG=1 RESTORECONFIG=1
;; ;;
h) h)
usage usage
;; ;;
*) *)
usage usage
;; ;;
esac esac
done done
shift $((OPTIND-1)) shift $((OPTIND-1))
# clean up old files, clone master, set checkout to commit if needed. # clean up old files, clone master, set checkout to commit if needed.
echo "[+] Cloning to $GIT_FOLDER..." echo "[+] Cloning to $GIT_FOLDER..."
rm $GIT_FOLDER -rf rm $GIT_FOLDER -rf
git clone $GIT_URL $GIT_FOLDER -q git clone $GIT_URL $GIT_FOLDER -q
cd $GIT_FOLDER cd $GIT_FOLDER
if [ $VERSION != "master" ]; then if [ $VERSION != "master" ]; then
git checkout $VERSION -q git checkout $VERSION -q
fi fi
echo "[+] Installing $(git log -1 --format="%h")" echo "[+] Installing $(git log -1 --format="%h")"
echo "[+] Updating..." echo "[+] Updating..."
if [ $BACKUPCONFIG -eq 1 ]; then if [ $BACKUPCONFIG -eq 1 ]; then
echo "[+] Creating backup of config.yml" echo "[+] Creating backup of config.yml and hostname references"
mv /root/pwnagotchi/config.yml /root/config.yml.bak -f mv /root/pwnagotchi/config.yml /root/config.bak -f
fi mv /etc/hosts /root/hosts.bak -f
rm /root/pwnagotchi -rf # ensures old files are removed mv /etc/hostname /root/hostname.bak -f
rsync -aPq $GIT_FOLDER/sdcard/boot/* /boot/ mv /etc/network/interfaces /root/interfaces.bak -f
rsync -aPq $GIT_FOLDER/sdcard/rootfs/* / fi
cd /tmp rm /root/pwnagotchi -rf # ensures old files are removed
rm $GIT_FOLDER -rf rsync -aPq $GIT_FOLDER/sdcard/boot/* /boot/
if [ $RESTORECONFIG -eq 1 ]; then rsync -aPq $GIT_FOLDER/sdcard/rootfs/* /
echo "[+] Restoring backup of config.yml" cd /tmp
mv /root/config.yml.bak /root/pwnagotchi/config.yml -f rm $GIT_FOLDER -rf
fi if [ $RESTORECONFIG -eq 1 ]; then
echo "[+] Restoring backup of config.yml and hostname references"
echo "[+] Restarting pwnagotchi in $MODE mode. $( screen -X -S pwnagotchi quit)" mv /root/config.yml.bak /root/pwnagotchi/config.yml -f
if [ $MODE == "auto" ]; then mv /root/hosts.bak /etc/hosts -f
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.auto mv /root/hostname.bak /etc/hostname -f
elif [ $MODE == "manual" ]; then mv /root/interfaces.bak /etc/network/interfaces -f
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.manual fi
fi
echo "[+] Finished" echo "[+] Restarting pwnagotchi in $MODE mode. $( screen -X -S pwnagotchi quit)"
if [ $MODE == "auto" ]; then
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.auto
elif [ $MODE == "manual" ]; then
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.manual
fi
echo "[+] Finished"

View File

@ -11,6 +11,9 @@
# #
# By default this script does nothing. # By default this script does nothing.
# Powersave (Disable HDMI) ~30ma # Powersave (Disable HDMI) ~30ma
/opt/vc/bin/tvservice -o sleep 10
if ! /opt/vc/bin/tvservice -s | grep HDMI; then
/opt/vc/bin/tvservice -o
fi
/root/pwnagotchi/scripts/startup.sh & /root/pwnagotchi/scripts/startup.sh &
exit 0 exit 0

View File

@ -2,6 +2,8 @@
main: main:
# currently implemented: en (default), de, nl, it # currently implemented: en (default), de, nl, it
lang: en lang: en
# custom plugins path, if null only default plugins with be loaded
plugins: null
# monitor interface to use # monitor interface to use
iface: mon0 iface: mon0
# command to run to bring the mon interface up in case it's not up already # command to run to bring the mon interface up in case it's not up already
@ -21,7 +23,7 @@ main:
ai: ai:
# if false, only the default 'personality' will be used # if false, only the default 'personality' will be used
enabled: true enabled: false
path: /root/brain.nn path: /root/brain.nn
# 1.0 - laziness = probability of start training # 1.0 - laziness = probability of start training
laziness: 0.1 laziness: 0.1
@ -89,7 +91,10 @@ personality:
# ui configuration # ui configuration
ui: ui:
# ePaper display can update every 3 secs anyway # 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.3 fps: 0.3
display: display:
enabled: true enabled: true

View File

@ -9,9 +9,4 @@ do
done done
echo 0 >/sys/class/leds/led0/brightness echo 0 >/sys/class/leds/led0/brightness
sleep 0.3 sleep 0.3
# Powersave options
# Disable power LED ~30ma
echo none >/sys/class/leds/led0/trigger
echo 1 >/sys/class/leds/led0/brightness

View File

@ -5,7 +5,7 @@ import time
import traceback import traceback
import core import core
import pwnagotchi import pwnagotchi, pwnagotchi.plugins as plugins
from pwnagotchi.log import SessionParser from pwnagotchi.log import SessionParser
from pwnagotchi.voice import Voice from pwnagotchi.voice import Voice
@ -25,39 +25,49 @@ args = parser.parse_args()
if args.do_clear: if args.do_clear:
print("clearing the display ...") print("clearing the display ...")
with open(args.config, 'rt') as fp: with open(args.config, 'rt') as fp:
config = yaml.safe_load(fp) config = yaml.safe_load(fp)
cleardisplay=config['ui']['display']['type'] cleardisplay = config['ui']['display']['type']
if cleardisplay in ('inkyphat', 'inky'): if cleardisplay in ('inkyphat', 'inky'):
print("inky display") print("inky display")
from inky import InkyPHAT from inky import InkyPHAT
epd = InkyPHAT(config['ui']['display']['color'])
epd.set_border(InkyPHAT.BLACK) epd = InkyPHAT(config['ui']['display']['color'])
self._render_cb = self._inky_render epd.set_border(InkyPHAT.BLACK)
elif cleardisplay in ('papirus', 'papi'): self._render_cb = self._inky_render
print("papirus display") elif cleardisplay in ('papirus', 'papi'):
from pwnagotchi.ui.papirus.epd import EPD print("papirus display")
os.environ['EPD_SIZE'] = '2.0' from pwnagotchi.ui.papirus.epd import EPD
epd = EPD()
epd.clear() os.environ['EPD_SIZE'] = '2.0'
elif cleardisplay in ('waveshare_1', 'ws_1', 'waveshare1', 'ws1'): epd = EPD()
print("waveshare v1 display") epd.clear()
from pwnagotchi.ui.waveshare.v1.epd2in13 import EPD elif cleardisplay in ('waveshare_1', 'ws_1', 'waveshare1', 'ws1'):
epd = EPD() print("waveshare v1 display")
epd.init(epd.lut_full_update) from pwnagotchi.ui.waveshare.v1.epd2in13 import EPD
epd.Clear(0xFF)
elif cleardisplay in ('waveshare_2', 'ws_2', 'waveshare2', 'ws2'): epd = EPD()
print("waveshare v2 display") epd.init(epd.lut_full_update)
from pwnagotchi.ui.waveshare.v2.waveshare import EPD epd.Clear(0xFF)
epd = EPD() elif cleardisplay in ('waveshare_2', 'ws_2', 'waveshare2', 'ws2'):
epd.init(epd.FULL_UPDATE) print("waveshare v2 display")
epd.Clear(0xff) from pwnagotchi.ui.waveshare.v2.waveshare import EPD
else:
print("unknown display type %s" % cleardisplay) epd = EPD()
quit() epd.init(epd.FULL_UPDATE)
epd.Clear(0xff)
else:
print("unknown display type %s" % cleardisplay)
quit()
with open(args.config, 'rt') as fp: with open(args.config, 'rt') as fp:
config = yaml.safe_load(fp) config = yaml.safe_load(fp)
plugins.load_from_path(plugins.default_path)
if 'plugins' in config['main'] and config['main']['plugins'] is not None:
plugins.load_from_path(config['main']['plugins'])
plugins.on('loaded')
display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()}) display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
agent = Agent(view=display, config=config) agent = Agent(view=display, config=config)
@ -65,6 +75,9 @@ core.log("%s@%s (v%s)" % (pwnagotchi.name(), agent._identity, pwnagotchi.version
# for key, value in config['personality'].items(): # for key, value in config['personality'].items():
# core.log(" %s: %s" % (key, value)) # core.log(" %s: %s" % (key, value))
for _, plugin in plugins.loaded.items():
core.log("plugin '%s' v%s loaded from %s" % (plugin.__name__, plugin.__version__, plugin.__file__))
if args.do_manual: if args.do_manual:
core.log("entering manual mode ...") core.log("entering manual mode ...")
@ -112,13 +125,15 @@ core.logfile = config['main']['log']
agent.start_ai() agent.start_ai()
agent.setup_events() agent.setup_events()
agent.set_ready() agent.set_starting()
agent.start_monitor_mode() agent.start_monitor_mode()
agent.start_event_polling() agent.start_event_polling()
# print initial stats # print initial stats
agent.next_epoch() agent.next_epoch()
agent.set_ready()
while True: while True:
try: try:
# recon on all channels # recon on all channels

View File

@ -1,7 +1,5 @@
import subprocess import subprocess
version = '1.0.0a'
_name = None _name = None

View File

@ -8,6 +8,7 @@ import _thread
import core import core
import pwnagotchi.plugins as plugins
from bettercap.client import Client from bettercap.client import Client
from pwnagotchi.mesh.utils import AsyncAdvertiser from pwnagotchi.mesh.utils import AsyncAdvertiser
from pwnagotchi.ai.train import AsyncTrainer from pwnagotchi.ai.train import AsyncTrainer
@ -44,32 +45,41 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
pass pass
return False return False
def config(self):
return self._config
def supported_channels(self): def supported_channels(self):
return self._supported_channels return self._supported_channels
def on_ai_ready(self): def set_starting(self):
self._view.on_ai_ready() self._view.on_starting()
def set_ready(self): def set_ready(self):
self._view.on_starting() plugins.on('ready', self)
def set_free_channel(self, channel): def set_free_channel(self, channel):
self._view.on_free_channel(channel) self._view.on_free_channel(channel)
plugins.on('free_channel', self, channel)
def set_bored(self): def set_bored(self):
self._view.on_bored() self._view.on_bored()
plugins.on('bored', self)
def set_sad(self): def set_sad(self):
self._view.on_sad() self._view.on_sad()
plugins.on('sad', self)
def set_excited(self): def set_excited(self):
self._view.on_excited() self._view.on_excited()
plugins.on('excited', self)
def set_lonely(self): def set_lonely(self):
self._view.on_lonely() self._view.on_lonely()
plugins.on('lonely', self)
def set_rebooting(self): def set_rebooting(self):
self._view.on_rebooting() self._view.on_rebooting()
plugins.on('rebooting', self)
def setup_events(self): def setup_events(self):
core.log("connecting to %s ..." % self.url) core.log("connecting to %s ..." % self.url)
@ -128,6 +138,7 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
self.start_advertising() self.start_advertising()
def wait_for(self, t, sleeping=True): def wait_for(self, t, sleeping=True):
plugins.on('sleep' if sleeping else 'wait', self, t)
self._view.wait(t, sleeping) self._view.wait(t, sleeping)
self._epoch.track(sleep=True, inc=t) self._epoch.track(sleep=True, inc=t)
@ -179,6 +190,7 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
def set_access_points(self, aps): def set_access_points(self, aps):
self._access_points = aps self._access_points = aps
plugins.on('wifi_update', self, aps)
self._epoch.observe(aps, self._advertiser.peers() if self._advertiser is not None else ()) self._epoch.observe(aps, self._advertiser.peers() if self._advertiser is not None else ())
return self._access_points return self._access_points
@ -327,6 +339,7 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
try: try:
for h in [e for e in self.events() if e['tag'] == 'wifi.client.handshake']: for h in [e for e in self.events() if e['tag'] == 'wifi.client.handshake']:
filename = h['data']['file']
sta_mac = h['data']['station'] sta_mac = h['data']['station']
ap_mac = h['data']['ap'] ap_mac = h['data']['ap']
key = "%s -> %s" % (sta_mac, ap_mac) key = "%s -> %s" % (sta_mac, ap_mac)
@ -334,18 +347,20 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
if key not in self._handshakes: if key not in self._handshakes:
self._handshakes[key] = h self._handshakes[key] = h
new_shakes += 1 new_shakes += 1
apsta = self._find_ap_sta_in(sta_mac, ap_mac, s) ap_and_station = self._find_ap_sta_in(sta_mac, ap_mac, s)
if apsta is None: if ap_and_station is None:
core.log("!!! captured new handshake: %s !!!" % key) core.log("!!! captured new handshake: %s !!!" % key)
self._last_pwnd = ap_mac self._last_pwnd = ap_mac
plugins.on('handshake', self, filename, ap_mac, sta_mac)
else: else:
(ap, sta) = apsta (ap, sta) = ap_and_station
self._last_pwnd = ap['hostname'] if ap['hostname'] != '' and ap[ self._last_pwnd = ap['hostname'] if ap['hostname'] != '' and ap[
'hostname'] != '<hidden>' else ap_mac 'hostname'] != '<hidden>' else ap_mac
core.log("!!! captured new handshake on channel %d: %s (%s) -> %s [%s (%s)] !!!" % ( \ core.log("!!! captured new handshake on channel %d: %s (%s) -> %s [%s (%s)] !!!" % ( \
ap['channel'], ap['channel'],
sta['mac'], sta['vendor'], sta['mac'], sta['vendor'],
ap['hostname'], ap['mac'], ap['vendor'])) ap['hostname'], ap['mac'], ap['vendor']))
plugins.on('handshake', self, filename, ap, sta)
except Exception as e: except Exception as e:
core.log("error: %s" % e) core.log("error: %s" % e)
@ -419,6 +434,7 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
except Exception as e: except Exception as e:
self._on_error(ap['mac'], e) self._on_error(ap['mac'], e)
plugins.on('association', self, ap)
if throttle > 0: if throttle > 0:
time.sleep(throttle) time.sleep(throttle)
self._view.on_normal() self._view.on_normal()
@ -439,6 +455,7 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
except Exception as e: except Exception as e:
self._on_error(sta['mac'], e) self._on_error(sta['mac'], e)
plugins.on('deauthentication', self, ap, sta)
if throttle > 0: if throttle > 0:
time.sleep(throttle) time.sleep(throttle)
self._view.on_normal() self._view.on_normal()
@ -470,6 +487,9 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
self._current_channel = channel self._current_channel = channel
self._epoch.track(hop=True) self._epoch.track(hop=True)
self._view.set('channel', '%d' % channel) self._view.set('channel', '%d' % channel)
plugins.on('channel_hop', self, channel)
except Exception as e: except Exception as e:
core.log("error: %s" % e) core.log("error: %s" % e)
@ -509,6 +529,8 @@ class Agent(Client, AsyncAdvertiser, AsyncTrainer):
core.log("%d epochs with activity -> excited" % self._epoch.active_for) core.log("%d epochs with activity -> excited" % self._epoch.active_for)
self.set_excited() 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']: if self._epoch.blind_for >= self._config['main']['mon_max_blind_epochs']:
core.log("%d epochs without visible access points -> rebooting ..." % self._epoch.blind_for) core.log("%d epochs without visible access points -> rebooting ..." % self._epoch.blind_for)
self._reboot() self._reboot()

View File

@ -7,6 +7,7 @@ import pwnagotchi.mesh.wifi as wifi
from pwnagotchi.ai.reward import RewardFunction from pwnagotchi.ai.reward import RewardFunction
class Epoch(object): class Epoch(object):
def __init__(self, config): def __init__(self, config):
self.epoch = 0 self.epoch = 0
@ -92,7 +93,8 @@ class Epoch(object):
try: try:
peers_per_chan[peer.last_channel - 1] += 1.0 peers_per_chan[peer.last_channel - 1] += 1.0
except IndexError as e: except IndexError as e:
core.log("got peer data on channel %d, we can store %d channels" % (peer.last_channel, wifi.NumChannels)) core.log(
"got peer data on channel %d, we can store %d channels" % (peer.last_channel, wifi.NumChannels))
# normalize # normalize
aps_per_chan = [e / num_aps for e in aps_per_chan] aps_per_chan = [e / num_aps for e in aps_per_chan]

View File

@ -7,6 +7,7 @@ import json
import core import core
import pwnagotchi.plugins as plugins
import pwnagotchi.ai as ai import pwnagotchi.ai as ai
from pwnagotchi.ai.epoch import Epoch from pwnagotchi.ai.epoch import Epoch
@ -68,14 +69,14 @@ class Stats(object):
core.log("[ai] saving %s" % self.path) core.log("[ai] saving %s" % self.path)
data = json.dumps({ data = json.dumps({
'born_at': self.born_at, 'born_at': self.born_at,
'epochs_lived': self.epochs_lived, 'epochs_lived': self.epochs_lived,
'epochs_trained': self.epochs_trained, 'epochs_trained': self.epochs_trained,
'rewards': { 'rewards': {
'best': self.best_reward, 'best': self.best_reward,
'worst': self.worst_reward 'worst': self.worst_reward
} }
}) })
temp = "%s.tmp" % self.path temp = "%s.tmp" % self.path
with open(temp, 'wt') as fp: with open(temp, 'wt') as fp:
@ -98,6 +99,11 @@ class AsyncTrainer(object):
self._is_training = training self._is_training = training
self._training_epochs = for_epochs self._training_epochs = for_epochs
if training:
plugins.on('ai_training_start', self, for_epochs)
else:
plugins.on('ai_training_end', self)
def is_training(self): def is_training(self):
return self._is_training return self._is_training
@ -123,8 +129,10 @@ class AsyncTrainer(object):
def on_ai_training_step(self, _locals, _globals): def on_ai_training_step(self, _locals, _globals):
self._model.env.render() self._model.env.render()
plugins.on('ai_training_step', self, _locals, _globals)
def on_ai_policy(self, new_params): def on_ai_policy(self, new_params):
plugins.on('ai_policy', self, new_params)
core.log("[ai] setting new policy:") core.log("[ai] setting new policy:")
for name, value in new_params.items(): for name, value in new_params.items():
if name in self._config['personality']: if name in self._config['personality']:
@ -139,13 +147,19 @@ class AsyncTrainer(object):
self.run('set wifi.sta.ttl %d' % self._config['personality']['sta_ttl']) self.run('set wifi.sta.ttl %d' % self._config['personality']['sta_ttl'])
self.run('set wifi.rssi.min %d' % self._config['personality']['min_rssi']) self.run('set wifi.rssi.min %d' % self._config['personality']['min_rssi'])
def on_ai_ready(self):
self._view.on_ai_ready()
plugins.on('ai_ready', self)
def on_ai_best_reward(self, r): def on_ai_best_reward(self, r):
core.log("[ai] best reward so far: %s" % r) core.log("[ai] best reward so far: %s" % r)
self._view.on_motivated(r) self._view.on_motivated(r)
plugins.on('ai_best_reward', self, r)
def on_ai_worst_reward(self, r): def on_ai_worst_reward(self, r):
core.log("[ai] worst reward so far: %s" % r) core.log("[ai] worst reward so far: %s" % r)
self._view.on_demotivated(r) self._view.on_demotivated(r)
plugins.on('ai_worst_reward', self, r)
def _ai_worker(self): def _ai_worker(self):
self._model = ai.load(self._config, self, self._epoch) self._model = ai.load(self._config, self, self._epoch)

View File

@ -1,14 +1,13 @@
# SOME DESCRIPTIVE TITLE. # German language
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) 2019
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # dadav <33197631+dadav@users.noreply.github.com>, 2019.
# #
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-29 13:34+0200\n" "POT-Creation-Date: 2019-10-03 12:22+0200\n"
"PO-Revision-Date: 2019-09-29 14:00+0200\n" "PO-Revision-Date: 2019-09-29 14:00+0200\n"
"Last-Translator: dadav <33197631+dadav@users.noreply.github.com>\n" "Last-Translator: dadav <33197631+dadav@users.noreply.github.com>\n"
"Language-Team: DE <33197631+dadav@users.noreply.github.com>\n" "Language-Team: DE <33197631+dadav@users.noreply.github.com>\n"
@ -17,28 +16,19 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: voice.py:16 #: voice.py:18
msgid "ZzzzZZzzzzZzzz" msgid "ZzzzZZzzzzZzzz"
msgstr "" msgstr ""
#: voice.py:21
msgid ""
"Hi, I'm Pwnagotchi!\n"
"Starting ..."
msgstr ""
"Hi, ich bin\n"
"ein Pwnagotchi!\n"
"Starte ..."
#: voice.py:22 #: voice.py:22
msgid "" msgid "Hi, I'm Pwnagotchi! Starting ..."
"New day, new hunt,\n" msgstr "Hi, ich bin ein Pwnagotchi! Starte ..."
"new pwns!"
msgstr ""
"Neuer Tag, neue Jagd,\n"
"neue Pwns!"
#: voice.py:23 #: voice.py:23
msgid "New day, new hunt, new pwns!"
msgstr "Neuer Tag, neue Jagd, neue Pwns!"
#: voice.py:24
msgid "Hack the Planet!" msgid "Hack the Planet!"
msgstr "Hack den Planet!" msgstr "Hack den Planet!"
@ -47,298 +37,202 @@ msgid "AI ready."
msgstr "KI bereit." msgstr "KI bereit."
#: voice.py:29 #: voice.py:29
msgid "" msgid "The neural network is ready."
"The neural network\n" msgstr "Das neurale Netz ist bereit."
"is ready."
msgstr ""
"Das neurale Netz\n"
"ist bereit."
#: voice.py:39 #: voice.py:37
#, python-brace-format #, python-brace-format
msgid "" msgid "Hey, channel {channel} is free! Your AP will say thanks."
"Hey, channel {channel} is\n" msgstr "Hey, Channel {channel} ist frei! Dein AP wir des dir danken."
"free! Your AP will\n"
"say thanks."
msgstr ""
"Hey, Channel {channel} ist\n"
"frei! Dein AP wird\n"
"es dir danken."
#: voice.py:44 #: voice.py:41
msgid "I'm bored ..." msgid "I'm bored ..."
msgstr "Mir ist langweilig..." msgstr "Mir ist langweilig..."
#: voice.py:45 #: voice.py:42
msgid "Let's go for a walk!" msgid "Let's go for a walk!"
msgstr "Lass uns laufen gehen!" msgstr "Lass uns laufen gehen!"
#: voice.py:49 #: voice.py:45
msgid "" msgid "This is the best day of my life!"
"This is the best\n" msgstr "Das ist der beste Tag meines Lebens."
"day of my life!"
msgstr ""
"Das ist der beste\n"
"Tag meines Lebens."
#: voice.py:53 #: voice.py:48
msgid "Shitty day :/" msgid "Shitty day :/"
msgstr "Scheis Tag :/" msgstr "Scheis Tag :/"
#: voice.py:58 #: voice.py:52
msgid "I'm extremely bored ..." msgid "I'm extremely bored ..."
msgstr "Mir ist sau langweilig..." msgstr "Mir ist sau langweilig..."
#: voice.py:59 #: voice.py:53
msgid "I'm very sad ..." msgid "I'm very sad ..."
msgstr "Ich bin sehr traurig..." msgstr "Ich bin sehr traurig..."
#: voice.py:60 #: voice.py:54
msgid "I'm sad" msgid "I'm sad"
msgstr "Ich bin traurig" msgstr "Ich bin traurig"
#: voice.py:66 #: voice.py:59
msgid "I'm living the life!" msgid "I'm living the life!"
msgstr "Ich lebe das Leben!" msgstr "Ich lebe das Leben!"
#: voice.py:67 #: voice.py:60
msgid "I pwn therefore I am." msgid "I pwn therefore I am."
msgstr "Ich pwne, also bin ich." msgstr "Ich pwne, also bin ich."
#: voice.py:68 #: voice.py:61
msgid "So many networks!!!" msgid "So many networks!!!"
msgstr "So viele Netwerke!!!" msgstr "So viele Netwerke!!!"
#: voice.py:69 #: voice.py:62
msgid "" msgid "I'm having so much fun!"
"I'm having so much\n" msgstr "Ich habe sooo viel Spaß!"
"fun!"
msgstr ""
"Ich habe sooo viel\n"
"Spaß!"
#: voice.py:70 #: voice.py:63
msgid "" msgid "My crime is that of curiosity ..."
"My crime is that of\n" msgstr "Mein Verbrechen ist das der Neugier ..."
"curiosity ..."
msgstr ""
"Mein Verbrechen ist\n"
"das der Neugier ..."
#: voice.py:75 #: voice.py:67
#, python-brace-format #, python-brace-format
msgid "" msgid "Hello {name}! Nice to meet you. {name}"
"Hello\n" msgstr "Hallo {name}, nett Dich kennenzulernen."
"{name}!\n"
"Nice to meet you. {name}"
msgstr ""
"Hallo {name},\n"
"Nett Dich\n"
"kennenzulernen."
#: voice.py:76 #: voice.py:68
#, python-brace-format #, python-brace-format
msgid "" msgid "Unit {name} is nearby! {name}"
"Unit\n" msgstr "Gerät {name} ist in der nähe!!"
"{name}\n"
"is nearby! {name}"
msgstr ""
"Gerät {name}\n"
"ist in der\n"
"nähe!!"
#: voice.py:81 #: voice.py:72
#, python-brace-format #, python-brace-format
msgid "" msgid "Uhm ... goodbye {name}"
"Uhm ...\n" msgstr "Uhm ...tschüß {name}"
"goodbye\n"
"{name}"
msgstr ""
"Uhm ...\n"
"tschüß\n"
"{name}"
#: voice.py:82 #: voice.py:73
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} is gone ..."
"{name}\n" msgstr "{name} ist weg ..."
"is gone ..."
msgstr ""
"{name}\n"
"ist weg ..."
#: voice.py:87 #: voice.py:77
#, python-brace-format #, python-brace-format
msgid "" msgid "Whoops ... {name} is gone."
"Whoops ...\n" msgstr "Whoops ...{name} ist weg."
"{name}\n"
"is gone."
msgstr ""
"Whoops ...\n"
"{name}\n"
"ist weg."
#: voice.py:88 #: voice.py:78
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} missed!"
"{name}\n" msgstr "{name} verpasst!"
"missed!"
msgstr ""
"{name}\n"
"verpasst!"
#: voice.py:89 #: voice.py:79
msgid "Missed!" msgid "Missed!"
msgstr "Verpasst!" msgstr "Verpasst!"
#: voice.py:94 #: voice.py:83
msgid "" msgid "Nobody wants to play with me ..."
"Nobody wants to\n" msgstr "Niemand will mit mir spielen ..."
"play with me ..."
msgstr ""
"Niemand will mit\n"
"mir spielen ..."
#: voice.py:95 #: voice.py:84
msgid "I feel so alone ..." msgid "I feel so alone ..."
msgstr "" msgstr "Ich fühl michso alleine ..."
"Ich fühl mich\n"
"so alleine ..."
#: voice.py:96 #: voice.py:85
msgid "Where's everybody?!" msgid "Where's everybody?!"
msgstr "Wo sind denn alle?" msgstr "Wo sind denn alle?"
#: voice.py:101 #: voice.py:89
#, python-brace-format #, python-brace-format
msgid "Napping for {secs}s ..." msgid "Napping for {secs}s ..."
msgstr "Schlafe für {secs}s" msgstr "Schlafe für {secs}s"
#: voice.py:102 #: voice.py:90
msgid "Zzzzz" msgid "Zzzzz"
msgstr "" msgstr ""
#: voice.py:103 #: voice.py:91
#, python-brace-format #, python-brace-format
msgid "ZzzZzzz ({secs}s)" msgid "ZzzZzzz ({secs}s)"
msgstr "" msgstr ""
#: voice.py:112 #: voice.py:98
#, python-brace-format #, python-brace-format
msgid "Waiting for {secs}s ..." msgid "Waiting for {secs}s ..."
msgstr "Warte für {secs}s ..." msgstr "Warte für {secs}s ..."
#: voice.py:114 #: voice.py:100
#, python-brace-format #, python-brace-format
msgid "Looking around ({secs}s)" msgid "Looking around ({secs}s)"
msgstr "Schaue mich um ({secs}s)" msgstr "Schaue mich um ({secs}s)"
#: voice.py:106
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what}, lass uns Freunde sein!"
#: voice.py:107
#, python-brace-format
msgid "Associating to {what}"
msgstr "Verbinde mit {what}"
#: voice.py:108
#, python-brace-format
msgid "Yo {what}!"
msgstr ""
#: voice.py:112
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Ich denke, dass {mac} kein WiFi brauch!"
#: voice.py:113
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Deauthentifiziere {mac}"
#: voice.py:114
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Kicke {mac}!"
#: voice.py:118
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Cool, wir haben {num} neue Handshake{plural}!"
#: voice.py:121 #: voice.py:121
#, python-brace-format msgid "Ops, something went wrong ... Rebooting ..."
msgid "" msgstr "Ops, da ist etwas schief gelaufen ...Starte neu ..."
"Hey\n"
"{what}\n"
"let's be friends!"
msgstr ""
"Hey\n"
"{what}\n"
"lass uns Freunde sein!"
#: voice.py:122 #: voice.py:124
#, python-brace-format
msgid ""
"Associating to\n"
"{what}"
msgstr ""
"Verbinde mit\n"
"{what}"
#: voice.py:123
#, python-brace-format
msgid ""
"Yo\n"
"{what}!"
msgstr ""
#: voice.py:128
#, python-brace-format
msgid ""
"Just decided that\n"
"{mac}\n"
"needs no WiFi!"
msgstr ""
"Ich denke,\n"
"dass {mac}\n"
"kein WiFi brauch!"
#: voice.py:129
#, python-brace-format
msgid ""
"Deauthenticating\n"
"{mac}"
msgstr ""
"Deauthentifiziere\n"
"{mac}"
#: voice.py:130
#, python-brace-format
msgid ""
"Kickbanning\n"
"{mac}!"
msgstr ""
"Kicke\n"
"{mac}!"
#: voice.py:135
#, python-brace-format
msgid ""
"Cool, we got {num}\n"
"new handshake{plural}!"
msgstr ""
"Cool, wir haben {num}\n"
"neue Handshake{plural}!"
#: voice.py:139
msgid ""
"Ops, something\n"
"went wrong ...\n"
"Rebooting ..."
msgstr ""
"Ops, da ist etwas\n"
"schief gelaufen ...\n"
"Starte neu ..."
#: voice.py:143
#, python-brace-format #, python-brace-format
msgid "Kicked {num} stations\n" msgid "Kicked {num} stations\n"
msgstr "{num} Stationen gekicked\n" msgstr "{num} Stationen gekicked\n"
#: voice.py:144 #: voice.py:125
#, python-brace-format #, python-brace-format
msgid "Made {num} new friends\n" msgid "Made {num} new friends\n"
msgstr "{num} Freunde gefunden\n" msgstr "{num} Freunde gefunden\n"
#: voice.py:145 #: voice.py:126
#, python-brace-format #, python-brace-format
msgid "Got {num} handshakes\n" msgid "Got {num} handshakes\n"
msgstr "{num} Handshakes aufgez.\n" msgstr "{num} Handshakes aufgez.\n"
#: voice.py:147 #: voice.py:128
msgid "Met 1 peer" msgid "Met 1 peer"
msgstr "1 Peer getroffen." msgstr "1 Peer getroffen."
#: voice.py:149 #: voice.py:130
#, python-brace-format #, python-brace-format
msgid "Met {num} peers" msgid "Met {num} peers"
msgstr "{num} Peers getroffen" msgstr "{num} Peers getroffen"
#: voice.py:154 #: voice.py:135
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met " "I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi " "{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet" "#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "" msgstr ""
"Ich war {duration} am Pwnen und habe {deauthed} Clients gekickt! Außerdem habe ich " "Ich war {duration} am Pwnen und habe {deauthed} Clients gekickt! Außerdem "
"{associated} neue Freunde getroffen und {handshakes} Handshakes gefressen! #pwnagotchi " "habe ich {associated} neue Freunde getroffen und {handshakes} Handshakes "
"#pwnlog #pwnlife #hacktheplanet #skynet" "gefressen! #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"

View File

@ -0,0 +1,247 @@
# pwnigotchi voice data
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR Periklis Fregkos <fregkos@gmail.com>, 2019.
# CO AUTHOR Panos Vasilopoulos <hello@alwayslivid.com>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-03 12:22+0200\n"
"PO-Revision-Date: 2019-10-03 08:00+0000\n"
"Last-Translator: Periklis Fregkos <fregkos@gmail.com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n"
"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: voice.py:18
msgid "ZzzzZZzzzzZzzz"
msgstr ""
#: voice.py:22
#, fuzzy
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr "Γειά, είμαι το Pwnagotchi!Εκκινούμαι ..."
#: voice.py:23
#, fuzzy
msgid "New day, new hunt, new pwns!"
msgstr "Νέα μέρα, νέο κυνήγι,νέα pwns!"
#: voice.py:24
msgid "Hack the Planet!"
msgstr "Hackαρε τον πλανήτη!"
#: voice.py:28
msgid "AI ready."
msgstr "ΤΝ έτοιμη."
#: voice.py:29
#, fuzzy
msgid "The neural network is ready."
msgstr "Το νευρωνικό δίκτυοείναι έτοιμο."
#: voice.py:37
#, fuzzy, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr "Ε, το κανάλι {channel} είναιελεύθερο! Το AP σου θαείναι ευγνώμων."
#: voice.py:41
msgid "I'm bored ..."
msgstr "Βαριέμαι ..."
#: voice.py:42
msgid "Let's go for a walk!"
msgstr "Ας πάμε μια βόλτα!"
#: voice.py:45
#, fuzzy
msgid "This is the best day of my life!"
msgstr "Είναι η καλύτερημέρα της ζωής μου!"
#: voice.py:48
msgid "Shitty day :/"
msgstr "Σκατένια μέρα :/"
#: voice.py:52
msgid "I'm extremely bored ..."
msgstr "Βαριέμαι πάρα πολύ ..."
#: voice.py:53
msgid "I'm very sad ..."
msgstr "Είμαι πολύ λυπημένο ..."
#: voice.py:54
msgid "I'm sad"
msgstr "Είμαι λυπημένο"
#: voice.py:59
msgid "I'm living the life!"
msgstr "Ζω την ζωή μου!"
#: voice.py:60
msgid "I pwn therefore I am."
msgstr "Pwnάρω, άρα υπάρχω."
#: voice.py:61
msgid "So many networks!!!"
msgstr "Τόσα πολλά δίκτυα!!!"
#: voice.py:62
#, fuzzy
msgid "I'm having so much fun!"
msgstr "Περνάω τέλεια!"
#: voice.py:63
#, fuzzy
msgid "My crime is that of curiosity ..."
msgstr "Η περιέργεια είναιτο μόνο έγκλημά μου ..."
#: voice.py:67
#, fuzzy, python-brace-format
msgid "Hello {name}! Nice to meet you. {name}"
msgstr "Γειά {name}!Χάρηκα για τη γνωριμία. {name}"
#: voice.py:68
#, fuzzy, python-brace-format
msgid "Unit {name} is nearby! {name}"
msgstr "Η μονάδα{name}είναι κοντά! {name}"
#: voice.py:72
#, fuzzy, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr "Εμμ ...αντίο{name}"
#: voice.py:73
#, fuzzy, python-brace-format
msgid "{name} is gone ..."
msgstr "Το {name}έφυγε ..."
#: voice.py:77
#, fuzzy, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr "Ουπς ... Εξαφανίστηκε το{name}."
#: voice.py:78
#, fuzzy, python-brace-format
msgid "{name} missed!"
msgstr "Έχασα το{name}!"
#: voice.py:79
msgid "Missed!"
msgstr "Το έχασα!"
#: voice.py:83
#, fuzzy
msgid "Nobody wants to play with me ..."
msgstr "Κανείς δε θέλει ναπαίξει μαζί μου ..."
#: voice.py:84
msgid "I feel so alone ..."
msgstr "Νιώθω μοναχός μου ..."
#: voice.py:85
msgid "Where's everybody?!"
msgstr "Μα, πού πήγαν όλοι;!"
#: voice.py:89
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Ξεκουράζομαι για {secs}s ..."
#: voice.py:90
msgid "Zzzzz"
msgstr ""
#: voice.py:91
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr ""
#: voice.py:98
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Περιμένω για {secs}s ..."
#: voice.py:100
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Ψάχνω τριγύρω ({secs})"
#: voice.py:106
#, fuzzy, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Εε!{what},ας γίνουμε φίλοι!"
#: voice.py:107
#, fuzzy, python-brace-format
msgid "Associating to {what}"
msgstr "Συνδέομαι με το{what}"
#: voice.py:108
#, fuzzy, python-brace-format
msgid "Yo {what}!"
msgstr "Που'σαι ρε τρελέ{what}!"
#: voice.py:112
#, fuzzy, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Μόλις αποφάσισα ότι η{mac}δε χρείαζεται WiFi!"
#: voice.py:113
#, fuzzy, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Πετάω έξω την{mac}"
#: voice.py:114
#, fuzzy, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Μπανάρω την{mac}!"
#: voice.py:118
#, fuzzy, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Τέλεια δικέ μου, πήραμε {num}νέες χειραψίες!"
#: voice.py:121
#, fuzzy
msgid "Ops, something went wrong ... Rebooting ..."
msgstr "Ουπς, κάτιπήγε λάθος ...Επανεκκινούμαι ..."
#: voice.py:124
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Έριξα {num} σταθμούς\n"
#: voice.py:125
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Έκανα {num} νέους φίλους\n"
#: voice.py:126
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Πήρα {num} χειραψίες\n"
#: voice.py:128
msgid "Met 1 peer"
msgstr "Γνώρισα 1 φίλο"
#: voice.py:130
#, python-brace-format
msgid "Met {num} peers"
msgstr "Γνώρισα {num} φίλους"
#: voice.py:135
#, 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} πελάτες! Επίσης γνώρισα "
"{associated} νέους φίλους και καταβρόχθισα {handshakes} χειραψίες! "
"#pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"

View File

@ -0,0 +1,237 @@
# pwnigotchi voice data
# Copyright (C) 2019
# 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-10-03 12:22+0200\n"
"PO-Revision-Date: 2019-10-03 10:34+0200\n"
"Last-Translator: quantumsheep <7271496+quantumsheep@users.noreply.github."
"com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n"
"Language: french\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: voice.py:18
msgid "ZzzzZZzzzzZzzz"
msgstr ""
#: voice.py:22
msgid "Hi, I'm Pwnagotchi! Starting ..."
msgstr ""
#: voice.py:23
msgid "New day, new hunt, new pwns!"
msgstr ""
#: voice.py:24
msgid "Hack the Planet!"
msgstr ""
#: voice.py:28
msgid "AI ready."
msgstr ""
#: voice.py:29
msgid "The neural network is ready."
msgstr ""
#: voice.py:37
#, python-brace-format
msgid "Hey, channel {channel} is free! Your AP will say thanks."
msgstr ""
#: voice.py:41
msgid "I'm bored ..."
msgstr ""
#: voice.py:42
msgid "Let's go for a walk!"
msgstr ""
#: voice.py:45
msgid "This is the best day of my life!"
msgstr ""
#: voice.py:48
msgid "Shitty day :/"
msgstr ""
#: voice.py:52
msgid "I'm extremely bored ..."
msgstr ""
#: voice.py:53
msgid "I'm very sad ..."
msgstr ""
#: voice.py:54
msgid "I'm sad"
msgstr ""
#: voice.py:59
msgid "I'm living the life!"
msgstr ""
#: voice.py:60
msgid "I pwn therefore I am."
msgstr ""
#: voice.py:61
msgid "So many networks!!!"
msgstr ""
#: voice.py:62
msgid "I'm having so much fun!"
msgstr ""
#: voice.py:63
msgid "My crime is that of curiosity ..."
msgstr ""
#: voice.py:67
#, python-brace-format
msgid "Hello {name}! Nice to meet you. {name}"
msgstr ""
#: voice.py:68
#, python-brace-format
msgid "Unit {name} is nearby! {name}"
msgstr ""
#: voice.py:72
#, python-brace-format
msgid "Uhm ... goodbye {name}"
msgstr ""
#: voice.py:73
#, python-brace-format
msgid "{name} is gone ..."
msgstr ""
#: voice.py:77
#, python-brace-format
msgid "Whoops ... {name} is gone."
msgstr ""
#: voice.py:78
#, python-brace-format
msgid "{name} missed!"
msgstr ""
#: voice.py:79
msgid "Missed!"
msgstr ""
#: voice.py:83
msgid "Nobody wants to play with me ..."
msgstr ""
#: voice.py:84
msgid "I feel so alone ..."
msgstr ""
#: voice.py:85
msgid "Where's everybody?!"
msgstr ""
#: voice.py:89
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr ""
#: voice.py:90
msgid "Zzzzz"
msgstr ""
#: voice.py:91
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr ""
#: voice.py:98
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr ""
#: voice.py:100
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr ""
#: voice.py:106
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr ""
#: voice.py:107
#, python-brace-format
msgid "Associating to {what}"
msgstr ""
#: voice.py:108
#, python-brace-format
msgid "Yo {what}!"
msgstr ""
#: voice.py:112
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr ""
#: voice.py:113
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr ""
#: voice.py:114
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr ""
#: voice.py:118
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr ""
#: voice.py:121
msgid "Ops, something went wrong ... Rebooting ..."
msgstr ""
#: voice.py:124
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr ""
#: voice.py:125
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr ""
#: voice.py:126
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr ""
#: voice.py:128
msgid "Met 1 peer"
msgstr ""
#: voice.py:130
#, python-brace-format
msgid "Met {num} peers"
msgstr ""
#: voice.py:135
#, 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 ""

View File

@ -1,339 +0,0 @@
# pwnigotchi voice data
# Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR Perilis Fregkos <fregkos@gmail.com>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-29 13:42+0200\n"
"PO-Revision-Date: 2019-10-01 16:22+0000\n"
"Last-Translator: Panos Vasilopoulos <hello@alwayslivid.com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n"
"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: voice.py:16
msgid "ZzzzZZzzzzZzzz"
msgstr ""
#: voice.py:21
msgid ""
"Hi, I'm Pwnagotchi!\n"
"Starting ..."
msgstr ""
"Γεία, είμαι το Pwnagotchi!\n"
"Εκκινούμαι ..."
#: voice.py:22
msgid ""
"New day, new hunt,\n"
"new pwns!"
msgstr ""
"Νέα μέρα, νέο κυνήγι,\n"
"νέα pwns!"
#: voice.py:23
msgid "Hack the Planet!"
msgstr "Hackαρε τον πλανήτη!"
#: voice.py:28
msgid "AI ready."
msgstr "ΤΝ έτοιμη."
#: voice.py:29
msgid ""
"The neural network\n"
"is ready."
msgstr ""
"Το νευρωνικό δίκτυο\n"
"είναι έτοιμο."
#: voice.py:39
#, python-brace-format
msgid ""
"Hey, channel {channel} is\n"
"free! Your AP will\n"
"say thanks."
msgstr ""
"Ε, το κανάλι {channel} είναι\n"
"ελεύθερο! Το AP σου θα\n"
"είναι ευγνώμων."
#: voice.py:44
msgid "I'm bored ..."
msgstr "Βαριέμαι ..."
#: voice.py:45
msgid "Let's go for a walk!"
msgstr "Ας πάμε μια βόλτα!"
#: voice.py:49
msgid ""
"This is the best\n"
"day of my life!"
msgstr ""
"Είναι η καλύτερη\n"
"μέρα της ζωής μου!"
#: voice.py:53
msgid "Shitty day :/"
msgstr "Σκατένια μέρα :/"
#: voice.py:58
msgid "I'm extremely bored ..."
msgstr "Βαριέμαι πάρα πολύ ..."
#: voice.py:59
msgid "I'm very sad ..."
msgstr "Είμαι πολύ λυπημένο ..."
#: voice.py:60
msgid "I'm sad"
msgstr "Είμαι λυπημένο"
#: voice.py:66
msgid "I'm living the life!"
msgstr "Ζω την ζωή μου!"
#: voice.py:67
msgid "I pwn therefore I am."
msgstr "Pwnάρω, άρα υπάρχω."
#: voice.py:68
msgid "So many networks!!!"
msgstr "Τόσα πολλά δίκτυα!!!"
#: voice.py:69
msgid ""
"I'm having so much\n"
"fun!"
msgstr "Περνάω τέλεια!"
#: voice.py:70
msgid ""
"My crime is that of\n"
"curiosity ..."
msgstr ""
"Η περιέργεια είναι\n"
"το μόνο έγκλημά μου ..."
#: voice.py:75
#, python-brace-format
msgid ""
"Hello\n"
"{name}!\n"
"Nice to meet you. {name}"
msgstr ""
"Γειά {name}!\n"
"Χάρηκα για τη γνωριμία. {name}"
#: voice.py:76
#, python-brace-format
msgid ""
"Unit\n"
"{name}\n"
"is nearby! {name}"
msgstr ""
"Η μονάδα\n"
"{name}\n"
"είναι κοντά! {name}"
#: voice.py:81
#, python-brace-format
msgid ""
"Uhm ...\n"
"goodbye\n"
"{name}"
msgstr ""
"Εμμ ...\n"
"αντίο\n"
"{name}"
#: voice.py:82
#, python-brace-format
msgid ""
"{name}\n"
"is gone ..."
msgstr ""
"Το {name}\n"
"έφυγε ..."
#: voice.py:87
#, python-brace-format
msgid ""
"Whoops ...\n"
"{name}\n"
"is gone."
msgstr ""
"Ουπς ... \n"
"Εξαφανίστηκε το\n"
"{name}."
#: voice.py:88
#, python-brace-format
msgid ""
"{name}\n"
"missed!"
msgstr ""
"Έχασα το\n"
"{name}!"
#: voice.py:89
msgid "Missed!"
msgstr "Το έχασα!"
#: voice.py:94
msgid ""
"Nobody wants to\n"
"play with me ..."
msgstr ""
"Κανείς δε θέλει να\n"
"παίξει μαζί μου ..."
#: voice.py:95
msgid "I feel so alone ..."
msgstr "Νιώθω μοναχός μου ..."
#: voice.py:96
msgid "Where's everybody?!"
msgstr "Μα, πού πήγαν όλοi;!"
#: voice.py:101
#, python-brace-format
msgid "Napping for {secs}s ..."
msgstr "Ξεκουράζομαι για {secs}s ..."
#: voice.py:102
msgid "Zzzzz"
msgstr ""
#: voice.py:103
#, python-brace-format
msgid "ZzzZzzz ({secs}s)"
msgstr ""
#: voice.py:112
#, python-brace-format
msgid "Waiting for {secs}s ..."
msgstr "Περιμένω για {secs}s ..."
#: voice.py:114
#, python-brace-format
msgid "Looking around ({secs}s)"
msgstr "Ψάχνω τριγύρω ({secs})"
#: voice.py:121
#, python-brace-format
msgid ""
"Hey\n"
"{what}\n"
"let's be friends!"
msgstr ""
"Εε!\n"
"{what},\n"
"ας γίνουμε φίλοι!"
#: voice.py:122
#, python-brace-format
msgid ""
"Associating to\n"
"{what}"
msgstr ""
"Συνδέομαι με το\n"
"{what}"
#: voice.py:123
#, python-brace-format
msgid ""
"Yo\n"
"{what}!"
msgstr ""
"Που'σ ρε τρελέ\n"
"{what}!"
#: voice.py:128
#, python-brace-format
msgid ""
"Just decided that\n"
"{mac}\n"
"needs no WiFi!"
msgstr ""
"Μόλις αποφάσισα ότι η\n"
"{mac}\n"
"δε χρείαζεται WiFi!"
#: voice.py:129
#, python-brace-format
msgid ""
"Deauthenticating\n"
"{mac}"
msgstr ""
"Πετάω έξω την\n"
"{mac}"
#: voice.py:130
#, python-brace-format
msgid ""
"Kickbanning\n"
"{mac}!"
msgstr ""
"Μπανάρω την\n"
"{mac}!"
#: voice.py:135
#, python-brace-format
msgid ""
"Cool, we got {num}\n"
"new handshake{plural}!"
msgstr ""
"Τέλεια δικέ μου, πήραμε {num}\n"
"νέες χειραψίες{plural}!"
#: voice.py:139
msgid ""
"Ops, something\n"
"went wrong ...\n"
"Rebooting ..."
msgstr ""
"Ουπς, κάτι\n"
"πήγε λάθος ...\n"
"Επανεκκινούμαι ..."
#: voice.py:143
#, python-brace-format
msgid "Kicked {num} stations\n"
msgstr "Έριξα {num} σταθμούς\n"
#: voice.py:144
#, python-brace-format
msgid "Made {num} new friends\n"
msgstr "Έκανα {num} νέους φίλους\n"
#: voice.py:145
#, python-brace-format
msgid "Got {num} handshakes\n"
msgstr "Πήρα {num} χειραψίες\n"
#: voice.py:147
msgid "Met 1 peer"
msgstr "Γνώρισα 1 φίλο"
#: voice.py:149
#, python-brace-format
msgid "Met {num} peers"
msgstr "Γνώρισα {num} φίλους"
#: voice.py:154
#, 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} πελάτες! Επίσης γνώρισα "
"{associated} νέους φίλους και καταβρόχθισα {handshakes} χειραψίες! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet"

View File

@ -1,347 +1,239 @@
# pwnigotchi voice data # pwnaigotchi voice data
# Copyright (C) 2019 # Copyright (C) 2019
# This file is distributed under the same license as the pwnagotchi package. # This file is distributed under the same license as the pwnagotchi package.
# 5h4d0wb0y <28193209+5h4d0wb0y@users.noreply.github.com>, 2019. # FIRST AUTHOR 5h4d0wb0y <28193209+5h4d0wb0y@users.noreply.github.com>, 2019.
# #
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-01 14:15+0200\n" "POT-Creation-Date: 2019-10-03 13:10+0200\n"
"PO-Revision-Date: 2019-10-01 14:00+0200\n" "PO-Revision-Date: 2019-10-02 17:20+0000\n"
"Last-Translator: 5h4d0wb0y <28193209+5h4d0wb0y@users.noreply.github.com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n" "Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n"
"Language: italian\n" "Language: italian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:18 #: voice.py:18
msgid "ZzzzZZzzzzZzzz" msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:23
msgid ""
"Hi, I'm Pwnagotchi!\n"
"Starting ..."
msgstr "" msgstr ""
"Ciao, sono Pwnagotchi!\n"
"Avviamento ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:24 #: voice.py:22
msgid "" msgid "Hi, I'm Pwnagotchi! Starting ..."
"New day, new hunt,\n" msgstr "Ciao! Piacere Pwnagotchi! Caricamento ..."
"new pwns!"
msgstr ""
"Nuovo giorno, nuova caccia,\n"
"nuovi pwns!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:25 #: voice.py:23
#, fuzzy
msgid "New day, new hunt, new pwns!"
msgstr "Nuovo giorno...nuovi handshakes!!!"
#: voice.py:24
msgid "Hack the Planet!" msgid "Hack the Planet!"
msgstr "Hack il pianeta!" msgstr ""
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:30 #: voice.py:28
msgid "AI ready." msgid "AI ready."
msgstr "IA pronta." msgstr "IA pronta."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:31 #: voice.py:29
msgid "" msgid "The neural network is ready."
"The neural network\n" msgstr "La rete neurale è pronta."
"is ready."
msgstr ""
"La rete neurale\n"
"è pronta."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:41 #: voice.py:37
#, python-brace-format #, python-brace-format
msgid "" msgid "Hey, channel {channel} is free! Your AP will say thanks."
"Hey, channel {channel} is\n" msgstr "Hey, il canale {channel} è libero! Il tuo AP ringrazia."
"free! Your AP will\n"
"say thanks."
msgstr ""
"Hey, il canale {channel} è\n"
"libero! Il tuo AP\n"
"dirà grazie."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:46 #: voice.py:41
msgid "I'm bored ..." msgid "I'm bored ..."
msgstr "Sono annoiato ..." msgstr "Che noia ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:47 #: voice.py:42
msgid "Let's go for a walk!" msgid "Let's go for a walk!"
msgstr "Andiamo a fare una \npasseggiata!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:51
msgid ""
"This is the best\n"
"day of my life!"
msgstr "" msgstr ""
"Questo è il migliore\n" "Andiamo a fare una passeggiata!"
"giorno della mia vita!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:55 #: voice.py:45
msgid "This is the best day of my life!"
msgstr "Questo è il più bel giorno della mia vita!!!!"
#: voice.py:48
msgid "Shitty day :/" msgid "Shitty day :/"
msgstr "Giorno di merda :/" msgstr "Giorno di merda :/"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:60 #: voice.py:52
msgid "I'm extremely bored ..." msgid "I'm extremely bored ..."
msgstr "" msgstr "Sono estremamente annoiato ..."
"Sono estremamente\n"
"annoiato ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:61 #: voice.py:53
msgid "I'm very sad ..." msgid "I'm very sad ..."
msgstr "Sono molto triste ..." msgstr "Sono molto triste..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:62 #: voice.py:54
msgid "I'm sad" msgid "I'm sad"
msgstr "Sono triste" msgstr "Sono triste"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:68 #: voice.py:59
msgid "I'm living the life!" msgid "I'm living the life!"
msgstr "Sto vivendo la vita!" msgstr "Mi sento vivo!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:69 #: voice.py:60
msgid "I pwn therefore I am." msgid "I pwn therefore I am."
msgstr "Possiedo quindi sono." msgstr "Pwn ergo sum."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:70 #: voice.py:61
msgid "So many networks!!!" msgid "So many networks!!!"
msgstr "Così tante reti!!!" msgstr "Qui è pieno di reti!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:71 #: voice.py:62
msgid "" msgid "I'm having so much fun!"
"I'm having so much\n" msgstr "Mi sto divertendo tantissimo!"
"fun!"
#: voice.py:63
msgid "My crime is that of curiosity ..."
msgstr "" msgstr ""
"Mi sto divertendo\n"
"tanto!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:72 #: voice.py:67
msgid ""
"My crime is that of\n"
"curiosity ..."
msgstr ""
"La mia colpa è di\n"
"essere curioso ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:77
#, python-brace-format #, python-brace-format
msgid "" msgid "Hello {name}! Nice to meet you. {name}"
"Hello\n" msgstr "Ciao {name}! E' un piacere. {name}"
"{name}!\n"
"Nice to meet you. {name}"
msgstr ""
"Ciao\n"
"{name}!\n"
"Piacere di conoscerti. {name}"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:78 #: voice.py:68
#, python-brace-format #, python-brace-format
msgid "" msgid "Unit {name} is nearby! {name}"
"Unit\n" msgstr "L'Unità {name} è vicina! {name}"
"{name}\n"
"is nearby! {name}"
msgstr ""
"L'Unità\n"
"{name}\n"
"è vicina! {name}"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:83 #: voice.py:72
#, python-brace-format #, python-brace-format
msgid "" msgid "Uhm ... goodbye {name}"
"Uhm ...\n" msgstr "Uhm ... addio {name}, mi mancherai..."
"goodbye\n"
"{name}"
msgstr ""
"Uhm ...\n"
"addio\n"
"{name}"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:84 #: voice.py:73
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} is gone ..."
"{name}\n" msgstr "{name} se n'è andato ..."
"is gone ..."
msgstr ""
"{name}\n"
"è andato ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:89 #: voice.py:77
#, python-brace-format #, python-brace-format
msgid "" msgid "Whoops ... {name} is gone."
"Whoops ...\n" msgstr "Whoops ...{name} se n'è andato."
"{name}\n"
"is gone."
msgstr ""
"Whoops ...\n"
"{name}\n"
"è andato."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:90 #: voice.py:78
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} missed!"
"{name}\n" msgstr "{name} è scomparso..."
"missed!"
msgstr ""
"{name}\n"
"perso!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:91 #: voice.py:79
msgid "Missed!" msgid "Missed!"
msgstr "Perso!" msgstr "Ehi! Dove sei andato!?"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:96 #: voice.py:83
msgid "" msgid "Nobody wants to play with me ..."
"Nobody wants to\n" msgstr "Nessuno vuole giocare con me..."
"play with me ..."
msgstr ""
"Nessuno vuole\n"
"giocare con me..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:97 #: voice.py:84
msgid "I feel so alone ..." msgid "I feel so alone ..."
msgstr "Mi sento così solo ..." msgstr "Mi sento così solo..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:98 #: voice.py:85
msgid "Where's everybody?!" msgid "Where's everybody?!"
msgstr "Dove sono tutti?!" msgstr "Dove sono tutti?!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:103 #: voice.py:89
#, python-brace-format #, python-brace-format
msgid "Napping for {secs}s ..." msgid "Napping for {secs}s ..."
msgstr "Pisolino per {secs}i ..." msgstr "Schiaccio un pisolino per {secs}s ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:104 #: voice.py:90
msgid "Zzzzz" msgid "Zzzzz"
msgstr "Zzzzz" msgstr ""
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:105 #: voice.py:91
#, python-brace-format #, python-brace-format
msgid "ZzzZzzz ({secs}s)" msgid "ZzzZzzz ({secs}s)"
msgstr "ZzzZzzz ({secs}i)" msgstr ""
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:114 #: voice.py:98
#, python-brace-format #, python-brace-format
msgid "Waiting for {secs}s ..." msgid "Waiting for {secs}s ..."
msgstr "In attesa di {secs}i ..." msgstr "Aspetto {secs}s ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:116 #: voice.py:100
#, python-brace-format #, python-brace-format
msgid "Looking around ({secs}s)" msgid "Looking around ({secs}s)"
msgstr "Guardando intorno ({secs}s)" msgstr "Do uno sguardo qui intorno... ({secs}s)"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:123 #: voice.py:106
#, python-brace-format #, python-brace-format
msgid "" msgid "Hey {what} let's be friends!"
"Hey\n" msgstr "Hey {what}! Diventiamo amici!"
"{what}\n"
"let's be friends!"
msgstr ""
"Hey\n"
"{what}\n"
"diventiamo amici!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:124 #: voice.py:107
#, python-brace-format #, python-brace-format
msgid "" msgid "Associating to {what}"
"Associating to\n" msgstr "Collegamento con {what} in corso..."
"{what}"
msgstr ""
"Associarci a\n"
"{what}"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:125 #: voice.py:108
#, python-brace-format #, python-brace-format
msgid "" msgid "Yo {what}!"
"Yo\n" msgstr "Yo {what}!"
"{what}!"
msgstr ""
"Yo\n"
"{what}!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:130 #: voice.py:112
#, python-brace-format #, python-brace-format
msgid "" msgid "Just decided that {mac} needs no WiFi!"
"Just decided that\n" msgstr "Ho appena deciso che {mac} non necessita di WiFi!"
"{mac}\n"
"needs no WiFi!"
msgstr ""
"Ho appena deciso che\n"
"{mac}\n"
"non necessita di\n"
"WiFi!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:131 #: voice.py:113
#, python-brace-format #, python-brace-format
msgid "" msgid "Deauthenticating {mac}"
"Deauthenticating\n"
"{mac}"
msgstr "" msgstr ""
"Dissociarci da\n"
"{mac}"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:132 #: voice.py:114
#, python-brace-format #, python-brace-format
msgid "" msgid "Kickbanning {mac}!"
"Kickbanning\n" msgstr "Sto prendendo a calci {mac}!"
"{mac}!"
msgstr ""
"Sto prendendo\n"
"a calci\n"
"{mac}!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:137 #: voice.py:118
#, python-brace-format #, python-brace-format
msgid "" msgid "Cool, we got {num} new handshake{plural}!"
"Cool, we got {num}\n" msgstr "Bene, abbiamo {num} handshake{plural} in più!"
"new handshake{plural}!"
msgstr ""
"Bene, abbiamo {num}\n"
"nuovi handshake{plural}!"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:141 #: voice.py:121
msgid "" msgid "Ops, something went wrong ... Rebooting ..."
"Ops, something\n" msgstr "Ops, qualcosa è andato storto ... Riavvio ..."
"went wrong ...\n"
"Rebooting ..."
msgstr ""
"Ops, qualcosa\n"
"è andato storto ...\n"
"Riavvio ..."
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:145 #: voice.py:124
#, python-brace-format #, python-brace-format
msgid "Kicked {num} stations\n" msgid "Kicked {num} stations\n"
msgstr "Calciate {num} stazioni\n" msgstr "{num} stazioni pestate\n"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:146 #: voice.py:125
#, python-brace-format #, python-brace-format
msgid "Made {num} new friends\n" msgid "Made {num} new friends\n"
msgstr "Fatti {num} nuovi amici\n" msgstr "{num} nuovi amici\n"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:147 #: voice.py:126
#, python-brace-format #, python-brace-format
msgid "Got {num} handshakes\n" msgid "Got {num} handshakes\n"
msgstr "Presi {num} handshakes\n" msgstr "{num} handshakes presi\n"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:149 #: voice.py:128
msgid "Met 1 peer" msgid "Met 1 peer"
msgstr "Incontrato 1 peer" msgstr "1 peer incontrato"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:151 #: voice.py:130
#, python-brace-format #, python-brace-format
msgid "Met {num} peers" msgid "Met {num} peers"
msgstr "Incontrati {num} peers" msgstr "{num} peers incontrati"
#: /home/sh4d0wb0y/Projects/GitHub/pwnagotchi/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/voice.py:156 #: voice.py:135
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met " "I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi " "{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet" "#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "" msgstr ""
"Ho lavorato per {duration} e preso a calci i clienti di {deauthed}! Ho anche " "Ho lavorato per {duration} e preso a calci {deauthed} clients! Ho anche "
"incontrato{associate} nuovi amici e ho mangiato {handshakes} handshakes! " "incontrato {associate} nuovi amici e ho mangiato {handshakes} handshakes! "
"#pwnagotchi#pwnlog #pwnlife #hacktheplanet #skynet" "#pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"

View File

@ -4,11 +4,11 @@
# FIRST AUTHOR <33197631+dadav@users.noreply.github.com>, 2019. # FIRST AUTHOR <33197631+dadav@users.noreply.github.com>, 2019.
# kovach <2214005+kovachwt@users.noreply.github.com>, 2019. # kovach <2214005+kovachwt@users.noreply.github.com>, 2019.
# #
#, fuzzymsgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-29 13:42+0200\n" "POT-Creation-Date: 2019-10-03 12:44+0200\n"
"PO-Revision-Date: 2019-09-30 23:53+0200\n" "PO-Revision-Date: 2019-09-30 23:53+0200\n"
"Last-Translator: kovach <2214005+kovachwt@users.noreply.github.com>\n" "Last-Translator: kovach <2214005+kovachwt@users.noreply.github.com>\n"
"Language-Team: \n" "Language-Team: \n"
@ -17,27 +17,21 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: voice.py:16 #: voice.py:18
msgid "ZzzzZZzzzzZzzz" msgid "ZzzzZZzzzzZzzz"
msgstr "ДреееММмммМммм" msgstr "ДреееММмммМммм"
#: voice.py:21
msgid ""
"Hi, I'm Pwnagotchi!\n"
"Starting ..."
msgstr ""
"Здраво, јас сум Pwnagotchi!\n"
"Почнувам ..."
#: voice.py:22 #: voice.py:22
msgid "" #, fuzzy
"New day, new hunt,\n" msgid "Hi, I'm Pwnagotchi! Starting ..."
"new pwns!" msgstr "Здраво, јас сум Pwnagotchi!Почнувам ..."
msgstr ""
"Нов ден, нов лов,\n"
"ќе си газиме!"
#: voice.py:23 #: voice.py:23
#, fuzzy
msgid "New day, new hunt, new pwns!"
msgstr "Нов ден, нов лов,ќе си газиме!"
#: voice.py:24
msgid "Hack the Planet!" msgid "Hack the Planet!"
msgstr "Хак д Планет!" msgstr "Хак д Планет!"
@ -46,290 +40,202 @@ msgid "AI ready."
msgstr "AI спремно." msgstr "AI спремно."
#: voice.py:29 #: voice.py:29
msgid "" #, fuzzy
"The neural network\n" msgid "The neural network is ready."
"is ready." msgstr "Невронската мрежае спремна."
msgstr ""
"Невронската мрежа\n"
"е спремна."
#: voice.py:39 #: voice.py:37
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "Hey, channel {channel} is free! Your AP will say thanks."
"Hey, channel {channel} is\n" msgstr "Еј, каналот {channel} еслободен! APто ќе тикаже фала."
"free! Your AP will\n"
"say thanks."
msgstr ""
"Еј, каналот {channel} е\n"
"слободен! APто ќе ти\n"
"каже фала."
#: voice.py:44 #: voice.py:41
msgid "I'm bored ..." msgid "I'm bored ..."
msgstr "Досаднооо ..." msgstr "Досаднооо ..."
#: voice.py:45 #: voice.py:42
msgid "Let's go for a walk!" msgid "Let's go for a walk!"
msgstr "Ајде да шетнеме!" msgstr "Ајде да шетнеме!"
#: voice.py:49 #: voice.py:45
msgid "" #, fuzzy
"This is the best\n" msgid "This is the best day of my life!"
"day of my life!" msgstr "Ова ми е најдобриот ден во животот!"
msgstr ""
"Ова ми е најдобриот \n"
"ден во животот!"
#: voice.py:53 #: voice.py:48
msgid "Shitty day :/" msgid "Shitty day :/"
msgstr "Срање ден :/" msgstr "Срање ден :/"
#: voice.py:58 #: voice.py:52
msgid "I'm extremely bored ..." msgid "I'm extremely bored ..."
msgstr "Ултра досадно ..." msgstr "Ултра досадно ..."
#: voice.py:59 #: voice.py:53
msgid "I'm very sad ..." msgid "I'm very sad ..."
msgstr "Многу тажно ..." msgstr "Многу тажно ..."
#: voice.py:60 #: voice.py:54
msgid "I'm sad" msgid "I'm sad"
msgstr "Тажно" msgstr "Тажно"
#: voice.py:66 #: voice.py:59
msgid "I'm living the life!" msgid "I'm living the life!"
msgstr "Ммхх животче!" msgstr "Ммхх животче!"
#: voice.py:67 #: voice.py:60
msgid "I pwn therefore I am." msgid "I pwn therefore I am."
msgstr "Си газам значи постојам." msgstr "Си газам значи постојам."
#: voice.py:68 #: voice.py:61
msgid "So many networks!!!" msgid "So many networks!!!"
msgstr "Мммм колку мрежи!!!" msgstr "Мммм колку мрежи!!!"
#: voice.py:69 #: voice.py:62
msgid "" #, fuzzy
"I'm having so much\n" msgid "I'm having so much fun!"
"fun!"
msgstr "Јухуу забавноо ее!" msgstr "Јухуу забавноо ее!"
#: voice.py:70 #: voice.py:63
msgid "" #, fuzzy
"My crime is that of\n" msgid "My crime is that of curiosity ..."
"curiosity ..." msgstr "Виновен сум само заљубопитност ..."
msgstr ""
"Виновен сум само за\n"
"љубопитност ..."
#: voice.py:75 #: voice.py:67
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "Hello {name}! Nice to meet you. {name}"
"Hello\n" msgstr "Здраво{name}!Мило ми е. {name}"
"{name}!\n"
"Nice to meet you. {name}"
msgstr ""
"Здраво\n"
"{name}!\n"
"Мило ми е. {name}"
#: voice.py:76 #: voice.py:68
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "Unit {name} is nearby! {name}"
"Unit\n" msgstr "Опаа{name}е во близина! {name}"
"{name}\n"
"is nearby! {name}"
msgstr ""
"Опаа\n"
"{name}\n"
"е во близина! {name}"
#: voice.py:81 #: voice.py:72
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "Uhm ... goodbye {name}"
"Uhm ...\n" msgstr "Хмм ...чао{name}"
"goodbye\n"
"{name}"
msgstr ""
"Хмм ...\n"
"чао\n"
"{name}"
#: voice.py:82 #: voice.py:73
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "{name} is gone ..."
"{name}\n" msgstr "{name}го снема ..."
"is gone ..."
msgstr ""
"{name}\n"
"го снема ..."
#: voice.py:87 #: voice.py:77
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "Whoops ... {name} is gone."
"Whoops ...\n" msgstr "Уупс ...{name}го снема."
"{name}\n"
"is gone."
msgstr ""
"Уупс ...\n"
"{name}\n"
"го снема."
#: voice.py:88 #: voice.py:78
#, python-brace-format #, fuzzy, python-brace-format
msgid "" msgid "{name} missed!"
"{name}\n" msgstr "{name}промаши!"
"missed!"
msgstr ""
"{name}\n"
"промаши!"
#: voice.py:89 #: voice.py:79
msgid "Missed!" msgid "Missed!"
msgstr "Промаши!" msgstr "Промаши!"
#: voice.py:94 #: voice.py:83
msgid "" #, fuzzy
"Nobody wants to\n" msgid "Nobody wants to play with me ..."
"play with me ..." msgstr "Никој не сака даси игра со мене ..."
msgstr ""
"Никој не сака да\n"
"си игра со мене ..."
#: voice.py:95 #: voice.py:84
msgid "I feel so alone ..." msgid "I feel so alone ..."
msgstr "Толку сам ..." msgstr "Толку сам ..."
#: voice.py:96 #: voice.py:85
msgid "Where's everybody?!" msgid "Where's everybody?!"
msgstr "Каде се сите?!" msgstr "Каде се сите?!"
#: voice.py:101 #: voice.py:89
#, python-brace-format #, python-brace-format
msgid "Napping for {secs}s ..." msgid "Napping for {secs}s ..."
msgstr "Ќе дремнам {secs}с ..." msgstr "Ќе дремнам {secs}с ..."
#: voice.py:102 #: voice.py:90
msgid "Zzzzz" msgid "Zzzzz"
msgstr "Дреммм" msgstr "Дреммм"
#: voice.py:103 #: voice.py:91
#, python-brace-format #, python-brace-format
msgid "ZzzZzzz ({secs}s)" msgid "ZzzZzzz ({secs}s)"
msgstr "Дремммм ({secs}с)" msgstr "Дремммм ({secs}с)"
#: voice.py:112 #: voice.py:98
#, python-brace-format #, python-brace-format
msgid "Waiting for {secs}s ..." msgid "Waiting for {secs}s ..."
msgstr "Чекам {secs}с ..." msgstr "Чекам {secs}с ..."
#: voice.py:114 #: voice.py:100
#, python-brace-format #, python-brace-format
msgid "Looking around ({secs}s)" msgid "Looking around ({secs}s)"
msgstr "Шарам наоколу ({secs}с)" msgstr "Шарам наоколу ({secs}с)"
#: voice.py:106
#, fuzzy, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Еј{what}ајде да се дружиме!"
#: voice.py:107
#, fuzzy, python-brace-format
msgid "Associating to {what}"
msgstr "Се закачувам на{what}"
#: voice.py:108
#, fuzzy, python-brace-format
msgid "Yo {what}!"
msgstr "Јо{what}!"
#: voice.py:112
#, fuzzy, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Знаеш што, на{mac}не му треба WiFi!"
#: voice.py:113
#, fuzzy, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "Го деавтентицирам{mac}"
#: voice.py:114
#, fuzzy, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Кикбан{mac}!"
#: voice.py:118
#, fuzzy, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Кул, фативме {num}нови ракувања!"
#: voice.py:121 #: voice.py:121
#, python-brace-format #, fuzzy
msgid "" msgid "Ops, something went wrong ... Rebooting ..."
"Hey\n" msgstr "Упс, нешто не еко што треба ...Рестартирам ..."
"{what}\n"
"let's be friends!"
msgstr ""
"Еј\n"
"{what}\n"
"ајде да се дружиме!"
#: voice.py:122 #: voice.py:124
#, python-brace-format
msgid ""
"Associating to\n"
"{what}"
msgstr ""
"Се закачувам на\n"
"{what}"
#: voice.py:123
#, python-brace-format
msgid ""
"Yo\n"
"{what}!"
msgstr ""
"Јо\n"
"{what}!"
#: voice.py:128
#, python-brace-format
msgid ""
"Just decided that\n"
"{mac}\n"
"needs no WiFi!"
msgstr ""
"Знаеш што, на\n"
"{mac}\n"
"не му треба WiFi!"
#: voice.py:129
#, python-brace-format
msgid ""
"Deauthenticating\n"
"{mac}"
msgstr ""
"Го деавтентицирам\n"
"{mac}"
#: voice.py:130
#, python-brace-format
msgid ""
"Kickbanning\n"
"{mac}!"
msgstr ""
"Кикбан\n"
"{mac}!"
#: voice.py:135
#, python-brace-format
msgid ""
"Cool, we got {num}\n"
"new handshake{plural}!"
msgstr ""
"Кул, фативме {num}\n"
"нови ракувања!"
#: voice.py:139
msgid ""
"Ops, something\n"
"went wrong ...\n"
"Rebooting ..."
msgstr ""
"Упс, нешто не е\n"
"ко што треба ...\n"
"Рестартирам ..."
#: voice.py:143
#, python-brace-format #, python-brace-format
msgid "Kicked {num} stations\n" msgid "Kicked {num} stations\n"
msgstr "Избацив {num} станици" msgstr "Избацив {num} станици\n"
#: voice.py:144 #: voice.py:125
#, python-brace-format #, python-brace-format
msgid "Made {num} new friends\n" msgid "Made {num} new friends\n"
msgstr "{num} нови другарчиња" msgstr "{num} нови другарчиња\n"
#: voice.py:145 #: voice.py:126
#, python-brace-format #, python-brace-format
msgid "Got {num} handshakes\n" msgid "Got {num} handshakes\n"
msgstr "Фатив {num} ракувања" msgstr "Фатив {num} ракувања\n"
#: voice.py:147 #: voice.py:128
msgid "Met 1 peer" msgid "Met 1 peer"
msgstr "Запознав 1 пријател" msgstr "Запознав 1 пријател"
#: voice.py:149 #: voice.py:130
#, python-brace-format #, python-brace-format
msgid "Met {num} peers" msgid "Met {num} peers"
msgstr "Запознав {num} пријатели" msgstr "Запознав {num} пријатели"
#: voice.py:154 #: voice.py:135
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met " "I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
@ -337,5 +243,5 @@ msgid ""
"#pwnlog #pwnlife #hacktheplanet #skynet" "#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "" msgstr ""
"Си газам веќе {duration} и избацив {deauthed} клиенти! Запознав {associated} " "Си газам веќе {duration} и избацив {deauthed} клиенти! Запознав {associated} "
"нови другарчиња и лапнав {handshakes} ракувања! #pwnagotchi #pwnlog " "нови другарчиња и лапнав {handshakes} ракувања! #pwnagotchi #pwnlog #pwnlife "
"#pwnlife #hacktheplanet #skynet" "#hacktheplanet #skynet"

View File

@ -3,43 +3,32 @@
# This file is distributed under the same license as the pwnagotchi package. # This file is distributed under the same license as the pwnagotchi package.
# FIRST AUTHOR justin-p@users.noreply.github.com, 2019. # FIRST AUTHOR justin-p@users.noreply.github.com, 2019.
# #
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-29 13:42+0200\n" "POT-Creation-Date: 2019-10-03 12:44+0200\n"
"PO-Revision-Date: 2019-09-29 14:00+0200\n" "PO-Revision-Date: 2019-09-29 14:00+0200\n"
"Last-Translator: Justin-P <justin-p@users.noreply.github.com>\n" "Last-Translator: Justin-P <justin-p@users.noreply.github.com>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n" "Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n"
"Language: english\n" "Language: nl\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: voice.py:16 #: voice.py:18
msgid "ZzzzZZzzzzZzzz" msgid "ZzzzZZzzzzZzzz"
msgstr "ZzzzZZzzzzZzzz" msgstr "ZzzzZZzzzzZzzz"
#: voice.py:21
msgid ""
"Hi, I'm Pwnagotchi!\n"
"Starting ..."
msgstr ""
"Hoi, Ik ben\n"
"Pwnagotchi!\n"
"Opstarten ..."
#: voice.py:22 #: voice.py:22
msgid "" msgid "Hi, I'm Pwnagotchi! Starting ..."
"New day, new hunt,\n" msgstr "Hoi, Ik ben Pwnagotchi! Opstarten ..."
"new pwns!"
msgstr ""
"Nieuwe dag,\n"
"nieuwe jacht,\n"
"nieuwe pwns!"
#: voice.py:23 #: voice.py:23
msgid "New day, new hunt, new pwns!"
msgstr "Nieuwe dag, nieuwe jacht, nieuwe pwns!"
#: voice.py:24
msgid "Hack the Planet!" msgid "Hack the Planet!"
msgstr "Hack de Wereld!" msgstr "Hack de Wereld!"
@ -48,301 +37,203 @@ msgid "AI ready."
msgstr "AI is klaar." msgstr "AI is klaar."
#: voice.py:29 #: voice.py:29
msgid "" msgid "The neural network is ready."
"The neural network\n" msgstr "Neuronen netwerkis klaar voor gebruik."
"is ready."
msgstr ""
"Neuronen netwerk\n"
"is klaar voor gebruik."
#: voice.py:39 #: voice.py:37
#, python-brace-format #, python-brace-format
msgid "" msgid "Hey, channel {channel} is free! Your AP will say thanks."
"Hey, channel {channel} is\n" msgstr "Hey, kanaal {channel} is vrij! Je AP zal je bedanken."
"free! Your AP will\n"
"say thanks."
msgstr ""
"Hey, kanaal {channel} is\n"
"vrij! Je AP zal je\n"
"bedanken."
#: voice.py:44 #: voice.py:41
msgid "I'm bored ..." msgid "I'm bored ..."
msgstr "Ik verveel me ..." msgstr "Ik verveel me ..."
#: voice.py:45 #: voice.py:42
msgid "Let's go for a walk!" msgid "Let's go for a walk!"
msgstr "Laten we een rondje lopen!" msgstr "Laten we een rondje lopen!"
#: voice.py:49 #: voice.py:45
msgid "" msgid "This is the best day of my life!"
"This is the best\n" msgstr "Dit is de beste dag van mijn leven!"
"day of my life!"
msgstr ""
"Dit is de beste\n"
"dag van mijn leven!"
#: voice.py:53 #: voice.py:48
msgid "Shitty day :/" msgid "Shitty day :/"
msgstr "Ruk dag :/" msgstr "Ruk dag :/"
#: voice.py:58 #: voice.py:52
msgid "I'm extremely bored ..." msgid "I'm extremely bored ..."
msgstr "Ik verveel me \n" msgstr "Ik verveel me kapot ..."
"kapot ..."
#: voice.py:59 #: voice.py:53
msgid "I'm very sad ..." msgid "I'm very sad ..."
msgstr "Ik ben erg\n" msgstr "Ik ben ergverdrietig ..."
"verdrietig ..."
#: voice.py:60 #: voice.py:54
msgid "I'm sad" msgid "I'm sad"
msgstr "Ik ben verdrietig" msgstr "Ik ben verdrietig"
#: voice.py:66 #: voice.py:59
msgid "I'm living the life!" msgid "I'm living the life!"
msgstr "Beter kan het leven\n" msgstr "Beter kan het levenniet worden!"
"niet worden!"
#: voice.py:67 #: voice.py:60
msgid "I pwn therefore I am." msgid "I pwn therefore I am."
msgstr "Ik pwn daarom besta ik." msgstr "Ik pwn daarom besta ik."
#: voice.py:68 #: voice.py:61
msgid "So many networks!!!" msgid "So many networks!!!"
msgstr "Zo veel netwerken!!!" msgstr "Zo veel netwerken!!!"
#: voice.py:69 #: voice.py:62
msgid "" msgid "I'm having so much fun!"
"I'm having so much\n"
"fun!"
msgstr "Dit is zo leuk!" msgstr "Dit is zo leuk!"
#: voice.py:70 #: voice.py:63
msgid "" #, fuzzy
"My crime is that of\n" msgid "My crime is that of curiosity ..."
"curiosity ..." msgstr "Mijn enige misdrijfis mijn nieuwsgierigheid ..."
msgstr ""
"Mijn enige misdrijf\n"
"is mijn \n"
"nieuwsgierigheid ..."
#: voice.py:75 #: voice.py:67
#, python-brace-format #, python-brace-format
msgid "" msgid "Hello {name}! Nice to meet you. {name}"
"Hello\n" msgstr "Hallo {name}! Leuk je te ontmoeten. {name}"
"{name}!\n"
"Nice to meet you. {name}"
msgstr ""
"Hallo\n"
"{name}!\n"
"Leuk je te ontmoeten. {name}"
#: voice.py:76 #: voice.py:68
#, python-brace-format #, python-brace-format
msgid "" msgid "Unit {name} is nearby! {name}"
"Unit\n" msgstr "Unit {name} is dichtbij! {name}"
"{name}\n"
"is nearby! {name}"
msgstr ""
"Unit\n"
"{name}\n"
"is dichtbij! {name}"
#: voice.py:81 #: voice.py:72
#, python-brace-format #, python-brace-format
msgid "" msgid "Uhm ... goodbye {name}"
"Uhm ...\n" msgstr "Uhm ...tot ziens {name}"
"goodbye\n"
"{name}"
msgstr ""
"Uhm ...\n"
"tot ziens\n"
"{name}"
#: voice.py:82 #: voice.py:73
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} is gone ..."
"{name}\n" msgstr "{name} is weg"
"is gone ..."
msgstr ""
"{name}\n"
"is weg"
#: voice.py:87 #: voice.py:77
#, python-brace-format #, python-brace-format
msgid "" msgid "Whoops ... {name} is gone."
"Whoops ...\n" msgstr "Whoopsie ...{name} is weg"
"{name}\n"
"is gone."
msgstr ""
"Whoopsie ...\n"
"{name}\n"
"is weg"
#: voice.py:88 #: voice.py:78
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} missed!"
"{name}\n" msgstr "{name} gemist!"
"missed!"
msgstr ""
"{name}\n"
"gemist!"
#: voice.py:89 #: voice.py:79
msgid "Missed!" msgid "Missed!"
msgstr "Gemist!" msgstr "Gemist!"
#: voice.py:94 #: voice.py:83
msgid "" msgid "Nobody wants to play with me ..."
"Nobody wants to\n" msgstr "Niemand wil metmij spelen ..."
"play with me ..."
msgstr ""
"Niemand wil met\n"
"mij spelen ..."
#: voice.py:95 #: voice.py:84
msgid "I feel so alone ..." msgid "I feel so alone ..."
msgstr "Zo alleen ..." msgstr "Zo alleen ..."
#: voice.py:96 #: voice.py:85
msgid "Where's everybody?!" msgid "Where's everybody?!"
msgstr "Waar is iedereen?!" msgstr "Waar is iedereen?!"
#: voice.py:101 #: voice.py:89
#, python-brace-format #, python-brace-format
msgid "Napping for {secs}s ..." msgid "Napping for {secs}s ..."
msgstr "Dutje doen voor {secs}s ..." msgstr "Dutje doen voor {secs}s ..."
#: voice.py:102 #: voice.py:90
msgid "Zzzzz" msgid "Zzzzz"
msgstr "Zzzzz" msgstr "Zzzzz"
#: voice.py:103 #: voice.py:91
#, python-brace-format #, python-brace-format
msgid "ZzzZzzz ({secs}s)" msgid "ZzzZzzz ({secs}s)"
msgstr "" msgstr ""
#: voice.py:112 #: voice.py:98
#, python-brace-format #, python-brace-format
msgid "Waiting for {secs}s ..." msgid "Waiting for {secs}s ..."
msgstr "Even {secs}s wachten ..." msgstr "Even {secs}s wachten ..."
#: voice.py:114 #: voice.py:100
#, python-brace-format #, python-brace-format
msgid "Looking around ({secs}s)" msgid "Looking around ({secs}s)"
msgstr "Rond kijken ({secs}s)" msgstr "Rond kijken ({secs}s)"
#: voice.py:106
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr "Hey {what}, laten we vriendenworden!"
#: voice.py:107
#, python-brace-format
msgid "Associating to {what}"
msgstr "Verbinden met {what}"
#: voice.py:108
#, python-brace-format
msgid "Yo {what}!"
msgstr ""
#: voice.py:112
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr "Ik vind dat {mac} genoeg WiFiheeft gehad!"
#: voice.py:113
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr "De-autoriseren {mac}"
#: voice.py:114
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr "Ik ga {mac} even kicken!"
#: voice.py:118
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr "Gaaf, we hebben {num} nieuwe handshake{plural}!"
#: voice.py:121 #: voice.py:121
#, python-brace-format msgid "Ops, something went wrong ... Rebooting ..."
msgid "" msgstr "Oops, iets ging fout ...Rebooting ..."
"Hey\n"
"{what}\n"
"let's be friends!"
msgstr ""
"Hey\n"
"{what}\n"
"Laten we vrienden\n"
"worden!"
#: voice.py:122 #: voice.py:124
#, python-brace-format
msgid ""
"Associating to\n"
"{what}"
msgstr ""
"Verbinden met\n"
"{what}"
#: voice.py:123
#, python-brace-format
msgid ""
"Yo\n"
"{what}!"
msgstr ""
#: voice.py:128
#, python-brace-format
msgid ""
"Just decided that\n"
"{mac}\n"
"needs no WiFi!"
msgstr "Ik vind dat\n"
"{mac}\n"
"genoeg WiFi\n"
"heeft gehad!"
#: voice.py:129
#, python-brace-format
msgid ""
"Deauthenticating\n"
"{mac}"
msgstr ""
"De-autoriseren\n"
"{mac}"
#: voice.py:130
#, python-brace-format
msgid ""
"Kickbanning\n"
"{mac}!"
msgstr ""
"Ik ga\n"
"{mac}\n"
"even kicken!"
#: voice.py:135
#, python-brace-format
msgid ""
"Cool, we got {num}\n"
"new handshake{plural}!"
msgstr ""
"Gaaf, we hebben {num}\n"
"nieuwe handshake{plural}!"
#: voice.py:139
msgid ""
"Ops, something\n"
"went wrong ...\n"
"Rebooting ..."
msgstr ""
"Oops, iets"
"ging fout ...\n"
"Rebooting ..."
#: voice.py:143
#, python-brace-format #, python-brace-format
msgid "Kicked {num} stations\n" msgid "Kicked {num} stations\n"
msgstr "{num} stations gekicked\n" msgstr "{num} stations gekicked\n"
#: voice.py:144 #: voice.py:125
#, python-brace-format #, python-brace-format
msgid "Made {num} new friends\n" msgid "Made {num} new friends\n"
msgstr "{num} nieuwe vrienden\n" msgstr "{num} nieuwe vrienden\n"
#: voice.py:145 #: voice.py:126
#, python-brace-format #, python-brace-format
msgid "Got {num} handshakes\n" msgid "Got {num} handshakes\n"
msgstr "{num} nieuwe handshakes\n" msgstr "{num} nieuwe handshakes\n"
#: voice.py:147 #: voice.py:128
msgid "Met 1 peer" msgid "Met 1 peer"
msgstr "1 peer ontmoet" msgstr "1 peer ontmoet"
#: voice.py:149 #: voice.py:130
#, python-brace-format #, python-brace-format
msgid "Met {num} peers" msgid "Met {num} peers"
msgstr "{num} peers ontmoet" msgstr "{num} peers ontmoet"
#: voice.py:154 #: voice.py:135
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met " "I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi " "{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
"#pwnlog #pwnlife #hacktheplanet #skynet" "#pwnlog #pwnlife #hacktheplanet #skynet"
msgstr "" msgstr ""
"Ik heb gepwned voor {duration} and heb {deauthed} clients gekicked! Ik heb ook " "Ik heb gepwned voor {duration} and heb {deauthed} clients gekicked! Ik heb "
"{associated} nieuwe vrienden gevonden en heb {handshakes} handshakes gegeten! " "ook {associated} nieuwe vrienden gevonden en heb {handshakes} handshakes "
"#pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet" "gegeten! #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet"

View File

@ -1,39 +1,35 @@
# pwnigotchi voice data # SOME DESCRIPTIVE TITLE.
# Copyright (C) 2019 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the pwnagotchi package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <33197631+dadav@users.noreply.github.com>, 2019. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-29 13:42+0200\n" "POT-Creation-Date: 2019-10-03 13:10+0200\n"
"PO-Revision-Date: 2019-09-29 14:00+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: dadav <33197631+dadav@users.noreply.github.com>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github.com>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: english\n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: voice.py:16 #: voice.py:18
msgid "ZzzzZZzzzzZzzz" msgid "ZzzzZZzzzzZzzz"
msgstr "" msgstr ""
#: voice.py:21
msgid ""
"Hi, I'm Pwnagotchi!\n"
"Starting ..."
msgstr ""
#: voice.py:22 #: voice.py:22
msgid "" msgid "Hi, I'm Pwnagotchi! Starting ..."
"New day, new hunt,\n"
"new pwns!"
msgstr "" msgstr ""
#: voice.py:23 #: voice.py:23
msgid "New day, new hunt, new pwns!"
msgstr ""
#: voice.py:24
msgid "Hack the Planet!" msgid "Hack the Planet!"
msgstr "" msgstr ""
@ -42,244 +38,196 @@ msgid "AI ready."
msgstr "" msgstr ""
#: voice.py:29 #: voice.py:29
msgid "" msgid "The neural network is ready."
"The neural network\n"
"is ready."
msgstr "" msgstr ""
#: voice.py:39 #: voice.py:37
#, python-brace-format #, python-brace-format
msgid "" msgid "Hey, channel {channel} is free! Your AP will say thanks."
"Hey, channel {channel} is\n"
"free! Your AP will\n"
"say thanks."
msgstr "" msgstr ""
#: voice.py:44 #: voice.py:41
msgid "I'm bored ..." msgid "I'm bored ..."
msgstr "" msgstr ""
#: voice.py:45 #: voice.py:42
msgid "Let's go for a walk!" msgid "Let's go for a walk!"
msgstr "" msgstr ""
#: voice.py:49 #: voice.py:45
msgid "" msgid "This is the best day of my life!"
"This is the best\n"
"day of my life!"
msgstr "" msgstr ""
#: voice.py:53 #: voice.py:48
msgid "Shitty day :/" msgid "Shitty day :/"
msgstr "" msgstr ""
#: voice.py:58 #: voice.py:52
msgid "I'm extremely bored ..." msgid "I'm extremely bored ..."
msgstr "" msgstr ""
#: voice.py:59 #: voice.py:53
msgid "I'm very sad ..." msgid "I'm very sad ..."
msgstr "" msgstr ""
#: voice.py:60 #: voice.py:54
msgid "I'm sad" msgid "I'm sad"
msgstr "" msgstr ""
#: voice.py:66 #: voice.py:59
msgid "I'm living the life!" msgid "I'm living the life!"
msgstr "" msgstr ""
#: voice.py:67 #: voice.py:60
msgid "I pwn therefore I am." msgid "I pwn therefore I am."
msgstr "" msgstr ""
#: voice.py:68 #: voice.py:61
msgid "So many networks!!!" msgid "So many networks!!!"
msgstr "" msgstr ""
#: voice.py:69 #: voice.py:62
msgid "" msgid "I'm having so much fun!"
"I'm having so much\n"
"fun!"
msgstr "" msgstr ""
#: voice.py:70 #: voice.py:63
msgid "" msgid "My crime is that of curiosity ..."
"My crime is that of\n"
"curiosity ..."
msgstr "" msgstr ""
#: voice.py:75 #: voice.py:67
#, python-brace-format #, python-brace-format
msgid "" msgid "Hello {name}! Nice to meet you. {name}"
"Hello\n"
"{name}!\n"
"Nice to meet you. {name}"
msgstr "" msgstr ""
#: voice.py:76 #: voice.py:68
#, python-brace-format #, python-brace-format
msgid "" msgid "Unit {name} is nearby! {name}"
"Unit\n"
"{name}\n"
"is nearby! {name}"
msgstr "" msgstr ""
#: voice.py:81 #: voice.py:72
#, python-brace-format #, python-brace-format
msgid "" msgid "Uhm ... goodbye {name}"
"Uhm ...\n"
"goodbye\n"
"{name}"
msgstr "" msgstr ""
#: voice.py:82 #: voice.py:73
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} is gone ..."
"{name}\n"
"is gone ..."
msgstr "" msgstr ""
#: voice.py:87 #: voice.py:77
#, python-brace-format #, python-brace-format
msgid "" msgid "Whoops ... {name} is gone."
"Whoops ...\n"
"{name}\n"
"is gone."
msgstr "" msgstr ""
#: voice.py:88 #: voice.py:78
#, python-brace-format #, python-brace-format
msgid "" msgid "{name} missed!"
"{name}\n"
"missed!"
msgstr "" msgstr ""
#: voice.py:89 #: voice.py:79
msgid "Missed!" msgid "Missed!"
msgstr "" msgstr ""
#: voice.py:94 #: voice.py:83
msgid "" msgid "Nobody wants to play with me ..."
"Nobody wants to\n"
"play with me ..."
msgstr "" msgstr ""
#: voice.py:95 #: voice.py:84
msgid "I feel so alone ..." msgid "I feel so alone ..."
msgstr "" msgstr ""
#: voice.py:96 #: voice.py:85
msgid "Where's everybody?!" msgid "Where's everybody?!"
msgstr "" msgstr ""
#: voice.py:101 #: voice.py:89
#, python-brace-format #, python-brace-format
msgid "Napping for {secs}s ..." msgid "Napping for {secs}s ..."
msgstr "" msgstr ""
#: voice.py:102 #: voice.py:90
msgid "Zzzzz" msgid "Zzzzz"
msgstr "" msgstr ""
#: voice.py:103 #: voice.py:91
#, python-brace-format #, python-brace-format
msgid "ZzzZzzz ({secs}s)" msgid "ZzzZzzz ({secs}s)"
msgstr "" msgstr ""
#: voice.py:112 #: voice.py:98
#, python-brace-format #, python-brace-format
msgid "Waiting for {secs}s ..." msgid "Waiting for {secs}s ..."
msgstr "" msgstr ""
#: voice.py:114 #: voice.py:100
#, python-brace-format #, python-brace-format
msgid "Looking around ({secs}s)" msgid "Looking around ({secs}s)"
msgstr "" msgstr ""
#: voice.py:106
#, python-brace-format
msgid "Hey {what} let's be friends!"
msgstr ""
#: voice.py:107
#, python-brace-format
msgid "Associating to {what}"
msgstr ""
#: voice.py:108
#, python-brace-format
msgid "Yo {what}!"
msgstr ""
#: voice.py:112
#, python-brace-format
msgid "Just decided that {mac} needs no WiFi!"
msgstr ""
#: voice.py:113
#, python-brace-format
msgid "Deauthenticating {mac}"
msgstr ""
#: voice.py:114
#, python-brace-format
msgid "Kickbanning {mac}!"
msgstr ""
#: voice.py:118
#, python-brace-format
msgid "Cool, we got {num} new handshake{plural}!"
msgstr ""
#: voice.py:121 #: voice.py:121
#, python-brace-format msgid "Ops, something went wrong ... Rebooting ..."
msgid ""
"Hey\n"
"{what}\n"
"let's be friends!"
msgstr "" msgstr ""
#: voice.py:122 #: voice.py:124
#, python-brace-format
msgid ""
"Associating to\n"
"{what}"
msgstr ""
#: voice.py:123
#, python-brace-format
msgid ""
"Yo\n"
"{what}!"
msgstr ""
#: voice.py:128
#, python-brace-format
msgid ""
"Just decided that\n"
"{mac}\n"
"needs no WiFi!"
msgstr ""
#: voice.py:129
#, python-brace-format
msgid ""
"Deauthenticating\n"
"{mac}"
msgstr ""
#: voice.py:130
#, python-brace-format
msgid ""
"Kickbanning\n"
"{mac}!"
msgstr ""
#: voice.py:135
#, python-brace-format
msgid ""
"Cool, we got {num}\n"
"new handshake{plural}!"
msgstr ""
#: voice.py:139
msgid ""
"Ops, something\n"
"went wrong ...\n"
"Rebooting ..."
msgstr ""
#: voice.py:143
#, python-brace-format #, python-brace-format
msgid "Kicked {num} stations\n" msgid "Kicked {num} stations\n"
msgstr "" msgstr ""
#: voice.py:144 #: voice.py:125
#, python-brace-format #, python-brace-format
msgid "Made {num} new friends\n" msgid "Made {num} new friends\n"
msgstr "" msgstr ""
#: voice.py:145 #: voice.py:126
#, python-brace-format #, python-brace-format
msgid "Got {num} handshakes\n" msgid "Got {num} handshakes\n"
msgstr "" msgstr ""
#: voice.py:147 #: voice.py:128
msgid "Met 1 peer" msgid "Met 1 peer"
msgstr "" msgstr ""
#: voice.py:149 #: voice.py:130
#, python-brace-format #, python-brace-format
msgid "Met {num} peers" msgid "Met {num} peers"
msgstr "" msgstr ""
#: voice.py:154 #: voice.py:135
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met " "I've been pwning for {duration} and kicked {deauthed} clients! I've also met "

View File

@ -160,6 +160,9 @@ class SessionParser(object):
break break
lines.reverse() lines.reverse()
if len(lines) == 0:
lines.append("Initial Session");
self.last_session = lines self.last_session = lines
self.last_session_id = hashlib.md5(lines[0].encode()).hexdigest() self.last_session_id = hashlib.md5(lines[0].encode()).hexdigest()
self.last_saved_session_id = self._get_last_saved_session_id() self.last_saved_session_id = self._get_last_saved_session_id()

View File

@ -1,7 +1,7 @@
import _thread import _thread
import core import core
import pwnagotchi import pwnagotchi, pwnagotchi.plugins as plugins
from pwnagotchi.mesh import get_identity from pwnagotchi.mesh import get_identity
@ -37,6 +37,8 @@ class AsyncAdvertiser(object):
def _on_new_unit(self, peer): def _on_new_unit(self, peer):
self._view.on_new_peer(peer) self._view.on_new_peer(peer)
plugins.on('peer_detected', self, peer)
def _on_lost_unit(self, peer): def _on_lost_unit(self, peer):
self._view.on_lost_peer(peer) self._view.on_lost_peer(peer)
plugins.on('peer_lost', self, peer)

View File

@ -0,0 +1,43 @@
import os
import glob
import importlib, importlib.util
default_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "default")
loaded = {}
def dummy_callback():
pass
def on(event_name, *args, **kwargs):
global loaded
cb_name = 'on_%s' % event_name
for _, plugin in loaded.items():
if cb_name in plugin.__dict__:
# print("calling %s %s(%s)" %(cb_name, args, kwargs))
plugin.__dict__[cb_name](*args, **kwargs)
def load_from_file(filename):
plugin_name = os.path.basename(filename.replace(".py", ""))
spec = importlib.util.spec_from_file_location(plugin_name, filename)
instance = importlib.util.module_from_spec(spec)
spec.loader.exec_module(instance)
return plugin_name, instance
def load_from_path(path):
global loaded
for filename in glob.glob(os.path.join(path, "*.py")):
name, plugin = load_from_file(filename)
if name in loaded:
raise Exception("plugin %s already loaded from %s" % (name, plugin.__file__))
elif not plugin.__enabled__:
# print("plugin %s is not enabled" % name)
pass
else:
loaded[name] = plugin
return loaded

View File

@ -0,0 +1,162 @@
__author__ = 'evilsocket@gmail.com'
__version__ = '1.0.0'
__name__ = 'hello_world'
__license__ = 'GPL3'
__description__ = 'An example plugin for pwnagotchi that implements all the available callbacks.'
__enabled__ = False # IMPORTANT: set this to True to enable your plugin.
from pwnagotchi.ui.components import LabeledValue
from pwnagotchi.ui.view import BLACK
import pwnagotchi.ui.fonts as fonts
import core
# called when the plugin is loaded
def on_loaded():
core.log("WARNING: plugin %s should be disabled!" % __name__)
# called to setup the ui elements
def on_ui_setup(ui):
# add custom UI elements
ui.add_element('ups', LabeledValue(color=BLACK, label='UPS', value='0%/0V', position=(ui.width() / 2 - 25, 0),
label_font=fonts.Bold, text_font=fonts.Medium))
# called when the ui is updated
def on_ui_update(ui):
# update those elements
some_voltage = 0.1
some_capacity = 100.0
ui.set('ups', "%4.2fV/%2i%%" % (some_voltage, some_capacity))
# called when the hardware display setup is done, display is an hardware specific object
def on_display_setup(display):
pass
# called when everything is ready and the main loop is about to start
def on_ready(agent):
core.log("unit is ready")
# you can run custom bettercap commands if you want
# agent.run('ble.recon on')
# or set a custom state
# agent.set_bored()
# called when the AI finished loading
def on_ai_ready(agent):
pass
# called when the AI finds a new set of parameters
def on_ai_policy(agent, policy):
pass
# called when the AI starts training for a given number of epochs
def on_ai_training_start(agent, epochs):
pass
# called after the AI completed a training epoch
def on_ai_training_step(agent, _locals, _globals):
pass
# called when the AI has done training
def on_ai_training_end(agent):
pass
# called when the AI got the best reward so far
def on_ai_best_reward(agent, reward):
pass
# called when the AI got the best reward so far
def on_ai_worst_reward(agent, reward):
pass
# called when a non overlapping wifi channel is found to be free
def on_free_channel(agent, channel):
pass
# called when the status is set to bored
def on_bored(agent):
pass
# called when the status is set to sad
def on_sad(agent):
pass
# called when the status is set to excited
def on_excited(agent):
pass
# called when the status is set to lonely
def on_lonely(agent):
pass
# called when the agent is rebooting the board
def on_rebooting(agent):
pass
# called when the agent is waiting for t seconds
def on_wait(agent, t):
pass
# called when the agent is sleeping for t seconds
def on_sleep(agent, t):
pass
# called when the agent refreshed its access points list
def on_wifi_update(agent, access_points):
pass
# called when the agent is sending an association frame
def on_association(agent, access_point):
pass
# callend when the agent is deauthenticating a client station from an AP
def on_deauthentication(agent, access_point, client_station):
pass
# callend when the agent is tuning on a specific channel
def on_channel_hop(agent, channel):
pass
# called when a new handshake is captured, access_point and client_station are json objects
# if the agent could match the BSSIDs to the current list, otherwise they are just the strings of the BSSIDs
def on_handshake(agent, filename, access_point, client_station):
pass
# called when an epoch is over (where an epoch is a single loop of the main algorithm)
def on_epoch(agent, epoch, epoch_data):
pass
# called when a new peer is detected
def on_peer_detected(agent, peer):
pass
# called when a known peer is lost
def on_peer_lost(agent, peer):
pass

View File

@ -0,0 +1,47 @@
__author__ = 'evilsocket@gmail.com'
__version__ = '1.0.0'
__name__ = 'gps'
__license__ = 'GPL3'
__description__ = 'Save GPS coordinates whenever an handshake is captured.'
__enabled__ = True # set to false if you just don't use GPS
import core
import json
import os
device = '/dev/ttyUSB0'
speed = 19200
running = False
def on_loaded():
core.log("GPS plugin loaded for %s" % device)
def on_ready(agent):
global running
if os.path.exists(device):
core.log("enabling GPS bettercap's module for %s" % device)
try:
agent.run('gps off')
except:
pass
agent.run('set gps.device %s' % device)
agent.run('set gps.speed %d' % speed)
agent.run('gps on')
running = True
else:
core.log("no GPS detected")
def on_handshake(agent, filename, access_point, client_station):
if running:
info = agent.session()
gps = info['gps']
gps_filename = filename.replace('.pcap', '.gps.json')
core.log("saving GPS to %s (%s)" % (gps_filename, gps))
with open(gps_filename, 'w+t') as fp:
json.dump(gps, fp)

View File

@ -0,0 +1,65 @@
# Based on UPS Lite v1.1 from https://github.com/xenDE
#
# funtions for get UPS status - needs enable "i2c" in raspi-config
#
# https://github.com/linshuqin329/UPS-Lite
#
# For Raspberry Pi Zero Ups Power Expansion Board with Integrated Serial Port S3U4
# https://www.ebay.de/itm/For-Raspberry-Pi-Zero-Ups-Power-Expansion-Board-with-Integrated-Serial-Port-S3U4/323873804310
# https://www.aliexpress.com/item/32888533624.html
__author__ = 'evilsocket@gmail.com'
__version__ = '1.0.0'
__name__ = 'ups_lite'
__license__ = 'GPL3'
__description__ = 'A plugin that will add a voltage indicator for the UPS Lite v1.1'
__enabled__ = False
import struct
from pwnagotchi.ui.components import LabeledValue
from pwnagotchi.ui.view import BLACK
import pwnagotchi.ui.fonts as fonts
# TODO: add enable switch in config.yml an cleanup all to the best place
class UPS:
def __init__(self):
# only import when the module is loaded and enabled
import smbus
# 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1)
self._bus = smbus.SMBus(1)
def voltage(self):
try:
address = 0x36
read = self._bus.read_word_data(address, 2)
swapped = struct.unpack("<H", struct.pack(">H", read))[0]
return swapped * 1.25 / 1000 / 16
except:
return 0.0
def capacity(self):
try:
address = 0x36
read = self._bus.read_word_data(address, 4)
swapped = struct.unpack("<H", struct.pack(">H", read))[0]
return swapped / 256
except:
return 0.0
ups = None
def on_loaded():
global ups
ups = UPS()
def on_ui_setup(ui):
ui.add_element('ups', LabeledValue(color=BLACK, label='UPS', value='0%/0V', position=(ui.width() / 2 - 25, 0),
label_font=fonts.Bold, text_font=fonts.Medium))
def on_ui_update(ui):
ui.set('ups', "%4.2fV/%2i%%" % (ups.voltage(), ups.capacity()))

View File

@ -1,4 +1,5 @@
from PIL import Image from PIL import Image
from textwrap import TextWrapper
class Widget(object): class Widget(object):
@ -39,14 +40,21 @@ class FilledRect(Widget):
class Text(Widget): class Text(Widget):
def __init__(self, value="", position=(0, 0), font=None, color=0): def __init__(self, value="", position=(0, 0), font=None, color=0, wrap=False, max_length=0):
super().__init__(position, color) super().__init__(position, color)
self.value = value self.value = value
self.font = font self.font = font
self.wrap = wrap
self.max_length = max_length
self.wrapper = TextWrapper(width=self.max_length, replace_whitespace=False) if wrap else None
def draw(self, canvas, drawer): def draw(self, canvas, drawer):
if self.value is not None: if self.value is not None:
drawer.text(self.xy, self.value, font=self.font, fill=self.color) if self.wrap:
text = '\n'.join(self.wrapper.wrap(self.value))
else:
text = self.value
drawer.text(self.xy, text, font=self.font, fill=self.color)
class LabeledValue(Widget): class LabeledValue(Widget):

View File

@ -4,7 +4,7 @@ from threading import Lock
import shutil import shutil
import core import core
import os import os
import pwnagotchi import pwnagotchi, pwnagotchi.plugins as plugins
from pwnagotchi.ui.view import WHITE, View from pwnagotchi.ui.view import WHITE, View
@ -146,6 +146,8 @@ class Display(View):
else: else:
core.log("unknown display type %s" % self._display_type) core.log("unknown display type %s" % self._display_type)
plugins.on('display_setup', self._display)
self.on_render(self._on_view_rendered) self.on_render(self._on_view_rendered)
def image(self): def image(self):

View File

@ -15,3 +15,4 @@ LONELY = '(ب__ب)'
SAD = '(╥☁╥ )' SAD = '(╥☁╥ )'
FRIEND = '(♥‿‿♥)' FRIEND = '(♥‿‿♥)'
BROKEN = '(☓‿‿☓)' BROKEN = '(☓‿‿☓)'
DEBUG = '(#__#)'

View File

@ -6,6 +6,11 @@ class State(object):
self._state = state self._state = state
self._lock = Lock() self._lock = Lock()
self._listeners = {} self._listeners = {}
self._changes = {}
def add_element(self, key, elem):
self._state[key] = elem
self._changes[key] = True
def add_listener(self, key, cb): def add_listener(self, key, cb):
with self._lock: with self._lock:
@ -19,10 +24,29 @@ class State(object):
with self._lock: with self._lock:
return self._state[key].value if key in self._state else None return self._state[key].value if key in self._state else None
def reset(self):
with self._lock:
self._changes = {}
def changes(self, ignore=()):
with self._lock:
changes = []
for change in self._changes.keys():
if change not in ignore:
changes.append(change)
return changes
def has_changes(self):
with self._lock:
return len(self._changes) > 0
def set(self, key, value): def set(self, key, value):
with self._lock: with self._lock:
if key in self._state: if key in self._state:
prev = self._state[key].value prev = self._state[key].value
self._state[key].value = value self._state[key].value = value
if key in self._listeners and self._listeners[key] is not None and prev != value:
self._listeners[key](prev, value) if prev != value:
self._changes[key] = True
if key in self._listeners and self._listeners[key] is not None:
self._listeners[key](prev, value)

View File

@ -4,7 +4,7 @@ import time
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
import core import core
import pwnagotchi import pwnagotchi.plugins as plugins
from pwnagotchi.voice import Voice from pwnagotchi.voice import Voice
import pwnagotchi.ui.fonts as fonts import pwnagotchi.ui.fonts as fonts
@ -41,7 +41,7 @@ def setup_display_specifics(config):
name_pos = (int(width / 2) - 15, int(height * .15)) name_pos = (int(width / 2) - 15, int(height * .15))
status_pos = (int(width / 2) - 15, int(height * .30)) status_pos = (int(width / 2) - 15, int(height * .30))
elif config['ui']['display']['type'] in ('ws_1', 'ws1', 'waveshare_1', 'waveshare1', elif config['ui']['display']['type'] in ('ws_1', 'ws1', 'waveshare_1', 'waveshare1',
'ws_2', 'ws2', 'waveshare_2', 'waveshare2'): 'ws_2', 'ws2', 'waveshare_2', 'waveshare2'):
fonts.setup(10, 9, 10, 35) fonts.setup(10, 9, 10, 35)
@ -78,22 +78,25 @@ class View(object):
label_font=fonts.Bold, label_font=fonts.Bold,
text_font=fonts.Medium), text_font=fonts.Medium),
# 'square': Rect([1, 11, 124, 111]),
'line1': Line([0, int(self._height * .12), self._width, int(self._height * .12)], color=BLACK), 'line1': Line([0, int(self._height * .12), self._width, int(self._height * .12)], color=BLACK),
'line2': Line( 'line2': Line(
[0, self._height - int(self._height * .12), self._width, self._height - int(self._height * .12)], [0, self._height - int(self._height * .12), self._width, self._height - int(self._height * .12)],
color=BLACK), color=BLACK),
# 'histogram': Histogram([4, 94], color = BLACK),
'face': Text(value=faces.SLEEP, position=face_pos, color=BLACK, font=fonts.Huge), 'face': Text(value=faces.SLEEP, position=face_pos, color=BLACK, font=fonts.Huge),
'friend_face': Text(value=None, position=(0, 90), font=fonts.Bold, color=BLACK), 'friend_face': Text(value=None, position=(0, 90), font=fonts.Bold, color=BLACK),
'friend_name': Text(value=None, position=(40, 93), font=fonts.BoldSmall, color=BLACK), 'friend_name': Text(value=None, position=(40, 93), font=fonts.BoldSmall, color=BLACK),
'name': Text(value='%s>' % 'pwnagotchi', position=name_pos, color=BLACK, font=fonts.Bold), 'name': Text(value='%s>' % 'pwnagotchi', position=name_pos, color=BLACK, font=fonts.Bold),
# 'face2': Bitmap( '/root/pwnagotchi/data/images/face_happy.bmp', (0, 20)),
'status': Text(value=self._voice.default(), position=status_pos, color=BLACK, font=fonts.Medium), 'status': Text(value=self._voice.default(),
position=status_pos,
color=BLACK,
font=fonts.Medium,
wrap=True,
# the current maximum number of characters per line, assuming each character is 6 pixels wide
max_length=(self._width - status_pos[0]) // 6),
'shakes': LabeledValue(label='PWND ', value='0 (00)', color=BLACK, 'shakes': LabeledValue(label='PWND ', value='0 (00)', color=BLACK,
position=(0, self._height - int(self._height * .12) + 1), label_font=fonts.Bold, position=(0, self._height - int(self._height * .12) + 1), label_font=fonts.Bold,
@ -105,7 +108,23 @@ class View(object):
for key, value in state.items(): for key, value in state.items():
self._state.set(key, value) self._state.set(key, value)
_thread.start_new_thread(self._refresh_handler, ()) plugins.on('ui_setup', self)
if config['ui']['fps'] > 0.0:
_thread.start_new_thread(self._refresh_handler, ())
self._ignore_changes = ()
else:
core.log("ui.fps is 0, the display will only update for major changes")
self._ignore_changes = ('uptime', 'name')
def add_element(self, key, elem):
self._state.add_element(key, elem)
def width(self):
return self._width
def height(self):
return self._height
def on_state_change(self, key, cb): def on_state_change(self, key, cb):
self._state.add_listener(key, cb) self._state.add_listener(key, cb)
@ -218,12 +237,12 @@ class View(object):
if sleeping: if sleeping:
if secs > 1: if secs > 1:
self.set('face', faces.SLEEP) self.set('face', faces.SLEEP)
self.set('status', self._voice.on_napping(secs)) self.set('status', self._voice.on_napping(int(secs)))
else: else:
self.set('face', faces.SLEEP2) self.set('face', faces.SLEEP2)
self.set('status', self._voice.on_awakening()) self.set('status', self._voice.on_awakening())
else: else:
self.set('status', self._voice.on_waiting(secs)) self.set('status', self._voice.on_waiting(int(secs)))
if step % 2 == 0: if step % 2 == 0:
self.set('face', faces.LOOK_R) self.set('face', faces.LOOK_R)
else: else:
@ -289,13 +308,24 @@ class View(object):
self.set('status', self._voice.on_rebooting()) self.set('status', self._voice.on_rebooting())
self.update() self.update()
def on_custom(self, text):
self.set('face', faces.DEBUG)
self.set('status', self._voice.custom(text))
self.update()
def update(self): def update(self):
with self._lock: with self._lock:
self._canvas = Image.new('1', (self._width, self._height), WHITE) changes = self._state.changes(ignore=self._ignore_changes)
drawer = ImageDraw.Draw(self._canvas) if len(changes):
self._canvas = Image.new('1', (self._width, self._height), WHITE)
drawer = ImageDraw.Draw(self._canvas)
for key, lv in self._state.items(): plugins.on('ui_update', self)
lv.draw(self._canvas, drawer)
for cb in self._render_cbs: for key, lv in self._state.items():
cb(self._canvas) lv.draw(self._canvas, drawer)
for cb in self._render_cbs:
cb(self._canvas)
self._state.reset()

View File

@ -1,218 +1,225 @@
# //***************************************************************************** # *****************************************************************************
# * | File : epd2in13.py # * | File : epd2in13.py
# * | Author : Waveshare team # * | Author : Waveshare team
# * | Function : Electronic paper driver # * | Function : Electronic paper driver
# * | Info : # * | Info :
# *---------------- # *----------------
# * | This version: V3.1 # * | This version: V4.0
# * | Date : 2019-03-20 # * | Date : 2019-06-20
# * | Info : python3 demo # # | Info : python demo
# * fix: TurnOnDisplay() # -----------------------------------------------------------------------------
# ******************************************************************************// # Permission is hereby granted, free of charge, to any person obtaining a copy
# Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documnetation files (the "Software"), to deal
# of this software and associated documnetation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights
# in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# to use, copy, modify, merge, publish, distribute, sublicense, and//or sell # copies of the Software, and to permit persons to whom the Software is
# copies of the Software, and to permit persons to whom the Software is # furished to do so, subject to the following conditions:
# furished to do so, subject to the following conditions: #
# # The above copyright notice and this permission notice shall be included in
# The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software.
# all copies or substantial portions of the Software. #
# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE.
# THE SOFTWARE. #
#
import logging
from . import epdconfig from . import epdconfig
from PIL import Image import numpy as np
import RPi.GPIO as GPIO
# import numpy as np # Display resolution
EPD_WIDTH = 122
# Display resolution EPD_HEIGHT = 250
EPD_WIDTH = 122
EPD_HEIGHT = 250 class EPD:
def __init__(self):
class EPD: self.reset_pin = epdconfig.RST_PIN
def __init__(self): self.dc_pin = epdconfig.DC_PIN
self.reset_pin = epdconfig.RST_PIN self.busy_pin = epdconfig.BUSY_PIN
self.dc_pin = epdconfig.DC_PIN self.cs_pin = epdconfig.CS_PIN
self.busy_pin = epdconfig.BUSY_PIN self.width = EPD_WIDTH
self.width = EPD_WIDTH self.height = EPD_HEIGHT
self.height = EPD_HEIGHT
lut_full_update = [ lut_full_update = [
0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11, 0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
] ]
lut_partial_update = [ lut_partial_update = [
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
] ]
# Hardware reset # Hardware reset
def reset(self): def reset(self):
epdconfig.digital_write(self.reset_pin, GPIO.HIGH) epdconfig.digital_write(self.cs_pin, 0)
epdconfig.delay_ms(200) epdconfig.digital_write(self.reset_pin, 1)
epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset epdconfig.delay_ms(200)
epdconfig.delay_ms(200) epdconfig.digital_write(self.reset_pin, 0)
epdconfig.digital_write(self.reset_pin, GPIO.HIGH) epdconfig.delay_ms(10)
epdconfig.delay_ms(200) epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(200)
def send_command(self, command): epdconfig.digital_write(self.cs_pin, 1)
epdconfig.digital_write(self.dc_pin, GPIO.LOW)
epdconfig.spi_writebyte([command]) def send_command(self, command):
epdconfig.digital_write(self.cs_pin, 0)
def send_data(self, data): epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.dc_pin, GPIO.HIGH) epdconfig.spi_writebyte([command])
epdconfig.spi_writebyte([data]) epdconfig.digital_write(self.cs_pin, 1)
def wait_until_idle(self): def send_data(self, data):
# print("busy") epdconfig.digital_write(self.cs_pin, 0)
while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy epdconfig.digital_write(self.dc_pin, 1)
epdconfig.delay_ms(100) epdconfig.spi_writebyte([data])
# print("free busy") epdconfig.digital_write(self.cs_pin, 1)
def TurnOnDisplay(self): def ReadBusy(self):
self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
self.send_data(0xC4) epdconfig.delay_ms(100)
self.send_command(0x20) # MASTER_ACTIVATION
self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE def TurnOnDisplay(self):
self.wait_until_idle() self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
self.send_data(0xC4)
def init(self, lut): self.send_command(0x20) # MASTER_ACTIVATION
if (epdconfig.module_init() != 0): self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE
return -1
# EPD hardware init start logging.debug("e-Paper busy")
self.reset() self.ReadBusy()
self.send_command(0x01) # DRIVER_OUTPUT_CONTROL logging.debug("e-Paper busy release")
self.send_data((EPD_HEIGHT - 1) & 0xFF)
self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF) def init(self, lut):
self.send_data(0x00) # GD = 0 SM = 0 TB = 0 if (epdconfig.module_init() != 0):
return -1
self.send_command(0x0C) # BOOSTER_SOFT_START_CONTROL # EPD hardware init start
self.send_data(0xD7) self.reset()
self.send_data(0xD6) self.send_command(0x01) # DRIVER_OUTPUT_CONTROL
self.send_data(0x9D) self.send_data((EPD_HEIGHT - 1) & 0xFF)
self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF)
self.send_command(0x2C) # WRITE_VCOM_REGISTER self.send_data(0x00) # GD = 0 SM = 0 TB = 0
self.send_data(0xA8) # VCOM 7C
self.send_command(0x0C) # BOOSTER_SOFT_START_CONTROL
self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD self.send_data(0xD7)
self.send_data(0x1A) # 4 dummy lines per gate self.send_data(0xD6)
self.send_data(0x9D)
self.send_command(0x3B) # SET_GATE_TIME
self.send_data(0x08) # 2us per line self.send_command(0x2C) # WRITE_VCOM_REGISTER
self.send_data(0xA8) # VCOM 7C
self.send_command(0X3C) # BORDER_WAVEFORM_CONTROL
self.send_data(0x03) self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD
self.send_data(0x1A) # 4 dummy lines per gate
self.send_command(0X11) # DATA_ENTRY_MODE_SETTING
self.send_data(0x03) # X increment; Y increment self.send_command(0x3B) # SET_GATE_TIME
self.send_data(0x08) # 2us per line
# WRITE_LUT_REGISTER
self.send_command(0x32) self.send_command(0X3C) # BORDER_WAVEFORM_CONTROL
for count in range(30): self.send_data(0x03)
self.send_data(lut[count])
self.send_command(0X11) # DATA_ENTRY_MODE_SETTING
return 0 self.send_data(0x03) # X increment; Y increment
## # WRITE_LUT_REGISTER
# @brief: specify the memory area for data R//W self.send_command(0x32)
## for count in range(30):
def SetWindows(self, x_start, y_start, x_end, y_end): self.send_data(lut[count])
self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
self.send_data((x_start >> 3) & 0xFF) return 0
self.send_data((x_end >> 3) & 0xFF)
self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION ##
self.send_data(y_start & 0xFF) # @brief: specify the memory area for data R/W
self.send_data((y_start >> 8) & 0xFF) ##
self.send_data(y_end & 0xFF) def SetWindows(self, x_start, y_start, x_end, y_end):
self.send_data((y_end >> 8) & 0xFF) self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
self.send_data((x_start >> 3) & 0xFF)
## self.send_data((x_end >> 3) & 0xFF)
# @brief: specify the start point for data R//W self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
## self.send_data(y_start & 0xFF)
def SetCursor(self, x, y): self.send_data((y_start >> 8) & 0xFF)
self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER self.send_data(y_end & 0xFF)
# x point must be the multiple of 8 or the last 3 bits will be ignored self.send_data((y_end >> 8) & 0xFF)
self.send_data((x >> 3) & 0xFF)
self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER ##
self.send_data(y & 0xFF) # @brief: specify the start point for data R/W
self.send_data((y >> 8) & 0xFF) ##
self.wait_until_idle() def SetCursor(self, x, y):
self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
def getbuffer(self, image): # x point must be the multiple of 8 or the last 3 bits will be ignored
if self.width%8 == 0: self.send_data((x >> 3) & 0xFF)
linewidth = self.width//8 self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
else: self.send_data(y & 0xFF)
linewidth = self.width//8 + 1 self.send_data((y >> 8) & 0xFF)
self.ReadBusy()
buf = [0xFF] * (linewidth * self.height)
image_monocolor = image.convert('1') def getbuffer(self, image):
imwidth, imheight = image_monocolor.size if self.width%8 == 0:
pixels = image_monocolor.load() linewidth = int(self.width/8)
else:
if(imwidth == self.width and imheight == self.height): linewidth = int(self.width/8) + 1
# print("Vertical")
for y in range(imheight): buf = [0xFF] * (linewidth * self.height)
for x in range(imwidth): image_monocolor = image.convert('1')
if pixels[x, y] == 0: imwidth, imheight = image_monocolor.size
# x = imwidth - x pixels = image_monocolor.load()
buf[x // 8 + y * linewidth] &= ~(0x80 >> (x % 8))
elif(imwidth == self.height and imheight == self.width): if(imwidth == self.width and imheight == self.height):
# print("Horizontal") for y in range(imheight):
for y in range(imheight): for x in range(imwidth):
for x in range(imwidth): if pixels[x, y] == 0:
newx = y # x = imwidth - x
newy = self.height - x - 1 buf[int(x / 8) + y * linewidth] &= ~(0x80 >> (x % 8))
if pixels[x, y] == 0: elif(imwidth == self.height and imheight == self.width):
# newy = imwidth - newy - 1 for y in range(imheight):
buf[newx // 8 + newy*linewidth] &= ~(0x80 >> (y % 8)) for x in range(imwidth):
return buf newx = y
newy = self.height - x - 1
if pixels[x, y] == 0:
def display(self, image): # newy = imwidth - newy - 1
if self.width%8 == 0: buf[int(newx / 8) + newy*linewidth] &= ~(0x80 >> (y % 8))
linewidth = self.width//8 return buf
else:
linewidth = self.width//8 + 1
def display(self, image):
self.SetWindows(0, 0, EPD_WIDTH, EPD_HEIGHT); if self.width%8 == 0:
for j in range(0, self.height): linewidth = int(self.width/8)
self.SetCursor(0, j); else:
self.send_command(0x24); linewidth = int(self.width/8) + 1
for i in range(0, linewidth):
self.send_data(image[i + j * linewidth]) self.SetWindows(0, 0, self.width, self.height);
self.TurnOnDisplay() for j in range(0, self.height):
self.SetCursor(0, j);
def Clear(self, color): self.send_command(0x24);
if self.width%8 == 0: for i in range(0, linewidth):
linewidth = self.width//8 self.send_data(image[i + j * linewidth])
else: self.TurnOnDisplay()
linewidth = self.width//8 + 1
def Clear(self, color):
self.SetWindows(0, 0, EPD_WIDTH, EPD_HEIGHT); if self.width%8 == 0:
for j in range(0, self.height): linewidth = int(self.width/8)
self.SetCursor(0, j); else:
self.send_command(0x24); linewidth = int(self.width/8) + 1
for i in range(0, linewidth):
self.send_data(color) self.SetWindows(0, 0, self.width, self.height);
self.TurnOnDisplay() for j in range(0, self.height):
self.SetCursor(0, j);
def sleep(self): self.send_command(0x24);
self.send_command(0x10) #enter deep sleep for i in range(0, linewidth):
# self.send_data(0x01) self.send_data(color)
epdconfig.delay_ms(100) self.TurnOnDisplay()
### END OF FILE ### def sleep(self):
self.send_command(0x10) #enter deep sleep
self.send_data(0x01)
epdconfig.delay_ms(100)
epdconfig.module_exit()
### END OF FILE ###

View File

@ -1,19 +1,13 @@
# /***************************************************************************** # /*****************************************************************************
# * | File : EPD_1in54.py # * | File : epdconfig.py
# * | Author : Waveshare team # * | Author : Waveshare team
# * | Function : Hardware underlying interface # * | Function : Hardware underlying interface
# * | Info : # * | Info :
# *---------------- # *----------------
# * | This version: V2.0 # * | This version: V1.0
# * | Date : 2018-11-01 # * | Date : 2019-06-21
# * | Info : # * | Info :
# * 1.Remove: # ******************************************************************************
# digital_write(self, pin, value)
# digital_read(self, pin)
# delay_ms(self, delaytime)
# set_lut(self, lut)
# self.lut = self.lut_full_update
# ******************************************************************************/
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal # of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights # in the Software without restriction, including without limitation the rights
@ -33,41 +27,128 @@
# THE SOFTWARE. # THE SOFTWARE.
# #
import os
import spidev import logging
import RPi.GPIO as GPIO import sys
import time import time
# Pin definition
RST_PIN = 17
DC_PIN = 25
CS_PIN = 8
BUSY_PIN = 24
# SPI device, bus = 0, device = 0 class RaspberryPi:
SPI = spidev.SpiDev(0, 0) # Pin definition
RST_PIN = 17
DC_PIN = 25
CS_PIN = 8
BUSY_PIN = 24
def digital_write(pin, value): def __init__(self):
GPIO.output(pin, value) import spidev
import RPi.GPIO
def digital_read(pin): self.GPIO = RPi.GPIO
return GPIO.input(BUSY_PIN)
def delay_ms(delaytime): # SPI device, bus = 0, device = 0
time.sleep(delaytime / 1000.0) self.SPI = spidev.SpiDev(0, 0)
def spi_writebyte(data): def digital_write(self, pin, value):
SPI.writebytes(data) self.GPIO.output(pin, value)
def digital_read(self, pin):
return self.GPIO.input(self.BUSY_PIN)
def delay_ms(self, delaytime):
time.sleep(delaytime / 1000.0)
def spi_writebyte(self, data):
self.SPI.writebytes(data)
def module_init(self):
self.GPIO.setmode(self.GPIO.BCM)
self.GPIO.setwarnings(False)
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
self.SPI.max_speed_hz = 4000000
self.SPI.mode = 0b00
return 0
def module_exit(self):
logging.debug("spi end")
self.SPI.close()
logging.debug("close 5V, Module enters 0 power consumption ...")
self.GPIO.output(self.RST_PIN, 0)
self.GPIO.output(self.DC_PIN, 0)
self.GPIO.cleanup()
class JetsonNano:
# Pin definition
RST_PIN = 17
DC_PIN = 25
CS_PIN = 8
BUSY_PIN = 24
def __init__(self):
import ctypes
find_dirs = [
os.path.dirname(os.path.realpath(__file__)),
'/usr/local/lib',
'/usr/lib',
]
self.SPI = None
for find_dir in find_dirs:
so_filename = os.path.join(find_dir, 'sysfs_software_spi.so')
if os.path.exists(so_filename):
self.SPI = ctypes.cdll.LoadLibrary(so_filename)
break
if self.SPI is None:
raise RuntimeError('Cannot find sysfs_software_spi.so')
import Jetson.GPIO
self.GPIO = Jetson.GPIO
def digital_write(self, pin, value):
self.GPIO.output(pin, value)
def digital_read(self, pin):
return self.GPIO.input(self.BUSY_PIN)
def delay_ms(self, delaytime):
time.sleep(delaytime / 1000.0)
def spi_writebyte(self, data):
self.SPI.SYSFS_software_spi_transfer(data[0])
def module_init(self):
self.GPIO.setmode(self.GPIO.BCM)
self.GPIO.setwarnings(False)
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
self.SPI.SYSFS_software_spi_begin()
return 0
def module_exit(self):
logging.debug("spi end")
self.SPI.SYSFS_software_spi_end()
logging.debug("close 5V, Module enters 0 power consumption ...")
self.GPIO.output(self.RST_PIN, 0)
self.GPIO.output(self.DC_PIN, 0)
self.GPIO.cleanup()
if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'):
implementation = RaspberryPi()
else:
implementation = JetsonNano()
for func in [x for x in dir(implementation) if not x.startswith('_')]:
setattr(sys.modules[__name__], func, getattr(implementation, func))
def module_init():
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(RST_PIN, GPIO.OUT)
GPIO.setup(DC_PIN, GPIO.OUT)
GPIO.setup(CS_PIN, GPIO.OUT)
GPIO.setup(BUSY_PIN, GPIO.IN)
SPI.max_speed_hz = 2000000
SPI.mode = 0b00
return 0;
### END OF FILE ### ### END OF FILE ###

View File

@ -0,0 +1 @@
version = '1.0.0antani'

View File

@ -17,129 +17,108 @@ class Voice:
def default(self): def default(self):
return self._('ZzzzZZzzzzZzzz') return self._('ZzzzZZzzzzZzzz')
def on_starting(self): def on_starting(self):
return random.choice([ \ return random.choice([
self._('Hi, I\'m Pwnagotchi!\nStarting ...'), self._('Hi, I\'m Pwnagotchi! Starting ...'),
self._('New day, new hunt,\nnew pwns!'), self._('New day, new hunt, new pwns!'),
self._('Hack the Planet!')]) self._('Hack the Planet!')])
def on_ai_ready(self): def on_ai_ready(self):
return random.choice([ return random.choice([
self._('AI ready.'), self._('AI ready.'),
self._('The neural network\nis ready.')]) self._('The neural network is ready.')])
def on_normal(self): def on_normal(self):
return random.choice([ \ return random.choice([
'', '',
'...']) '...'])
def on_free_channel(self, channel): def on_free_channel(self, channel):
return self._('Hey, channel {channel} is\nfree! Your AP will\nsay thanks.').format(channel=channel) return self._('Hey, channel {channel} is free! Your AP will say thanks.').format(channel=channel)
def on_bored(self): def on_bored(self):
return random.choice([ \ return random.choice([
self._('I\'m bored ...'), self._('I\'m bored ...'),
self._('Let\'s go for a walk!')]) self._('Let\'s go for a walk!')])
def on_motivated(self, reward): def on_motivated(self, reward):
return self._('This is the best\nday of my life!') return self._('This is the best day of my life!')
def on_demotivated(self, reward): def on_demotivated(self, reward):
return self._('Shitty day :/') return self._('Shitty day :/')
def on_sad(self): def on_sad(self):
return random.choice([ \ return random.choice([
self._('I\'m extremely bored ...'), self._('I\'m extremely bored ...'),
self._('I\'m very sad ...'), self._('I\'m very sad ...'),
self._('I\'m sad'), self._('I\'m sad'),
'...']) '...'])
def on_excited(self): def on_excited(self):
return random.choice([ \ return random.choice([
self._('I\'m living the life!'), self._('I\'m living the life!'),
self._('I pwn therefore I am.'), self._('I pwn therefore I am.'),
self._('So many networks!!!'), self._('So many networks!!!'),
self._('I\'m having so much\nfun!'), self._('I\'m having so much fun!'),
self._('My crime is that of\ncuriosity ...')]) self._('My crime is that of curiosity ...')])
def on_new_peer(self, peer): def on_new_peer(self, peer):
return random.choice([ \ return random.choice([
self._('Hello\n{name}!\nNice to meet you. {name}').format(name=peer.name()), self._('Hello {name}! Nice to meet you. {name}').format(name=peer.name()),
self._('Unit\n{name}\nis nearby! {name}').format(name=peer.name())]) self._('Unit {name} is nearby! {name}').format(name=peer.name())])
def on_lost_peer(self, peer): def on_lost_peer(self, peer):
return random.choice([ \ return random.choice([
self._('Uhm ...\ngoodbye\n{name}').format(name=peer.name()), self._('Uhm ... goodbye {name}').format(name=peer.name()),
self._('{name}\nis gone ...').format(name=peer.name())]) self._('{name} is gone ...').format(name=peer.name())])
def on_miss(self, who): def on_miss(self, who):
return random.choice([ \ return random.choice([
self._('Whoops ...\n{name}\nis gone.').format(name=who), self._('Whoops ... {name} is gone.').format(name=who),
self._('{name}\nmissed!').format(name=who), self._('{name} missed!').format(name=who),
self._('Missed!')]) self._('Missed!')])
def on_lonely(self): def on_lonely(self):
return random.choice([ \ return random.choice([
self._('Nobody wants to\nplay with me ...'), self._('Nobody wants to play with me ...'),
self._('I feel so alone ...'), self._('I feel so alone ...'),
self._('Where\'s everybody?!')]) self._('Where\'s everybody?!')])
def on_napping(self, secs): def on_napping(self, secs):
return random.choice([ \ return random.choice([
self._('Napping for {secs}s ...').format(secs=secs), self._('Napping for {secs}s ...').format(secs=secs),
self._('Zzzzz'), self._('Zzzzz'),
self._('ZzzZzzz ({secs}s)').format(secs=secs)]) self._('ZzzZzzz ({secs}s)').format(secs=secs)])
def on_awakening(self): def on_awakening(self):
return random.choice(['...', '!']) return random.choice(['...', '!'])
def on_waiting(self, secs): def on_waiting(self, secs):
return random.choice([ \ return random.choice([
self._('Waiting for {secs}s ...').format(secs=secs), self._('Waiting for {secs}s ...').format(secs=secs),
'...', '...',
self._('Looking around ({secs}s)').format(secs=secs)]) self._('Looking around ({secs}s)').format(secs=secs)])
def on_assoc(self, ap): def on_assoc(self, ap):
ssid, bssid = ap['hostname'], ap['mac'] ssid, bssid = ap['hostname'], ap['mac']
what = ssid if ssid != '' and ssid != '<hidden>' else bssid what = ssid if ssid != '' and ssid != '<hidden>' else bssid
return random.choice([ \ return random.choice([
self._('Hey\n{what}\nlet\'s be friends!').format(what=what), self._('Hey {what} let\'s be friends!').format(what=what),
self._('Associating to\n{what}').format(what=what), self._('Associating to {what}').format(what=what),
self._('Yo\n{what}!').format(what=what)]) self._('Yo {what}!').format(what=what)])
def on_deauth(self,sta):
return random.choice([ \
self._('Just decided that\n{mac}\nneeds no WiFi!').format(mac=sta['mac']),
self._('Deauthenticating\n{mac}').format(mac=sta['mac']),
self._('Kickbanning\n{mac}!').format(mac=sta['mac'])])
def on_deauth(self, sta):
return random.choice([
self._('Just decided that {mac} needs no WiFi!').format(mac=sta['mac']),
self._('Deauthenticating {mac}').format(mac=sta['mac']),
self._('Kickbanning {mac}!').format(mac=sta['mac'])])
def on_handshakes(self, new_shakes): def on_handshakes(self, new_shakes):
s = 's' if new_shakes > 1 else '' s = 's' if new_shakes > 1 else ''
return self._('Cool, we got {num}\nnew handshake{plural}!').format(num=new_shakes, plural=s) return self._('Cool, we got {num} new handshake{plural}!').format(num=new_shakes, plural=s)
def on_rebooting(self): def on_rebooting(self):
return self._("Ops, something\nwent wrong ...\nRebooting ...") return self._("Ops, something went wrong ... Rebooting ...")
def on_log(self, log): def on_log(self, log):
status = self._('Kicked {num} stations\n').format(num=log.deauthed) status = self._('Kicked {num} stations\n').format(num=log.deauthed)
@ -151,10 +130,13 @@ class Voice:
status += self._('Met {num} peers').format(num=log.peers) status += self._('Met {num} peers').format(num=log.peers)
return status return status
def on_log_tweet(self, log): def on_log_tweet(self, log):
return self._('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').format( return self._(
duration=log.duration_human, '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').format(
deauthed=log.deauthed, duration=log.duration_human,
associated=log.associated, deauthed=log.deauthed,
handshakes=log.handshakes) associated=log.associated,
handshakes=log.handshakes)
def custom(self, text):
return self._(text)

View File

@ -10,3 +10,4 @@ file_read_backwards
numpy numpy
inky inky
smbus smbus
pillow

View File

@ -9,5 +9,3 @@ if ifconfig | grep usb0 | grep RUNNING; then
else else
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.auto sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.auto
fi fi