Class: ElFinderFtp::FtpAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/el_finder_ftp/ftp_adapter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server) ⇒ FtpAdapter

Returns a new instance of FtpAdapter.



7
8
9
10
11
12
13
14
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 7

def initialize(server)
  @server = {
    response_cache_expiry_seconds: 30,
    passive: false,
  }.merge(server)

  @cached_responses = {}
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



5
6
7
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 5

def connection
  @connection
end

#serverObject (readonly)

Returns the value of attribute server.



5
6
7
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 5

def server
  @server
end

Instance Method Details

#children(pathname, with_directory) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 37

def children(pathname, with_directory)
  cached :children, pathname do
    ftp_context do
      ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Fetching children of #{pathname}"
      list("-la", pathname).map { |e|
        entry = Net::FTP::List.parse(e)

        # Skip . and .. entries
        next if entry.basename =~ /^\.+$/
        # ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m      Seeing #{e}"
        
        if with_directory
          pathname.fullpath + ::ElFinderFtp::FtpPathname.new(self, entry)
        else
          ::ElFinderFtp::FtpPathname.new(self, entry)
        end
      }.compact
    end
  end
end

#closeObject



26
27
28
29
30
31
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 26

def close
  if connected?
    ElFinderFtp::Connector.logger.info "  \e[1;32mFTP:\e[0m  Closing connection to #{server[:host]}"
    @connection.close 
  end      
end

#connectObject



16
17
18
19
20
21
22
23
24
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 16

def connect
  unless connected?
    ElFinderFtp::Connector.logger.info "  \e[1;32mFTP:\e[0m  Connecting to #{server[:host]} as #{server[:username]}"
    @connection = Net::FTP.new( server[:host], server[:username], server[:password] )
    @connection.passive = server[:passive]
  end

  @connection
end

#connected?Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 33

def connected?
  self.connection && !self.connection.closed?
end

#delete(pathname) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 177

def delete(pathname)
  ftp_context do
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Deleting #{pathname}"
    if pathname.directory?
      rmdir(pathname.to_s)
    else
      delete(pathname.to_s)
    end
  end
  clear_cache(pathname)
end

#exist?(pathname) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 75

def exist?(pathname)
  cached :exist?, pathname do
    ftp_context do
      ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Testing existence of #{pathname}"
      begin
        # Test if the file exists            
        size(pathname.to_s)
        true
      rescue Net::FTPPermError => ex
        # Can't "size" directories, but the error returned is different than if the file 
        # doesn't exist at all
        if ex.message.match /(?:The system cannot find the file specified|Could not get file size)/
          false
        else
          true
        end
      end
    end
  end
end

#mkdir(pathname) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 161

def mkdir(pathname)
  ftp_context do
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Creating directory #{pathname}"
    mkdir(pathname.to_s)
  end
  clear_cache(pathname)
end

#move(pathname, new_name) ⇒ Object

Both rename and move perform an FTP RNFR/RNTO (rename). Move differs because it first changes to the parent of the source pathname and uses a relative path for the RNFR. This seems to allow the (Microsoft) FTP server to rename a directory into another directory (e.g. /subdir/target -> /target )



152
153
154
155
156
157
158
159
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 152

def move(pathname, new_name)
  ftp_context(pathname.dirname) do
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Moving #{pathname} to #{new_name}"
    rename(pathname.basename.to_s, new_name.to_s)
  end
  clear_cache(pathname)
  clear_cache(new_name)
end

#mtime(pathname) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 125

def mtime(pathname)
  cached :mtime, pathname do
    ftp_context do
      ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Getting modified time of #{pathname}"
      begin
        mtime(pathname.to_s)
      rescue Net::FTPPermError => e
        # This command doesn't work on directories
        0
      end
    end
  end
end

#path_type(pathname) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 96

def path_type(pathname)
  cached :path_type, pathname do
    ftp_context do
      ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Getting type of #{pathname}"
      begin
        chdir(pathname.to_s)
        :directory
      rescue Net::FTPPermError => e
        :file
      end
    end
  end
end

#rename(pathname, new_name) ⇒ Object



139
140
141
142
143
144
145
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 139

def rename(pathname, new_name)
  ftp_context do
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Renaming #{pathname} to #{new_name}"
    rename(pathname.to_s, new_name.to_s)
  end
  clear_cache(pathname)
end

#retrieve(pathname) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 189

def retrieve(pathname)
  ftp_context do
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Retrieving #{pathname}"
    content = StringIO.new()
    begin
      retrbinary("RETR #{pathname}", 10240) do |block|
        content << block
      end
      content.string
    ensure
      content.close
    end
  end
end

#rmdir(pathname) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 169

def rmdir(pathname)
  ftp_context do
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Removing directory #{pathname}"
    rmdir(pathname.to_s)
  end
  clear_cache(pathname)
end

#size(pathname) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 110

def size(pathname)
  cached :size, pathname do
    ftp_context do
      ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Getting size of #{pathname}"
      begin
        size(pathname.to_s)
      rescue Net::FTPPermError => e
        nil
      rescue Net::FTPReplyError => e
        nil
      end
    end
  end
end

#store(pathname, content) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 204

def store(pathname, content)
  ftp_context do        
    ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Storing #{pathname}"
    # If content is a string, wrap it in a StringIO
    content = StringIO.new(content) if content.is_a? String
    begin
      storbinary("STOR #{pathname}", content, 10240)
    ensure
      content.close if content.respond_to?(:close)
    end
  end
  clear_cache(pathname)
end

#touch(pathname, options = {}) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/el_finder_ftp/ftp_adapter.rb', line 58

def touch(pathname, options={})
  unless exist?(pathname)
    ftp_context do
      ElFinderFtp::Connector.logger.debug "  \e[1;32mFTP:\e[0m    Touching #{pathname}"
      empty_file = StringIO.new("")
      # File does not exist, create
      begin
        storlines("STOR #{pathname}", empty_file)
      ensure
        empty_file.close
      end
    end
    clear_cache(pathname)
  end
  true
end