~bernd-sch/onehundredscopes/sshsearch

« back to all changes in this revision

Viewing changes to unity-lens-sshsearch.py

  • Committer: Bernd Schlapsi
  • Date: 2012-01-08 12:10:45 UTC
  • Revision ID: brot@gmx.info-20120108121045-mn5xtyc0w0kppvve
1. updated README
2. add file monitoring for the config and known_hosts file
3. add support to define the ssh user in the search term

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from gi.repository import Unity
29
29
 
30
30
BUS_NAME = "net.launchpad.lens.sshsearch"
 
31
 
 
32
SSH_DEFAULT_PORT = '22'
31
33
SSHCONFIG = os.path.join('~', '.ssh', 'config')
32
34
SSHCONFIG_EXPAND = os.path.expanduser(SSHCONFIG)
33
35
KNOWN_HOSTS = os.path.join('~', '.ssh', 'known_hosts')
34
36
KNOWN_HOSTS_EXPAND = os.path.expanduser(KNOWN_HOSTS)
 
37
 
35
38
TERMINAL_APP = 'gnome-terminal'
36
39
TERMINAL_APP_MIMETYPE = 'application-x-desktop'
 
40
 
37
41
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
38
42
ICON_FILE = os.path.join(SCRIPT_DIR, 'unity-lens-sshsearch.png')
39
43
 
71
75
 
72
76
        self._lens.add_local_scope (self._scope);
73
77
        self._lens.export ()
74
 
        
75
 
        self._config_hosts = self.__read_config()
76
 
        self._known_hosts = self.__read_known_hosts()
77
 
        print self._config_hosts
78
 
        print self._known_hosts
79
 
        
80
 
    def __read_config(self):
81
 
        c = paramiko.SSHConfig()
82
 
        c.parse(open(SSHCONFIG_EXPAND))
83
 
        return [h['host'].lower() for h in c._config if h['host'] != '*']
84
 
        
85
 
    def __read_known_hosts(self):
86
 
        h = paramiko.HostKeys(KNOWN_HOSTS_EXPAND)
87
 
        hosts = [host for host in h.keys() if len(host) != 60] 
88
 
        return hosts
 
78
 
 
79
        # read/parse ssh-config file
 
80
        self._config_file = Gio.file_new_for_path(SSHCONFIG_EXPAND)
 
81
        self._config_monitor = self._config_file.monitor_file(flags=Gio.FileMonitorFlags.NONE, cancellable=None)
 
82
        self._config_monitor.connect('changed', self.__read_config)
 
83
        self._config_hosts = self.__read_config(None, self._config_file, None, Gio.FileMonitorEvent.CREATED)
 
84
 
 
85
        # read/parse ssh-known_hosts file
 
86
        self._knownhosts_file = Gio.file_new_for_path(KNOWN_HOSTS_EXPAND)
 
87
        self._knownhosts_monitor = self._knownhosts_file.monitor_file(flags=Gio.FileMonitorFlags.NONE, cancellable=None)
 
88
        self._known_hosts = self.__read_known_hosts(None, self._knownhosts_file, None, Gio.FileMonitorEvent.CREATED)
 
89
        
 
90
    def __read_config(self, filemonitor, file, other_file, event_type):
 
91
        config_hosts = []
 
92
 
 
93
        if not file.query_exists(None):
 
94
            return config_hosts
 
95
 
 
96
        if (event_type in (Gio.FileMonitorEvent.CREATED,
 
97
                           Gio.FileMonitorEvent.CHANGED,
 
98
                           Gio.FileMonitorEvent.CHANGES_DONE_HINT)): 
 
99
            c = paramiko.SSHConfig()
 
100
            c.parse(open(file.get_path()))
 
101
            config_hosts = [h['host'].lower() for h in c._config if h['host'] != '*']
 
102
 
 
103
        return config_hosts
 
104
        
 
105
    def __read_known_hosts(self, filemonitor, file, other_file, event_type):
 
106
        known_hosts = []
 
107
        if not file.query_exists(None):
 
108
            return known_hosts
 
109
 
 
110
        if (event_type in (Gio.FileMonitorEvent.CREATED,
 
111
                           Gio.FileMonitorEvent.CHANGED,
 
112
                           Gio.FileMonitorEvent.CHANGES_DONE_HINT)): 
 
113
            h = paramiko.HostKeys(KNOWN_HOSTS_EXPAND)
 
114
            known_hosts = [host for host in h.keys() if len(host) != 60]
 
115
 
 
116
        return known_hosts
89
117
        
90
118
    def on_search_changed (self, entry, *args):
91
119
        search = self._scope.props.active_search or None
105
133
        results = self._scope.props.global_results_model
106
134
        self.update_results_model(search_string, results)
107
135
 
 
136
    def __parse_hoststring(self, hoststring, user):
 
137
        # assign host and port
 
138
        host = hoststring
 
139
        port = SSH_DEFAULT_PORT
 
140
        if hoststring.startswith('['):
 
141
            host, port = hoststring[1:].split(']:')
 
142
 
 
143
        # assign target
 
144
        target = host
 
145
        if user:
 
146
            target = '%s@%s' % (user, host)
 
147
 
 
148
        # assign connection-description 
 
149
        conn_desc = target
 
150
        if port != SSH_DEFAULT_PORT:
 
151
            conn_desc = '%s:%s' % (target, port)
 
152
 
 
153
        return target, port, conn_desc
 
154
 
108
155
    def update_results_model(self, search, model):
109
156
        if search is None or search == '':
110
157
            return
111
158
         
112
159
        model.clear()
113
 
        found = [host for host in self._config_hosts if host.find(search) >= 0]
 
160
        searchparts = search.split('@')
 
161
        searchhost = searchparts[-1]
 
162
        searchuser = ''
 
163
        if len(searchparts) == 2:
 
164
            searchuser = searchparts[0]
 
165
            
 
166
        found = [host for host in self._config_hosts if host.find(searchhost) >= 0]
114
167
        for host in found:
115
 
            model.append('ssh://config/%s' % host,
 
168
            target, port, conn_desc = self.__parse_hoststring(host, searchuser)
 
169
            model.append('ssh://config/%s/%s' % (searchuser, host),
116
170
                         TERMINAL_APP,
117
171
                         0,
118
172
                         TERMINAL_APP_MIMETYPE,
119
 
                         host, host, '')
 
173
                         conn_desc, conn_desc, '')
120
174
                         
121
 
        found = [host for host in self._known_hosts if host.find(search) >= 0]
 
175
        found = [host for host in self._known_hosts if host.find(searchhost) >= 0]
122
176
        for host in found:
123
 
            model.append('ssh://known_hosts/%s' % host,
 
177
            target, port, conn_desc = self.__parse_hoststring(host, searchuser)
 
178
            model.append('ssh://known_hosts/%s/%s' % (searchuser, host),
124
179
                         TERMINAL_APP,
125
180
                         1,
126
181
                         TERMINAL_APP_MIMETYPE,
127
 
                         host, host, '')
128
 
 
129
 
    def __parse_hoststring(self, hoststring):
130
 
        if hoststring.startswith('['):
131
 
            return hoststring[1:].split(']:')
132
 
        return hoststring, 22
 
182
                         conn_desc, conn_desc, '')
133
183
 
134
184
    def on_activate_uri (self, scope, uri):
135
 
        hoststring = uri.split('/')[-1]
136
 
        host, port = self.__parse_hoststring(hoststring)
 
185
        uri_splitted = uri.split('/')
 
186
        hoststring = uri_splitted[-1]
 
187
        user = uri_splitted[-2]
 
188
        target, port, conn_desc = self.__parse_hoststring(hoststring, user)
137
189
 
138
 
        if port == 22:
139
 
            GLib.spawn_command_line_async('%s -e "ssh %s"' % (TERMINAL_APP, host))
 
190
        if port == SSH_DEFAULT_PORT:
 
191
            # don't call with the port option, because the host definition
 
192
            # could be from the ~/.ssh/config file
 
193
            GLib.spawn_command_line_async('%s -e "ssh %s"' % (TERMINAL_APP, target))
140
194
        else:
141
 
            GLib.spawn_command_line_async('%s -e "ssh -p %s %s"' % (TERMINAL_APP, port, host))
 
195
            GLib.spawn_command_line_async('%s -e "ssh -p %s %s"' % (TERMINAL_APP, port, target))
142
196
 
143
197
        return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri='')
144
198