filesnake / filesnake / gui /

# -*- coding=utf-8 -*-

from ..pygtkhelpers.ui.objectlist import ObjectList, Column
from ..pygtkhelpers.delegates import SlaveView,ToplevelView
from ..pygtkhelpers.utils import gsignal,refresh_gui

from gobject import GObject
import datetime
import time

class TransferList(SlaveView):
    The widget that displays the filesnake transfers

    def create_ui(self):        
        listing = ObjectList([
                Column("filename", str, resizable = True),
                Column("status", str),
                Column("size", str),
                Column("complete", int, use_progress=True),
                Column("peer", str)

        self.objectlist = listing

    def append(self, item):
        item.connect("changed", self.objectlist.update)
class TransfersDialog(ToplevelView):
    def create_ui(self):
        self.transferlist = TransferList()
        self.add_slave(self.transferlist, "transferlist_cont")
    def on_widget__delete_event(self, w, e): 
        return True

    def add_transfer(self, name, filename, size):
        Add a new transfer and return the object connected with the GUI
        newmon = TransferMonitor(filename, size)
        newmon.peer = name
        return newmon

    def append(self, item):
        # Item must be a TransferMonitor
        item.connect("changed", self.objectlist.update)
    def remove_completed(self):
        for item in self.objectlist:
            if item.completed == 100:

def prettify_byte_size(size):
    '''Makes a nice representation of sizes:
    - 10 b
    - 10.2 Kb
    - 56.1 Mb
    - 3.6 Gb
    if size < 1024:
        return "{0} b".format(size)
    elif 1024 <= size <  1048576:
        return "{0:.1f} Kb".format(size/1024.0)
    elif 1048576 <= size < 1073741824:
        return "{0:.1f} Mb".format(size/1048576.0)  
    elif size >= 1073741824:
        return "{0:.1f} Gb".format(size/1073741824.0)  

class TransferMonitor(GObject):
    This class monitors a transfer, and updates the info associated
    with the transfer, it's observed by the GUI


    def __init__(self, filename, size):
        super(TransferMonitor, self).__init__()
        self.filename = filename
        self.size = size        # Total size of the transfer
        self.progress = 0       # bytes transferred
        self.status = "waiting" # status of the transfer
        self.speed = 0          # Speed in byte/sec
        #self.ETA = 0            # Estimate of the time
        self.complete = 0
        self._count = 0
    def ETA(self):
        if self._speed==0:
            return u"∞"
            # Seconds remaining
            s = (self._size - self.progress) / self._speed
            # Formatting a nice string
            hours, remainder = divmod(s, 3600)
            minutes, seconds = divmod(remainder, 60)
            return "%dh:%dm:%ds"%(hours,minutes,seconds)

    def size(self):
        return prettify_byte_size(self._size)
    def size(self, value):
        self._size = value

    def speed(self):
        value = self._speed
        return prettify_byte_size(value)+"/s"
    def speed(self, value):
        Set speed in byte/s
        self._speed = value

    def update_speed(self):
        '''This function keep tracks of the time between two
        "producing" calls, letting displaying the speed
        if not hasattr(self, "_old_progress"):
            self._old_progress = self.progress

        prog =  self.progress - self._old_progress 
        self._old_progress = self.progress
        self.speed = prog/self.time_interval()

    def time_interval(self):
        Keeps a time interval between two calls
        if not hasattr(self,"_prec"):
        cur = time.time()
                                # Avoid zero division error
        ret = cur - self._prec
        return ret

    def producing(self,data):
        Called when the source is producing data
        self.status = "receiving"
        chunk = len(data)
        # self._size is the size in byte
        if self.progress + chunk > self._size:
            raise ValueError("Producing more data that the declared one")
        self.progress += chunk        
        self.complete = self.progress*100/self._size 

        if self._count%100 == 0:

        if self.progress == self.size:
    def pause(self):
        Called when the source is paused
        self.status = "pause"
    def stop(self):
        Called when the source has stopped sending files, ungracefully
        self.status = "stop"
    def finish(self):
        The source has finished to do its stuff
        self.status = "finished"

def test():
    a = TransfersDialog()
    for i in range(3):
        mon = a.add_transfer("galois", "filename%d"%i, 1024)
    for i in range(100):

def test_monitor():
    tm = TransferMonitor("hello.pdf", 1400)
    tm.speed = 15
    res = tm.speed 
    assert (res == "15 b/s")
    tm.speed = 0
    res = tm.speed
    assert (res == "0 b/s")
    tm.speed = 10000
    res = tm.speed
    assert (res== "9.8 Kb/s")

def test_eta():
    tm = TransferMonitor("hello.pdf", 1400)
    tm.speed = 15
    eta = tm.ETA
    assert eta == "0h:1m:33s"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.