mirror of
https://github.com/jayofelony/pwnagotchi.git
synced 2025-07-01 18:37:27 -04:00
new: implemented text auto wrapping. (closes #46)
This commit is contained in:
@ -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):
|
||||||
|
@ -78,22 +78,26 @@ 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,
|
||||||
@ -300,6 +304,11 @@ 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)
|
self._canvas = Image.new('1', (self._width, self._height), WHITE)
|
||||||
|
@ -18,74 +18,74 @@ class Voice:
|
|||||||
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)])
|
||||||
@ -94,7 +94,7 @@ class Voice:
|
|||||||
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)])
|
||||||
@ -102,23 +102,23 @@ class Voice:
|
|||||||
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):
|
def on_deauth(self, sta):
|
||||||
return random.choice([ \
|
return random.choice([
|
||||||
self._('Just decided that\n{mac}\nneeds no WiFi!').format(mac=sta['mac']),
|
self._('Just decided that {mac} needs no WiFi!').format(mac=sta['mac']),
|
||||||
self._('Deauthenticating\n{mac}').format(mac=sta['mac']),
|
self._('Deauthenticating {mac}').format(mac=sta['mac']),
|
||||||
self._('Kickbanning\n{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)
|
||||||
|
Reference in New Issue
Block a user