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'])))