#!/usr/bin/env python3 # -*- coding: UTF-8 -*- # # generated by wxGlade 0.6.8 on Sun Mar 9 14:56:37 2014 # application_name = u'NeMo' application_version = u'0.1.0' import json import os import subprocess import wx # begin wxGlade: dependencies import gettext # end wxGlade # begin wxGlade: extracode # end wxGlade class NeMo(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: NeMo.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((900, 480)) self.text_ctrl_stdout = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.text_ctrl_stderr = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: NeMo.__set_properties self.SetTitle(_("NeMo")) self.text_ctrl_stdout.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) self.text_ctrl_stderr.SetForegroundColour(wx.Colour(255, 0, 0)) self.text_ctrl_stderr.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) # end wxGlade self.SetTitle(_("%s - V%s" % (application_name, application_version))) def __do_layout(self): # begin wxGlade: NeMo.__do_layout main_sizer = wx.BoxSizer(wx.HORIZONTAL) output_sizer = wx.BoxSizer(wx.VERTICAL) stderr_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("stderr")), wx.HORIZONTAL) stdout_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("stdout")), wx.HORIZONTAL) action_sizer = wx.BoxSizer(wx.VERTICAL) action_sizer.Add((0, 0), 0, 0, 0) action_sizer.Add((0, 0), 0, 0, 0) main_sizer.Add(action_sizer, 1, wx.EXPAND, 0) stdout_sizer.Add(self.text_ctrl_stdout, 1, wx.EXPAND, 0) output_sizer.Add(stdout_sizer, 1, wx.EXPAND, 0) stderr_sizer.Add(self.text_ctrl_stderr, 1, wx.EXPAND, 0) output_sizer.Add(stderr_sizer, 1, wx.EXPAND, 0) main_sizer.Add(output_sizer, 3, wx.EXPAND, 0) self.SetSizer(main_sizer) self.Layout() self.Centre() # end wxGlade self.action_sizer = action_sizer def AddStaBu(self, stabu): self.action_sizer.Add(stabu, 0, wx.EXPAND, 0) self.Layout() # end of class NeMo class StaBu(wx.BoxSizer): SSH_FS = 'ssh' WEB_DAV = 'dav' FTP_FS = 'ftp' def __init__(self, wx_frame, stdout, stderr, **kwargs): self.wx_frame = wx_frame self.stdout = stdout self.stderr = stderr for key in ['name', 'prot', 'remote_host', 'remote_path', 'local_path', 'user', 'port']: setattr(self, key, kwargs[key]) for key, value in [('password', None), ]: setattr(self, key, kwargs.get(key, value)) wx.BoxSizer.__init__(self, wx.HORIZONTAL) self.button = wx.Button(wx_frame, wx.ID_ANY, _(self.name)) self.panel = wx.Panel(wx_frame, wx.ID_ANY) if kwargs.get('hidden', False): self.button.Hide() self.panel.Hide() elif kwargs.get('disabled', False): self.button.Disable() self.Add(self.button, 3, 0, 0) self.Add(self.panel, 1, wx.EXPAND, 0) wx_frame.Bind(wx.EVT_BUTTON, self.mount_pressed, self.button) self.panel.Bind(wx.EVT_LEFT_UP, self.open_pressed) wx_frame.Bind(wx.EVT_IDLE, self.panel_update, None) wx_frame.AddStaBu(self) def set_password(self): if self.password == None: box = wx.PasswordEntryDialog(self.wx_frame, 'Please enter password for %(name)s:' % self.__dict__, 'Password') if box.ShowModal() == wx.ID_OK: self.password = box.GetValue() box.Destroy() def error_msg(self, msg): self.stderr.write('nemo-file (%s): ' % self.name) self.stderr.write(msg) def panel_update(self, event): if self.is_mounted(): #self.button_open.SetBackgroundColour('green') self.panel.SetBackgroundColour('green') else: #self.button_open.SetBackgroundColour('red') self.panel.SetBackgroundColour('red') event.Skip() def mount_pressed(self, event): if self.is_mounted(): self.umount() else: self.mount() event.Skip() def open_pressed(self, event): for prog in ['nautilus', 'dolphin', 'nemo', 'thunar']: try: subprocess.Popen([prog, self.local_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: pass else: break event.Skip() def check_prot(self): test_cmd = self.mount_cmd(True) if test_cmd == None: self.__ok__ = False self.error_msg('Protocol not supported!\n') #TODO: try to execute test_cmd to get info that progs are installed def is_mounted(self): p = subprocess.Popen(["mount"], stdout=subprocess.PIPE) out, err = p.communicate() self.stderr.write(err or '') if self.local_path in out.decode('utf-8'): return True else: return False def umount(self): self.stdout.write('umounting %s\n' % (self.local_path)) p = subprocess.Popen(['fusermount', '-u', self.local_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() if not self.is_mounted(): self.stdout.write('SUCCESS.\n') else: self.stdout.write('FAILED.\n') self.stdout.write(out or '') self.stderr.write(err or '') def mount(self): cmd = self.mount_cmd() self.stdout.write('mounting %(name)s to %(local_path)s\n' % self.__dict__) if cmd != None: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() out = out.decode('utf-8') err = err.decode('utf-8') if self.password != None: out = out.replace(self.password, u'*****') err = err.replace(self.password, u'*****') if self.is_mounted(): self.stdout.write('SUCCESS.\n') else: self.stdout.write('FAILED.\n') self.password = None self.stdout.write(out or '') self.stderr.write(err or '') else: self.stdout.write('FAILED.\n') def mount_cmd(self, test_cmd=False): if self.prot == self.SSH_FS: if test_cmd: return ['sshfs', '--version'] return ['sshfs', '%(user)s@%(remote_host)s:%(remote_path)s' % self.__dict__, self.local_path] elif self.prot == self.WEB_DAV: if test_cmd: return ['wdfs', '--version'] self.set_password() return ['wdfs', '-o', 'accept_sslcert,username=%(user)s,password=%(password)s' % self.__dict__, self.remote_host + self.remote_path, self.local_path] elif self.prot == self.FTP_FS: if test_cmd: return ['curlftpfs', '--version'] self.set_password() return ['curlftpfs', 'ftp://%(user)s:%(password)s@%(remote_host)s:%(port)s%(remote_path)s' % self.__dict__, self.local_path] else: return None if __name__ == "__main__": gettext.install("app") # replace with the appropriate catalog name app = wx.App(0) nemo_frame = NeMo(None, wx.ID_ANY, "") # with open(os.path.abspath(os.path.join(os.path.expanduser('~'), '.nemo.json')), 'r') as fh: config = json.load(fh) for entry in config: StaBu(nemo_frame, nemo_frame.text_ctrl_stdout, nemo_frame.text_ctrl_stderr, **entry) # app.SetTopWindow(nemo_frame) nemo_frame.Show() app.MainLoop()