filesnake / filesnake / gui / main_win.py

# Pygtkhelpers imports
from ..pygtkhelpers.delegates import WindowView
from ..pygtkhelpers.ui.dialogs import yesno
from ..pygtkhelpers.ui import dialogs
import gtk

# GUI imports
from .menu import UserMenu
from .userlist import UserList,UserDiscovery
from .statusbar import StatusBar
from .transfers import TransferMonitor,TransfersDialog
from ..helpers.path import get_size
from .preferences import PreferencesDialog
import statusbar

# Networking imports
from ..networking.client import SendingClient
from ..networking.interfaces import IUIController
from ..helpers.path import avail_filename
from ..settings import dest_dir

from zope.interface import implements
from twisted.python import components

# Others
import os
import logging

cur_dir = os.path.dirname(__file__)
media_dir = os.path.join(cur_dir,"glade","images")

class FileSnakeGUI(WindowView):
    '''
    Main Entity of the application, it spawns clients and performs
    user requests. Optionally it delegates operation to other
    components
    '''
    
    builder_file = "main_win.glade"
    
    def __init__(self):
        super(FileSnakeGUI, self).__init__()
        
    def create_ui(self):
        icon_path = os.path.join(media_dir,"16.png")
        icon = gtk.gdk.pixbuf_new_from_file(icon_path)
        
        self.window1.set_icon(icon)
        self.window1.set_title("filesnake")
        
        self.transfer = TransfersDialog()
        self.transfer.widget.set_icon(icon) # Dirty but effective
        
        self.userlist = UserList()
        self.userdiscovery = UserDiscovery(self.userlist)
        self.statusbar = StatusBar(self)
        
        # Contextual Menus
        self.usermenu = UserMenu(self)
        self.preferences_dialog = PreferencesDialog()
        
        self.add_slave(self.userlist,"userlist_cont")
        self.add_slave(self.statusbar,"statusbar_cont")

    # As a server
    def request_authorization(self, name, filename, size):
        '''Request authorization to send a file '''
        response = yesno(
            "Authorize {0} to send a file?".format(name),
            "{0} want to send '{1}' of this dimension: {2}".format(name,filename,size)
            )
        if response == gtk.RESPONSE_YES:
            statusbar.log("request accepted")
            return True
        elif response == gtk.RESPONSE_NO:
            statusbar.log("request refused")
            return False
    # As a client
    def send_file(self):
        '''
        Fetch the file from the gui and send it to the selected
        recipient
        '''
        info = self.userlist.get_selected_user()

        if info==None:
            statusbar.log("nobody selected!!!")
            return
        
        filename = dialogs.open(title='Send a file')
        
        if filename:
            monitor = TransferMonitor(filename, get_size(filename))
            client = SendingClient(info.name, info.address, info.port)
            
            d = client.request_session(filename, get_size(filename))
            d.addCallback(lambda secret: client.send_file(secret, filename, monitor=monitor))
            
        else:
            statusbar.log("sending aborted")
    
    def send_folder(self):
        'XXX Code duplicated with send_file, can be splitted in smaller functionalities'
        info = self.userlist.get_selected_user()

        if info==None:
            statusbar.log("nobody selected!!!")
            return
        
        folder = dialogs.select_folder(title='Select a folder')
        
        if folder:
            monitor = TransferMonitor(folder, get_size(folder))
            client = SendingClient(info.name, info.address, info.port)
            
            d = client.request_session(folder, get_size(folder))
            d.addCallback(lambda secret: client.send_folder(secret, folder, monitor=monitor))
        else:
            statusbar.log("sending aborted")
    
    def log(self,msg):
        statusbar.log(msg)
    
    # Callbacks
    
    def on_sendfile__activate(self, *a):
        self.send_file()
        
    def on_sendfolder__activate(self, *a):
        self.send_folder()
    
    def on_preferences__activate(self, *a):
        self.preferences_dialog.show()

    def on_quit__activate(self, *a):
        self.hide_and_quit()
    
    def on_window1__delete_event(self, *a):
        self.hide_and_quit()


class UIControllerAdapter():
    
    implements(IUIController)
    
    def __init__(self, gui):
        self._gui = gui
        
    def get_file_handler(self, basename, size):
        return FileHandler(basename, size)
    
    def get_monitor(self, name, basename, size):
        # Maybe this method needs other data
        mon = self._gui.transfer.add_transfer(name, basename, size)
        return mon
        
    def authorize(self, name, basename, size):
        return self._gui.request_authorization(name, basename, size)

components.registerAdapter(UIControllerAdapter,
                           FileSnakeGUI,
                           IUIController)

class FileHandler(object):
    
    @property
    def dest(self):
        return self._dest

    @dest.setter
    def dest(self, basename):
        dest = os.path.join(dest_dir(), basename)
        self._dest = avail_filename(dest)

    def __init__(self, basename, size):
        self.basename = basename
        self.size = size
        
    def save_data(self,data):
        logging.debug("data received on file "+self.dest)
        # Here we can double check if the client is sending too much
        # data at a time
        
        if not hasattr(self,"fd"):
            logging.debug("Creating file: ",self.dest)
            self.fd = open(self.dest, "w")
        self.fd.write(data)
        
def test_run():
    fs = FileSnakeGUI()
    fs.show_and_run()

if __name__ == '__main__':
    test_run()
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 ProjectModifiedEvent.java.
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.