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