(''Note: Newer version on #Python Wiki, see below. '''ALSO, I need to remove all that experimental "tag" function stuff....''''')
Based on IckyWiki by DirckBlaskey, this wiki is comparable in size but I'm doing a little refactoring on it. See if you can find the differences:
#! D:/PYTHON21/PYTHONW.EXE
""" NicksWiki - (still concerned about file locking?) """
### DirckBlaskey 8/3/01 1:50PDT http://www.danbala.com
### NickBensema 8/3/01 6:58MST http://www.io.com/~nickb
import os, sys, re, cgi, time, winsound
os.chdir("c:\\mydocu~1\\testpiki\\") # yes, it's My Documents.
DWiki,Default = os.path.basename(sys.argv[0]), 'FrontPage'
RLink = '[d^:]' % DWiki
def tag(t, *text): return "<%s>%s%s>" % (t, "".join(text), t)
def huh(w): return "
%s ???huh???
" % RLink
def exists(w): return os.access(w, os.R_OK)
def contents(w): return exists(w) and open(w).read()
def wlink(w, op="get", t=None):
return '%s' % (DWiki, op, w, t or w)
def flink(w, t): return wlink(w, t.split()[0].lower(), t.title())
wsearch = re.compile("(^|[^A-Za-z0-9\?=]+)(([A-Z][a-z]+){2,})").search
Env, Args = os.environ.get, {} # Env temporarily not-in-use
for i in cgi.FieldStorage().list: Args[i.name] = i.value
Words = {}
for word in filter(wsearch, os.listdir(".")): Words[word] = os.path.getmtime(word)
print "Content-type: text/html\r\n\r\n",
class Main:
def __init__(self):
op,word = Args.get('op', "get"), Args.get('word', Default)
if not word.isalpha(): op,word = "recent",Default # close hack door
print getattr(self, op, huh)(word) # self.op(word) or ?huh?
def get(self, w):
winsound.Beep(440,60)
d = wikifi(contents(w) or "Please create this page.")
return '''%s%s%s
%s
%s %s %s''' % (w, RLink,
wlink(w,"search"), d, flink(w,"Edit Page"),
flink(w,"Like Pages"), flink(w,"Recent Changes"))
def edit(self, w):
winsound.Beep(2600,60)
d = contents(w) or "Describe "+w
return '''%s
''' % (w, DWiki, w, w, time.time(), d)
def save(self, w):
for x in xrange(1,5): winsound.Beep(440 * (2**x), 100)
if int(Args["date"]) < Words[w]:
winsound.Beep(120,1000)
return "Couldn't save; file changed by someone else.
"
if "Data" in Args:
open(w, "wb").write(Args["Data"])
return self.get(w)
def recent(self, w):
datelist = [(date, word) for word, date in Words.items()]
datelist.sort()
lines = "\n".join(["%s %s" % (wlink(w), time.ctime(d))
for d, w in datelist[-20:]])
return ('''
Recent Changes
%sRecent Changes
%s
''' % (RLink, lines))
def search(self, w):
winsound.Beep(120,60)
findmatches = re.compile(w).search
pages = [x for x in Words.keys() if findmatches(contents(x))]
lines = ''.join(map(wlink, pages))
return ('''
Searched %s
%sSearch results for: %s
%s
''' % (w, RLink, wlink(w), lines))
def like(self, w):
winsound.Beep(120,60); winsound.Beep(200,60); winsound.Beep(120,60)
first, last = re.match("^([A-Z][a-z]+).*?([A-Z][a-z]+)$", w).groups()
findFirst = re.compile("^%s[A-Z]" % first).search
findLast = re.compile("[a-z]%s$" % last).search
matchesFirst = "".join(map(wlink, filter(findFirst,Words.keys())))
matchesLast = "".join(map(wlink, filter(findLast,Words.keys())))
return ('''Pages like %s
%sPages like: %s
''' %
(w, RLink, wlink(w), matchesFirst, matchesLast))
def wikifi(a):
r = ""
while True:
match = wsearch(a)
if not match: break
s, e = match.start(2), match.end(2)
w = a[s:e]
if exists(w): w = wlink(w, "get")
else: w += wlink(w, "edit", "?")
r, a = r + a[:s] + w, a[e:]
return r + a
if __name__=="__main__":
try: Main()
except: cgi.print_exception()
I'm trying to do things OnceAndOnlyOnce, and that's why I've added functions '''exists()''' and '''contents()'''. It added two lines of code, but allowed me to remove '''except:''' clauses which originally trapped file-not-found errors, which saved me... ''ahem''... two lines. But still, it uses a read-access check to see if the file exists. I hardly need the Words dictionary at all. In fact, the only function that uses Words anymore is the search() function, which no longer uses popen(). And I'm well aware that Dirck's search() didn't need the Words dictionary. Soon mine won't either. :)
I have Python 2.1 and I love list comprehensions, so expect some of those in my code.
I also changed wlink() so that it accepted the wikiword first, so that I could default the operator to "get".
I removed the msvcrt code, throwing caution to the wind, since writing the data files in binary mode seems to work fine on my system.
I'll add LikePages real soon now; it was working in a previous version.
--NickBensema
'''Update 8/6/01 4:33am:''' First, I got rid of the pickled Words file, made the program too fragile. I also made the program detect its own name as I had several versions of the file and I didn't want them pointing at each other. It'd be pretty easy to change that "Words[word] = 1" to grab the file's date, and thus pave the way for '''file locking!''' I'd like Recent Changes first, though....
'''Update 8/6/01 7:04am:''' File locking is working in the latest version. Find further notes and versions here: http://twistedmatrix.com/users/jh.twistd/python/moin.cgi/NicksWiki -- I figured I'd move it to #Python's wiki because those people might be more motivated to rip this code apart. I also added winsound.Beep() calls so that it makes noise when people call up my server.
----
CategoryWikiImplementation