#!/usr/bin/python import os import random import tempfile import subprocess import time import json import core import chatter import inflect ## system globals SOURCE = os.path.join("/home", "endorphant", "projects", "ttbp", "bin") LIVE = "http://tilde.town/~" FEEDBACK = os.path.join("/home", "endorphant", "ttbp-mail") USERFILE = os.path.join("/home", "endorphant", "projects", "ttbp", "users.txt") p = inflect.engine() ## user globals USER = os.path.basename(os.path.expanduser("~")) PATH = os.path.join("/home", USER, ".ttbp") PUBLIC = os.path.join("/home", USER, "public_html") WWW = os.path.join(PATH, "www") CONFIG = os.path.join(PATH, "config") TTBPRC = os.path.join(CONFIG, "ttbprc") DATA = os.path.join(PATH, "entries") SETTINGS = { "editor": "none", "publish dir": False } ## ui globals BANNER = open(os.path.join(SOURCE, "config", "banner.txt")).read() SPACER = "\n\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" ## ref EDITORS = ["vim", "vi", "emacs", "pico", "nano"] SUBJECTS = ["help request", "bug report", "feature suggestion", "general comment"] ## def redraw(leftover=""): os.system("clear") print(BANNER) print(SPACER) if leftover: print("> "+leftover+"\n") def start(): redraw() #print(chatter.say("greet")+", "+chatter.say("friend")) #print("(remember, you can always press ctrl-c to come home)\n") print("if you don't want to be here at any point, press and it'll all go away.\njust keep in mind that you might lose anything you've started here.\n") print(check_init()) try: redraw() print(main_menu()) except ValueError or SyntaxError: redraw("oh no i didn't understand that. let's go home and start over.") print(main_menu()) except KeyboardInterrupt: redraw("eject button fired! going home now.") print(main_menu()) def stop(): return "\n\t"+chatter.say("bye") def check_init(): global SETTINGS print("\n\n") if os.path.exists(os.path.join(os.path.expanduser("~"),".ttbp")): print(chatter.say("greet")+", "+USER+".") while not os.path.isfile(TTBPRC): setup_handler() try: SETTINGS = json.load(open(TTBPRC)) except ValueError: setup_handler() raw_input("\n\npress to explore your feels.\n\n") core.load() return "" else: return init() def init(): try: raw_input("i don't recognize you, stranger. let's make friends.\n\npress to begin, or to get out of here. \n\n") except KeyboardInterrupt: print("\n\nthanks for checking in! i'll always be here.\n\n") quit() users = open(USERFILE, 'a') users.write(USER+"\n") users.close() subprocess.call(["mkdir", PATH]) subprocess.call(["mkdir", CONFIG]) subprocess.call(["mkdir", DATA]) #subprocess.call(["cp", os.path.join(SOURCE, "config", "defaults", "header.txt"), CONFIG]) header = gen_header() headerfile = open(os.path.join(CONFIG, "header.txt"), 'w') for line in header: headerfile.write(line) headerfile.close() subprocess.call(["cp", os.path.join(SOURCE, "config", "defaults", "footer.txt"), CONFIG]) setup() subprocess.call(["cp", os.path.join(SOURCE, "config", "defaults", "style.css"), WWW]) core.load() raw_input("\nyou're all good to go, "+chatter.say("friend")+"! hit to continue.\n\n") return "" def gen_header(): header = [] header.append("") header.append("\n") header.append("\n\t") header.append("\n\t\t~"+USER+" on TTBP") header.append("\n\t\t") header.append("\n\t") header.append("\n\t") header.append("\n\t\t
") header.append("\n\t\t\t

~"+USER+"@TTBP

") header.append("\n\t\t
\n") header.append("\n\t\t\n\n\n\n") header.append("\n\t\t\n") header.append("\n\t\t
\n") return header def setup_handler(): print("\nyour ttbp configuration doesn't look right. let's make you a fresh copy.\n\n") try: setup() except KeyboardInterrupt: print("\n\nsorry, trying again.\n\n") setup() def setup(): global SETTINGS # editor selection print_menu(EDITORS) choice = raw_input("\npick your favorite text editor: ") while choice not in ['0', '1', '2', '3', '4']: choice = raw_input("\nplease pick a number from the list: ") SETTINGS["editor"] = EDITORS[int(choice)] redraw("text editor set to: "+SETTINGS["editor"]) # publish directory selection if SETTINGS["publish dir"]: print("\tcurrent publish dir:\t"+os.path.join(PUBLIC, SETTINGS["publish dir"])+"\n\n") choice = raw_input("\nwhere do you want your blog published? (leave blank to use default \"blog\") ") if not choice: choice = "blog" publishing = os.path.join(PUBLIC, choice) while os.path.exists(publishing): second = raw_input("\n"+publishing+" already exists!\nif you're sure you want to use it, hit to confirm. otherwise, pick another location: ") if second == "": break choice = second publishing = os.path.join(PUBLIC, choice) SETTINGS["publish dir"] = choice # set up publish directory if not os.path.exists(publishing): subprocess.call(["mkdir", publishing]) subprocess.call(["touch", os.path.join(publishing, "index.html")]) index = open(os.path.join(publishing, "index.html"), "w") index.write("

ttbp blog placeholder

") index.close() if os.path.exists(WWW): subprocess.call(["rm", WWW]) subprocess.call(["ln", "-s", publishing, WWW]) print("\n\tpublishing to "+LIVE+USER+"/"+SETTINGS["publish dir"]+"/\n\n") # save settings ttbprc = open(TTBPRC, "w") ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':'))) ttbprc.close() return SETTINGS ## menus def print_menu(menu): i = 0 for x in menu: line = [] line.append("\t[ ") if i < 10: line.append(" ") line.append(str(i)+" ] "+x) print("".join(line)) i += 1 def main_menu(): #os.system("clear") #print(BANNER) #redraw() menuOptions = [ "record your feels", "review your feels", "check out your neighbors", "browse global feels", "change your settings", "send some feedback", "(wip) see credits"] #print(SPACER) print("you're at ttbp home. remember, you can always press to come back here.\n\n") print_menu(menuOptions) #print("how are you feeling today? ") try: choice = raw_input("\ntell me about your feels (enter 'none' to quit): ") except KeyboardInterrupt: redraw("eject button fired! going home now.") return main_menu() if choice == '0': redraw() today = time.strftime("%Y%m%d") write_entry(os.path.join(DATA, today+".txt")) elif choice == '1': redraw("here are your recorded feels, listed by date:\n\n") view_own() elif choice == '2': users = find_ttbps() redraw("the following "+p.no("user", len(users))+" "+p.plural("is", len(users))+" recording feels on ttbp:\n\n") view_neighbors(users) elif choice == '3': redraw("now viewing most recent entries\n\n") view_feed() elif choice == '4': pretty_settings = "\n\ttext editor:\t" +SETTINGS["editor"] pretty_settings += "\n\tpublish dir:\t" +os.path.join(PUBLIC, SETTINGS["publish dir"]) redraw("now changing your settings. press if you didn't mean to do this.\n\ncurrent settings "+pretty_settings+"\n") setup() raw_input("\nyou're all good to go, "+chatter.say("friend")+"! hit to continue.\n\n") redraw() elif choice == '5': redraw() feedback_menu() elif choice == '6': redraw(DUST) elif choice == "none": return stop() else: redraw(INVALID) return main_menu() def feedback_menu(): print("you're about to send mail to ~endorphant about ttbp\n\n") print_menu(SUBJECTS) choice = raw_input("\npick a category for your feedback: ") cat = "" if choice in ['0', '1', '2', '3']: cat = SUBJECTS[int(choice)] raw_input("\ncomposing a "+cat+" to ~endorphant.\n\npress to open an external text editor. mail will be sent once you save and quit.\n") redraw(send_feedback(cat)) return else: redraw(INVALID) return feedback_menu() ## handlers def write_entry(entry=os.path.join(DATA, "test.txt")): raw_input("\nfeels will be recorded for today, "+time.strftime("%d %B %Y")+".\n\nif you've already started recording feels for this day, you \ncan pick up where you left off.\n\npress to begin recording your feels.\n\n") subprocess.call([SETTINGS["editor"], entry]) core.load_files() core.write("index.html") redraw("posted to "+LIVE+USER+"/"+SETTINGS["publish dir"]+"/index.html\n\nthanks for sharing your feels!") return def send_feedback(subject="none", mailbox=os.path.join(FEEDBACK, USER+"-"+time.strftime("%Y%m%d-%H%M")+".msg")): mail = "" temp = tempfile.NamedTemporaryFile() subprocess.call([SETTINGS["editor"], temp.name]) mail = open(temp.name, 'r').read() outfile = open(mailbox, 'w') outfile.write("from:\t\t~"+USER+"\n") outfile.write("subject:\t"+subject+"\n") outfile.write("date:\t"+time.strftime("%d %B %y")+"\n") outfile.write(mail) outfile.close() return "mail sent. thanks for writing! i'll try to respond to you soon." def view_neighbors(users): userList = [] for user in users: userRC = json.load(open(os.path.join("/home", user, ".ttbp", "config", "ttbprc"))) url = LIVE+user+"/"+userRC["publish dir"] count = 0 for filename in os.listdir(os.path.join("/home", user, ".ttbp", "entries")): if os.path.splitext(filename)[1] == ".txt" and len(os.path.splitext(filename)[0]) == 8: count += 1 pad = "" if len(user) < 8: pad = "\t" user = "~"+user if len(user) < 8: user += "\t" userList.append("\t"+user+"\t"+url+pad+"\t("+p.no("feel", count)+")") userList.sort() print_menu(userList) raw_input("\n\npress to go back home.\n\n") redraw() return def view_own(): filenames = [] for entry in os.listdir(DATA): filenames.append(os.path.join(DATA, entry)) metas = core.meta(filenames) entries = [] for entry in metas: #print(entry) entries.append(""+entry[4]+" ("+p.no("word", entry[2])+") ") view_entries(metas, entries, "here are your recorded feels, listed by date: \n\n") redraw() return def view_entries(metas, entries, prompt): print_menu(entries) choice = list_select(entries, "pick an entry from the list, or to go home: ") redraw("now reading ~"+metas[choice][5]+"'s feels on "+metas[choice][4]+"\n> press to return to feels list.\n\n") show_entry(metas[choice][0]) #redraw("here are your recorded feels, listed by date:\n\n") redraw(prompt) return view_entries(metas, entries, prompt) def show_entry(filename): subprocess.call(["less", filename]) return def view_feed(): feedList = [] for townie in find_ttbps(): entryDir = os.path.join("/home", townie, ".ttbp", "entries") filenames = os.listdir(entryDir) for entry in filenames: feedList.append(os.path.join(entryDir, entry)) metas = core.meta(feedList) metas.sort(key = lambda entry:entry[3]) metas.reverse() entries = [] for entry in metas[0:10]: pad = "" if len(entry[5]) < 8: pad = "\t" entries.append("~"+entry[5]+pad+"\ton "+entry[4]+" ("+p.no("word", entry[2])+") ") #print_menu(entries) view_entries(metas, entries, "most recent ten entries: \n\n") redraw() return ##### def find_ttbps(): # looks for users with a valid ttbp config and returns a list of them 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 list_select(options, prompt): # runs the prompt for the list until a valid index is imputted ans = "" invalid = True while invalid: choice = raw_input("\n\n"+prompt) try: ans = int(choice) except ValueError: choice = raw_input("\n\n"+prompt+"\n\n") invalid = False if ans >= len(options): return list_select(options, prompt) return ans ##### start()