====== Mystic Python Examples ====== This page contains examples of code using Mystic Python. Use the table of contents to jump to the various examples below. ----- ===== Simple Message Reader ===== ##################################################### # Simple Message Reader Example using Mystic Python # ##################################################### # Reads messages in the user's current message base # With a pause prompt and basic navigation from mystic_bbs import * # Load the current user and then load their current message base # but fail if they have not selected a message base user = getuser(0) mbase = getmbaseid(user["mbase"]) if mbase is None: writeln ("|CRYou have not selected a message base yet!|CR|CR|PA") quit() # Open the message base then check to make sure its open before reading # data from it msg = msg_open(mbase["path"] + mbase["filename"]); if msg is None: quit() done = False # Seek to the first message in the base and loop while a message # is found, calling msg_next after each message so the next one # will be loaded. Seek must be called first even if reading # from the first message. msg_seek(msg, 0) while msg_found(msg) and not done and not shutdown(): # Load the message header information into a dictionary # and the message text into a list msghdr = msg_gethdr(msg) msgtext = msg_gettxt(msg) # Show the message header, setting a line counter that can # be used to pause the screen writeln("|16|CL|15Msg#: " + str(msghdr["number"]) + " of " + str(msghdr["highmsg"])) writeln("|14From: " + msghdr["from"]); writeln("|13 To: " + msghdr["to"]); writeln("|11Subj: " + msghdr["subj"]); writeln("|09-------------------------------------------------------------------------------|07"); pausecount = 4 # loop through each line in the message (list) and pause when # we get more than 23 lines for line in msgtext: # before printing a line check if we need to pause if pausecount >= 23: pausecount = 1 write("|14*PAUSE* Continue? (|15Y|14)es, (|15N|14)o, (|15Q|14)uit: |07") ch = onekey(chr(13) + 'YNQ', False) # after getting input, erase the pause prompt then process the input backspace(wherex(), True) if ch == 'Q': done = True break elif ch == 'N': break # increase pause counter and send a line of message text # unless it is a kludge line: if (line == "") or (line != "" and line[0] != chr(1)): pausecount += 1 writeln(line) # At end of message, so lets give a prompt if we didn't get a quit # from the pause prompt: if not done: write("|CR|09MSG READER: (|11A|09)gain, (|11P|09)revious, (|11ENTER|09) Next, (|11Q|09) to Quit: ") ch = onekey(chr(13) + 'APQ', True); if ch == 'A': # do nothing here so it redisplays the same msg pass elif ch == 'P': if msghdr["number"] != 1: msg_prev(msg) elif ch == 'Q': done = True break else: msg_next(msg); # Close the message base and report that we're done msg_close(msg) writeln("|CR|12Program complete: Press a key|PN"); ----- ===== MCI Helper Functions ===== import mystic_bbs as bbs; def stripmci (str): pos = str.find("|") while pos != -1: str = str[:pos] + str[pos+3:] pos = str.find("|") return str def mcilen (str): return len(stripmci(str)) text = "|12This is a |14test"; bbs.rwriteln(stripmci(text)); bbs.rwriteln(str(mcilen(text))) bbs.writeln("|PA") ----- ===== Simple File Lister ===== ################################################### # Simple File Listing Example using Mystic Python # ################################################### # List files in the user's current file base from mystic_bbs import * # filelist flags file_offline = int("01") file_invalid = int("02") file_deleted = int("04") file_failed = int("08") file_free = int("10") file_hatched = int("20") # Load the current user and then load their current file base # but fail if they have not selected a file base user = getuser(0) fbase = getfbaseid(user["fbase"]) if fbase is None: writeln ("|CRYou have not selected a file base yet!|CR|CR|PA") quit() # Open the file list then check to make sure its open before reading # data from it flist = fl_open(fbase["filename"]); if flist is None: writeln("Cannot open file listing. Press a key|PN") quit() done = False # Seek to the first file in the list and loop while a file is found calling # next after each file so the next one will be loaded. Seek should always be # called before cycling through the list fl_seek(flist, 0, True) while fl_found(flist) and not done and not shutdown(): # Load the file information into a dictionary and then get the file # description fileinfo = fl_getfile(flist) filedesc = fl_getdesc(flist) # Show the file writeln("|CL|14File #" + str(fileinfo["number"]) + " of " + str(fileinfo["total"])) writeln("") writeln("|09File: |11" + fileinfo["filename"]) writeln("|09Date: " + datestr(dated2u(fileinfo["date"]), "NNN DD YYYY HH:II:SS")) writeln("Size: " + str(fileinfo["size"])) writeln("DLs : " + str(fileinfo["dls"])) writeln("ULer: " + fileinfo["ulname"]) flags = "" if fileinfo["flags"] & file_offline: flags = flags + "OFFLINE " if fileinfo["flags"] & file_invalid: flags = flags + "INVALID " if fileinfo["flags"] & file_deleted: flags = flags + "DELETED " if fileinfo["flags"] & file_failed: flags = flags + "FAILED " if fileinfo["flags"] & file_free: flags = flags + "FREE " if fileinfo["flags"] & file_hatched: flags = flags + "HATCHED " if flags == "": flags = "NONE" writeln("Flag: |13" + flags) writeln("") writeln("|14Description (" + str(fileinfo["lines"]) + " lines):") writeln("|03") # only print up to the first 10 lines so we can fit it on the screen for line in range(min(fileinfo["lines"], 10)): writeln(filedesc[line]) writeln("") write("|16|09File List: (|11A|09)gain, (|11P|09)revious, (|11ENTER|09) Next, (|11Q|09) to Quit: |14") ch = onekey(chr(13) + 'APQ', True); if ch == 'A': # do nothing here so it redisplays the same file pass elif ch == 'P': fl_prev(flist) elif ch == 'Q': done = True break else: fl_next(flist); # Close the file list and report that we're done fl_close(flist) writeln("|CR|12Program complete: Press a key|PN"); ===== View Dictionaries and Lists ===== from mystic_bbs import * # Dump contents of a dictionary or list to the screen with # screen pause def dump (obj, linecount): if linecount == 1: textcolor(7) if type(obj) == dict: for k, v in obj.items(): if hasattr(v, '__iter__'): writeln(k) dump(v, linecount) else: writeln ("{} : {}".format(k,v)) linecount = linecount + 1 if linecount == 23: write("|PA|07") elif type(obj) == list: for v in obj: if hasattr(v, '__iter__'): dump(v, linecount) else: writeln ("{}".format(v)) linecount = linecount + 1 if linecount == 23: write("|PA|07") else: writeln("{}".format(obj)) linecount = linecount + 1 if linecount == 23: write("|PA|07") # grab the current user and dump the contents of their user dictionary # This function can be used to dump anything, users, bases, groups, etc writeln("|CL|14Dumping contents of user:|07") user = getuser(0) dump(user, 1)