code cleanup

moved a whole bunch of functions around for better code clarity. it's
3am and i can't sleep, so i vaguely expect to have to revert this in the
morning.
master
endorphant 2016-05-27 03:21:11 -04:00
parent 82cbcd535c
commit 3a08bcb116
3 changed files with 242 additions and 226 deletions

View File

@ -72,8 +72,8 @@ SPACER = "\n"
INVALID = "please pick a number from the list of options!\n\n" INVALID = "please pick a number from the list of options!\n\n"
DUST = "sorry about the dust, but this part is still under construction. check back later!\n\n" DUST = "sorry about the dust, but this part is still under construction. check back later!\n\n"
QUITS = ['exit', 'quit', 'q', 'x'] QUITS = ['exit', 'quit', 'q', 'x']
BACKS = ['back', 'b', 'q']
EJECT = "eject button fired! going home now." EJECT = "eject button fired! going home now."
RAINBOW = True
## ref ## ref
@ -156,13 +156,13 @@ def check_init():
## ttbprc validation ## ttbprc validation
while not os.path.isfile(TTBPRC): while not os.path.isfile(TTBPRC):
setup_handler() setup_repair()
try: try:
SETTINGS = json.load(open(TTBPRC)) SETTINGS = json.load(open(TTBPRC))
except ValueError: except ValueError:
setup_handler() setup_repair()
## PATCH CHECK HERE ## version checker
if build_mismatch(): if build_mismatch():
switch_build() switch_build()
if not updated(): if not updated():
@ -170,7 +170,7 @@ def check_init():
## when ready, enter main program and load core engine ## when ready, enter main program and load core engine
raw_input("press <enter> to explore your feels.\n\n") raw_input("press <enter> to explore your feels.\n\n")
core.load() core.load(SETTINGS)
return "" return ""
else: else:
@ -217,7 +217,7 @@ press <enter> to begin, or <ctrl-c> to get out of here.
## run user-interactive setup and load core engine ## run user-interactive setup and load core engine
setup() setup()
core.load() core.load(SETTINGS)
raw_input("\nyou're all good to go, "+chatter.say("friend")+"! hit <enter> to continue.\n\n") raw_input("\nyou're all good to go, "+chatter.say("friend")+"! hit <enter> to continue.\n\n")
return "" return ""
@ -251,9 +251,9 @@ def gen_header():
""" """
return header return header
def setup_handler(): def setup_repair():
''' '''
setup wrapper function setup repair function
* calls setup() * calls setup()
* handles ^c * handles ^c
@ -281,7 +281,7 @@ def setup():
global SETTINGS global SETTINGS
print("\n\ttext editor:\t" +SETTINGS.get("editor")) print("\n\ttext editor:\t" +SETTINGS.get("editor"))
if publishing(): if core.publishing():
print("\tpublish dir:\t" +os.path.join(PUBLIC, SETTINGS.get("publish dir"))) print("\tpublish dir:\t" +os.path.join(PUBLIC, SETTINGS.get("publish dir")))
print("\tpubishing:\t"+str(SETTINGS.get("publishing"))+"\n") print("\tpubishing:\t"+str(SETTINGS.get("publishing"))+"\n")
@ -292,9 +292,9 @@ def setup():
# publishing selection # publishing selection
SETTINGS.update({"publishing":select_publishing()}) SETTINGS.update({"publishing":select_publishing()})
update_publishing() update_publishing()
redraw("blog publishing: "+str(publishing())) redraw("blog publishing: "+str(core.publishing()))
if publishing(): if core.publishing():
print("publish directory: ~"+USER+"/public_html/"+SETTINGS.get("publish dir")) print("publish directory: ~"+USER+"/public_html/"+SETTINGS.get("publish dir"))
# save settings # save settings
@ -309,25 +309,6 @@ def setup():
## menus ## menus
def print_menu(menu):
'''
pretty menu handler
* takes list of options and prints them
'''
i = 0
for x in menu:
line = []
line.append(util.attach_rainbow())
line.append("\t[ ")
if i < 10:
line.append(" ")
line.append(str(i)+" ] "+x)
line.append(util.attach_reset())
print("".join(line))
i += 1
def main_menu(): def main_menu():
''' '''
main navigation menu main navigation menu
@ -344,7 +325,7 @@ def main_menu():
"read documentation"] "read documentation"]
print("you're at ttbp home. remember, you can always press <ctrl-c> to come back here.\n\n") print("you're at ttbp home. remember, you can always press <ctrl-c> to come back here.\n\n")
print_menu(menuOptions) util.print_menu(menuOptions, RAINBOW)
try: try:
choice = raw_input("\ntell me about your feels (or 'quit' to exit): ") choice = raw_input("\ntell me about your feels (or 'quit' to exit): ")
@ -356,12 +337,12 @@ def main_menu():
redraw() redraw()
today = time.strftime("%Y%m%d") today = time.strftime("%Y%m%d")
write_entry(os.path.join(DATA, today+".txt")) write_entry(os.path.join(DATA, today+".txt"))
www_neighbors(find_ttbps()) core.www_neighbors()
elif choice == '1': elif choice == '1':
redraw("your recorded feels, listed by date:\n") redraw("your recorded feels, listed by date:\n")
view_feels(USER) view_feels(USER)
elif choice == '2': elif choice == '2':
users = find_ttbps() users = core.find_ttbps()
redraw("the following "+p.no("user", len(users))+" "+p.plural("is", len(users))+" recording feels on ttbp:\n") redraw("the following "+p.no("user", len(users))+" "+p.plural("is", len(users))+" recording feels on ttbp:\n")
view_neighbors(users) view_neighbors(users)
elif choice == '3': elif choice == '3':
@ -370,7 +351,7 @@ def main_menu():
elif choice == '4': elif choice == '4':
redraw("now changing your settings. press <ctrl-c> if you didn't mean to do this.") redraw("now changing your settings. press <ctrl-c> if you didn't mean to do this.")
try: try:
setup() core.load(setup()) # reload settings to core
except KeyboardInterrupt(): except KeyboardInterrupt():
redraw(EJECT) redraw(EJECT)
redraw() redraw()
@ -399,7 +380,7 @@ def feedback_menu():
print("you're about to send mail to ~endorphant about ttbp\n\n") print("you're about to send mail to ~endorphant about ttbp\n\n")
print_menu(SUBJECTS) util.print_menu(SUBJECTS, RAINBOW)
choice = raw_input("\npick a category for your feedback: ") choice = raw_input("\npick a category for your feedback: ")
cat = "" cat = ""
@ -473,10 +454,10 @@ def view_neighbors(users):
sortedUsers.append(user[0]) sortedUsers.append(user[0])
userIndex.append(user[2]) userIndex.append(user[2])
print_menu(sortedUsers) util.print_menu(sortedUsers, RAINBOW)
#raw_input("\n\npress <enter> to go back home.\n\n") #raw_input("\n\npress <enter> to go back home.\n\n")
choice = list_select(sortedUsers, "pick a townie to browse their feels, or type 'back' to go home: ") choice = util.list_select(sortedUsers, "pick a townie to browse their feels, or type 'back' to go home: ")
if choice is not False: if choice is not False:
redraw("~"+userIndex[choice]+"'s recorded feels, listed by date: \n") redraw("~"+userIndex[choice]+"'s recorded feels, listed by date: \n")
@ -571,7 +552,7 @@ editor.
left = "" left = ""
if publishing(): if core.publishing():
core.load_files() core.load_files()
core.write("index.html") core.write("index.html")
left = "posted to "+LIVE+USER+"/"+SETTINGS["publish dir"]+"/index.html\n\n>" left = "posted to "+LIVE+USER+"/"+SETTINGS["publish dir"]+"/index.html\n\n>"
@ -613,9 +594,9 @@ def list_entries(metas, entries, prompt):
displays a list of entries for reading selection displays a list of entries for reading selection
''' '''
print_menu(entries) util.print_menu(entries, RAINBOW)
choice = list_select(entries, "pick an entry from the list, or type 'back' to go back: ") choice = util.list_select(entries, "pick an entry from the list, or type 'back' to go back: ")
if choice is not False: if choice is not False:
@ -646,7 +627,7 @@ def view_feed():
feedList = [] feedList = []
for townie in find_ttbps(): for townie in core.find_ttbps():
entryDir = os.path.join("/home", townie, ".ttbp", "entries") entryDir = os.path.join("/home", townie, ".ttbp", "entries")
filenames = os.listdir(entryDir) filenames = os.listdir(entryDir)
@ -674,124 +655,13 @@ def view_feed():
## misc helpers ## misc helpers
def find_ttbps():
'''
returns a list of users with a ttbp by checking for a valid ttbprc
'''
users = []
for townie in os.listdir("/home"):
if os.path.exists(os.path.join("/home", townie, ".ttbp", "config", "ttbprc")):
users.append(townie)
return users
def www_neighbors(users):
'''
takes a list of users with publiishing turned on and prepares it for www output
'''
userList = []
for user in users:
if not publishing(user):
continue
userRC = json.load(open(os.path.join("/home", user, ".ttbp", "config", "ttbprc")))
url = LIVE+user+"/"+userRC["publish dir"]
lastfile = ""
files = os.listdir(os.path.join("/home", user, ".ttbp", "entries"))
files.sort()
for filename in files:
if core.valid(filename):
lastfile = os.path.join("/home", user, ".ttbp", "entries", filename)
if lastfile:
last = os.path.getctime(lastfile)
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(last)) + " (utc"+time.strftime("%z")[0]+time.strftime("%z")[2]+")"
else:
timestamp = ""
last = 0
userList.append(["<a href=\""+url+"\">~"+user+"</a> "+timestamp, last])
# sort user by most recent entry
userList.sort(key = lambda userdata:userdata[1])
userList.reverse()
sortedUsers = []
for user in userList:
sortedUsers.append(user[0])
core.write_global_feed(sortedUsers)
def list_select(options, prompt):
'''
given a list, cycles through the prompt until a valid index is imputted
'''
ans = ""
invalid = True
while invalid:
choice = raw_input("\n\n"+prompt)
if choice in BACKS:
return False
try:
ans = int(choice)
except ValueError:
return list_select(options, prompt)
invalid = False
if ans >= len(options):
return list_select(options, prompt)
return ans
def input_yn(query):
'''
given a query, returns boolean True or False by processing y/n input
'''
try:
ans = raw_input(query+" [y/n] ")
except KeyboardInterrupt:
input_yn(query)
while ans not in ["y", "n"]:
ans = raw_input("'y' or 'n' please: ")
if ans == "y":
return True
else:
return False
def publishing(username = USER):
'''
checks .ttbprc for whether or not user opted for www publishing
'''
ttbprc = {}
if username == USER:
ttbprc = SETTINGS
else:
ttbprc = json.load(open(os.path.join("/home", username, ".ttbp", "config", "ttbprc")))
return ttbprc.get("publishing")
def select_editor(): def select_editor():
''' '''
setup helper for editor selection setup helper for editor selection
''' '''
print_menu(EDITORS) util.print_menu(EDITORS, RAINBOW)
choice = raw_input("\npick your favorite text editor: ") choice = raw_input("\npick your favorite text editor: ")
while choice not in ['0', '1', '2', '3', '4', '5']: while choice not in ['0', '1', '2', '3', '4', '5']:
choice = raw_input("\nplease pick a number from the list: ") choice = raw_input("\nplease pick a number from the list: ")
@ -837,7 +707,7 @@ def select_publishing():
setup helper for toggling publishing setup helper for toggling publishing
''' '''
publish = input_yn("""\ publish = util.input_yn("""\
do you want to publish your feels online? do you want to publish your feels online?
if yes, your feels will be published to a directory of your choice in if yes, your feels will be published to a directory of your choice in
@ -872,7 +742,7 @@ def update_publishing():
global SETTINGS global SETTINGS
if publishing(): if core.publishing():
oldDir = SETTINGS.get("publish dir") oldDir = SETTINGS.get("publish dir")
newDir = select_publish_dir() newDir = select_publish_dir()
SETTINGS.update({"publish dir": newDir}) SETTINGS.update({"publish dir": newDir})

View File

@ -33,6 +33,7 @@ import time
import subprocess import subprocess
import re import re
import mistune import mistune
import json
import chatter import chatter
@ -47,21 +48,24 @@ DATA = os.path.join(PATH, "entries")
FEED = os.path.join(SOURCE, "www", "index.html") FEED = os.path.join(SOURCE, "www", "index.html")
DOCS = os.path.join(SOURCE, "www", "help.html") DOCS = os.path.join(SOURCE, "www", "help.html")
NOPUB = os.path.join(CONFIG, "nopub") NOPUB = os.path.join(CONFIG, "nopub")
SETTINGS = {}
HEADER = "" HEADER = ""
FOOTER = "" FOOTER = ""
FILES = [] FILES = []
def load(): def load(ttbprc):
''' '''
get all them globals set up!! get all them globals set up!!
''' '''
global HEADER global HEADER
global FOOTER global FOOTER
global SETTINGS
HEADER = open(os.path.join(CONFIG, "header.txt")).read() HEADER = open(os.path.join(CONFIG, "header.txt")).read()
FOOTER = open(os.path.join(CONFIG, "footer.txt")).read() FOOTER = open(os.path.join(CONFIG, "footer.txt")).read()
SETTINGS = ttbprc
load_files() load_files()
@ -92,6 +96,9 @@ def load_files():
FILES.sort() FILES.sort()
FILES.reverse() FILES.reverse()
## html outputting
def write(outurl="default.html"): def write(outurl="default.html"):
''' '''
main page renderer main page renderer
@ -191,74 +198,6 @@ def write_entry(filename):
return entry return entry
def parse_date(file):
'''
parses date out of pre-validated filename
* assumes a filename of YYYYMMDD.txt
* returns a list:
[0] 'YYYY'
[1] 'MM'
[2] 'DD'
'''
rawdate = os.path.splitext(os.path.basename(file))[0]
date = [rawdate[0:4], rawdate[4:6], rawdate[6:]]
return date
def meta(entries = FILES):
'''
metadata generator
* takes a list of filenames and returns a 2d list:
[0] absolute path
[1] mtime
[2] wc -w
[3] timestamp "DD month YYYY at HH:MM"
[4] entry date YYYY-MM-DD
[5] author
* sorted in reverse date order by [4]
'''
meta = []
for filename in entries:
mtime = os.path.getmtime(filename)
wc = subprocess.check_output(["wc","-w",filename]).split()[0]
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(mtime))
date = "-".join(parse_date(filename))
author = os.path.split(os.path.split(os.path.split(os.path.split(filename)[0])[0])[0])[1]
meta.append([filename, mtime, wc, timestamp, date, author])
meta.sort(key = lambda filename:filename[4])
meta.reverse()
return meta
def valid(filename):
'''
filename validator
* check if the filename is YYYYMMDD.txt
'''
filesplit = os.path.splitext(os.path.basename(filename))
if filesplit[1] != ".txt":
return False
pattern = '^((19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|1\d|2\d|3[01])$'
if not re.match(pattern, filesplit[0]):
return False
return True
def write_global_feed(blogList): def write_global_feed(blogList):
''' '''
main ttbp index printer main ttbp index printer
@ -319,6 +258,143 @@ def write_global_feed(blogList):
outfile.close() outfile.close()
## misc helpers
def meta(entries = FILES):
'''
metadata generator
* takes a list of filenames and returns a 2d list:
[0] absolute path
[1] mtime
[2] wc -w
[3] timestamp "DD month YYYY at HH:MM"
[4] entry date YYYY-MM-DD
[5] author
* sorted in reverse date order by [4]
'''
meta = []
for filename in entries:
mtime = os.path.getmtime(filename)
wc = subprocess.check_output(["wc","-w",filename]).split()[0]
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(mtime))
date = "-".join(parse_date(filename))
author = os.path.split(os.path.split(os.path.split(os.path.split(filename)[0])[0])[0])[1]
meta.append([filename, mtime, wc, timestamp, date, author])
meta.sort(key = lambda filename:filename[4])
meta.reverse()
return meta
def valid(filename):
'''
filename validator
* check if the filename is YYYYMMDD.txt
'''
filesplit = os.path.splitext(os.path.basename(filename))
if filesplit[1] != ".txt":
return False
pattern = '^((19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|1\d|2\d|3[01])$'
if not re.match(pattern, filesplit[0]):
return False
return True
def parse_date(file):
'''
parses date out of pre-validated filename
* assumes a filename of YYYYMMDD.txt
* returns a list:
[0] 'YYYY'
[1] 'MM'
[2] 'DD'
'''
rawdate = os.path.splitext(os.path.basename(file))[0]
date = [rawdate[0:4], rawdate[4:6], rawdate[6:]]
return date
def find_ttbps():
'''
returns a list of users with a ttbp by checking for a valid ttbprc
'''
users = []
for townie in os.listdir("/home"):
if os.path.exists(os.path.join("/home", townie, ".ttbp", "config", "ttbprc")):
users.append(townie)
return users
def publishing(username = USER):
'''
checks .ttbprc for whether or not user opted for www publishing
'''
ttbprc = {}
if username == USER:
ttbprc = SETTINGS
else:
ttbprc = json.load(open(os.path.join("/home", username, ".ttbp", "config", "ttbprc")))
return ttbprc.get("publishing")
def www_neighbors():
'''
takes a list of users with publiishing turned on and prepares it for www output
'''
userList = []
for user in find_ttbps():
if not publishing(user):
continue
userRC = json.load(open(os.path.join("/home", user, ".ttbp", "config", "ttbprc")))
url = LIVE+user+"/"+userRC["publish dir"]
lastfile = ""
files = os.listdir(os.path.join("/home", user, ".ttbp", "entries"))
files.sort()
for filename in files:
if valid(filename):
lastfile = os.path.join("/home", user, ".ttbp", "entries", filename)
if lastfile:
last = os.path.getctime(lastfile)
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(last)) + " (utc"+time.strftime("%z")[0]+time.strftime("%z")[2]+")"
else:
timestamp = ""
last = 0
userList.append(["<a href=\""+url+"\">~"+user+"</a> "+timestamp, last])
# sort user by most recent entry
userList.sort(key = lambda userdata:userdata[1])
userList.reverse()
sortedUsers = []
for user in userList:
sortedUsers.append(user[0])
write_global_feed(sortedUsers)
############# #############
############# #############
############# #############

View File

@ -24,10 +24,12 @@ import time
import random import random
import colorama import colorama
## misc globals
BACKS = ['back', 'b', 'q']
## color stuff
colorama.init() colorama.init()
textcolors = [ colorama.Fore.RED, colorama.Fore.GREEN, colorama.Fore.YELLOW, colorama.Fore.BLUE, colorama.Fore.MAGENTA, colorama.Fore.WHITE, colorama.Fore.CYAN] textcolors = [ colorama.Fore.RED, colorama.Fore.GREEN, colorama.Fore.YELLOW, colorama.Fore.BLUE, colorama.Fore.MAGENTA, colorama.Fore.WHITE, colorama.Fore.CYAN]
lastcolor = colorama.Fore.RESET lastcolor = colorama.Fore.RESET
p = inflect.engine() p = inflect.engine()
@ -125,3 +127,71 @@ def genID(digits=5):
x += 1 x += 1
return id return id
def print_menu(menu, rainbow=False):
'''
A pretty menu handler that takes an incoming lists of
options and prints them nicely.
Set rainbow=True for colorized menus.
'''
i = 0
for x in menu:
line = []
if rainbow:
line.append(attach_rainbow())
line.append("\t[ ")
if i < 10:
line.append(" ")
line.append(str(i)+" ] "+x)
line.append(attach_reset())
print("".join(line))
i += 1
def list_select(options, prompt):
'''
Given a list and query prompt, returns either False as an
eject flag, or an integer index of the list Catches cancel
option from list defined by BACKS; otherwise, retries on
ValueError or IndexError.
'''
ans = ""
invalid = True
choice = raw_input("\n\n"+prompt)
if choice in BACKS:
return False
try:
ans = int(choice)
except ValueError:
return list_select(options, prompt)
try:
options[ans]
except IndexError:
return list_select(options, prompt)
return ans
def input_yn(query):
'''
Given a query, returns boolean True or False by processing y/n input
'''
try:
ans = raw_input(query+" [y/n] ")
except KeyboardInterrupt:
input_yn(query)
while ans not in ["y", "n"]:
ans = raw_input("'y' or 'n' please: ")
if ans == "y":
return True
else:
return False