#!/usr/bin/env python import getpass, urllib2, ClientForm, tempfile, os, time, webbrowser, sys import getopt from sys import argv def quote_paranoid(text): """ Convert utf-8 string to sequence of lower case English characters. """ text = text.encode('utf-8') result = '' for char in text: result += chr(ord('a') + ord(char)/16) +\ chr(ord('a') + ord(char)%16) return result def webbrowser_open(u): os.spawnvp(os.P_NOWAIT, "firefox", ["firefox", u]) AETHER_TOP = "http://www.example.com/aether.cgi" EDITOR = os.environ.get("EDITOR", "vim") PASS = getpass.getpass() def get_edit_form(page): url = AETHER_TOP + "?action=edit&password=%s&name=%s" % (PASS, page) forms = ClientForm.ParseResponse(urllib2.urlopen(url)) for f in forms: try: action = f.get_value("action") except ClientForm.ControlNotFoundError: continue if action == "edit": global F; F=f return f def get_current_text(page): f = get_edit_form(page) return f.get_value("text") def preview_text(page, newtext): f = get_edit_form(page) f.method = 'GET' f['text'] = newtext u = f.click("preview") return u.get_full_url() def upload_file(page, local, remote): if os.path.basename(local) == remote: print "uploading %s on page %s" % (remote, page) else: print "uploading %s as %s on page %s" % (local, remote, page) qPASS = quote_paranoid(PASS) qpage = quote_paranoid(page) url = AETHER_TOP + "?action=attachments&password=%s&name=%s" % (qPASS,qpage) forms = ClientForm.ParseResponse(urllib2.urlopen(url)) f = forms[0] f.add_file(open(local, "rb"), filename=remote, name="file") u = f.click("attach") urllib2.urlopen(u) def edit_page(page): t = get_current_text(page) fd, name = tempfile.mkstemp(suffix=".ae", text=True) os.write(fd, t) os.close(fd) pid = os.spawnvp(os.P_NOWAIT, EDITOR, [EDITOR, name]) ost = os.stat(name) while 1: nst = os.stat(name) if ost.st_mtime != nst.st_mtime: ost = nst new_text = open(name).read() u = preview_text(page, new_text) webbrowser_open(u) sts = os.waitpid(0, os.P_NOWAIT) if sts[0] == pid: break time.sleep(1) os.unlink(name) opts, args = getopt.getopt(argv[1:], "+nur:") do_new_entry = do_upload = False for k, v in opts: if k == "-n": do_new_entry = True if k == "-u": do_upload = True if k == "-r": AETHER_TOP = v if do_upload: page = args[0] for filename in args[1:]: if "=" in filename: remote, local = filename.split("=", 1) else: remote = os.path.basename(filename) local = filename upload_file(page, local, remote) else: if do_new_entry: if args: page = args[0] + "/0" + str(int(time.time())) else: page = "0" + str(int(time.time())) else: if args: page = args[0] else: page = "sandbox" edit_page(page)