#!/usr/bin/env python
"""
Bookmarker - A bookmarks CGI, like delicious and such.
License: GPL 2; share and enjoy!
Author: Sean B. Palmer, inamidst.com
"""
import cgitb; cgitb.enable()
import sys, os, re, cgi, time, urllib
r_line = re.compile(r'^([^"<>\s]+) (?:- )?(.*?)(?: +\(([^()]+)\))?$')
r_title = re.compile(r'(?ims)
([^<]+)')
method = os.environ.get('REQUEST_METHOD')
bufsize = 2048
class Grab(urllib.URLopener):
def __init__(self, *args):
self.version = "Mozilla/5.0 (Bookmarker)"
urllib.URLopener.__init__(self, *args)
def http_error_default(self, url, fp, errcode, errmsg, headers):
return urllib.addinfourl(fp, [headers, errcode], "http:" + url)
urllib._urlopener = Grab()
if method == 'POST':
form = cgi.FieldStorage()
form.__call__ = lambda s: form[s].value
def serve(status, body, mime=None):
mime = mime or 'text/html'
sys.stdout.write("Status: %s\r\n" % status)
sys.stdout.write("Content-Type: %s; charset=utf-8\r\n\r\n" % mime)
sys.stdout.write(body)
sys.exit()
def getTitle(uri):
try: u = urllib.urlopen(uri)
except: return uri
else:
info = u.info()
if isinstance(info, list): return uri
if not info.get('Content-Type').count('text/html'):
u.close()
return uri
html = ''
while 1:
s = u.read(bufsize)
if not s: break
html += s
m = r_title.search(html)
if m:
u.close()
title = m.group(1)
return title.replace('\n', ' ').replace('\r', ' ')
u.close()
return uri
def add():
# @@ get SCRIPT_NAME and munge it
serve(200, """
""")
def mkindex():
b = {}
f = open('raw-bookmarks.txt')
while 1:
line = f.readline()
if not line: break
line = line.rstrip('\r\n')
t, uri, title, desc = line.split('\t')
if b.has_key(t[:10]):
b[t[:10]].append((t[-8:], uri, title, desc))
else: b[t[:10]] = [(t[-8:], uri, title, desc)]
f.close()
days = b.keys()
days.sort()
days.reverse()
result = ['Some Bookmarks']
link = ''
result.append(link)
result.append('
Some Bookmarks
')
for day in days:
pages = b[day]
pages.sort()
result.append('
%s:
' % day)
result.append('
')
for (t, uri, title, desc) in pages:
li = '
%s ' % (uri, title)
if desc: li += desc + ' '
li += '(%s)
' % t
result.append(li)
result.append('
')
result.append('')
result.append('Sean B. Palmer')
result.append('')
f = open('bookmarks.html', 'w')
f.write('\n'.join(result))
f.close()
def post():
if not form.has_key('text'):
serve(500, '
Form must have key "text".
\n')
text = form('text')
if not text.strip():
mkindex()
serve(200, "Rebuilt!\n", "text/plain")
lines = text.splitlines()
t = time.strftime('%Y-%m-%dT%H:%M:%S', time.gmtime())
f = open('raw-bookmarks.txt', 'a')
for line in lines:
line = line.strip()
if not line: continue
if line.find(' ') < 0:
uri = line
title = getTitle(uri)
desc = ''
else:
m = r_line.match(line)
if m:
uri, title, desc = m.groups()
else: serve(500, '
Invalid line: %r
\n' % line)
uri = uri.replace('\t', '%09')
title = (title or '').strip().replace('\t', ' ')
desc = (desc or '').strip().replace('\t', ' ')
f.write(t + '\t' + uri + '\t' + title + '\t' + desc + '\n')
f.close()
mkindex()
serve(200, "Added!\n", "text/plain")
def main(args=None):
if method == 'GET': add()
elif method == 'POST': post()
else: serve(501, "