from time import time import settings import state from websocket import trigger_event import logging logger = logging.getLogger(__name__) class Bandwidth(object): _last = {} def __init__(self): self._upload = Bucket('uploadRate') self._download = Bucket('downloadRate') self.update() def update(self): bandwidth = { 'up': self._upload.rate, 'down': self._download.rate } if bandwidth != self._last: trigger_event('bandwidth', bandwidth) self._last = bandwidth state.main.call_later(1, self.update) def download(self, amount): return self._download.consume(amount) def upload(self, amount): return self._upload.consume(amount) class Bucket(object): _rate = 0 fill_rate = None def __init__(self, pref): self._pref = pref self.update() self.timestamp = time() self.rate_timestamp = time() def update(self): rate = settings.preferences.get(self._pref, '') if rate and rate.isdigit(): rate = max(float(rate) * 1024, 0) if rate != self.fill_rate: self.capacity = max(rate, 2*16*1024) self._tokens = rate self.fill_rate = rate else: self.fill_rate = None def consume(self, tokens): self.update() if self.fill_rate is None: self._rate += tokens return True if tokens <= self.tokens: self._tokens -= tokens self._rate += tokens else: return False return True def get_tokens(self): now = time() if self._tokens < self.capacity: delta = self.fill_rate * (now - self.timestamp) self._tokens = min(self.capacity, self._tokens + delta) self.timestamp = now return self._tokens tokens = property(get_tokens) def get_rate(self): now = time() rate = self._rate * (now - self.rate_timestamp) self._rate = 0 self.rate_timestamp = now return rate rate = property(get_rate)