Table of Contents

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

msgread.mpy
#####################################################
# 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

mcihelp.mpy
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

filelist.mpy
###################################################
# 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

dump.mpy
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)