CP at NUCC put these scripts together to handle communication with the BOINC server for our element14 Presents collaboration.
boinc.py
import subprocess
class boinc():
  # Executes boinccmd commands
  def cmd(self, command):
    try:
      command.insert(0, "boinccmd")
      p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      return p.communicate()
    except OSError:
      print("[-] Boinccmd is not installed. Try apt-get install boinc-client")
      quit()
    except:
      print("[-] Error! '%s' failed." % (command))
      return None
  def get_tasks(self):
    return self.fss_parser(self.bcmd_rparse(self.cmd(["--get_tasks"])))
  def bcmd_rparse(self, resp):
    if resp == ('',''): # No Message, No Error. Looks like things went well.
      return True
    #fail
    # there seems to be a bug with certain boinccmd communications to boinc clients, change this to check for resp0 before returning false for the presence of resp1
    if resp[1].startswith("Operation failed: Error 2"):
      return resp[0].strip()
    mesres = {
      "can't connect to"                       : "[-] Boinccmd can't contact worker. Check BOINC client settings/process.",
      "Operation failed: read() failed"        : "[-] Boinccmd can't contact worker. BOINC client seems to be running, check remote GUI RPC settings.",
      "RPC error: Already attached to project" : "[-] Worker is already attached to project.",
      "RPC error: No such project"             : "[-] Worker is not attached to this project.",
      "RPC error: no such result"              : "[-] No such result. No such task exists?"}
    if resp[1]:
      for mr in mesres:
        if resp[1].startswith(mr):
          print(mesres[mr])
          return False
      print("Error!" + resp[1])
      return False
    return resp[0].strip() # FSS or other data
  def fss_parser(self, fss_raw):
    if fss_raw in ["", None, False]: # I did this for reasons, what they are I no longer remember
      return None
    if "======== " not in fss_raw:
      fss_data = self.fss_subparser(fss_raw)
      return fss_data
    fss_chunks = fss_raw.split("======== ")
    fss_data   = {}
    for chunk in fss_chunks:
      name = chunk.strip().split("\n")[0][0:-9]
      if name is not "":
        fss_data[name] = None
        if ") -----------" not in chunk: # This section has no subsections
          fss_data[name] = self.fss_subparser(chunk)
        else: # This section should have subsections
          fss_data[name] = []
          for chunklet in chunk.split(") -----------")[1:]:
            chunklet = chunklet.split("GUI URL:")[0] # We don't need the rest
            fss_data[name].append(self.fss_subparser(chunklet))
    return fss_data
  def fss_subparser(self, fss_chunk):
    data = {}
    for line in fss_chunk.strip().split("\n"):
      if ":" in line:
        if line.strip().endswith(":"):
          line += "N/A" # "default" value for if no value exists
        var, val  = line.strip().split(":",1)
        data[var.strip()] = val.strip()
    return data
start_here.sh (run as root on startup)
sudo apt-get install boinc-client boinccmd --project_attach http://setiathome.berkeley.edu/ [your BOINC project ID] boinccmd --project_attach http://asteroidsathome.net/boinc/ [your BOINC project ID]
tasks.py (to get percentage complete updates)
import boinc
bnc = boinc.boinc()
tasks  =  bnc.get_tasks()['Tasks']
for task in tasks:
  print task
  print
print
for key, value in tasks[0].iteritems():
  print '%s: %s' % (key,value)
print
print
for task in tasks:
  done_percent = task['fraction done']
  print "task %s is %s done" % (task['name'], "{0:.2%}".format(float(task['fraction done'])))