Program to mount remote filesystems
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

nemo.py 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. #
  4. # generated by wxGlade 0.6.8 on Sun Mar 9 14:56:37 2014
  5. #
  6. application_name = u'NeMo'
  7. application_version = u'0.1.0'
  8. import json
  9. import os
  10. import subprocess
  11. import wx
  12. # begin wxGlade: dependencies
  13. import gettext
  14. # end wxGlade
  15. # begin wxGlade: extracode
  16. # end wxGlade
  17. class NeMo(wx.Frame):
  18. def __init__(self, *args, **kwds):
  19. # begin wxGlade: NeMo.__init__
  20. kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
  21. wx.Frame.__init__(self, *args, **kwds)
  22. self.SetSize((900, 480))
  23. self.text_ctrl_stdout = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
  24. self.text_ctrl_stderr = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
  25. self.__set_properties()
  26. self.__do_layout()
  27. # end wxGlade
  28. def __set_properties(self):
  29. # begin wxGlade: NeMo.__set_properties
  30. self.SetTitle(_("NeMo"))
  31. self.text_ctrl_stdout.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
  32. self.text_ctrl_stderr.SetForegroundColour(wx.Colour(255, 0, 0))
  33. self.text_ctrl_stderr.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
  34. # end wxGlade
  35. self.SetTitle(_("%s - V%s" % (application_name, application_version)))
  36. def __do_layout(self):
  37. # begin wxGlade: NeMo.__do_layout
  38. main_sizer = wx.BoxSizer(wx.HORIZONTAL)
  39. output_sizer = wx.BoxSizer(wx.VERTICAL)
  40. stderr_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("stderr")), wx.HORIZONTAL)
  41. stdout_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("stdout")), wx.HORIZONTAL)
  42. action_sizer = wx.BoxSizer(wx.VERTICAL)
  43. action_sizer.Add((0, 0), 0, 0, 0)
  44. action_sizer.Add((0, 0), 0, 0, 0)
  45. main_sizer.Add(action_sizer, 1, wx.EXPAND, 0)
  46. stdout_sizer.Add(self.text_ctrl_stdout, 1, wx.EXPAND, 0)
  47. output_sizer.Add(stdout_sizer, 1, wx.EXPAND, 0)
  48. stderr_sizer.Add(self.text_ctrl_stderr, 1, wx.EXPAND, 0)
  49. output_sizer.Add(stderr_sizer, 1, wx.EXPAND, 0)
  50. main_sizer.Add(output_sizer, 3, wx.EXPAND, 0)
  51. self.SetSizer(main_sizer)
  52. self.Layout()
  53. self.Centre()
  54. # end wxGlade
  55. self.action_sizer = action_sizer
  56. def AddStaBu(self, stabu):
  57. self.action_sizer.Add(stabu, 0, wx.EXPAND, 0)
  58. self.Layout()
  59. # end of class NeMo
  60. class StaBu(wx.BoxSizer):
  61. SSH_FS = 'ssh'
  62. WEB_DAV = 'dav'
  63. FTP_FS = 'ftp'
  64. def __init__(self, wx_frame, stdout, stderr, **kwargs):
  65. self.wx_frame = wx_frame
  66. self.stdout = stdout
  67. self.stderr = stderr
  68. for key in ['name', 'prot', 'remote_host', 'remote_path', 'local_path', 'user', 'port']:
  69. setattr(self, key, kwargs[key])
  70. for key, value in [('password', None), ]:
  71. setattr(self, key, kwargs.get(key, value))
  72. wx.BoxSizer.__init__(self, wx.HORIZONTAL)
  73. self.button = wx.Button(wx_frame, wx.ID_ANY, _(self.name))
  74. self.panel = wx.Panel(wx_frame, wx.ID_ANY)
  75. if kwargs.get('hidden', False):
  76. self.button.Hide()
  77. self.panel.Hide()
  78. elif kwargs.get('disabled', False):
  79. self.button.Disable()
  80. self.Add(self.button, 3, 0, 0)
  81. self.Add(self.panel, 1, wx.EXPAND, 0)
  82. wx_frame.Bind(wx.EVT_BUTTON, self.mount_pressed, self.button)
  83. self.panel.Bind(wx.EVT_LEFT_UP, self.open_pressed)
  84. wx_frame.Bind(wx.EVT_IDLE, self.panel_update, None)
  85. wx_frame.AddStaBu(self)
  86. def set_password(self):
  87. if self.password == None:
  88. box = wx.PasswordEntryDialog(self.wx_frame, 'Please enter password for %(name)s:' % self.__dict__, 'Password')
  89. if box.ShowModal() == wx.ID_OK:
  90. self.password = box.GetValue()
  91. box.Destroy()
  92. def error_msg(self, msg):
  93. self.stderr.write('nemo-file (%s): ' % self.name)
  94. self.stderr.write(msg)
  95. def panel_update(self, event):
  96. if self.is_mounted():
  97. #self.button_open.SetBackgroundColour('green')
  98. self.panel.SetBackgroundColour('green')
  99. else:
  100. #self.button_open.SetBackgroundColour('red')
  101. self.panel.SetBackgroundColour('red')
  102. event.Skip()
  103. def mount_pressed(self, event):
  104. if self.is_mounted():
  105. self.umount()
  106. else:
  107. self.mount()
  108. event.Skip()
  109. def open_pressed(self, event):
  110. for prog in ['nautilus', 'dolphin', 'nemo', 'thunar']:
  111. try:
  112. subprocess.Popen([prog, self.local_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  113. except OSError:
  114. pass
  115. else:
  116. break
  117. event.Skip()
  118. def check_prot(self):
  119. test_cmd = self.mount_cmd(True)
  120. if test_cmd == None:
  121. self.__ok__ = False
  122. self.error_msg('Protocol not supported!\n')
  123. #TODO: try to execute test_cmd to get info that progs are installed
  124. def is_mounted(self):
  125. p = subprocess.Popen(["mount"], stdout=subprocess.PIPE)
  126. out, err = p.communicate()
  127. self.stderr.write(err or '')
  128. if self.local_path in out.decode('utf-8'):
  129. return True
  130. else:
  131. return False
  132. def umount(self):
  133. self.stdout.write('umounting %s\n' % (self.local_path))
  134. p = subprocess.Popen(['fusermount', '-u', self.local_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  135. out, err = p.communicate()
  136. if not self.is_mounted():
  137. self.stdout.write('SUCCESS.\n')
  138. else:
  139. self.stdout.write('FAILED.\n')
  140. self.stdout.write(out or '')
  141. self.stderr.write(err or '')
  142. def mount(self):
  143. cmd = self.mount_cmd()
  144. self.stdout.write('mounting %(name)s to %(local_path)s\n' % self.__dict__)
  145. if cmd != None:
  146. p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  147. out, err = p.communicate()
  148. out = out.decode('utf-8')
  149. err = err.decode('utf-8')
  150. if self.password != None:
  151. out = out.replace(self.password, u'*****')
  152. err = err.replace(self.password, u'*****')
  153. if self.is_mounted():
  154. self.stdout.write('SUCCESS.\n')
  155. else:
  156. self.stdout.write('FAILED.\n')
  157. self.password = None
  158. self.stdout.write(out or '')
  159. self.stderr.write(err or '')
  160. else:
  161. self.stdout.write('FAILED.\n')
  162. def mount_cmd(self, test_cmd=False):
  163. if self.prot == self.SSH_FS:
  164. if test_cmd:
  165. return ['sshfs', '--version']
  166. return ['sshfs', '%(user)s@%(remote_host)s:%(remote_path)s' % self.__dict__, self.local_path]
  167. elif self.prot == self.WEB_DAV:
  168. if test_cmd:
  169. return ['wdfs', '--version']
  170. self.set_password()
  171. return ['wdfs', '-o', 'accept_sslcert,username=%(user)s,password=%(password)s' % self.__dict__, self.remote_host + self.remote_path, self.local_path]
  172. elif self.prot == self.FTP_FS:
  173. if test_cmd:
  174. return ['curlftpfs', '--version']
  175. self.set_password()
  176. return ['curlftpfs', 'ftp://%(user)s:%(password)s@%(remote_host)s:%(port)s%(remote_path)s' % self.__dict__, self.local_path]
  177. else:
  178. return None
  179. if __name__ == "__main__":
  180. gettext.install("app") # replace with the appropriate catalog name
  181. app = wx.App(0)
  182. nemo_frame = NeMo(None, wx.ID_ANY, "")
  183. #
  184. with open(os.path.abspath(os.path.join(os.path.expanduser('~'), '.nemo.json')), 'r') as fh:
  185. config = json.load(fh)
  186. for entry in config:
  187. StaBu(nemo_frame, nemo_frame.text_ctrl_stdout, nemo_frame.text_ctrl_stderr, **entry)
  188. #
  189. app.SetTopWindow(nemo_frame)
  190. nemo_frame.Show()
  191. app.MainLoop()