Class: Remote

Inherits:
Object show all
Defined in:
lib/xiki/remote.rb

Constant Summary collapse

@@temp_dir =
"/tmp/remote_rb"
@@connections =
{}

Class Method Summary collapse

Class Method Details

.calculate_local_path(path, server) ⇒ Object



187
188
189
# File 'lib/xiki/remote.rb', line 187

def self.calculate_local_path path, server
  "#{@@temp_dir}/#{server},#{path.gsub('/', ',')[1..-1]}"
end

.calculate_remote_path(path) ⇒ Object



191
192
193
# File 'lib/xiki/remote.rb', line 191

def self.calculate_remote_path path
  path.gsub(/^#{@@temp_dir}\/.+?,/, '/').gsub(',', '/')
end

.command(root) ⇒ Object

, *path_append



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/xiki/remote.rb', line 88

def self.command root #, *path_append

  the_command = root[-1][/\$ ?(.+)/, 1]

  # Pull off command
  while(root.last =~ /^\$/) do   # Remove all !foo lines from root
    root.pop
  end
  root = root.join('')

  connection = self.connection root

  user, server, port, path = self.split_root(root)

  path << "/" unless path =~ /\/$/   # Add slash to path if none there

  timeout(6) do
    out = connection.exec!("cd \"#{path}\" && #{the_command}")
    #       out = connection.exec!("cd \"#{path}\"; #{the_command}")
    out ||= ""

    Tree.under out, :escape=>'| ', :no_slash=>1
  end
end

.connection(root) ⇒ Object



117
118
119
120
121
122
# File 'lib/xiki/remote.rb', line 117

def self.connection root
  user, server, port, path = self.split_root root
  address = "#{user}@#{server}:#{port}"
  @@connections[address] ||= self.new_connection user, server, port.to_i
  @@connections[address]
end

.connectionsObject



113
114
115
# File 'lib/xiki/remote.rb', line 113

def self.connections
  @@connections
end

.dir(root, *path_append) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/xiki/remote.rb', line 30

def self.dir root, *path_append

  connection = self.connection root

  user, server, port, path = self.split_root(root)

  # Add slash to path if none there
  path << "/" unless path =~ /\/$/

  path_passed = path_append.size > 0

  if path_passed  # If anything in array
    path << "#{path_append.join('')}"  # append to path
    path.sub! /^\/\//, '/'
  end

  timeout(15) do
    if path =~ /\/$/   # If a dir
      out = connection.exec!("ls -pa #{path}")
      out ||= ""
      out = out.split("\n").grep(/^[^#]+$/).join("\n")   # Weed out #...#
      out.gsub!(/@/, '/')   # Change @ to /

      # Get rid of . and ..
      out = out.split("\n").select{|o| o !~ /^\.+\/$/}.join("\n")+"\n"
      self.sort(out)

    else   # If a file

      Dir.mkdir @@temp_dir unless File.exists? @@temp_dir
      local_path = self.calculate_local_path path, server

      was_open = Files.open? local_path

      # Download if not open already
      unless was_open
        begin
          connection.sftp.download!(path, local_path)
        rescue Exception=>e
          # If doesn't exist, we'll just create
        end
      end

      View.to_after_bar
      View.open local_path

      # TODO: save root path as var in buffer
      $el.make_local_variable :remote_rb_server_root
      server_root = "/#{user}@#{server}#{port ? ":#{port}" : ""}/"
      $el.elvar.remote_rb_server_root = server_root

      # TODO save timestamp in buffer var
      # - Use it to determine whether file changed when saving

    end
  end
end

.file_contents(whole_path) ⇒ Object

Called when dir or file is launched



24
25
26
27
28
# File 'lib/xiki/remote.rb', line 24

def self.file_contents whole_path
  user, server, port, path = self.split_root(whole_path)
  connection = self.connection whole_path
  connection.sftp.download!(path)
end

.initObject



195
196
197
# File 'lib/xiki/remote.rb', line 195

def self.init
  # TODO remove this
end


13
14
15
16
17
18
19
20
21
# File 'lib/xiki/remote.rb', line 13

def self.menu
  "
  - docs/
    > Summary
    | You can browse files and run commands on remote servers.
    @ /[email protected]/tmp/
  << see) @servers/
  "
end

.new_connection(user, server, port) ⇒ Object



124
125
126
127
128
129
130
131
132
# File 'lib/xiki/remote.rb', line 124

def self.new_connection user, server, port
  begin
    timeout(6) do
      Net::SSH.start(server, user, :port => port.to_i, :paranoid => false)
    end
  rescue Exception => e
    raise "Timed out: #{e.message}"
  end
end

.remote_buffer_name(server, path) ⇒ Object



156
157
158
159
# File 'lib/xiki/remote.rb', line 156

def self.remote_buffer_name(server, path)
  dir, file = path.match(/(.+\/)(.+)/)[1..2]
  "*remote #{file} (#{server}:#{dir})"
end

.save_fileObject



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/xiki/remote.rb', line 161

def self.save_file
  local_path = View.file
  # Error out if not in right place
  if local_path !~ /^#{@@temp_dir}/
    View.beep
    return View.message("This isn't a file the Remote code_tree retrieved")
  end

  # Save if modified
  $el.save_buffer if $el.buffer_modified_p

  remote_path = $el.elvar.remote_rb_server_root


  # Convert to path
  remote_path = self.calculate_remote_path local_path
  begin   # Do save
    connection = self.connection $el.elvar.remote_rb_server_root
    connection.sftp.upload!(local_path, remote_path)
    View.message "successfully saved remotely!"
  rescue Exception => e
    View.message "- error: #{e.message}"
  end

end

.sort(lines) ⇒ Object



151
152
153
154
# File 'lib/xiki/remote.rb', line 151

def self.sort lines
  l = lines.split("\n")
  l.sort!{|a,b| a.sub(/(.+)\//, "\\1") <=> b.sub(/(.+)\//, "\\1")}
end

.split_root(root) ⇒ Object

Splits name@server:port/path



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/xiki/remote.rb', line 135

def self.split_root root   # Splits name@server:port/path
  root = root.dup   # Append / at end if no / exists
  root << "/" unless root =~ /\/$/

  user, server_port, path = root.match(/^(.+?)@(.+?)(\/.*?)\/?$/)[1..3]

  if(server_port =~ /(.+?):(.+)/)
    server, port = $1, $2
  else
    server, port = server_port, "22"
  end

  user.sub! /^\//, ''
  [user, server, port, path]
end