summaryrefslogtreecommitdiffstats
path: root/BitTorrent/StatusLight.py
diff options
context:
space:
mode:
Diffstat (limited to 'BitTorrent/StatusLight.py')
-rw-r--r--BitTorrent/StatusLight.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/BitTorrent/StatusLight.py b/BitTorrent/StatusLight.py
new file mode 100644
index 0000000..11cbf14
--- /dev/null
+++ b/BitTorrent/StatusLight.py
@@ -0,0 +1,108 @@
+from BitTorrent.platform import bttime
+
+class StatusLight(object):
+
+ initial_state = 'stopped'
+
+ states = {
+ # state : (stock icon name, tool tip),
+ 'stopped' : ('bt-status-stopped',
+ _("Paused")),
+ 'empty' : ('bt-status-stopped',
+ _("No torrents")),
+ 'starting' : ('bt-status-starting',
+ _("Starting download")),
+ 'pre-natted': ('bt-status-pre-natted',
+ _("Starting download")),
+ 'running' : ('bt-status-running',
+ _("Running normally")),
+ 'natted' : ('bt-status-natted',
+ _("Downloads may be slow:\nProbably firewalled/NATted")),
+ 'broken' : ('bt-status-broken',
+ _("Check network connection")),
+ }
+
+ messages = {
+ # message : default new state,
+ 'stop' : 'stopped' ,
+ 'empty' : 'empty' ,
+ 'start' : 'starting' ,
+ 'seen_peers' : 'pre-natted',
+ 'seen_remote_peers' : 'running' ,
+ 'broken' : 'broken' ,
+ }
+
+ transitions = {
+ # state : { message : custom new state, },
+ 'pre-natted' : { 'start' : 'pre-natted',
+ 'seen_peers' : 'pre-natted',},
+ 'running' : { 'start' : 'running' ,
+ 'seen_peers' : 'running' ,},
+ 'natted' : { 'start' : 'natted' ,
+ 'seen_peers' : 'natted' ,},
+ 'broken' : { 'start' : 'broken' ,},
+ #TODO: add broken transitions
+ }
+
+ time_to_nat = 60 * 5 # 5 minutes
+
+ def __init__(self):
+ self.mystate = self.initial_state
+ self.start_time = None
+
+ def send_message(self, message):
+ if message not in self.messages.keys():
+ #print 'bad message', message
+ return
+ new_state = self.messages[message]
+ if self.transitions.has_key(self.mystate):
+ if self.transitions[self.mystate].has_key(message):
+ new_state = self.transitions[self.mystate][message]
+
+ # special pre-natted timeout logic
+ if new_state == 'pre-natted':
+ if (self.mystate == 'pre-natted' and
+ bttime() - self.start_time > self.time_to_nat):
+ # go to natted state after a while
+ new_state = 'natted'
+ elif self.mystate != 'pre-natted':
+ # start pre-natted timer
+ self.start_time = bttime()
+
+ if new_state != self.mystate:
+ #print 'changing state from', self.mystate, 'to', new_state
+ self.mystate = new_state
+ self.change_state()
+
+ def change_state(self):
+ pass
+
+
+import gtk
+
+class GtkStatusLight(gtk.EventBox, StatusLight):
+
+ def __init__(self, main):
+ gtk.EventBox.__init__(self)
+ StatusLight.__init__(self)
+ self.main = main
+ self.image = None
+ self.images = {}
+ for k,(s,t) in self.states.items():
+ i = gtk.Image()
+ i.set_from_stock(s, gtk.ICON_SIZE_LARGE_TOOLBAR)
+ i.show()
+ self.images[k] = i
+ self.set_size_request(24,24)
+ self.main.tooltips.set_tip(self, 'tooltip')
+ self.send_message('stop')
+
+ def change_state(self):
+ state = self.mystate
+ assert self.states.has_key(state)
+ if self.image is not None:
+ self.remove(self.image)
+ self.image = self.images[state]
+ self.add(self.image)
+ stock, tooltip = self.states[state]
+ self.main.tooltips.set_tip(self, tooltip)