#!/usr/bin/python #################### ### MUME journal ### ### by Tabris ### #################### # # v0.5 - NumTo4Str() becomes NumToStr() and is based on entrynumlength, -v can view a range (-v [start] [end]) # in addition to a single entry (-v [entry]), showinfo variable to hide program name and version, # 3 column -S/-SA/-SR view if statusdisplay set to 'short' # December 20, 2013. # # v0.4 - -status changes, -SA (alphabetize) and -SR (biggest to smallest) as opposed to chronologically, NumTo4Str() # # v0.3 - command-line argument shortcuts, displaylength/page system for -r, -s, and -S # # v0.2 - JournalStatus # # v0.1 - basic structure, AddEntry, LoadJournal, ReadJournal, RemoveEntry, SaveJournal, SearchJournal, ViewEntry # # MUME Journal allows you to save information regarding mume characters, and can # be integrated into a client via shell commands. import cPickle as pickle import os, re, string, sys, time version = 'v0.5' journalpath = '/home/tabris/mumedb/' journalfile = journalpath + '.mumejournal' displaylength = 25 entrynumlength = 5 showinfo = 1 statusdisplay = 'short' # 'long' or 'short' ####################### def NumToStr(inputnum): """ Take an input number and return a [entrynumlength]-byte string. """ outputstr = str(inputnum) if (len(outputstr) > entrynumlength): outputstr = "E" * entrynumlength else: while (len(outputstr) < entrynumlength): outputstr = " " + outputstr return outputstr ################################## def AddEntry(j, category, jentry): """ Appends a journal entry to the journal. """ j.append([time.asctime(), category, jentry]) return ############################# def SortHelper(elementinput): """ Unpack the index to allow sorting by rank. """ return elementinput[1] ############################# def StatusHelper(statuslist): """ Converts the numeric element [1] in each element into display-ready strings. """ outputlist = [] for element in statuslist: category = element[0] rank = element[1] srank = NumToStr(rank) outputlist.append([category, srank]) return outputlist ###################### def DisplayStat(stat): """ Display a single journal category in Status mode. """ print stat[1] + " - " + stat[0] return True ###################################### def Display3Stats(stats): """ Display 3 journal categories in Status mode. """ stat1buff = " " * (23 - (len(stats[0][1]) + len(stats[0][0]))) stat2buff = " " * (23 - (len(stats[1][1]) + len(stats[1][0]))) stat1 = stats[0][1] + " - " + stats[0][0] if (stats[1][0] != ""): stat2 = stats[1][1] + " - " + stats[1][0] else: stat2 = "" if (stats[2][0] != ""): stat3 = stats[2][1] + " - " + stats[2][0] else: stat3 = "" print stat1 + stat1buff + stat2 + stat2buff + stat3 return True ############################################# def JournalStatusL(j, display, statusoption): """ Displays journal statistics in long mode. """ dindex = 0 status = [] for entry in j: found = False for stat in status: if (entry[1] == stat[0]): stat[1] += 1 found = True if (found == False): status.append([entry[1], 1]) print "" if (statusoption == 'alpha'): status.sort() elif (statusoption == 'rank'): status.sort(key=SortHelper, reverse=True) status = StatusHelper(status) for stat in status: dindex += 1 if (display[1] == '0'): DisplayStat(stat) elif ((dindex >= (1 + ((int(display[1]) - 1) * display[0]))) and (dindex <= (int(display[1]) * display[0]))): DisplayStat(stat) print "-" * 50 print len(j), "total entries in", len(status) ,"categories." return True ############################################# def JournalStatusS(j, display, statusoption): """ Displays journal statistics in short mode. """ dindex = 0 # Determine number of categories status = [] # and number of entries in each. for entry in j: found = False for stat in status: if (entry[1] == stat[0]): stat[1] += 1 found = True if (found == False): status.append([entry[1], 1]) print "" if (statusoption == 'alpha'): status.sort() elif (statusoption == 'rank'): status.sort(key=SortHelper, reverse=True) status = StatusHelper(status) for stat in status: dindex += 1 statusrows = dindex / 3 # Determine number of rows. if ((dindex % 3) > 0): statusrows += 1 statusrow = 0 # Display each row. while (statusrow < statusrows): stat1 = status[statusrow] try: stat2 = status[statusrow + statusrows] except: stat2 = ["",""] try: stat3 = status[statusrow + (statusrows * 2)] except: stat3 = ["",""] Display3Stats([stat1, stat2, stat3]) statusrow += 1 print "-" * 80 print len(j), "total entries in", len(status) ,"categories." return True ####################################################### def JournalStatus(j, display, statusoption = 'chrono'): """ Forward to short or long status view. """ if (statusdisplay == 'short'): JournalStatusS(j, display, statusoption) elif (statusdisplay == 'long'): JournalStatusL(j, display, statusoption) return True ########################## def LoadJournal(j, jfile): """ Loads a journal from jfile and returns it. """ try: IFILE = open(jfile, 'r') except: print "Unable to open " + jfile + "." else: try: j = pickle.load(IFILE) except: print "Unable to load data from " + jfile + "." else: IFILE.close() return j ###################################### def ReadJournal(j, display, category): """ Displays all entries in a category. """ cateentries = 0 index = -1 for entry in j: index += 1 if (entry[1] == category): cateentries += 1 catepages = cateentries / display[0] if ((cateentries % display[0]) != 0): catepages += 1 if (showinfo and (display[1] != '0')): print "[" + category + "] has " + str(cateentries) + " entries totaling " + str(catepages) + " pages." dindex = 0 index = -1 for entry in j: index += 1 if (entry[1] == category): dindex += 1 if (display[1] == '0'): ViewEntry(j, index) elif (int(display[1]) < 0): if ((dindex >= (cateentries - (display[0] * abs(int(display[1]))) + 1)) and (dindex < (cateentries - (display[0] * (abs(int(display[1]))) - display[0]) + 1))): ViewEntry(j, index) elif ((dindex >= (1 + ((int(display[1]) - 1) * display[0]))) and (dindex <= (int(display[1]) * display[0]))): ViewEntry(j, index) return ############################# def RemoveEntry(j, entrynum): """ Remove a journal entry from the journal. """ try: j.pop(int(entrynum)) except: print "Invalid entry number." else: print "Entry #" + entrynum + " removed." return ########################## def SaveJournal(j, jfile): """ Saves the journal to jfile. """ try: OFILE = open(jfile, 'w') except: print "Unable of open journal file for save." return False else: try: pickle.dump(j, OFILE, -1) except: print "Unable to save data to journal file." OFILE.close() return False else: OFILE.close() return True ########################################## def SearchJournal(j, display, searchterm): """ Searches journal for a term and displays results. """ dindex = 0 searchpat = re.compile(searchterm + "+", re.IGNORECASE) index = -1 for entry in j: index += 1 if (re.search(searchpat, str(entry[2]))): dindex += 1 if (display[1] == '0'): ViewEntry(j, index) elif ((dindex >= (1 + ((int(display[1]) - 1) * display[0]))) and (dindex <= (int(display[1]) * display[0]))): ViewEntry(j, index) return ######################################## def ViewEntries(j, entrynum, endnumber): """ Displays a specific entry or range of entries. """ entrynumerical = int(entrynum) while(entrynumerical <= int(endnumber)): ViewEntry(j, entrynumerical) entrynumerical += 1 return ########################### def ViewEntry(j, entrynum): """ Displays a specific entry. """ try: entry = j[int(entrynum)] except: print "Invalid entry number: #" + str(entrynum) else: message = "" for mess in entry[2]: message += " " message += mess entrynumster = NumToStr(int(entrynum)) print "#" + entrynumster, str(entry[0][4:]), "[" + str(entry[1]) + "]:" + message return ################## def JournalHelp(): """ Displays mumejournal help. """ print "" print "Command-line arguments (only one can be given per invocation):" print "" print " -h, --help This information." print "" print " -u, --update [category] [entrydata] Add an entry." print " -R, --remove [entrynumber] Removes an entry." print "" print " -v, --view [entrynumber] ([endnumber]) View an entry." print " -r, --read [category] ([page#]) View all entries in a category." print " [page#] can be negative for tail." print " -s, --search [searchterms] Displays entries from all categories that have the search term." print "" print " -S, --status Displays journal categories (Chronologically)." print " -SA Displays journal categories (Alphabetically)." print " -SR Displays journal categories (by Rank)." return True ############ ### MAIN ### ############ if (showinfo): print "MUME Journal " + version + " by Tabris" args = sys.argv journal = [] journal = LoadJournal(journal, journalfile) if (len(args) <= 1): print "No command given, try '--help' for more information." elif (len(args) == 2): if ((args[1] == '--help') or (args[1] == '-h')): JournalHelp() elif ((args[1] == '--status') or (args[1] == '-S')): JournalStatus(journal, [displaylength, '0'], 'chrono') elif (args[1] == '-SA'): JournalStatus(journal, [displaylength, '0'], 'alpha') elif (args[1] == '-SR'): JournalStatus(journal, [displaylength, '0'], 'rank') else: print "Command not recognized, try '--help' for more information." elif (len(args) == 3): if ((args[1] == '--read') or (args[1] == '-r')): ReadJournal(journal, [displaylength, '0'], args[2]) elif ((args[1] == '-remove') or (args[1] == '-R')): RemoveEntry(journal, args[2]) elif ((args[1] == '--search') or (args[1] == '-s')): SearchJournal(journal, [displaylength, '0'], args[2]) elif ((args[1] == '--view') or (args[1] == '-v')): ViewEntry(journal, args[2]) elif ((args[1] == '--status') or (args[1] == '-S')): JournalStatus(journal, [displaylength, args[2]]) elif (args[1] == '-SA'): JournalStatus(journal, [displaylength, args[2]], 'alpha') elif (args[1] == '-SR'): JournalStatus(journal, [displaylength, args[2]], 'rank') else: print "Command not recognized, try '--help' for more information." elif (len(args) >= 4): if ((args[1] == '--update') or (args[1] == '-u')): AddEntry(journal, args[2], args[3:]) elif ((args[1] == '--view') or (args[1] == '-v')): ViewEntries(journal, args[2], args[3]) elif ((args[1] == '--read') or (args[1] == '-r')): ReadJournal(journal, [displaylength, args[3]], args[2]) elif ((args[1] == '--search') or (args[1] == '-s')): SearchJournal(journal, [displaylength, args[3]], args[2]) else: print "Command not recognized, try '--help' for more information." SaveJournal(journal, journalfile) if (showinfo): print ""