321 lines
8.7 KiB
Plaintext
Executable File
321 lines
8.7 KiB
Plaintext
Executable File
import sys, pickle
|
|
from random import randint
|
|
from pprint import pprint as pp
|
|
from mystic_bbs import *
|
|
|
|
NODELIST = "/mystic/data/nodelist.txt"
|
|
RATING_FILE = "/mystic/scripts/mL-nlparse.dat"
|
|
dictNodelist = {}
|
|
ratingsDB = {}
|
|
canexit = "no"
|
|
screenWidth = 80
|
|
screenDepth = 24
|
|
AUTHOR = "MeaTLoTioN"
|
|
cRESET = "|16|07"
|
|
hBG = "|20"
|
|
hFG = "|14"
|
|
fBG = "|20"
|
|
fFG = "|14"
|
|
barOffset = 1
|
|
highlightedBBS = ""
|
|
|
|
KEY_UP = chr(72)
|
|
KEY_DOWN = chr(80)
|
|
KEY_ESCAPE = chr(27)
|
|
KEY_ENTER = chr(13)
|
|
KEY_TAB = chr(9)
|
|
KEY_LEFT = chr(75)
|
|
KEY_RIGHT = chr(77)
|
|
|
|
def saveDB():
|
|
global ratingsDB
|
|
global RATING_FILE
|
|
with open(RATING_FILE, 'wb') as fhandle:
|
|
pickle.dump(ratingsDB, fhandle, protocol=pickle.HIGHEST_PROTOCOL)
|
|
|
|
def loadDB():
|
|
global ratingsDB
|
|
global RATING_FILE
|
|
try:
|
|
with open(RATING_FILE, 'rb') as fhandle:
|
|
ratingsDB = pickle.load(fhandle)
|
|
except:
|
|
pass
|
|
|
|
def stripmci(str):
|
|
pos = str.find("|")
|
|
while pos != -1 :
|
|
str = str[:pos] + str[pos+3:]
|
|
pos = str.find("|")
|
|
return str
|
|
|
|
def initNodelist():
|
|
with open(NODELIST) as f:
|
|
lines = f.readlines()
|
|
|
|
for line in lines:
|
|
if line.startswith(";"):
|
|
pass
|
|
else:
|
|
tmp = line.strip("\n").split(",")
|
|
if tmp[0] == "Zone":
|
|
ZONE = tmp[1]
|
|
elif tmp[0] == "Region" or tmp[0] == "Host":
|
|
REGION = tmp[1]
|
|
else:
|
|
NODE = tmp[1]
|
|
BBS_NAME = tmp[2]
|
|
if BBS_NAME not in dictNodelist:
|
|
dictNodelist[BBS_NAME] = {}
|
|
|
|
BBS_NAME_PRETTY = BBS_NAME.replace("_"," ")
|
|
BBS_LOCATION = tmp[3]
|
|
BBS_SYSOP = tmp[4]
|
|
|
|
test = [string for string in tmp if "NA" in string]
|
|
if test:
|
|
BBS_ADDRESS_FULL = test[0][4:]
|
|
else:
|
|
BBS_ADDRESS_FULL = "Private"
|
|
|
|
BBS_ADDRESS = BBS_ADDRESS_FULL.split(":")[0]
|
|
|
|
if ":" in BBS_ADDRESS_FULL:
|
|
BBS_PORT = BBS_ADDRESS_FULL.split(":")[1]
|
|
else:
|
|
BBS_PORT = 23
|
|
|
|
try:
|
|
if [match for match in tmp if "MY" in match]:
|
|
BBS_SOFTWARE = "Mystic"
|
|
elif [match for match in tmp if "SC" in match]:
|
|
BBS_SOFTWARE = "Synchronet"
|
|
elif [match for match in tmp if "SYNC" in match]:
|
|
BBS_SOFTWARE = "Synchronet"
|
|
elif [match for match in tmp if "MB" in match]:
|
|
BBS_SOFTWARE = "MBSE"
|
|
elif [match for match in tmp if "LGCX" in match]:
|
|
BBS_SOFTWARE = "Legacy/X"
|
|
elif [match for match in tmp if "ENIG" in match]:
|
|
BBS_SOFTWARE = "Enigma1/2"
|
|
elif [match for match in tmp if "CNET" in match]:
|
|
BBS_SOFTWARE = "CNET"
|
|
elif [match for match in tmp if "PCB" in match]:
|
|
BBS_SOFTWARE = "PC Board"
|
|
elif [match for match in tmp if "OBV2" in match]:
|
|
BBS_SOFTWARE = "Oblivion 2"
|
|
elif [match for match in tmp if "WLDC" in match]:
|
|
BBS_SOFTWARE = "Wildcat"
|
|
else:
|
|
BBS_SOFTWARE = "n/a"
|
|
except:
|
|
BBS_SOFTWARE = "Undefined"
|
|
|
|
d = dictNodelist[BBS_NAME]
|
|
d["NAME"] = BBS_NAME_PRETTY
|
|
d["LOCATION"] = BBS_LOCATION
|
|
d["SYSOP"] = BBS_SYSOP
|
|
d["ADDRESS"] = BBS_ADDRESS
|
|
d["PORT"] = BBS_PORT
|
|
d["SOFTWARE"] = BBS_SOFTWARE
|
|
d["RATING"] = 0
|
|
|
|
if "NODE_ADDRESSES" not in d:
|
|
d["NODE_ADDRESSES"] = []
|
|
NODE_ADDRESS = "%s:%s/%s" % (ZONE,REGION,NODE)
|
|
d["NODE_ADDRESSES"].append(NODE_ADDRESS)
|
|
|
|
def init():
|
|
write("|CL")
|
|
header()
|
|
footer()
|
|
gotoxy(1,2)
|
|
|
|
def header():
|
|
MSG = "BBS Name".ljust(22)+" "+"SysOp".ljust(15)+" "+"Location".ljust(15)+" "+"Software".ljust(15)+" "+"Rating".ljust(6)+" "
|
|
gotoxy(1,1)
|
|
write(hBG+hFG+" "*screenWidth)
|
|
gotoxy(1,1)
|
|
write(MSG+cRESET)
|
|
|
|
def footer():
|
|
MSG = "Mystic Nodelist Browser v1.0 by "+AUTHOR
|
|
lMSG = len(MSG)
|
|
gotoxy(1,screenDepth)
|
|
write(fBG+fFG+" "*screenWidth)
|
|
gotoxy((screenWidth/2)-(lMSG/2),screenDepth)
|
|
write(MSG)
|
|
write(cRESET)
|
|
|
|
def getBBS(o, s):
|
|
global barOffset
|
|
selectedBBS = ""
|
|
count = 0
|
|
tmpDict = sorted(dictNodelist, reverse=False)
|
|
for BBS in tmpDict:
|
|
count += 1
|
|
if count == o+s:
|
|
selectedBBS = BBS
|
|
return selectedBBS
|
|
|
|
def showList(offset = 0):
|
|
global barOffset
|
|
global highlightedBBS
|
|
R = 1
|
|
count = 0
|
|
gotoxy(1,2)
|
|
write("|16|07")
|
|
tmpDict = sorted(dictNodelist, reverse=False)
|
|
for BBS in tmpDict:
|
|
count += 1
|
|
if count < offset+1:
|
|
pass
|
|
else:
|
|
R += 1
|
|
if R < screenDepth:
|
|
if barOffset+1 == R:
|
|
gotoxy(1,R)
|
|
write('|21|15')
|
|
C1 = BBS.replace('_',' ').ljust(22)[:22]
|
|
C2 = dictNodelist[BBS]["SYSOP"].replace('_',' ').ljust(15)[:15]
|
|
C3 = dictNodelist[BBS]["LOCATION"].replace('_',' ').ljust(15)[:15]
|
|
C4 = dictNodelist[BBS]["SOFTWARE"].replace('_',' ').ljust(15)[:15]
|
|
try:
|
|
C5 = ratingsDB[BBS]
|
|
except:
|
|
C5 = 0
|
|
thisLine = C1+" "+C2+" "+C3+" "+C4+" "+"|10"+(chr(254)*C5).rjust(7)
|
|
pad = " "*(79-len(thisLine))
|
|
writeln(thisLine.ljust(79)+pad+"|16|07")
|
|
|
|
def drawWindow(x1, y1, x2, y2, title = ""):
|
|
for Y in range(y1, y2):
|
|
for X in range(x1, x2):
|
|
gotoxy(X, Y); write(' ')
|
|
for I in range(x1+1, x2-1):
|
|
gotoxy(I, y1+1); write('|13'+chr(205))
|
|
gotoxy(I, y2-2); write('|05'+chr(205))
|
|
for I in range(y1+1, y2-1):
|
|
gotoxy(x1+1, I); write('|13'+chr(186))
|
|
gotoxy(x2-1, I); write('|05'+chr(186))
|
|
if title:
|
|
ntitle = "[ |15"+title+"|13 ]"
|
|
ltitle = len(stripmci(ntitle))
|
|
center = ((x2-x1)/2)-(ltitle/2)+x1
|
|
gotoxy(center, y1+1); write('|13'+ntitle)
|
|
gotoxy(x1+1,y1+1); write('|13'+chr(201))
|
|
gotoxy(x2-1,y1+1); write('|13'+chr(187))
|
|
gotoxy(x1+1,y2-2); write('|05'+chr(200))
|
|
gotoxy(x2-1,y2-2); write('|05'+chr(188))
|
|
|
|
def showDetail(BBS):
|
|
write("|SS")
|
|
bbs = BBS.replace('_',' ')[:22]
|
|
sysop = dictNodelist[BBS]["SYSOP"].replace('_',' ')
|
|
location = dictNodelist[BBS]["LOCATION"].replace('_',' ')
|
|
software = dictNodelist[BBS]["SOFTWARE"]
|
|
#rating = dictNodelist[BBS]["RATING"]
|
|
try:
|
|
rating = ratingsDB[BBS]
|
|
except:
|
|
rating = 0
|
|
address = dictNodelist[BBS]["ADDRESS"]
|
|
port = dictNodelist[BBS]["PORT"]
|
|
node_addresses = dictNodelist[BBS]["NODE_ADDRESSES"]
|
|
drawWindow(15,4,65,20,bbs)
|
|
|
|
gotoxy(18,7); write("|13BBS SysOp")
|
|
gotoxy(18,8); write('|15'+sysop)
|
|
gotoxy(51,7); write("|13BBS Location")
|
|
gotoxy(41,8); write('|15'+location.rjust(22))
|
|
|
|
gotoxy(18,10); write("|13BBS Address")
|
|
gotoxy(18,11); write('|15'+address+':'+str(port))
|
|
gotoxy(51,10); write("|13BBS Software")
|
|
gotoxy(41,11); write('|15'+software.rjust(22))
|
|
|
|
gotoxy(18,14); write("|13Node Address(es)")
|
|
count = 0
|
|
row = 1
|
|
for node_address in node_addresses:
|
|
count += 1
|
|
if count > 3:
|
|
count = 1
|
|
row += 1
|
|
gotoxy(6+(count*12), 14+row); write('|15'+node_address)
|
|
|
|
gotoxy(18,18); write("|13[ |15Q to go back |13]")
|
|
gotoxy(35,18); write("|13[ |10"+(chr(254)*rating).ljust(7)+" |13]")
|
|
gotoxy(47,18); write("|13[ |15C to connect |13]")
|
|
gotoxy(1,25);
|
|
canend = "no"
|
|
while not canend == "yes":
|
|
ch = onekey(chr(13) + 'CQ'+KEY_RIGHT+KEY_LEFT, False)
|
|
if ch == 'Q':
|
|
canend = "yes"
|
|
if ch == 'C':
|
|
gotoxy(1,25);write('C pressed')
|
|
if ch == KEY_LEFT:
|
|
if rating > 0:
|
|
rating -= 1
|
|
ratingsDB[BBS] = rating
|
|
saveDB()
|
|
gotoxy(35,18); write("|13[ |10"+(chr(254)*rating).ljust(7)+" |13]")
|
|
if ch == KEY_RIGHT:
|
|
if rating < 7:
|
|
rating += 1
|
|
ratingsDB[BBS] = rating
|
|
saveDB()
|
|
gotoxy(35,18); write("|13[ |10"+(chr(254)*rating).ljust(7)+" |13]")
|
|
write("|RS")
|
|
|
|
def mainMenu():
|
|
global barOffset, offset, highlightedBBS
|
|
maxOffset = len(dictNodelist)-screenDepth-1
|
|
finished = "no"
|
|
highlightedBBS = getBBS(barOffset, offset)
|
|
showList(offset)
|
|
char, extended = getkey()
|
|
|
|
if extended:
|
|
if char == KEY_UP:
|
|
if barOffset > 1:
|
|
barOffset -= 1
|
|
if barOffset == 1:
|
|
if offset > 0:
|
|
offset -= 1
|
|
highlightedBBS = getBBS(barOffset, offset)
|
|
if char == KEY_DOWN:
|
|
if barOffset < screenDepth-2:
|
|
barOffset += 1
|
|
elif barOffset > screenDepth-3:
|
|
if offset < maxOffset:
|
|
offset += 1
|
|
highlightedBBS = getBBS(barOffset, offset)
|
|
if char == KEY_LEFT:
|
|
if offset > screenDepth-3:
|
|
offset -= screenDepth-3
|
|
else:
|
|
offset = 0
|
|
highlightedBBS = getBBS(barOffset, offset)
|
|
if char == KEY_RIGHT:
|
|
if offset < maxOffset - (screenDepth-3):
|
|
offset += screenDepth-3
|
|
else:
|
|
offset = maxOffset
|
|
highlightedBBS = getBBS(barOffset, offset)
|
|
else:
|
|
if char == KEY_ENTER:
|
|
showDetail(highlightedBBS)
|
|
if char == KEY_ESCAPE:
|
|
finished = "yes"
|
|
return finished
|
|
|
|
loadDB()
|
|
initNodelist()
|
|
offset = 0
|
|
init()
|
|
highlightedBBS = getBBS(0, 0)
|
|
while canexit == "no":
|
|
canexit = mainMenu()
|