From d9d399429c61e023c367ee60ebf0f847989715a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20S=C3=B6bbing?= Date: Wed, 13 Nov 2019 16:49:02 +0100 Subject: [PATCH 01/20] Improve German translations slightly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hendrik Söbbing --- pwnagotchi/locale/de/LC_MESSAGES/voice.mo | Bin 4547 -> 4928 bytes pwnagotchi/locale/de/LC_MESSAGES/voice.po | 60 +++++++++++++++------- pwnagotchi/locale/voice.pot | 2 +- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/pwnagotchi/locale/de/LC_MESSAGES/voice.mo b/pwnagotchi/locale/de/LC_MESSAGES/voice.mo index 683dca252c8c344d352b7143eb61c867eda6786e..f0885f3437aaaf463bb7426625d40f732547c565 100644 GIT binary patch delta 1916 zcmZ9MUuYaf9LFbVk|yotZ|4Wv5FXDeh2)-1-(ttjQ6pA1SO;Hp?T17!ntJKeTZ}q|9e*2l3oB93U zT^qbOTwU*KIBOUOknKpK-k2=>YXc9);YMRx;1SpZvv3spuos4K2)+w-|1#VRuS1>x z9d^LBCSwNR0PKeu$oZ;yhRK6$EI|ub;THHM?1Dc)DY^+;Vdq9;Zi53c_rPw}$6!0m zL4KyfLxxYn3-DDq3=cQg^p;>R_RUL7q~JBU6@CC^;4`=hUV~EnBb4GlVG`Dp7M&Y{ zihLim@F};YRDd_(cI=yWtXP5nYUk0bxkfM3m315aX zd=643^C498T!1?F4YcqNsIKng(!FpmOvC4(GIS0Stoa10$G(6H^xOFVTU92i`4DxG zq6sL&$Dty89?IiW@&0+J(tHHR;6|yyBY^ zMXgk;jv6}=rSN`4O{5Q$x_>`{&(Tl>DTHAE8{^FO#4Ei8O20CwEUD=YGS9o;7)YyU-RBYgaz%LbbG6=V{tZ$BtCT(_MKC^ngB~u@!5~sSN&6HjAot<_0%1Dq2 z-%C8+l(R0dhr+tnv3@B&GM%?GYaizeBX-Vbj!mynaDFkIY<;~g@D^OzdJ8l55Pz;- zZ5^zutDI@ywK16YmV8$Z$Jy6 z++Xwp8%*bYH-lpZl)EBFY_{T+E6x_(f-W5NgFL4Hmz$@ZUvNe1&)G?`#BCQum(3&- zn>HM|xmGIe)<1I<^WPVPD!%H2bjYrqs$h+{Dj_!wb zaH?bjznDW&u^8nelQdKLQfXd6+2vZ1qgdQ*+B{N*p%&LCLHfv?2)ec^b4*$ K?*&06Y5oDM^c)cY delta 1578 zcmYk+O>9(E7{>8;YH4j@+Myy8k$Q$gaV#AR6`@FgvLQeS5}*y}W}LZY#!P2w??54> znHZIoQIi`hgasjhDmOc;`wLzNBOzdtO0+)=kW=quwjw2=q9;=cD<)!fF?l8&tHj-%%4b&iQZU-AI$|z=gOEm0};4 z9yi9o;bM=tiqigH*$@$WM^_WaFp- zPa$L5H^@x~P`F_wp>+!@pb#<|c z!}aN!;8DYm6So@I)x=zoh<_AZh;OTNInQ^w;O}@>n@gwDwl$k~gOgYDMK@H)=KZqE z6pLP=yP\n" "Language-Team: DE <33197631+dadav@users.noreply.github.com>\n" @@ -20,7 +20,7 @@ msgid "ZzzzZZzzzzZzzz" msgstr "" msgid "Hi, I'm Pwnagotchi! Starting ..." -msgstr "Hi, ich bin ein Pwnagotchi! Starte ..." +msgstr "Hi, ich bin ein Pwnagotchi! Starte..." msgid "New day, new hunt, new pwns!" msgstr "Neuer Tag, neue Jagd, neue Pwns!" @@ -35,23 +35,30 @@ msgid "The neural network is ready." msgstr "Das neurale Netz ist bereit." msgid "Generating keys, do not turn off ..." -msgstr "Generiere Keys, nicht ausschalten ..." +msgstr "Generiere Keys, nicht ausschalten..." #, python-brace-format msgid "Hey, channel {channel} is free! Your AP will say thanks." -msgstr "Hey, Channel {channel} ist frei! Dein AP wir des dir danken." +msgstr "Hey, Channel {channel} ist frei! Dein AP wird es Dir danken." + +msgid "Reading last session logs ..." +msgstr "Lese die Logs der letzten Session..." + +#, python-brace-format +msgid "Read {lines_so_far} log lines so far ..." +msgstr "Bisher {lines_so_far} Zeilen im Log gelesen..." msgid "I'm bored ..." msgstr "Mir ist langweilig..." msgid "Let's go for a walk!" -msgstr "Lass uns laufen gehen!" +msgstr "Lass uns spazieren gehen!" msgid "This is the best day of my life!" -msgstr "Das ist der beste Tag meines Lebens." +msgstr "Das ist der beste Tag meines Lebens!" msgid "Shitty day :/" -msgstr "Scheis Tag :/" +msgstr "Scheißtag :/" msgid "I'm extremely bored ..." msgstr "Mir ist sau langweilig..." @@ -62,6 +69,13 @@ msgstr "Ich bin sehr traurig..." msgid "I'm sad" msgstr "Ich bin traurig" +#, fuzzy +msgid "Leave me alone ..." +msgstr "Lass mich in Ruhe..." + +msgid "I'm mad at you!" +msgstr "Ich bin sauer auf Dich!" + msgid "I'm living the life!" msgstr "Ich lebe das Leben!" @@ -75,27 +89,35 @@ msgid "I'm having so much fun!" msgstr "Ich habe sooo viel Spaß!" msgid "My crime is that of curiosity ..." -msgstr "Mein Verbrechen ist das der Neugier ..." +msgstr "Mein Verbrechen ist das der Neugier..." #, python-brace-format msgid "Hello {name}! Nice to meet you." msgstr "Hallo {name}, nett Dich kennenzulernen." +#, python-brace-format +msgid "Yo {name}! Sup?" +msgstr "Jo {name}! Was geht!?" + +#, python-brace-format +msgid "Hey {name} how are you doing?" +msgstr "Hey {name}, wie geht's?" + #, python-brace-format msgid "Unit {name} is nearby!" -msgstr "Gerät {name} ist in der nähe!!" +msgstr "Gerät {name} ist in der Nähe!" #, python-brace-format msgid "Uhm ... goodbye {name}" -msgstr "Uhm ...tschüß {name}" +msgstr "Uhm... tschüß {name}" #, python-brace-format msgid "{name} is gone ..." -msgstr "{name} ist weg ..." +msgstr "{name} ist weg..." #, python-brace-format msgid "Whoops ... {name} is gone." -msgstr "Whoops ...{name} ist weg." +msgstr "Whoops... {name} ist weg." #, python-brace-format msgid "{name} missed!" @@ -111,17 +133,17 @@ msgid "I love my friends!" msgstr "Ich liebe meine Freunde!" msgid "Nobody wants to play with me ..." -msgstr "Niemand will mit mir spielen ..." +msgstr "Niemand will mit mir spielen..." msgid "I feel so alone ..." -msgstr "Ich fühl michso alleine ..." +msgstr "Ich fühl' mich so allein..." msgid "Where's everybody?!" -msgstr "Wo sind denn alle?" +msgstr "Wo sind denn alle?!" #, python-brace-format msgid "Napping for {secs}s ..." -msgstr "Schlafe für {secs}s" +msgstr "Schlafe für {secs}s..." msgid "Zzzzz" msgstr "" @@ -138,7 +160,7 @@ msgstr "" #, python-brace-format msgid "Waiting for {secs}s ..." -msgstr "Warte für {secs}s ..." +msgstr "Warte für {secs}s..." #, python-brace-format msgid "Looking around ({secs}s)" @@ -158,7 +180,7 @@ msgstr "Jo {what}!" #, python-brace-format msgid "Just decided that {mac} needs no WiFi!" -msgstr "Ich denke, dass {mac} kein WiFi brauch!" +msgstr "Ich denke, dass {mac} kein WiFi braucht!" #, python-brace-format msgid "Deauthenticating {mac}" @@ -177,7 +199,7 @@ msgid "You have {count} new message{plural}!" msgstr "Cool, wir haben {num} neue Handshake{plural}!" msgid "Ops, something went wrong ... Rebooting ..." -msgstr "Ops, da ist etwas schief gelaufen ...Starte neu ..." +msgstr "Ops, da ist was schief gelaufen... Starte neu..." #, python-brace-format msgid "Kicked {num} stations\n" diff --git a/pwnagotchi/locale/voice.pot b/pwnagotchi/locale/voice.pot index c72d1316..93f75b9b 100644 --- a/pwnagotchi/locale/voice.pot +++ b/pwnagotchi/locale/voice.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-11-04 12:57+0100\n" +"POT-Creation-Date: 2019-11-18 18:29+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From 3351c251ef84630a3781f49fb9240156ed212c3c Mon Sep 17 00:00:00 2001 From: xenDE Date: Tue, 19 Nov 2019 00:56:59 +0100 Subject: [PATCH 02/20] fix gps timestamp parsing problem on timestamp parsing if microseconds are more then 6 numbers. will fix bug reported in this pr: https://github.com/evilsocket/pwnagotchi/pull/619 tested with testdata from https://github.com/xenDE/pwnagotchi-plugin-webgpsmap/tree/master/handshakes.gps-map-test before: [2019-11-19 00:37:51,946] [INFO] webgpsmap: scanning /root/handshakes.gps-map-test [2019-11-19 00:37:52,022] [INFO] webgpsmap: Found 4 .(geo|gps).json files from 5 handshakes. Fetching positions ... [2019-11-19 00:37:52,144] [ERROR] Lng is 0 [2019-11-19 00:37:52,241] [ERROR] Invalid isoformat string: '2019-11-14T12:30:41.097414739+01:00' [2019-11-19 00:37:52,280] [ERROR] Lng is 0 [2019-11-19 00:37:52,329] [INFO] webgpsmap loaded 2 positions after: [2019-11-19 00:48:04,652] [INFO] webgpsmap: scanning /root/handshakes.gps-map-test [2019-11-19 00:48:04,693] [INFO] webgpsmap: Found 5 .(geo|gps).json files from 6 handshakes. Fetching positions ... [2019-11-19 00:48:04,760] [ERROR] Lng is 0 [2019-11-19 00:48:04,822] [ERROR] Lng is 0 [2019-11-19 00:48:04,850] [INFO] webgpsmap loaded 3 positions --- pwnagotchi/plugins/default/webgpsmap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pwnagotchi/plugins/default/webgpsmap.py b/pwnagotchi/plugins/default/webgpsmap.py index fc8cedc9..cb1a2ad5 100644 --- a/pwnagotchi/plugins/default/webgpsmap.py +++ b/pwnagotchi/plugins/default/webgpsmap.py @@ -293,9 +293,9 @@ class PositionFile: elif 'Updated' in self._json: # convert gps datetime to unix timestamp: "2019-10-05T23:12:40.422996+01:00" date_iso_formated = self._json['Updated'] - # fill milliseconds to 6 numbers + # fill/cut microseconds to 6 numbers part1, part2, part3 = re.split('\.|\+', date_iso_formated) - part2 = part2.ljust(6, '0') + part2 = part2.ljust(6, '0')[:6] date_iso_formated = part1 + "." + part2 + "+" + part3 dateObj = datetime.datetime.fromisoformat(date_iso_formated) return_ts = int("%.0f" % dateObj.timestamp()) From cfc0ad1b486bb501ba835694f6653bb0efddec80 Mon Sep 17 00:00:00 2001 From: daniel156161 Date: Tue, 19 Nov 2019 05:03:21 +0100 Subject: [PATCH 03/20] fix backup.sh (find with type f for no zero byte files into archive) --- scripts/backup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/backup.sh b/scripts/backup.sh index 526d5bbd..6b91917f 100755 --- a/scripts/backup.sh +++ b/scripts/backup.sh @@ -54,4 +54,4 @@ ping -c 1 "${UNIT_HOSTNAME}" > /dev/null 2>&1 || { } echo "@ backing up $UNIT_HOSTNAME to $OUTPUT ..." -ssh "${UNIT_USERNAME}@${UNIT_HOSTNAME}" "sudo find ${FILES_TO_BACKUP} -print0 | xargs -0 sudo tar cv" | gzip -9 > "$OUTPUT" +ssh "${UNIT_USERNAME}@${UNIT_HOSTNAME}" "sudo find ${FILES_TO_BACKUP} -type f -print0 | xargs -0 sudo tar cv" | gzip -9 > "$OUTPUT" From 0ee0aaff37b890393ae0de31554502109f005f32 Mon Sep 17 00:00:00 2001 From: Arttumiro Date: Tue, 19 Nov 2019 15:38:11 +0200 Subject: [PATCH 04/20] Update to using .paw-gps.json files Remove old link due to it not being too good, update file extension to .paw-gps.json for better support on problems with webgpsmap. --- pwnagotchi/plugins/default/paw-gps.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pwnagotchi/plugins/default/paw-gps.py b/pwnagotchi/plugins/default/paw-gps.py index 0b477d7d..e92805b2 100644 --- a/pwnagotchi/plugins/default/paw-gps.py +++ b/pwnagotchi/plugins/default/paw-gps.py @@ -4,10 +4,7 @@ import pwnagotchi.plugins as plugins ''' You need an bluetooth connection to your android phone which is running PAW server with the GPS "hack" from Systemik and edited by shaynemk -NEW BETTER GUIDE HERE: https://community.pwnagotchi.ai/t/setting-up-paw-gps-on-android - -Old guide here, (not recommended if you plan on using it with the webgpsmap plugin) -https://raw.githubusercontent.com/systemik/pwnagotchi-bt-tether/master/GPS-via-PAW +GUIDE HERE: https://community.pwnagotchi.ai/t/setting-up-paw-gps-on-android ''' @@ -30,7 +27,7 @@ class PawGPS(plugins.Plugin): ip = self.options['ip'] gps = requests.get('http://' + ip + '/gps.xhtml') - gps_filename = filename.replace('.pcap', '.gps.json') + gps_filename = filename.replace('.pcap', '.paw-gps.json') logging.info("saving GPS to %s (%s)" % (gps_filename, gps)) with open(gps_filename, 'w+t') as f: From d045ed5afa91a9cdd1076619b95e4f444fdada73 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 Nov 2019 22:58:49 +0000 Subject: [PATCH 05/20] Added romanian language --- pwnagotchi/locale/ro/LC_MESSAGES/voice.mo | Bin 0 -> 5184 bytes pwnagotchi/locale/ro/LC_MESSAGES/voice.po | 249 ++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 pwnagotchi/locale/ro/LC_MESSAGES/voice.mo create mode 100644 pwnagotchi/locale/ro/LC_MESSAGES/voice.po diff --git a/pwnagotchi/locale/ro/LC_MESSAGES/voice.mo b/pwnagotchi/locale/ro/LC_MESSAGES/voice.mo new file mode 100644 index 0000000000000000000000000000000000000000..09bb9c44e2023dbcdb906c6956a8ea4538dbe6d1 GIT binary patch literal 5184 zcmbW3TWn=j8ON81C`C|EQ510<2ONg!In&N?nJEJ^Wd@kybf#%LTzrtMv(Gv`Yr6Md z$9-u%ZTeJA)CWk21Sex65)w>ENQ{^eV=$(T_Q7bP^57-P3%>Y-FUG`xzi;h*+RlhC z?woc0d#}CrTHodWUH)>zmCq`!2N*XqMz2un3GnEZ{Bb@10i~`6zYl%_d>Pya{v5m! z{5yCnc*RxK_j|!>cs>cr`Wf(}U>E!xxD0+4d=8ZJeheN4e+z2xnhz@VF>n;T0Xz=M zK6Bu;paVY%F4y=p_;H?J0zU%&6y&FV#h;w}d+;aVTi_SK=RZ{K`%6&d|6~39HYodC ziL##pZvy316`uWBB`DIY-|0D1^@E71i?^EgxP~^XvKk>^Q;2q#`@Fs8({5<$| zP~`am$WQ&6Ke5-JLD}~mQ2cQ{n~Q#jK@HA;$H1?Evi^tQE#U7!vCBU|(f?|c7yWJp zKLg$k%K5XP_&o+?{Te9t`8Fv2{T}!x_$s&$e3r%X-OoVb=N~{>_pchS;}F?@4=8dR z1Lggf>*pL4J3a$S99#h9+}ARM3vaU;kQbqgr|JP1OE;Hx9xhZ#-AA;#`2aDxdsd-o-_5}w?{5W9;l z?FF#CAO05t_p%p#<|xF$uq(ovCG|z;U)f( z7!|u5Wr!cdS7Jx8om^u3`xxR&vA@`Sk|Dl=lIng2p%E@pXvn9+Z_K3jGQ^gnjLR?a zpWXeORR7g!?*Bbhai>#=WSX=0UFI&7H)NggqFNYJEM>GyRR=o}C>(~~1bKSN>;biN< zsE#;2wXt5UZ`QQSSz>KNKjF(vPtNFN7som`1LQL4V$PXvR8Q?q^vrT{A;IGo@p{WOXvw5nxL9ms8O;vt5s=rnE`;n4Q}^cB;>KvR^GS zo7i}8*?i9|iHkWVDWjh5mT4n=9lJ0uW{h3eR+EY8XcLT9J?Ewq7BAUsfOf;v5V37- zDw4_G$fZ|1@S<=&UDI$yFS=+E;Z{2pOFC;hig9<5H!upHn^*+GKdYwZp=FIwZJQSC zVhXEQcRatg!$bDj!|AnU!+q=*DnuK-rw2#StsfYo_vDKMn4%sj^FnuQ0Tc2OYNqt=4`-O=FvJ-M2Oix77-H%+<8ZbK7aC>4AFHWyG)Df4uj?mb;h@SXMo&zOTq{f z^5lx1s42uf+b67ZkN0}A`7&lsvAe9(gJJz z^EN7)Q=R6c@DImK=&{yVYkXwZ_I*|~r}G8ZX+BUcPzIHt$OCdLo%zw5}IBd2k7b3QX^9-G2v6Z%}bP~x$))U&2jHYd|gW}QBo z@z5%V?~WIiTxwg9Pwr<6rm;zL-kM}W^3gCO96fYs{K!3b9~$4^F&(pXyvz~3m69_1 z@u0N;oy+#6drauek4#TZKe(gicx!Crgii|?-kcxwQKTTv9v~uIdaqQ4EVspdWzlUO z-dQIKb#2ysFpa!WdO{y=yJCdW+bm;EWi^Fqsp-viZKML*6@qqHez(4ppqk2BQi8iKB3D$oO3iVGRAFmYIE3w}MA&rWl@!Butc36k zwU-Z_)9o^KI)`K0>o!3dl}j5hq|_-Y!WnP+WMGzTuG26ix=*?Z5%FGPji?z%3E)&C zIfLLd4fTM0TQk3*Md@})j?y`IY#o)U&!b_1E+x*W-HCDJg~(k}ntM#jS6vt62;vXR zvq?>iZFkBuF)n4TZLw$Uh^@mmdD-7w#|=UUk`!JH z(?!M})os_)gz!>k(>-^AA!em|VOh%`XytLe3&iwzc=tErbL9Qcg8JBKY^UJ2g z3btK3Ti5-KryLrVp?jhJ?<^Mb4^?NA?YN{7KyODMVBlsm;hm!`GEs=KQ#EBttN1i& zZ>}d)ZPt_o(Z(xDKeOkFg`H-AQ))ld^}Z%luoD?%w?RwJk?!D<$!)>pmE;OFOSXY5 zCx~2lZ;cM20qccnp<7sStO)X+^ck^LyS}PxLXfi@UmCqa8j)U}+a&_7fJTlYoecodZ$#K-7aLn1zKtz^6%$ug-NJ7RCHtG;h;sYE*AHmdq zQ8A+8LXOKC2`3qh92;7SK0;{|m5Inq4&)Pw4tfX?F1BGIorNo5CrxT$X_a7drQ!-| zWS)v-q{EmjHeQfMQ8ERwlG&|`HYS#4<;GwEX*E1q2WJL@R!MzQJ`c|kM@SkYcZ%i0 z*;Sm16B>$!L$sYCj&@oNNuKp{wTlsv`kXttb)m3*3F;~?cbs!B?O5TlH)J>n%kFd? zXX!a)|GJXnY?n)3D9Jy&+Kv-RcURk?CJBwY-=Nnp=WnC)q6=(&ylf&rvCxOiHHIK literal 0 HcmV?d00001 diff --git a/pwnagotchi/locale/ro/LC_MESSAGES/voice.po b/pwnagotchi/locale/ro/LC_MESSAGES/voice.po new file mode 100644 index 00000000..8f770d4d --- /dev/null +++ b/pwnagotchi/locale/ro/LC_MESSAGES/voice.po @@ -0,0 +1,249 @@ +# Pwnagotchi translation. +# Copyright (C) 2019 +# This file is distributed under the same license as the pwnagotchi package. +# FIRST AUTHOR , 2019. +# +#, +msgid "" +msgstr "" +"Project-Id-Version: 0.0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-11-04 12:57+0100\n" +"PO-Revision-Date: 2019-11-20 00:18+594\n" +"Last-Translator: Ungureanu Radu-Andrei \n" +"Language-Team: pwnagotchi <33197631+dadav@users.noreply.github." +"com>\n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "ZzzzZZzzzzZzzz" +msgstr "" + +msgid "Hi, I'm Pwnagotchi! Starting ..." +msgstr "Buna, sunt Pwnagotchi! Pornesc..." + +msgid "New day, new hunt, new pwns!" +msgstr "O noua zi, o noua vanatoare, noi pwn-uri!" + +msgid "Hack the Planet!" +msgstr "Pirateaza planeta!" + +msgid "AI ready." +msgstr "AI-ul e gata." + +msgid "The neural network is ready." +msgstr "Rețeaua neuronală este gata." + +msgid "Generating keys, do not turn off ..." +msgstr "Se generează chei, nu închide..." + +#, python-brace-format +msgid "Hey, channel {channel} is free! Your AP will say thanks." +msgstr "Hey, canalul {channel} este liber! AP-ul tău îti va mulțumi." + +msgid "Reading last session logs ..." +msgstr "Se citesc log-urile din sesiunea anterioara..." + +#, python-brace-format +msgid "Read {lines_so_far} log lines so far ..." +msgstr "Am citit {lines_so_far} linii din log pana acum..." + +msgid "I'm bored ..." +msgstr "Sunt plictisit..." + +msgid "Let's go for a walk!" +msgstr "Hai să ne plimbăm!" + +msgid "This is the best day of my life!" +msgstr "Asta este cea mai buna zi din viața mea!" + +msgid "Shitty day :/" +msgstr "O zi proasta :/" + +msgid "I'm extremely bored ..." +msgstr "Sunt extrem de plictisit..." + +msgid "I'm very sad ..." +msgstr "Sunt foarte trist..." + +msgid "I'm sad" +msgstr "Sunt trist" + +msgid "Leave me alone ..." +msgstr "Lasă-mă in pace..." + +msgid "I'm mad at you!" +msgstr "Sunt supărat pe tine!" + +msgid "I'm living the life!" +msgstr "Trăiesc viața!" + +msgid "I pwn therefore I am." +msgstr "Eu pwn-ez, deci aici sunt." + +msgid "So many networks!!!" +msgstr "Atât de multe rețele!" + +msgid "I'm having so much fun!" +msgstr "Mă distrez așa de mult!" + +msgid "My crime is that of curiosity ..." +msgstr "Crima mea este una de curiozitate..." + +#, python-brace-format +msgid "Hello {name}! Nice to meet you." +msgstr "Bună {name}! Mă bucur să te cunosc." + +#, python-brace-format +msgid "Yo {name}! Sup?" +msgstr "Yo {name}! Cmf?" + +#, python-brace-format +msgid "Hey {name} how are you doing?" +msgstr "Hey {nume} ce mai faci?" + +#, python-brace-format +msgid "Unit {name} is nearby!" +msgstr "Unitatea {name} este aproape!" + +#, python-brace-format +msgid "Uhm ... goodbye {name}" +msgstr "Uhm... Pa {name}" + +#, python-brace-format +msgid "{name} is gone ..." +msgstr "{name} a dispărut." + +#, python-brace-format +msgid "Whoops ... {name} is gone." +msgstr "Oops... {name} a dispărut." + +#, python-brace-format +msgid "{name} missed!" +msgstr "{name} ratat!" + +msgid "Missed!" +msgstr "Ratat!" + +msgid "Good friends are a blessing!" +msgstr "Prietenii buni sunt o binecuvântare!" + +msgid "I love my friends!" +msgstr "Îmi iubesc prietenii!" + +msgid "Nobody wants to play with me ..." +msgstr "Nimeni nu vrea sa se joace cu mine..." + +msgid "I feel so alone ..." +msgstr "Mă simt așa de singuratic..." + +msgid "Where's everybody?!" +msgstr "Unde-i toată lumea?!" + +#, python-brace-format +msgid "Napping for {secs}s ..." +msgstr "Dorm pentru {secs}s..." + +msgid "Zzzzz" +msgstr "Zzzzz" + +#, python-brace-format +msgid "ZzzZzzz ({secs}s)" +msgstr "ZzzZzzz ({secs}s)" + +msgid "Good night." +msgstr "Noapte bună." + +msgid "Zzz" +msgstr "Zzz" + +#, python-brace-format +msgid "Waiting for {secs}s ..." +msgstr "Aștept pentru {secs}s..." + +#, python-brace-format +msgid "Looking around ({secs}s)" +msgstr "Mă uit împrejur ({secs}s)" + +#, python-brace-format +msgid "Hey {what} let's be friends!" +msgstr "Hey {what} hai să fim prieteni!" + +#, python-brace-format +msgid "Associating to {what}" +msgstr "Mă asociez cu {what}" + +#, python-brace-format +msgid "Yo {what}!" +msgstr "Yo {what}" + +#, python-brace-format +msgid "Just decided that {mac} needs no WiFi!" +msgstr "Am decis că lui {mac} nu-i trebuie WiFi!" + +#, python-brace-format +msgid "Deauthenticating {mac}" +msgstr "Îl deautentific pe {mac}" + +#, python-brace-format +msgid "Kickbanning {mac}!" +msgstr "Îi dau kickban lui {mac}" + +#, python-brace-format +msgid "Cool, we got {num} new handshake{plural}!" +msgstr "Șmecher, avem {num} de handshake-uri noi!" + +#, python-brace-format +msgid "You have {count} new message{plural}!" +msgstr "Ai {count} mesaj(e) nou/noi!" + +msgid "Ops, something went wrong ... Rebooting ..." +msgstr "OOps, ceva s-a întamplat... Îmi dau reboot...+" + +#, python-brace-format +msgid "Kicked {num} stations\n" +msgstr "Am dat afară {num} de stații\n" + +#, python-brace-format +msgid "Made {num} new friends\n" +msgstr "Am făcut {num} prieteni noi \n" + +#, python-brace-format +msgid "Got {num} handshakes\n" +msgstr "Am primit {num} de handshake-uri\n" + +msgid "Met 1 peer" +msgstr "Am întalnit un peer" + +#, python-brace-format +msgid "Met {num} peers" +msgstr "Am întalnit {num} de peer-uri" + +#, python-brace-format +msgid "" +"I've been pwning for {duration} and kicked {deauthed} clients! I've also met " +"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi " +"#pwnlog #pwnlife #hacktheplanet #skynet" +msgstr "Eu am făcut pwning pentru {duration} și am dat afara {deauthed} clienți! " +"De asemenea, am întalnit {associated} prieteni noi și am mancat {handshakes} de " +"handshake-uri! #pwnagotchi #pwnlog #pwnlife #hacktheplanet #skynet" + +msgid "hours" +msgstr "ore" + +msgid "minutes" +msgstr "minute" + +msgid "seconds" +msgstr "secunde" + +msgid "hour" +msgstr "oră" + +msgid "minute" +msgstr "minut" + +msgid "second" +msgstr "secundă" From c4a007e72aa2760a618d1bfb8784eb59ccae8ba1 Mon Sep 17 00:00:00 2001 From: xenDE Date: Wed, 20 Nov 2019 15:45:16 +0100 Subject: [PATCH 06/20] cleanup, fixes and add handling of .paw-gps.json cleanup logging, increase cache item count from 1024 to 2048, add handling of corrupt long/lat position null, added handling of .paw-gps.json files - tested with master --- pwnagotchi/plugins/default/webgpsmap.py | 162 +++++++++++++++--------- 1 file changed, 99 insertions(+), 63 deletions(-) diff --git a/pwnagotchi/plugins/default/webgpsmap.py b/pwnagotchi/plugins/default/webgpsmap.py index cb1a2ad5..85479f9b 100644 --- a/pwnagotchi/plugins/default/webgpsmap.py +++ b/pwnagotchi/plugins/default/webgpsmap.py @@ -9,7 +9,7 @@ from functools import lru_cache ''' 2do: - - make the cache handling multiple clients + - make+test the cache handling multiple clients - cleanup the javascript in a class and handle "/newest" additions - create map filters (only cracked APs, only last xx days, between 2 days with slider) http://www.gistechsolutions.com/leaflet/DEMO/filter/filter.html @@ -22,16 +22,10 @@ from functools import lru_cache class Webgpsmap(plugins.Plugin): __author__ = 'https://github.com/xenDE and https://github.com/dadav' - __version__ = '1.2.2' + __version__ = '1.3.0' __name__ = 'webgpsmap' __license__ = 'GPL3' __description__ = 'a plugin for pwnagotchi that shows a openstreetmap with positions of ap-handshakes in your webbrowser' - __help__ = """ -- install: copy "webgpsmap.py" and "webgpsmap.html" to your configured "custom_plugins" directory -- add webgpsmap.yml to your config -- connect your PC/Smartphone/* with USB, BT or other to your pwnagotchi and browse to http://pwnagotchi.local:8080/plugins/webgpsmap/ - (change pwnagotchi.local to your pwnagotchis IP, if needed) -""" ALREADY_SENT = list() SKIP = list() @@ -47,7 +41,7 @@ class Webgpsmap(plugins.Plugin): """ Plugin got loaded """ - logging.info("webgpsmap plugin loaded") + logging.info("[webgpsmap]: plugin loaded") def on_webhook(self, path, request): """ @@ -68,8 +62,8 @@ class Webgpsmap(plugins.Plugin): response_status = 500 response_mimetype = "application/xhtml+xml" response_header_contenttype = 'text/html' - except Exception as ex: - logging.error(ex) + except Exception as error: + logging.error(f"[webgpsmap] error: {error}") return else: if request.method == "GET": @@ -78,8 +72,8 @@ class Webgpsmap(plugins.Plugin): self.ALREADY_SENT = list() try: response_data = bytes(self.get_html(), "utf-8") - except Exception as ex: - logging.error(ex) + except Exception as error: + logging.error(f"[webgpsmap] error: {error}") return response_status = 200 response_mimetype = "application/xhtml+xml" @@ -92,8 +86,8 @@ class Webgpsmap(plugins.Plugin): response_status = 200 response_mimetype = "application/json" response_header_contenttype = 'application/json' - except Exception as ex: - logging.error(ex) + except Exception as error: + logging.error(f"[webgpsmap] error: {error}") return # elif path.startswith('/newest'): # # returns all positions newer then timestamp @@ -118,7 +112,7 @@ class Webgpsmap(plugins.Plugin): - 4😋4 + 4😋4 for bad boys ''', "utf-8") response_status = 404 try: @@ -126,12 +120,12 @@ class Webgpsmap(plugins.Plugin): if response_header_contenttype is not None: r.headers["Content-Type"] = response_header_contenttype return r - except Exception as ex: - logging.error(ex) + except Exception as error: + logging.error(f"[webgpsmap] error: {error}") return - # cache 1024 items - @lru_cache(maxsize=1024, typed=False) + # cache 2048 items + @lru_cache(maxsize=2048, typed=False) def _get_pos_from_file(self, path): return PositionFile(path) @@ -144,7 +138,7 @@ class Webgpsmap(plugins.Plugin): handshake_dir = gpsdir gps_data = dict() - logging.info("webgpsmap: scanning %s", handshake_dir) + logging.info(f"[webgpsmap] scanning {handshake_dir}") all_files = os.listdir(handshake_dir) @@ -156,33 +150,40 @@ class Webgpsmap(plugins.Plugin): all_geo_or_gps_files = [] for filename_pcap in all_pcap_files: filename_base = filename_pcap[:-5] # remove ".pcap" - logging.debug("webgpsmap: found: " + filename_base) + logging.debug(f"[webgpsmap] found: {filename_base}") filename_position = None + logging.debug("[webgpsmap] search for .gps.json") check_for = os.path.basename(filename_base) + ".gps.json" if check_for in all_files: filename_position = str(os.path.join(handshake_dir, check_for)) + logging.debug("[webgpsmap] search for .geo.json") check_for = os.path.basename(filename_base) + ".geo.json" if check_for in all_files: filename_position = str(os.path.join(handshake_dir, check_for)) + logging.debug("[webgpsmap] search for .paw-gps.json") + check_for = os.path.basename(filename_base) + ".paw-gps.json" + if check_for in all_files: + filename_position = str(os.path.join(handshake_dir, check_for)) + + logging.debug(f"[webgpsmap] end search for position data files and use {filename_position}") + if filename_position is not None: - # logging.debug("webgpsmap: -- found: %s %d" % (check_for, len(all_geo_or_gps_files)) ) all_geo_or_gps_files.append(filename_position) - # all_geo_or_gps_files = set(all_geo_or_gps_files) - set(SKIP) # remove skiped networks? No! + # all_geo_or_gps_files = set(all_geo_or_gps_files) - set(SKIP) # remove skipped networks? No! if newest_only: all_geo_or_gps_files = set(all_geo_or_gps_files) - set(self.ALREADY_SENT) - logging.info("webgpsmap: Found %d .(geo|gps).json files from %d handshakes. Fetching positions ...", - len(all_geo_or_gps_files), len(all_pcap_files)) + logging.info(f"[webgpsmap] Found {len(all_geo_or_gps_files)} position-data files from {len(all_pcap_files)} handshakes. Fetching positions ...") for pos_file in all_geo_or_gps_files: try: pos = self._get_pos_from_file(pos_file) - if not pos.type() == PositionFile.GPS and not pos.type() == PositionFile.GEO: + if not pos.type() == PositionFile.GPS and not pos.type() == PositionFile.GEO and not pos.type() == PositionFile.PAWGPS: continue ssid, mac = pos.ssid(), pos.mac() @@ -190,10 +191,17 @@ class Webgpsmap(plugins.Plugin): # invalid mac is strange and should abort; ssid is ok if not mac: raise ValueError("Mac can't be parsed from filename") + pos_type = 'unknown' + if pos.type() == PositionFile.GPS: + pos_type = 'gps' + elif pos.type() == PositionFile.GEO: + pos_type = 'geo' + elif pos.type() == PositionFile.PAWGPS: + pos_type = 'paw' gps_data[ssid+"_"+mac] = { 'ssid': ssid, 'mac': mac, - 'type': 'gps' if pos.type() == PositionFile.GPS else 'geo', + 'type': pos_type, 'lng': pos.lng(), 'lat': pos.lat(), 'acc': pos.accuracy(), @@ -201,24 +209,25 @@ class Webgpsmap(plugins.Plugin): 'ts_last': pos.timestamp_last(), } + # get ap password if exist check_for = os.path.basename(pos_file[:-9]) + ".pcap.cracked" if check_for in all_files: gps_data[ssid + "_" + mac]["pass"] = pos.password() self.ALREADY_SENT += pos_file - except json.JSONDecodeError as js_e: + except json.JSONDecodeError as error: self.SKIP += pos_file - logging.error(js_e) + logging.error(f"[webgpsmap] JSONDecodeError in: {error}") continue - except ValueError as v_e: + except ValueError as error: self.SKIP += pos_file - logging.error(v_e) + logging.error(f"[webgpsmap] ValueError: {error}") continue - except OSError as os_e: + except OSError as error: self.SKIP += pos_file - logging.error(os_e) + logging.error(f"[webgpsmap] OSError: {error}") continue - logging.info("webgpsmap loaded %d positions", len(gps_data)) + logging.info(f"[webgpsmap] loaded {len(gps_data)} positions") return gps_data def get_html(self): @@ -226,11 +235,10 @@ class Webgpsmap(plugins.Plugin): Returns the html page """ try: - template_file = os.path.dirname(os.path.realpath(__file__))+"/"+"webgpsmap.html" + template_file = os.path.dirname(os.path.realpath(__file__)) + "/" + "webgpsmap.html" html_data = open(template_file, "r").read() - except Exception as ex: - logging.error("error loading template file: %s", template_file) - logging.error(ex) + except Exception as error: + logging.error(f"[webgpsmap] error loading template file {template_file} - error: {error}") return html_data @@ -238,15 +246,18 @@ class PositionFile: """ Wraps gps / net-pos files """ - GPS = 0 - GEO = 1 + GPS = 1 + GEO = 2 + PAWGPS = 3 def __init__(self, path): self._file = path self._filename = os.path.basename(path) try: + logging.debug(f"[webgpsmap] loading {path}") with open(path, 'r') as json_file: self._json = json.load(json_file) + logging.debug(f"[webgpsmap] loaded {path}") except json.JSONDecodeError as js_e: raise js_e @@ -254,7 +265,7 @@ class PositionFile: """ Returns the mac from filename """ - parsed_mac = re.search(r'.*_?([a-zA-Z0-9]{12})\.(?:gps|geo)\.json', self._filename) + parsed_mac = re.search(r'.*_?([a-zA-Z0-9]{12})\.(?:gps|geo|paw-gps)\.json', self._filename) if parsed_mac: mac = parsed_mac.groups()[0] return mac @@ -264,7 +275,7 @@ class PositionFile: """ Returns the ssid from filename """ - parsed_ssid = re.search(r'(.+)_[a-zA-Z0-9]{12}\.(?:gps|geo)\.json', self._filename) + parsed_ssid = re.search(r'(.+)_[a-zA-Z0-9]{12}\.(?:gps|geo|paw-gps)\.json', self._filename) if parsed_ssid: return parsed_ssid.groups()[0] return None @@ -293,32 +304,37 @@ class PositionFile: elif 'Updated' in self._json: # convert gps datetime to unix timestamp: "2019-10-05T23:12:40.422996+01:00" date_iso_formated = self._json['Updated'] - # fill/cut microseconds to 6 numbers + # bad microseconds fix: fill/cut microseconds to 6 numbers part1, part2, part3 = re.split('\.|\+', date_iso_formated) part2 = part2.ljust(6, '0')[:6] + # timezone fix: 0200 >>> 02:00 + if len(part3) == 4: + part3 = part3[1:2].rjust(2, '0') + ':' + part3[3:4].rjust(2, '0') date_iso_formated = part1 + "." + part2 + "+" + part3 dateObj = datetime.datetime.fromisoformat(date_iso_formated) return_ts = int("%.0f" % dateObj.timestamp()) else: - # use file timestamp last modification of the pcap file + # use file timestamp last modification of the json file return_ts = int("%.0f" % os.path.getmtime(self._file)) return return_ts def password(self): """ - returns the password from file.pcap.cracked od None + returns the password from file.pcap.cracked or None """ return_pass = None - password_file_path = self._file[:-9] + ".pcap.cracked" + # 2do: make better filename split/remove extension because this one has problems with "." in path + base_filename, ext1, ext2 = re.split('\.', self._file) + password_file_path = base_filename + ".pcap.cracked" if os.path.isfile(password_file_path): try: password_file = open(password_file_path, 'r') return_pass = password_file.read() password_file.close() - except OSError as err: - print("OS error: {0}".format(err)) + except OSError as error: + logging.error(f"[webgpsmap] OS error: {format(error)}") except: - print("Unexpected error:", sys.exc_info()[0]) + logging.error(f"[webgpsmap] Unexpected error: {sys.exc_info()[0]}") raise return return_pass @@ -330,37 +346,57 @@ class PositionFile: return PositionFile.GPS if self._file.endswith('.geo.json'): return PositionFile.GEO + if self._file.endswith('.paw-gps.json'): + return PositionFile.PAWGPS return None def lat(self): try: - if self.type() == PositionFile.GPS: + lat = None + # try to get value from known formats + if 'Latitude' in self._json: lat = self._json['Latitude'] - if self.type() == PositionFile.GEO: - lat = self._json['location']['lat'] - if lat != 0: - return lat - raise ValueError("Lat is 0") + if 'lat' in self._json: + lat = self._json['lat'] # an old paw-gps format: {"long": 14.693561, "lat": 40.806375} + if 'location' in self._json: + if 'lat' in self._json['location']: + lat = self._json['location']['lat'] + # check value + if lat is None: + raise ValueError(f"Lat is None in {self._filename}") + if lat == 0: + raise ValueError(f"Lat is 0 in {self._filename}") + return lat except KeyError: pass return None def lng(self): try: - if self.type() == PositionFile.GPS: + lng = None + # try to get value from known formats + if 'Longitude' in self._json: lng = self._json['Longitude'] - if self.type() == PositionFile.GEO: - lng = self._json['location']['lng'] - if lng != 0: - return lng - raise ValueError("Lng is 0") + if 'long' in self._json: + lng = self._json['long'] # an old paw-gps format: {"long": 14.693561, "lat": 40.806375} + if 'location' in self._json: + if 'lng' in self._json['location']: + lng = self._json['location']['lng'] + # check value + if lng is None: + raise ValueError(f"Lng is None in {self._filename}") + if lng == 0: + raise ValueError(f"Lng is 0 in {self._filename}") + return lng except KeyError: pass return None def accuracy(self): if self.type() == PositionFile.GPS: - return 50.0 + return 50.0 # a default + if self.type() == PositionFile.PAWGPS: + return 50.0 # a default if self.type() == PositionFile.GEO: try: return self._json['accuracy'] From 83f741bbb0713bbb541dc4390bd08c9b5069d772 Mon Sep 17 00:00:00 2001 From: xenDE Date: Sat, 23 Nov 2019 02:05:01 +0100 Subject: [PATCH 07/20] fix: gpio needs to be a number fixes gpio id as string in config https://github.com/evilsocket/pwnagotchi/issues/643 --- pwnagotchi/plugins/default/gpio_buttons.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pwnagotchi/plugins/default/gpio_buttons.py b/pwnagotchi/plugins/default/gpio_buttons.py index 10075efe..cec7cf79 100644 --- a/pwnagotchi/plugins/default/gpio_buttons.py +++ b/pwnagotchi/plugins/default/gpio_buttons.py @@ -32,6 +32,7 @@ class GPIOButtons(plugins.Plugin): GPIO.setmode(GPIO.BCM) for gpio, command in gpios.items(): + gpio = int(gpio) self.ports[gpio] = command GPIO.setup(gpio, GPIO.IN, GPIO.PUD_UP) GPIO.add_event_detect(gpio, GPIO.FALLING, callback=self.runCommand, bouncetime=600) From 93e06d7f59285f60b9fa2d4e63237efc83ea40c0 Mon Sep 17 00:00:00 2001 From: xenDE Date: Sun, 24 Nov 2019 18:49:32 +0100 Subject: [PATCH 08/20] add filter for: SSID, MAC, isCracked, Password --- pwnagotchi/plugins/default/webgpsmap.html | 134 +++++++++++++++------- 1 file changed, 95 insertions(+), 39 deletions(-) diff --git a/pwnagotchi/plugins/default/webgpsmap.html b/pwnagotchi/plugins/default/webgpsmap.html index 13bfacbb..6c401ec1 100644 --- a/pwnagotchi/plugins/default/webgpsmap.html +++ b/pwnagotchi/plugins/default/webgpsmap.html @@ -9,7 +9,7 @@
+
+ +
0 APs
+
(⌐■  ■)
loading positions...
- \ No newline at end of file + From a7ea499fac82731ef3f28556f689a6799247160a Mon Sep 17 00:00:00 2001 From: dadav <33197631+dadav@users.noreply.github.com> Date: Mon, 25 Nov 2019 19:47:23 +0100 Subject: [PATCH 09/20] Should fail before write --- pwnagotchi/plugins/default/webcfg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pwnagotchi/plugins/default/webcfg.py b/pwnagotchi/plugins/default/webcfg.py index 52532f2c..0570833d 100644 --- a/pwnagotchi/plugins/default/webcfg.py +++ b/pwnagotchi/plugins/default/webcfg.py @@ -500,8 +500,9 @@ class WebConfig(plugins.Plugin): elif request.method == "POST": if path == "save-config": try: + parsed_yaml = yaml.safe_load(request.get_json()) with open('/etc/pwnagotchi/config.yml', 'w') as config_file: - yaml.safe_dump(request.get_json(), config_file, encoding='utf-8', + yaml.safe_dump(parsed_yaml, config_file, encoding='utf-8', allow_unicode=True, default_flow_style=False) _thread.start_new_thread(restart, (self.mode,)) From a03443986bc3047681bd0955560ba9bcf8cfec26 Mon Sep 17 00:00:00 2001 From: dadav <33197631+dadav@users.noreply.github.com> Date: Mon, 25 Nov 2019 20:08:20 +0100 Subject: [PATCH 10/20] Parse to str --- pwnagotchi/plugins/default/webcfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwnagotchi/plugins/default/webcfg.py b/pwnagotchi/plugins/default/webcfg.py index 0570833d..40f74772 100644 --- a/pwnagotchi/plugins/default/webcfg.py +++ b/pwnagotchi/plugins/default/webcfg.py @@ -500,7 +500,7 @@ class WebConfig(plugins.Plugin): elif request.method == "POST": if path == "save-config": try: - parsed_yaml = yaml.safe_load(request.get_json()) + parsed_yaml = yaml.safe_load(str(request.get_json())) with open('/etc/pwnagotchi/config.yml', 'w') as config_file: yaml.safe_dump(parsed_yaml, config_file, encoding='utf-8', allow_unicode=True, default_flow_style=False) From d2c44797e5f4f1a938790f4bcdd746708714967e Mon Sep 17 00:00:00 2001 From: Sayak Brahmachari Date: Tue, 26 Nov 2019 14:05:10 +0530 Subject: [PATCH 11/20] Prevent duplicate entries for reported networks Due to duplicate entries in `/root/.api-report.json`, [this code](https://github.com/evilsocket/pwnagotchi/blob/master/pwnagotchi/plugins/default/grid.py#L90) incorrectly reports the number of pwned networks, resulting in incorrect stats on the [pwnagotchi.ai website](https://pwnagotchi.ai/). --- pwnagotchi/plugins/default/grid.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pwnagotchi/plugins/default/grid.py b/pwnagotchi/plugins/default/grid.py index a727e249..23181aee 100644 --- a/pwnagotchi/plugins/default/grid.py +++ b/pwnagotchi/plugins/default/grid.py @@ -67,7 +67,8 @@ class Grid(plugins.Plugin): logging.info("grid plugin loaded.") def set_reported(self, reported, net_id): - reported.append(net_id) + if net_id not in reported: + reported.append(net_id) self.report.update(data={'reported': reported}) def check_inbox(self, agent): From 3c154ffe0cb5ef113727269676a5b1ee8f00deb8 Mon Sep 17 00:00:00 2001 From: Evgeny Zelenin Date: Wed, 27 Nov 2019 02:58:16 +0500 Subject: [PATCH 13/20] Update voice.po --- pwnagotchi/locale/ru/LC_MESSAGES/voice.po | 84 +++++++++++++++-------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/pwnagotchi/locale/ru/LC_MESSAGES/voice.po b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po index 146527f0..ce3ca753 100644 --- a/pwnagotchi/locale/ru/LC_MESSAGES/voice.po +++ b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po @@ -1,45 +1,51 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. +# Pwnagotchi Russian translation. +# Copyright (C) 2019 +# This file is distributed under the same license as the pwnagotchi package. # FIRST AUTHOR <25989971+adolfaka@users.noreply.github.com>, 2019. -# +# Second author , 2019 msgid "" msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-10-03 16:47+0200\n" -"PO-Revision-Date: 2019-10-05 18:50+0300\n" -"Language-Team: \n" +"Project-Id-Version: 0.0.2" +"Report-Msgid-Bugs-To: m-b-g@yandex.ru" +"POT-Creation-Date: 2019-11-27 16:47+0200" +"PO-Revision-Date: 2019-11-27 18:50+0300" +"Last-Translator: Evgeny Zelenin " +"Language-Team: ru" +"Language: ru" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2.4\n" -"Last-Translator: Elliot Manson\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" -"Language: ru_RU\n" + msgid "ZzzzZZzzzzZzzz" -msgstr "ZzzzZZzzzzZzzz" +msgstr "Хрррр..." msgid "Hi, I'm Pwnagotchi! Starting ..." -msgstr "Привет, я Pwnagotchi! Поехали …" +msgstr "Привет, я Pwnagotchi! Стартуем!" msgid "New day, new hunt, new pwns!" msgstr "Новый день, новая охота, новые взломы!" msgid "Hack the Planet!" -msgstr "Хак зе планет!" +msgstr "Взломай эту Планету!" msgid "AI ready." -msgstr "AI готов." +msgstr "A.I. готов." msgid "The neural network is ready." msgstr "Нейронная сеть готова." +msgid "Generating keys, do not turn off ..." +msgstr "Генерация ключей, не выключайте..." #, python-brace-format msgid "Hey, channel {channel} is free! Your AP will say thanks." msgstr "Эй, канал {channel} свободен! Ваша точка доступа скажет спасибо." +msgid "Reading last session logs ..." +msgstr "Чтение логов последнего сеанса..." + +#, python-brace-format +msgid "Read {lines_so_far} log lines so far ..." +msgstr "Чтение {lines_so_far} строк журнала..." msgid "I'm bored ..." msgstr "Мне скучно …" @@ -61,9 +67,14 @@ msgstr "Мне очень грустно …" msgid "I'm sad" msgstr "Мне грустно" +msgid "Leave me alone ..." +msgstr "Оставь меня в покое..." + +msgid "I'm mad at you!" +msgstr "Я зол на тебя!" msgid "I'm living the life!" -msgstr "Угараю по полной!" +msgstr "Живу полной жизнью!" msgid "I pwn therefore I am." msgstr "Я взламываю, поэтому я существую." @@ -75,15 +86,22 @@ msgid "I'm having so much fun!" msgstr "Мне так весело!" msgid "My crime is that of curiosity ..." -msgstr "Моe преступление - это любопытство …" +msgstr "Моe преступление - это из любопытства…" #, python-brace-format msgid "Hello {name}! Nice to meet you. {name}" -msgstr "Привет, {name}! Приятно познакомиться. {name}" +msgstr "Привет, {name}! Рад встрече с тобой!" #, python-brace-format msgid "Unit {name} is nearby! {name}" -msgstr "Цель {name} близко! {name}" +msgstr "Цель {name} близко!" +#, python-brace-format +msgid "Hey {name} how are you doing?" +msgstr "Хэй {nume}! Как дела?" + +#, python-brace-format +msgid "Unit {name} is nearby!" +msgstr "Цель {name} рядом!" #, python-brace-format msgid "Uhm ... goodbye {name}" @@ -91,11 +109,11 @@ msgstr "Хм … до свидания {name}" #, python-brace-format msgid "{name} is gone ..." -msgstr "{name} исчезла …" +msgstr "{name} ушла…" #, python-brace-format msgid "Whoops ... {name} is gone." -msgstr "Упс … {name} исчезла." +msgstr "Упс… {name} исчезла." #, python-brace-format msgid "{name} missed!" @@ -103,12 +121,17 @@ msgstr "{name} упустил!" msgid "Missed!" msgstr "Промахнулся!" +msgid "Good friends are a blessing!" +msgstr "Хорошие друзья - это благословение!" + +msgid "I love my friends!" +msgstr "Я люблю своих друзей!" msgid "Nobody wants to play with me ..." msgstr "Никто не хочет со мной играть ..." msgid "I feel so alone ..." -msgstr "Мне так одиноко …" +msgstr "Я так одинок…" msgid "Where's everybody?!" msgstr "Где все?!" @@ -118,11 +141,16 @@ msgid "Napping for {secs}s ..." msgstr "Дремлет {secs}с …" msgid "Zzzzz" -msgstr "Zzzzz" +msgstr "Хррр..." #, python-brace-format msgid "ZzzZzzz ({secs}s)" -msgstr "ZzzZzzz ({secs}c)" +msgstr "Хррррр.. ({secs}c)" +msgid "Good night." +msgstr "Доброй ночи." + +msgid "Zzz" +msgstr "Хрррр" #, python-brace-format msgid "Waiting for {secs}s ..." @@ -130,7 +158,7 @@ msgstr "Ждем {secs}c …" #, python-brace-format msgid "Looking around ({secs}s)" -msgstr "Оглядываюсь вокруг ({secs}с)" +msgstr "Осматриваюсь вокруг ({secs}с)" #, python-brace-format msgid "Hey {what} let's be friends!" From 48dc751d130d7c5ef639e5a0f550998cce9bec55 Mon Sep 17 00:00:00 2001 From: Evgeny Zelenin Date: Wed, 27 Nov 2019 12:09:24 +0500 Subject: [PATCH 14/20] Update voice.po --- pwnagotchi/locale/ru/LC_MESSAGES/voice.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwnagotchi/locale/ru/LC_MESSAGES/voice.po b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po index ce3ca753..d06a4f91 100644 --- a/pwnagotchi/locale/ru/LC_MESSAGES/voice.po +++ b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po @@ -86,7 +86,7 @@ msgid "I'm having so much fun!" msgstr "Мне так весело!" msgid "My crime is that of curiosity ..." -msgstr "Моe преступление - это из любопытства…" +msgstr "Моё преступление - это любопытство…" #, python-brace-format msgid "Hello {name}! Nice to meet you. {name}" From 07f8e7bd4ad01ea712ca1077f925608e2c39c320 Mon Sep 17 00:00:00 2001 From: Evgeny Zelenin Date: Wed, 27 Nov 2019 22:01:43 +0500 Subject: [PATCH 15/20] Update voice.po --- pwnagotchi/locale/ru/LC_MESSAGES/voice.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwnagotchi/locale/ru/LC_MESSAGES/voice.po b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po index d06a4f91..4103dae2 100644 --- a/pwnagotchi/locale/ru/LC_MESSAGES/voice.po +++ b/pwnagotchi/locale/ru/LC_MESSAGES/voice.po @@ -201,7 +201,7 @@ msgstr "Заимел {num} новых друзей\n" #, python-brace-format msgid "Got {num} handshakes\n" -msgstr "Получил {num} рукопожатие\n" +msgstr "Получил {num} рукопожатий\n" msgid "Met 1 peer" msgstr "Встретился один знакомый" From 7cb52ba33a0cdbcd395b76e0db26141b1bec093f Mon Sep 17 00:00:00 2001 From: dadav <33197631+dadav@users.noreply.github.com> Date: Mon, 25 Nov 2019 20:51:25 +0100 Subject: [PATCH 16/20] Add wpa-sec password download --- pwnagotchi/defaults.yml | 1 + pwnagotchi/plugins/default/wpa-sec.py | 99 ++++++++++++++++++++------- 2 files changed, 74 insertions(+), 26 deletions(-) diff --git a/pwnagotchi/defaults.yml b/pwnagotchi/defaults.yml index c3093ced..596ac67c 100644 --- a/pwnagotchi/defaults.yml +++ b/pwnagotchi/defaults.yml @@ -39,6 +39,7 @@ main: enabled: false api_key: ~ api_url: "https://wpa-sec.stanev.org" + download_results: false wigle: enabled: false api_key: ~ diff --git a/pwnagotchi/plugins/default/wpa-sec.py b/pwnagotchi/plugins/default/wpa-sec.py index ee99f105..7dd8a844 100644 --- a/pwnagotchi/plugins/default/wpa-sec.py +++ b/pwnagotchi/plugins/default/wpa-sec.py @@ -1,19 +1,27 @@ import os import logging +import threading import requests +from datetime import datetime from pwnagotchi.utils import StatusFile -import pwnagotchi.plugins as plugins +from pwnagotchi import plugins +from json.decoder import JSONDecodeError class WpaSec(plugins.Plugin): __author__ = '33197631+dadav@users.noreply.github.com' - __version__ = '2.0.1' + __version__ = '2.1.0' __license__ = 'GPL3' __description__ = 'This plugin automatically uploads handshakes to https://wpa-sec.stanev.org' def __init__(self): self.ready = False - self.report = StatusFile('/root/.wpa_sec_uploads', data_format='json') + self.lock = threading.Lock() + try: + self.report = StatusFile('/root/.wpa_sec_uploads', data_format='json') + except JSONDecodeError as json_err: + os.remove("/root/.wpa_sec_uploads") + self.report = StatusFile('/root/.wpa_sec_uploads', data_format='json') self.options = dict() self.skip = list() @@ -35,6 +43,29 @@ class WpaSec(plugins.Plugin): except requests.exceptions.RequestException as req_e: raise req_e + + def _download_from_wpasec(self, output, timeout=30): + """ + Downloads the results from wpasec and safes them to output + + Output-Format: bssid, station_mac, ssid, password + """ + api_url = self.options['api_url'] + if not api_url.endswith('/'): + api_url = f"{api_url}/" + api_url = f"{api_url}?api&dl=1" + + cookie = {'key': self.options['api_key']} + try: + result = requests.get(api_url, cookies=cookie, timeout=timeout) + with open(output, 'wb') as output_file: + output_file.write(result.content) + except requests.exceptions.RequestException as req_e: + raise req_e + except OSError as os_e: + raise os_e + + def on_loaded(self): """ Gets called when the plugin gets loaded @@ -53,32 +84,48 @@ class WpaSec(plugins.Plugin): """ Called in manual mode when there's internet connectivity """ - if self.ready: - config = agent.config() - display = agent.view() - reported = self.report.data_field_or('reported', default=list()) + with self.lock: + if self.ready: + config = agent.config() + display = agent.view() + reported = self.report.data_field_or('reported', default=list()) - handshake_dir = config['bettercap']['handshakes'] - handshake_filenames = os.listdir(handshake_dir) - handshake_paths = [os.path.join(handshake_dir, filename) for filename in handshake_filenames if - filename.endswith('.pcap')] - handshake_new = set(handshake_paths) - set(reported) - set(self.skip) + handshake_dir = config['bettercap']['handshakes'] + handshake_filenames = os.listdir(handshake_dir) + handshake_paths = [os.path.join(handshake_dir, filename) for filename in handshake_filenames if + filename.endswith('.pcap')] + handshake_new = set(handshake_paths) - set(reported) - set(self.skip) - if handshake_new: - logging.info("WPA_SEC: Internet connectivity detected. Uploading new handshakes to wpa-sec.stanev.org") + if handshake_new: + logging.info("WPA_SEC: Internet connectivity detected. Uploading new handshakes to wpa-sec.stanev.org") + + for idx, handshake in enumerate(handshake_new): + display.set('status', f"Uploading handshake to wpa-sec.stanev.org ({idx + 1}/{len(handshake_new)})") + display.update(force=True) + try: + self._upload_to_wpasec(handshake) + reported.append(handshake) + self.report.update(data={'reported': reported}) + logging.info("WPA_SEC: Successfully uploaded %s", handshake) + except requests.exceptions.RequestException as req_e: + self.skip.append(handshake) + logging.error("WPA_SEC: %s", req_e) + continue + except OSError as os_e: + logging.error("WPA_SEC: %s", os_e) + continue + + if 'download_results' in self.options and self.options['download_results']: + cracked_file = os.path.join(handshake_dir, 'wpa-sec.cracked.potfile') + if os.path.exists(cracked_file): + last_check = datetime.fromtimestamp(os.path.getmtime(cracked_file)) + if last_check is not None and ((datetime.now() - last_check).seconds / (60 * 60)) < 1: + return - for idx, handshake in enumerate(handshake_new): - display.set('status', f"Uploading handshake to wpa-sec.stanev.org ({idx + 1}/{len(handshake_new)})") - display.update(force=True) try: - self._upload_to_wpasec(handshake) - reported.append(handshake) - self.report.update(data={'reported': reported}) - logging.info("WPA_SEC: Successfully uploaded %s", handshake) + self._download_from_wpasec(os.path.join(handshake_dir, 'wpa-sec.cracked.potfile')) + logging.info("WPA_SEC: Downloaded cracked passwords.") except requests.exceptions.RequestException as req_e: - self.skip.append(handshake) - logging.error("WPA_SEC: %s", req_e) - continue + logging.debug("WPA_SEC: %s", req_e) except OSError as os_e: - logging.error("WPA_SEC: %s", os_e) - continue + logging.debug("WPA_SEC: %s", os_e) From cc5c46906f869a62d64ad74f61d8ccc539b845bd Mon Sep 17 00:00:00 2001 From: dadav <33197631+dadav@users.noreply.github.com> Date: Wed, 27 Nov 2019 18:31:41 +0100 Subject: [PATCH 17/20] Add plugins page --- pwnagotchi/plugins/__init__.py | 25 +++++++++++++-- pwnagotchi/plugins/default/bt-tether.py | 4 +++ pwnagotchi/plugins/default/example.py | 4 +++ pwnagotchi/ui/web/handler.py | 21 +++++++------ pwnagotchi/ui/web/static/css/style.css | 35 ++++++++++++++++++++- pwnagotchi/ui/web/templates/base.html | 3 +- pwnagotchi/ui/web/templates/plugins.html | 39 ++++++++++++++++++++++++ 7 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 pwnagotchi/ui/web/templates/plugins.html diff --git a/pwnagotchi/plugins/__init__.py b/pwnagotchi/plugins/__init__.py index 44c27879..c5efaf7d 100644 --- a/pwnagotchi/plugins/__init__.py +++ b/pwnagotchi/plugins/__init__.py @@ -6,7 +6,7 @@ import logging default_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "default") loaded = {} - +database = {} class Plugin: @classmethod @@ -18,6 +18,26 @@ class Plugin: logging.debug("loaded plugin %s as %s" % (plugin_name, plugin_instance)) loaded[plugin_name] = plugin_instance +def toggle_plugin(name, enable=True): + """ + Load or unload a plugin + + returns True if changed, otherwise False + """ + global loaded, database + if not enable and name in loaded: + if getattr(loaded[name], 'on_unload', None): + loaded[name].on_unload() + del loaded[name] + return True + + if enable and name in database and name not in loaded: + load_from_file(database[name]) + one(name, 'loaded') + return True + + return False + def on(event_name, *args, **kwargs): for plugin_name, plugin in loaded.items(): @@ -48,10 +68,11 @@ def load_from_file(filename): def load_from_path(path, enabled=()): - global loaded + global loaded, database logging.debug("loading plugins from %s - enabled: %s" % (path, enabled)) for filename in glob.glob(os.path.join(path, "*.py")): plugin_name = os.path.basename(filename.replace(".py", "")) + database[plugin_name] = filename if plugin_name in enabled: try: load_from_file(filename) diff --git a/pwnagotchi/plugins/default/bt-tether.py b/pwnagotchi/plugins/default/bt-tether.py index 6acaf270..5f986f84 100644 --- a/pwnagotchi/plugins/default/bt-tether.py +++ b/pwnagotchi/plugins/default/bt-tether.py @@ -466,7 +466,11 @@ class BTTether(plugins.Plugin): logging.info("BT-TETHER: Successfully loaded ...") self.ready = True + def on_unload(self): + self.ui.remove_element('bluetooth') + def on_ui_setup(self, ui): + self.ui = ui ui.add_element('bluetooth', LabeledValue(color=BLACK, label='BT', value='-', position=(ui.width() / 2 - 15, 0), label_font=fonts.Bold, text_font=fonts.Medium)) diff --git a/pwnagotchi/plugins/default/example.py b/pwnagotchi/plugins/default/example.py index 035a30d5..37eccb43 100644 --- a/pwnagotchi/plugins/default/example.py +++ b/pwnagotchi/plugins/default/example.py @@ -25,6 +25,10 @@ class Example(plugins.Plugin): def on_loaded(self): logging.warning("WARNING: this plugin should be disabled! options = " % self.options) + # called before the plugin is unloaded + def on_unload(self): + pass + # called hen there's internet connectivity def on_internet_available(self, agent): pass diff --git a/pwnagotchi/ui/web/handler.py b/pwnagotchi/ui/web/handler.py index c11b1731..788a3d1b 100644 --- a/pwnagotchi/ui/web/handler.py +++ b/pwnagotchi/ui/web/handler.py @@ -179,16 +179,19 @@ class Handler: def plugins(self, name, subpath): if name is None: - # show plugins overview - abort(404) + return render_template('plugins.html', loaded=plugins.loaded, database=plugins.database) + + if name == 'toggle' and request.method == 'POST': + checked = True if 'enabled' in request.form else False + return 'success' if plugins.toggle_plugin(request.form['plugin'], checked) else 'failed' + + if name in plugins.loaded and plugins.loaded[name] is not None and hasattr(plugins.loaded[name], 'on_webhook'): + try: + return plugins.loaded[name].on_webhook(subpath, request) + except Exception: + abort(500) else: - if name in plugins.loaded and hasattr(plugins.loaded[name], 'on_webhook'): - try: - return plugins.loaded[name].on_webhook(subpath, request) - except Exception: - abort(500) - else: - abort(404) + abort(404) # serve a message and shuts down the unit def shutdown(self): diff --git a/pwnagotchi/ui/web/static/css/style.css b/pwnagotchi/ui/web/static/css/style.css index 8acc2677..a005a1d6 100644 --- a/pwnagotchi/ui/web/static/css/style.css +++ b/pwnagotchi/ui/web/static/css/style.css @@ -31,4 +31,37 @@ a.read { p.messagebody { padding: 1em; -} \ No newline at end of file +} + +li.navitem { + width: 16.66% !important; + clear: none !important; +} + +/* Custom indentations are needed because the length of custom labels differs from + the length of the standard labels */ +.custom-size-flipswitch.ui-flipswitch .ui-btn.ui-flipswitch-on { + text-indent: -5.9em; +} + +.custom-size-flipswitch.ui-flipswitch .ui-flipswitch-off { + text-indent: 0.5em; +} + +/* Custom widths are needed because the length of custom labels differs from + the length of the standard labels */ +.custom-size-flipswitch.ui-flipswitch { + width: 8.875em; +} + +.custom-size-flipswitch.ui-flipswitch.ui-flipswitch-active { + padding-left: 7em; + width: 1.875em; +} + +@media (min-width: 28em) { + /*Repeated from rule .ui-flipswitch above*/ + .ui-field-contain > label + .custom-size-flipswitch.ui-flipswitch { + width: 1.875em; + } +} diff --git a/pwnagotchi/ui/web/templates/base.html b/pwnagotchi/ui/web/templates/base.html index c39e080f..be2d618f 100644 --- a/pwnagotchi/ui/web/templates/base.html +++ b/pwnagotchi/ui/web/templates/base.html @@ -47,6 +47,7 @@ ( '/inbox/new', 'new', 'mail', 'New' ), ( '/inbox/profile', 'profile', 'info', 'Profile' ), ( '/inbox/peers', 'peers', 'user', 'Peers' ), + ( '/plugins', 'plugins', 'grid', 'Plugins' ), ] %} {% set active_page = active_page|default('inbox') %} @@ -54,7 +55,7 @@
    {% for href, id, icon, caption in navigation %} -
  • +
  • {% endfor %} diff --git a/pwnagotchi/ui/web/templates/plugins.html b/pwnagotchi/ui/web/templates/plugins.html new file mode 100644 index 00000000..e96d2445 --- /dev/null +++ b/pwnagotchi/ui/web/templates/plugins.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% set active_page = "plugins" %} + +{% block title %} +Plugins +{% endblock %} + +{% block script %} +$(function(){ + $("input[type=checkbox]").change(function(e) { + var checkbox = $(this); + var form = checkbox.closest("form"); + var url = form.attr('action'); + + $.ajax({ + type: "POST", + url: url, + data: form.serialize(), + success: function(data) { + if( data.indexOf('failed') != -1 ) { + alert('Could not be toggled.'); + } + } + }); + }); +}); +{% endblock %} +{% block content %} +
    + {% for name in database.keys() %} +

    {{name}}

    +
    + + + +
    + {% endfor %} +
    +{% endblock %} From e72fd08fb4985462123f3175cc831b4b50207c88 Mon Sep 17 00:00:00 2001 From: Casey Diemel Date: Thu, 28 Nov 2019 14:39:15 -0500 Subject: [PATCH 18/20] added on_unfiltered_wifi_list Signed-off-by: Casey Diemel --- pwnagotchi/plugins/default/example.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pwnagotchi/plugins/default/example.py b/pwnagotchi/plugins/default/example.py index 37eccb43..58fe4488 100644 --- a/pwnagotchi/plugins/default/example.py +++ b/pwnagotchi/plugins/default/example.py @@ -122,6 +122,11 @@ class Example(plugins.Plugin): def on_wifi_update(self, agent, access_points): pass + # called when the agent refreshed an unfiltered access point list + # this list contains all access points that were detected BEFORE filtering + def on_unfiltered_ap_list(self, agent, access_points): + pass + # called when the agent is sending an association frame def on_association(self, agent, access_point): pass From 855bda9104fd1587caf5d4ffd7c11f274b958e87 Mon Sep 17 00:00:00 2001 From: Evg33 Date: Thu, 28 Nov 2019 23:02:22 +0300 Subject: [PATCH 19/20] feature/plugin/web/reboot --- pwnagotchi/ui/web/handler.py | 9 +++++++++ pwnagotchi/ui/web/templates/index.html | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/pwnagotchi/ui/web/handler.py b/pwnagotchi/ui/web/handler.py index 788a3d1b..f8552532 100644 --- a/pwnagotchi/ui/web/handler.py +++ b/pwnagotchi/ui/web/handler.py @@ -34,6 +34,7 @@ class Handler: self._app.add_url_rule('/ui', 'ui', self.with_auth(self.ui)) self._app.add_url_rule('/shutdown', 'shutdown', self.with_auth(self.shutdown), methods=['POST']) + self._app.add_url_rule('/reboot', 'reboot', self.with_auth(self.reboot), methods=['POST']) self._app.add_url_rule('/restart', 'restart', self.with_auth(self.restart), methods=['POST']) # inbox @@ -201,6 +202,14 @@ class Handler: finally: _thread.start_new_thread(pwnagotchi.shutdown, ()) + # serve a message and reboot the unit + def reboot(self): + try: + return render_template('status.html', title=pwnagotchi.name(), go_back_after=60, + message='Rebooting ...') + finally: + _thread.start_new_thread(pwnagotchi.reboot, ()) + # serve a message and restart the unit in the other mode def restart(self): mode = request.form['mode'] diff --git a/pwnagotchi/ui/web/templates/index.html b/pwnagotchi/ui/web/templates/index.html index 8463cd26..475a97a4 100644 --- a/pwnagotchi/ui/web/templates/index.html +++ b/pwnagotchi/ui/web/templates/index.html @@ -26,6 +26,13 @@ window.onload = function() { +
  • +
    + + +
    +
  • From f5a94fde9639e9e4afe6fa4938b5ec749046f2ad Mon Sep 17 00:00:00 2001 From: dadav <33197631+dadav@users.noreply.github.com> Date: Thu, 28 Nov 2019 21:55:20 +0100 Subject: [PATCH 20/20] Add url to plugin --- pwnagotchi/ui/web/templates/plugins.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pwnagotchi/ui/web/templates/plugins.html b/pwnagotchi/ui/web/templates/plugins.html index e96d2445..82714d58 100644 --- a/pwnagotchi/ui/web/templates/plugins.html +++ b/pwnagotchi/ui/web/templates/plugins.html @@ -7,13 +7,13 @@ Plugins {% block script %} $(function(){ - $("input[type=checkbox]").change(function(e) { + $('input[type=checkbox]').change(function(e) { var checkbox = $(this); - var form = checkbox.closest("form"); + var form = checkbox.closest('form'); var url = form.attr('action'); $.ajax({ - type: "POST", + type: 'POST', url: url, data: form.serialize(), success: function(data) { @@ -28,7 +28,9 @@ $(function(){ {% block content %}
    {% for name in database.keys() %} -

    {{name}}

    +

    + {{name}} +