#!/usr/bin/python# Filip Lundborg (filip@mkeyd.net)import socket,os# All the different daemon-statesstate={\ "0": "Up to date", \ "1": "Synchronizing", \ "2": "Not connected", \ "NA": "Not available" \ # except for that last one # it's for when we're not connected to the daemon. }class DB(): def __init__(self): self.connected=False self.state="NA" def connect(self): # try to connect try: self.cmd=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.iface=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.cmd.connect(os.path.expanduser("~/.dropbox/command_socket")) self.iface.connect(os.path.expanduser("~/.dropbox/iface_socket")) except Exception,e: return False # alright, so we're connected to both sockets self.connected=True self.tmp="" return True# def disconnect(self):# asdf# garbagecollector <3 def get_state(self): "Waits for a state change, and then returns it." if not self.connected: return state["NA"] tmp=self.tmp flg=False while True: t=self.iface.recv(1024) if t=="": self.connected=False return state["NA"] tmp+=t if len(t)>=1024: continue # there's more to get. res=tmp.split("done\n") self.tmp=tmp=res[-1] # put the rest back in tmp res=res[:-1] # and just take the whole commands for s in res: if s.startswith("change_state"): flg=True self.state=s[23] # magic numbers, terrible :S # it's from "change_state\nnew_state\t1\n" # we want the 1, which can be 0, 1 or 2. # look at the state dictionary further up. if flg: return state[self.state] def get_state_nonblocking(self): "Fetches the state, if there's a state change. Otherwise it returns the last state." if not self.connected: return state["NA"] # now we should fetch all the data from the iface-socket # and see if there's anything new interesting res=self.tmp while True: tmp=self.iface.recv(1024) if (tmp==""): self.connected=False return state["NA"] res+=tmp if len(tmp)<1000: break # if we didnt fill the buffer, there shouldn't be anything # more to fetch. res=res.split("done\n") for s in res: if s.startswith("change_state"): self.state=s[23] # same magic number, hehe. return state[self.state] def ask_for_state(self): """This one asks for the state directly to the daemon. For some reasen, it doesn't always give you a state... which leaves me clueless.""" if not self.connected: return state["NA"] self.cmd.send("get_dropbox_globals\nkeys\ticon_state\ndone\n") res=self.cmd.recv(1024) if res=="": self.connected=False return state["NA"] try: res=res.split("\t") if res[1][0] != "\n": self.state=res[1][0] else: # we didn't get a state this time. eh. self.state="NA" except Exception, e: # for some reason here, the daemon threw us a .. strange line back. self.state="NA" return state[self.state]# Actually, there should be pretty easy to add further commands.# Just like the old module, this could be modified to ask for different files status.# example usage:if __name__=="__main__": import time db=DB() while True: if not db.connect(): time.sleep(1) # to not wear out the CPU ;) while db.connected: print db.get_state()