Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 14th, 2012  |  syntax: None  |  size: 7.87 KB  |  hits: 12  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # SSHplus
  5. # A remote connect utlity, sshmenu compatible clone, and application starter.
  6. #
  7. # (C) 2011 Anil Gulecha
  8. # Based on sshlist, incorporating changes by Benjamin Heil's simplestarter
  9. #
  10. # This program is free software: you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation, either version 3 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22. #
  23. # Instructions
  24. #
  25. # 1. Copy file sshplus.py (this file) to /usr/local/bin
  26. # 2. Edit file .sshplus in your home directory to add menu entries, each
  27. #    line in the format NAME|COMMAND|ARGS
  28. # 3. Launch sshplus.py
  29. # 4. Or better yet, add it to gnome startup programs list so it's run on login.
  30.  
  31. import gobject
  32. import gtk
  33. import appindicator
  34. import os
  35. import pynotify
  36. import sys
  37. import shlex
  38.  
  39. _VERSION = "1.0"
  40.  
  41. _SETTINGS_FILE = os.getenv("HOME") + "/.sshplus"
  42. _SSHMENU_FILE = os.getenv("HOME") + "/.sshmenu"
  43.  
  44. _ABOUT_TXT = """A simple application starter as appindicator.
  45.  
  46. To add items to the menu, edit the file <i>.sshplus</i> in your home directory. Each entry must be on a new line in this format:
  47.  
  48. <tt>NAME|COMMAND|ARGS</tt>
  49.  
  50. If the item is clicked in the menu, COMMAND with arguments ARGS will be executed. ARGS can be empty. To insert a separator, add a line which only contains "sep". Lines starting with "#" will be ignored. You can set an unclickable label with the prefix "label:". Items from sshmenu configuration will be automatically added (except nested items). To insert a nested menu, use the prefix "folder:menu name". Subsequent items will be inserted in this menu, until a line containing an empty folder name is found: "folder:". After that, subsequent items get inserted in the parent menu. That means that more than one level of nested menus can be created.
  51.  
  52. Example file:
  53. <tt><small>
  54. Show top|gnome-terminal|-x top
  55. sep
  56.  
  57. # this is a comment
  58. label:SSH connections
  59. # create a folder named "Home"
  60. folder:Home
  61. SSH Ex|gnome-terminal|-x ssh user@1.2.3.4
  62. # to mark the end of items inside "Home", specify and empty folder:
  63. folder:
  64. # this item appears in the main menu
  65. SSH Ex|gnome-terminal|-x ssh user@1.2.3.4
  66.  
  67. label:RDP connections
  68. RDP Ex|rdesktop|-T "RDP-Server" -r sound:local 1.2.3.4
  69.  
  70. </small></tt>
  71. Copyright 2011 Anil Gulecha
  72. Incorporating changes from simplestarter, Benjamin Heil, http://www.bheil.net
  73.  
  74. Released under GPL3, http://www.gnu.org/licenses/gpl-3.0.html"""
  75.  
  76. def menuitem_response(w, item):
  77.     if item == '_about':
  78.         show_help_dlg(_ABOUT_TXT)
  79.     elif item == '_refresh':
  80.         newmenu = build_menu()
  81.         ind.set_menu(newmenu)
  82.         pynotify.Notification("SSHplus refreshed", "Menu list was refreshed from %s" % _SETTINGS_FILE).show()
  83.     elif item == '_quit':
  84.         sys.exit(0)
  85.     elif item == 'folder':
  86.         pass
  87.     else:
  88.         print item
  89.         os.spawnvp(os.P_NOWAIT, item['cmd'], [item['cmd']] + item['args'])
  90.         os.wait3(os.WNOHANG)
  91.  
  92. def show_help_dlg(msg, error=False):
  93.     if error:
  94.         dlg_icon = gtk.MESSAGE_ERROR
  95.     else:
  96.         dlg_icon = gtk.MESSAGE_INFO
  97.     md = gtk.MessageDialog(None, 0, dlg_icon, gtk.BUTTONS_OK)
  98.     try:
  99.         md.set_markup("<b>SSHplus %s</b>" % _VERSION)
  100.         md.format_secondary_markup(msg)
  101.         md.run()
  102.     finally:
  103.         md.destroy()
  104.    
  105. def add_separator(menu):
  106.     separator = gtk.SeparatorMenuItem()
  107.     separator.show()
  108.     menu.append(separator)
  109.  
  110. def add_menu_item(menu, caption, item=None):
  111.     menu_item = gtk.MenuItem(caption)
  112.     if item:
  113.         menu_item.connect("activate", menuitem_response, item)
  114.     else:
  115.         menu_item.set_sensitive(False)
  116.     menu_item.show()
  117.     menu.append(menu_item)
  118.     return menu_item
  119.  
  120. def get_sshmenuconfig():
  121.     if not os.path.exists(_SSHMENU_FILE):
  122.         return None
  123.     hostlist=open(os.getenv("HOME")+"/.sshmenu","r").read()
  124.     smenutitle=[]
  125.     smenuparams=[]
  126.     try:
  127.         for line in hostlist.split("\n"):
  128.             if line[2:7] == "title":
  129.                 smenutitle.append(line.split(":")[1])
  130.             if line[2:11] == "sshparams":
  131.                 smenuparams.append(line.split(":")[1])
  132.         if len(smenutitle) ==  len(smenuparams):
  133.             if len(smenutitle) != 0:
  134.                 return (smenutitle,smenuparams)
  135.         else:
  136.             if len(smenuparams) != 0:
  137.                 return (smenuparams,smenuparams)
  138.         return None
  139.     except:
  140.         return None
  141.  
  142. def get_sshplusconfig():
  143.     if not os.path.exists(_SETTINGS_FILE):
  144.         return []
  145.  
  146.     app_list = []
  147.     f = open(_SETTINGS_FILE, "r")
  148.     try:
  149.         for line in f.readlines():
  150.             line = line.rstrip()
  151.             if not line or line.startswith('#'):
  152.                 continue
  153.             elif line == "sep":
  154.                 app_list.append('sep')
  155.             elif line.startswith('label:'):
  156.                 app_list.append({
  157.                     'name': 'LABEL',
  158.                     'cmd': line[6:],
  159.                     'args': ''
  160.                 })
  161.             elif line.startswith('folder:'):
  162.                 app_list.append({
  163.                     'name': 'FOLDER',
  164.                     'cmd': line[7:],
  165.                     'args': ''
  166.                 })
  167.             else:
  168.                 try:
  169.                     name, cmd, args = line.split('|', 2)
  170.                     app_list.append({
  171.                         'name': name,
  172.                         'cmd': cmd,
  173.                         'args': [n.replace("\n", "") for n in shlex.split(args)],
  174.                     })
  175.                 except ValueError:
  176.                     print "The following line has errors and will be ignored:\n%s" % line
  177.     finally:
  178.         f.close()
  179.     return app_list
  180.  
  181. def build_menu():
  182.     if not os.path.exists(_SETTINGS_FILE) and not os.path.exists(_SSHMENU_FILE) :
  183.         show_help_dlg("<b>ERROR: No .sshmenu or .sshplus file found in home directory</b>\n\n%s" % \
  184.              _ABOUT_TXT, error=True)
  185.         sys.exit(1)
  186.  
  187.     app_list = get_sshplusconfig()
  188.  
  189.     #Add sshmenu config items if any
  190.     sshmenuitems = get_sshmenuconfig()
  191.     if sshmenuitems != None:
  192.         app_list.append("sep")
  193.         app_list.append({
  194.             'name': 'LABEL',
  195.             'cmd': "SSHmenu",
  196.             'args': ''
  197.         })
  198.         titles=sshmenuitems[0]
  199.         sshparams=sshmenuitems[1]
  200.         for i in range(len(titles)):
  201.             app_list.append({
  202.                 'name': titles[i],
  203.                 'cmd': "gnome-terminal",
  204.                 'args': [n.replace("\n", "") for n in shlex.split("-x ssh " + sshparams[i])],
  205.             })
  206.  
  207.     menu = gtk.Menu()
  208.     menus = [menu]
  209.  
  210.     for app in app_list:
  211.         if app == "sep":
  212.             add_separator(menus[-1])
  213.         elif app['name'] == "FOLDER" and not app['cmd']:
  214.             if len(menus) > 1:
  215.                 menus.pop()
  216.         elif app['name'] == "FOLDER":
  217.             menu_item = add_menu_item(menus[-1], app['cmd'], 'folder')
  218.             menus.append(gtk.Menu())
  219.             menu_item.set_submenu(menus[-1])
  220.         elif app['name'] == "LABEL":
  221.             add_menu_item(menus[-1], app['cmd'], None)
  222.         else:
  223.             add_menu_item(menus[-1], app['name'], app)
  224.  
  225.     add_separator(menu)
  226.     add_menu_item(menu, 'Refresh', '_refresh')
  227.     add_menu_item(menu, 'About', '_about')
  228.     add_separator(menu)
  229.     add_menu_item(menu, 'Quit', '_quit')
  230.     return menu
  231.  
  232. if __name__ == "__main__":
  233.     ind = appindicator.Indicator("sshplus", "stock_connect",
  234.                                  appindicator.CATEGORY_APPLICATION_STATUS)
  235.     #ind.set_label("Launch")
  236.     ind.set_status(appindicator.STATUS_ACTIVE)
  237.  
  238.     appmenu = build_menu()
  239.     ind.set_menu(appmenu)
  240.     gtk.main()