aboutsummaryrefslogtreecommitdiffstats
path: root/clients/urwid/main.py
diff options
context:
space:
mode:
authorBlake DeMarcy <ofunknowndescent@gmail.com>2017-04-05 16:33:25 -0500
committerBlake DeMarcy <ofunknowndescent@gmail.com>2017-04-05 16:33:25 -0500
commitef5d1a28696804e51343ee7a1c695d5c6c060c80 (patch)
treebe07b7a7d70785c8286c2852dd366c72571fccf9 /clients/urwid/main.py
parent19af814a933fa561fd2caf8da541d75b6f592c33 (diff)
downloadbbj-ef5d1a28696804e51343ee7a1c695d5c6c060c80.tar.gz
urwid client kinda does stuff now lmao
Diffstat (limited to 'clients/urwid/main.py')
-rw-r--r--clients/urwid/main.py138
1 files changed, 104 insertions, 34 deletions
diff --git a/clients/urwid/main.py b/clients/urwid/main.py
index 983bb78..0ca4249 100644
--- a/clients/urwid/main.py
+++ b/clients/urwid/main.py
@@ -1,7 +1,7 @@
-from time import sleep, localtime
+from time import time, sleep, localtime
+from random import choice, randrange
from string import punctuation
from subprocess import run
-from random import choice
from network import BBJ
import urwid
@@ -36,20 +36,35 @@ colors = [
class App:
def __init__(self):
+ self.mode = None
colors = [
- ("bar", "light magenta", "default", "underline"),
- ("button", "light red", "default")
+ ("bar", "light magenta", "default"),
+ ("button", "light red", "default"),
+ ("dim", "dark gray", "default"),
+
+ # map the bbj api color values for display
+ ("0", "default", "default"),
+ ("1", "light red", "default"),
+ ("2", "yellow", "default"),
+ ("3", "light green", "default"),
+ ("4", "light blue", "default"),
+ ("5", "light cyan", "default"),
+ ("6", "light magenta", "default")
]
self.loop = urwid.MainLoop(urwid.Frame(
- urwid.LineBox(ActionBox(urwid.SimpleFocusListWalker([]))),
- ), colors)
+ urwid.LineBox(ActionBox(urwid.SimpleFocusListWalker([])),
+ title="> > T I L D E T O W N < <",
+ tlcorner="@", tline="=", lline="|", rline="|",
+ bline="_", trcorner="@", brcorner="@", blcorner="@"
+
+ )), colors)
self.date_format = "{1}/{2}/{0}"
self.index()
def set_header(self, text, *format_specs):
self.loop.widget.header = urwid.AttrMap(urwid.Text(
- ("%s@bbj | " % network.user_name)
+ ("%s@bbj | " % (network.user_name or "anonymous"))
+ text.format(*format_specs)
), "bar")
@@ -61,30 +76,30 @@ class App:
self.loop.widget.footer = urwid.AttrMap(urwid.Text(text), "bar")
- def readable_delta(self, created, modified):
- delta = modified - created
- minutes = delta // 60
- if not minutes:
- return "less than a minute ago"
- elif minutes < 60:
- return "%d minutes ago" % minutes
- hours = delta // 60
- if hours == 1:
- return "about an hour ago"
- elif hours < 48:
+ def readable_delta(self, modified):
+ delta = time() - modified
+ hours, remainder = divmod(delta, 3600)
+ if hours > 48:
+ return self.date_format.format(*localtime(modified))
+ elif hours > 1:
return "%d hours ago" % hours
- return self.date_format.format(*localtime(modified))
+ elif hours == 1:
+ return "about an hour ago"
+ minutes, remainder = divmod(remainder, 60)
+ if minutes > 1:
+ return "%d minutes ago"
+ return "less than a minute ago"
def index(self):
+ self.mode = "index"
threads, usermap = network.thread_index()
self.set_header("{} threads", len(threads))
- self.set_footer("Compose")
+ self.set_footer("Refresh", "Compose", "/Search", "?Help")
walker = self.loop.widget.body.base_widget.body
+ walker.clear()
for thread in threads:
- button = urwid.Button("", self.thread_load, thread["thread_id"])
- super(urwid.Button, button).__init__(
- urwid.SelectableIcon(">>"))
+ button = cute_button(">>", self.thread_load, thread["thread_id"])
title = urwid.Text(thread["title"])
last_mod = thread["last_mod"]
@@ -92,31 +107,81 @@ class App:
infoline = "by ~{} @ {} | last active {}".format(
usermap[thread["author"]]["user_name"],
self.date_format.format(*localtime(created)),
- self.readable_delta(created, last_mod)
+ self.readable_delta(last_mod)
)
- walker.append(urwid.Columns([(3, urwid.AttrMap(button, "button")), title]))
- walker.append(urwid.Text(infoline))
- walker.append(urwid.Divider("-"))
+ [walker.append(element)
+ for element in [
+ urwid.Columns([(3, urwid.AttrMap(button, "button")), title]),
+ urwid.AttrMap(urwid.Text(infoline), "dim"),
+ urwid.AttrMap(urwid.Divider("-"), "dim")
+ ]]
def thread_load(self, button, thread_id):
+ self.mode = "thread"
thread, usermap = network.thread_load(thread_id)
walker = self.loop.widget.body.base_widget.body
walker.clear()
self.set_header("~{}: {}",
usermap[thread["author"]]["user_name"], thread["title"])
for message in thread["messages"]:
- pass
+ name = urwid.Text("~{}".format(usermap[message["author"]]["user_name"]))
+ info = "@ " + self.date_format.format(*localtime(message["created"]))
+ if message["edited"]:
+ info += " [edited]"
+ head = urwid.Columns([
+ (3, urwid.AttrMap(cute_button(">>"), "button")),
+ (len(name._text) + 1, urwid.AttrMap(name, str(usermap[message["author"]]["color"]))),
+ urwid.AttrMap(urwid.Text(info), "dim")
+ ])
+
+ [walker.append(element)
+ for element in [
+ head, urwid.Divider(), urwid.Text(message["body"]),
+ urwid.Divider(), urwid.AttrMap(urwid.Divider("-"), "dim")
+ ]]
+
+
class ActionBox(urwid.ListBox):
- pass
+ def keypress(self, size, key):
+ super(ActionBox, self).keypress(size, key)
+ if key.lower() in ["j", "n"]:
+ self._keypress_down(size)
+ elif key.lower() in ["k", "p"]:
+ self._keypress_up(size)
+ elif key.lower() == "q":
+ if app.mode == "index":
+ app.loop.stop()
+ # run("clear", shell=True)
+ width, height = urwid.raw_display.Screen().get_cols_rows()
+ for x in range(height - 1):
+ line = str()
+ for x in range(width):
+ line += choice([" ", choice(punctuation)])
+ motherfucking_rainbows(line)
+ sleep(0.008)
+ exit()
+ else: app.index()
+
+
+
+def cute_button(label, callback=None, data=None):
+ """
+ Urwid's default buttons are shit, and they have ugly borders.
+ This function returns buttons that are a bit easier to love.
+ """
+ button = urwid.Button("", callback, data)
+ super(urwid.Button, button).__init__(
+ urwid.SelectableIcon(label))
+ return button
def motherfucking_rainbows(string, inputmode=False, end="\n"):
"""
- I cANtT FeELLE MyYE FACECsEE ANYrrMOROeeee!!
+ I cANtT FeELLE MyYE FACECsEE ANYrrMOROeeee
"""
for character in string:
print(choice(colors) + character, end="")
@@ -195,7 +260,7 @@ def log_in():
try:
network.set_credentials(name, "")
# make it easy for people who use an empty password =)
- motherfucking_rainbows("~~logged in as {}~~".format(network.user_name))
+ motherfucking_rainbows("~~welcome back {}~~".format(network.user_name))
except ConnectionRefusedError:
def login_loop(prompt, positive):
@@ -206,7 +271,7 @@ def log_in():
login_loop("// R E J E C T E D //.", False)
login_loop("Enter your password", True)
- motherfucking_rainbows("~~logged in as {}~~".format(network.user_name))
+ motherfucking_rainbows("~~welcome back {}~~".format(network.user_name))
except ValueError:
motherfucking_rainbows("Nice to meet'cha, %s!" % name)
@@ -216,7 +281,12 @@ def log_in():
)
if response == "c":
- name = sane_value("user_name", "Pick a new name")
+ def nameloop(prompt, positive):
+ name = sane_value("user_name", prompt, positive)
+ if network.user_is_registered(name):
+ return nameloop("%s is already registered" % name, False)
+ return name
+ name = nameloop("Pick a new name", True)
def password_loop(prompt, positive=True):
response1 = paren_prompt(prompt, positive)
@@ -239,7 +309,7 @@ def main():
motherfucking_rainbows(obnoxious_logo)
print(welcome)
log_in()
- # sleep(1) # let that confirmation message shine
+ sleep(0.6) # let that confirmation message shine
if __name__ == "__main__":
global app
Un proyecto texto-plano.xyz