Initial nemo application
This commit is contained in:
parent
6dcc43c04b
commit
f9797139b9
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>nemo</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
8
.pydevproject
Normal file
8
.pydevproject
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/${PROJECT_DIR_NAME}</path>
|
||||
</pydev_pathproperty>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
</pydev_project>
|
219
nemo.py
Executable file
219
nemo.py
Executable file
@ -0,0 +1,219 @@
|
||||
#!/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()
|
83
nemo.wxg
Normal file
83
nemo.wxg
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- generated by wxGlade 0.6.8 on Tue Mar 11 21:21:15 2014 -->
|
||||
|
||||
<application path="nemo.py" name="" class="" option="0" language="python" top_window="nemo_frame" encoding="UTF-8" use_gettext="1" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0" indent_amount="4" indent_symbol="space" source_extension=".cpp" header_extension=".h">
|
||||
<object class="NeMo" name="nemo_frame" base="EditFrame">
|
||||
<style>wxDEFAULT_FRAME_STYLE</style>
|
||||
<title>NeMo</title>
|
||||
<centered>1</centered>
|
||||
<size>900, 480</size>
|
||||
<object class="wxBoxSizer" name="main_sizer" base="EditBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxBoxSizer" name="action_sizer" base="EditBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizerslot" />
|
||||
<object class="sizerslot" />
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>3</option>
|
||||
<object class="wxBoxSizer" name="output_sizer" base="EditBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxStaticBoxSizer" name="stdout_sizer" base="EditStaticBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<label>stdout</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_stdout" base="EditTextCtrl">
|
||||
<style>wxTE_MULTILINE|wxTE_READONLY</style>
|
||||
<font>
|
||||
<size>10</size>
|
||||
<family>default</family>
|
||||
<style>normal</style>
|
||||
<weight>bold</weight>
|
||||
<underlined>0</underlined>
|
||||
<face></face>
|
||||
</font>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxStaticBoxSizer" name="stderr_sizer" base="EditStaticBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<label>stderr</label>
|
||||
<object class="sizeritem">
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>0</border>
|
||||
<option>1</option>
|
||||
<object class="wxTextCtrl" name="text_ctrl_stderr" base="EditTextCtrl">
|
||||
<foreground>#ff0000</foreground>
|
||||
<style>wxTE_MULTILINE|wxTE_READONLY</style>
|
||||
<font>
|
||||
<size>10</size>
|
||||
<family>default</family>
|
||||
<style>normal</style>
|
||||
<weight>bold</weight>
|
||||
<underlined>0</underlined>
|
||||
<face></face>
|
||||
</font>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</application>
|
Loading…
x
Reference in New Issue
Block a user