--port flag; style fixes

pull/4/head
Blake DeMarcy 2017-04-13 02:08:19 -05:00
parent a4ee100b53
commit 4b55d702c5
2 changed files with 93 additions and 68 deletions

View File

@ -26,13 +26,22 @@ from datetime import datetime
from time import time, sleep from time import time, sleep
from subprocess import run from subprocess import run
from random import choice from random import choice
from sys import argv
import tempfile import tempfile
import urwid import urwid
import json import json
import os import os
try: try:
network = BBJ(host="127.0.0.1", port=7099) port_spec = argv.index("--port")
port = argv[port_spec+1]
except ValueError: # --port not specified
port = 7099
except IndexError: # flag given but no value
exit("thats not how this works, silly! --port 7099")
try:
network = BBJ(host="127.0.0.1", port=port)
except URLError as e: except URLError as e:
# print the connection error in red # print the connection error in red
exit("\033[0;31m%s\033[0m" % repr(e)) exit("\033[0;31m%s\033[0m" % repr(e))
@ -63,6 +72,7 @@ welcome = """>>> Welcome to Bulletin Butter & Jelly! ------------------@
format_help = [ format_help = [
"Quick reminder: \[rainbow: expressions work like this]\n\n" "Quick reminder: \[rainbow: expressions work like this]\n\n"
"BBJ supports **bolding**, __underlining__, and [rainbow: coloring] text " "BBJ supports **bolding**, __underlining__, and [rainbow: coloring] text "
"using markdown-style symbols as well as tag-like expressions. Markdown " "using markdown-style symbols as well as tag-like expressions. Markdown "
"is **NOT** fully implemented, but several of the more obvious concepts " "is **NOT** fully implemented, but several of the more obvious concepts "
@ -142,7 +152,6 @@ general_help = [
"dialogs or composers." "dialogs or composers."
] ]
colors = [ colors = [
"\033[1;31m", "\033[1;33m", "\033[1;33m", "\033[1;31m", "\033[1;33m", "\033[1;33m",
"\033[1;32m", "\033[1;34m", "\033[1;35m" "\033[1;32m", "\033[1;34m", "\033[1;35m"
@ -285,6 +294,18 @@ class App(object):
self.set_default_header() self.set_default_header()
def remove_overlays(self):
"""
Remove ALL urwid.Overlay objects which are currently covering the base
widget.
"""
while True:
try:
self.loop.widget = self.loop.widget[0]
except:
break
def switch_editor(self): def switch_editor(self):
""" """
Switch focus between the thread viewer and the open editor Switch focus between the thread viewer and the open editor
@ -305,9 +326,8 @@ class App(object):
self.loop.widget.footer[0].set_text( self.loop.widget.footer[0].set_text(
"[F1]Abort [F2]Swap [F3]Formatting Help [save/quit to send] " + focus) "[F1]Abort [F2]Swap [F3]Formatting Help [save/quit to send] " + focus)
# this hideous and awful sinful horrid unspeakable shithack changes # HACK WHY WHY WHY WHYW HWY
# the color of the help/title lines and editor border to reflect which # this sets the focus color for the editor frame
# object is currently in focus.
self.loop.widget.footer.contents[1][0].original_widget.attr_map = \ self.loop.widget.footer.contents[1][0].original_widget.attr_map = \
self.loop.widget.footer.contents[0][0].attr_map = {None: attr[0]} self.loop.widget.footer.contents[0][0].attr_map = {None: attr[0]}
self.loop.widget.header.attr_map = {None: attr[1]} self.loop.widget.header.attr_map = {None: attr[1]}
@ -332,22 +352,16 @@ class App(object):
return "less than a minute ago" return "less than a minute ago"
def quote_view_action(self, button, post_id): def quote_view_action(self, button, message):
message = self.thread["messages"][post_id] """
author = self.usermap[message["author"]] Callback function to view a quote from the message object menu.
color = str(author["color"]) """
pid_string = ">>%d" % post_id
title = [
("button", pid_string),
("default", " by "),
(color, "~" + author["user_name"])
]
widget = OptionsMenu( widget = OptionsMenu(
urwid.ListBox( urwid.ListBox(
urwid.SimpleFocusListWalker([ urwid.SimpleFocusListWalker([
*self.make_message_body(message) *self.make_message_body(message)
])), ])),
title=pid_string, title=">>%d" % message["post_id"],
**frame_theme() **frame_theme()
) )
@ -360,44 +374,45 @@ class App(object):
) )
def quote_view_menu(self, button, post_ids): def quote_view_menu(self, button, post_ids):
if len(post_ids) == 1: """
return self.quote_view_action(button, post_ids[0]) Receives a list of quote ids and makes a frilly menu to pick one to view.
# else: It retrieves messages objects from the thread and attaches them to a
# self.loop.widget = self.loop.widget[0] callback to `quote_view_action`
"""
buttons = [] buttons = []
for pid in post_ids: for pid in post_ids:
try: try:
message = self.thread["messages"][pid] message = self.thread["messages"][pid]
if len(post_ids) == 1:
return self.quote_view_action(button, message)
author = self.usermap[message["author"]] author = self.usermap[message["author"]]
color = str(author["color"])
label = [ label = [
("button", ">>%d " % pid), ("button", ">>%d " % pid),
"(", (color, author["user_name"]), ")"] "(",
except: (str(author["color"]),
label = ("button", ">>%d") author["user_name"]),
buttons.append(cute_button(label, self.quote_view_action, pid)) ")"
]
buttons.append(cute_button(label, self.quote_view_action, message))
except IndexError:
continue # users can submit >>29384234 garbage references
widget = OptionsMenu( widget = OptionsMenu(
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)), urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
title="View a Quote", title="View a Quote", **frame_theme()
**frame_theme()
) )
self.loop.widget = urwid.Overlay( self.loop.widget = urwid.Overlay(
widget, self.loop.widget, widget, self.loop.widget,
align=("relative", 50), align=("relative", 50),
valign=("relative", 50), valign=("relative", 50),
width=30, height=len(buttons) + 3,
height=len(buttons) + 3 width=30
) )
def remove_overlays(self):
while True:
try: self.loop.widget = self.loop.widget[0]
except: break
def edit_post(self, button, message): def edit_post(self, button, message):
@ -478,6 +493,33 @@ class App(object):
return [value_type(q) for q in quotes] return [value_type(q) for q in quotes]
def make_thread_body(self, thread):
"""
Returns the pile widget that comprises a thread in the index.
"""
button = cute_button(">>", self.thread_load, thread["thread_id"])
title = urwid.Text(thread["title"])
user = self.usermap[thread["author"]]
dateline = [
("default", "by "),
(str(user["color"]), "~%s " % user["user_name"]),
("dim", "@ %s" % self.timestring(thread["created"]))
]
infoline = "%d replies; active %s" % (
thread["reply_count"], self.timestring(thread["last_mod"], "delta"))
pile = urwid.Pile([
urwid.Columns([(3, urwid.AttrMap(button, "button", "hover")), title]),
urwid.Text(dateline),
urwid.AttrMap(urwid.Text(infoline), "dim"),
urwid.AttrMap(urwid.Divider("-"), "dim")
])
pile.thread = thread
return pile
def make_message_body(self, message, no_action=False): def make_message_body(self, message, no_action=False):
""" """
Returns the widgets that comprise a message in a thread, including the Returns the widgets that comprise a message in a thread, including the
@ -533,31 +575,7 @@ class App(object):
return date.strftime(directive) return date.strftime(directive)
def make_thread_body(self, thread):
"""
Returns the pile widget that comprises a thread in the index.
"""
button = cute_button(">>", self.thread_load, thread["thread_id"])
title = urwid.Text(thread["title"])
user = self.usermap[thread["author"]]
dateline = [
("default", "by "),
(str(user["color"]), "~%s " % user["user_name"]),
("dim", "@ %s" % self.timestring(thread["created"]))
]
infoline = "%d replies; active %s" % (
thread["reply_count"], self.timestring(thread["last_mod"], "delta"))
pile = urwid.Pile([
urwid.Columns([(3, urwid.AttrMap(button, "button", "hover")), title]),
urwid.Text(dateline),
urwid.AttrMap(urwid.Text(infoline), "dim"),
urwid.AttrMap(urwid.Divider("-"), "dim")
])
pile.thread = thread
return pile
def index(self): def index(self):
@ -874,7 +892,7 @@ class App(object):
urwid.Text(("opt_header", "App"), 'center'), urwid.Text(("opt_header", "App"), 'center'),
urwid.Divider(), urwid.Divider(),
urwid.CheckBox( urwid.CheckBox(
"Rainbow Vomit on Exit", "Dump rainbows on exit",
state=self.prefs["dramatic_exit"], state=self.prefs["dramatic_exit"],
on_state_change=self.toggle_exit on_state_change=self.toggle_exit
), ),

View File

@ -2,6 +2,7 @@ from src.exceptions import BBJException, BBJParameterError, BBJUserError
from src import db, schema, formatting from src import db, schema, formatting
from functools import wraps from functools import wraps
from uuid import uuid1 from uuid import uuid1
from sys import argv
import traceback import traceback
import cherrypy import cherrypy
import sqlite3 import sqlite3
@ -381,7 +382,6 @@ class API(object):
def api_http_error(status, message, traceback, version): def api_http_error(status, message, traceback, version):
return json.dumps(schema.error(2, "HTTP error {}: {}".format(status, message))) return json.dumps(schema.error(2, "HTTP error {}: {}".format(status, message)))
cherrypy.config.update({'server.socket_port': 7099})
CONFIG = { CONFIG = {
"/": { "/": {
@ -403,10 +403,17 @@ def run():
"1ccf1ab6b9802b09a313be1478a4d614") "1ccf1ab6b9802b09a313be1478a4d614")
finally: finally:
_c.close() _c.close()
del _c
cherrypy.quickstart(API(), "/api", CONFIG) cherrypy.quickstart(API(), "/api", CONFIG)
if __name__ == "__main__": if __name__ == "__main__":
print("yo lets do that -i shit mang") try:
port_spec = argv.index("--port")
port = argv[port_spec+1]
except ValueError: # --port not specified
port = 7099
except IndexError: # flag given but no value
exit("thats not how this works, silly! --port 7099")
cherrypy.config.update({'server.socket_port': int(port)})
run()