el_finder_s3 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'shellwords'
3
+ require 'image_size'
4
+
5
+ module ElFinderS3
6
+
7
+ # Represents default image handler.
8
+ # It uses *mogrify* to resize images and *convert* to create thumbnails.
9
+ class Image
10
+
11
+ def self.size(pathname)
12
+ return nil unless File.exist?(pathname)
13
+ s = ::ImageSize.new(File.open(pathname)).size.to_s
14
+ s = nil if s.empty?
15
+ return s
16
+ end
17
+
18
+ def self.resize(pathname, options = {})
19
+ return nil unless File.exist?(pathname)
20
+ system( ::Shellwords.join(['mogrify', '-resize', "#{options[:width]}x#{options[:height]}!", pathname.to_s]) )
21
+ end # of self.resize
22
+
23
+ def self.thumbnail(src, dst, options = {})
24
+ return nil unless File.exist?(src)
25
+ system( ::Shellwords.join(['convert', '-resize', "#{options[:width]}x#{options[:height]}", '-background', 'white', '-gravity', 'center', '-extent', "#{options[:width]}x#{options[:height]}", src.to_s, dst.to_s]) )
26
+ end # of self.resize
27
+
28
+ end # of class Image
29
+
30
+ end # of module ElFinderS3
@@ -0,0 +1,83 @@
1
+ module ElFinderS3
2
+
3
+ # Represents default MIME types recognizer.
4
+ class MimeType
5
+
6
+ # File extension to mime type mapping.
7
+ TYPES = {
8
+ 'ai' => 'application/postscript',
9
+ 'eps' => 'application/postscript',
10
+ 'exe' => 'application/octet-stream',
11
+ 'doc' => 'application/vnd.ms-word',
12
+ 'xls' => 'application/vnd.ms-excel',
13
+ 'ppt' => 'application/vnd.ms-powerpoint',
14
+ 'pps' => 'application/vnd.ms-powerpoint',
15
+ 'pdf' => 'application/pdf',
16
+ 'xml' => 'application/xml',
17
+ 'odt' => 'application/vnd.oasis.opendocument.text',
18
+ 'swf' => 'application/x-shockwave-flash',
19
+ # archives
20
+ 'gz' => 'application/x-gzip',
21
+ 'tgz' => 'application/x-gzip',
22
+ 'bz' => 'application/x-bzip2',
23
+ 'bz2' => 'application/x-bzip2',
24
+ 'tbz' => 'application/x-bzip2',
25
+ 'zip' => 'application/zip',
26
+ 'rar' => 'application/x-rar',
27
+ 'tar' => 'application/x-tar',
28
+ '7z' => 'application/x-7z-compressed',
29
+ # texts
30
+ 'txt' => 'text/plain',
31
+ 'php' => 'text/x-php',
32
+ 'html' => 'text/html',
33
+ 'htm' => 'text/html',
34
+ 'js' => 'text/javascript',
35
+ 'css' => 'text/css',
36
+ 'rtf' => 'text/rtf',
37
+ 'rtfd' => 'text/rtfd',
38
+ 'py' => 'text/x-python',
39
+ 'java' => 'text/x-java-source',
40
+ 'rb' => 'text/x-ruby',
41
+ 'sh' => 'text/x-shellscript',
42
+ 'pl' => 'text/x-perl',
43
+ 'sql' => 'text/x-sql',
44
+ # images
45
+ 'bmp' => 'image/x-ms-bmp',
46
+ 'jpg' => 'image/jpeg',
47
+ 'jpeg' => 'image/jpeg',
48
+ 'gif' => 'image/gif',
49
+ 'png' => 'image/png',
50
+ 'tif' => 'image/tiff',
51
+ 'tiff' => 'image/tiff',
52
+ 'tga' => 'image/x-targa',
53
+ 'psd' => 'image/vnd.adobe.photoshop',
54
+ # audio
55
+ 'mp3' => 'audio/mpeg',
56
+ 'mid' => 'audio/midi',
57
+ 'ogg' => 'audio/ogg',
58
+ 'mp4a' => 'audio/mp4',
59
+ 'wav' => 'audio/wav',
60
+ 'wma' => 'audio/x-ms-wma',
61
+ # video
62
+ 'avi' => 'video/x-msvideo',
63
+ 'dv' => 'video/x-dv',
64
+ 'mp4' => 'video/mp4',
65
+ 'mpeg' => 'video/mpeg',
66
+ 'mpg' => 'video/mpeg',
67
+ 'mov' => 'video/quicktime',
68
+ 'wm' => 'video/x-ms-wmv',
69
+ 'flv' => 'video/x-flv',
70
+ 'mkv' => 'video/x-matroska'
71
+ }
72
+
73
+ # Gets MIME type fort specified path.
74
+ # @param [::Pathname, String] pathname Path to recognize its MIME type.
75
+ # @return [String] MIME type if known; 'unknown/unknown' otherwise.
76
+ def self.for(pathname)
77
+ pathname = ::Pathname.new(pathname) if pathname.is_a?(String)
78
+ TYPES[pathname.extname.downcase[1..-1]] || 'application/octet-stream'
79
+ end # of for
80
+
81
+ end # of class MimeType
82
+
83
+ end # of module ElFinderS3
@@ -0,0 +1,250 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+
4
+ module ElFinderS3
5
+
6
+ class Pathname
7
+ attr_reader :root, :path, :adapter
8
+
9
+ #
10
+ def initialize(adapter_or_root, path = '.')
11
+ @adapter = adapter_or_root.is_a?(ElFinderS3::Pathname) ? adapter_or_root.adapter : adapter_or_root
12
+
13
+ @root = path.is_a?(ElFinderS3::Pathname) ? path.root : S3Pathname.new(@adapter, '/')
14
+
15
+ if path.is_a?(ElFinderS3::Pathname)
16
+ @path = path.path
17
+ elsif path.is_a?(ElFinderS3::S3Pathname)
18
+ @path = path
19
+ else
20
+ @path = S3Pathname.new(@adapter, path)
21
+ end
22
+ if absolute?
23
+ if @path.cleanpath.to_s.start_with?(@root.to_s)
24
+ @path = S3Pathname.new(@adapter, @path.to_s.slice((@root.to_s.length)..-1), @path.attrs)
25
+ elsif @path.cleanpath.to_s.start_with?(@root.realpath.to_s)
26
+ @path = S3Pathname.new(@adapter, @path.to_s.slice((@root.realpath.to_s.length)..-1), @path.attrs)
27
+ else
28
+ raise SecurityError, "Absolute paths are not allowed"
29
+ end
30
+ end
31
+ raise SecurityError, "Paths outside the root are not allowed" if outside_of_root?
32
+
33
+ end
34
+
35
+ # of initialize
36
+
37
+ def type(type)
38
+ @type = type
39
+ end
40
+
41
+ #
42
+ def +(other)
43
+ if other.is_a? ::ElFinderS3::Pathname
44
+ other = other.path
45
+ end
46
+ self.class.new(@adapter, @path + other)
47
+ end
48
+
49
+ # of +
50
+
51
+ #
52
+ def is_root?
53
+ @path.to_s == '.'
54
+ end
55
+
56
+ #
57
+ def absolute?
58
+ @path.absolute?
59
+ end
60
+
61
+ # of absolute?
62
+
63
+ #
64
+ def relative?
65
+ @path.relative?
66
+ end
67
+
68
+ # of relative?
69
+
70
+ #
71
+ def outside_of_root?
72
+ !cleanpath.to_s.start_with?(@root.to_s)
73
+ end
74
+
75
+ # of outside_of_root?
76
+
77
+ #
78
+ def fullpath
79
+ @fullpath ||= (@path.nil? ? @root : @root + @path)
80
+ b = @path.nil? ? @root : @root + @path
81
+ return @fullpath
82
+ end
83
+
84
+ # of fullpath
85
+
86
+ #
87
+ def cleanpath
88
+ fullpath.cleanpath
89
+ end
90
+
91
+ # of cleanpath
92
+
93
+ #
94
+ def realpath
95
+ fullpath.realpath
96
+ end
97
+
98
+ # of realpath
99
+
100
+ #
101
+ def basename(*args)
102
+ @path.basename(*args)
103
+ end
104
+
105
+ # of basename
106
+
107
+ #
108
+ def basename_sans_extension
109
+ @path.basename(@path.extname)
110
+ end
111
+
112
+ # of basename
113
+
114
+ #
115
+ def basename(*args)
116
+ @path.basename(*args)
117
+ end
118
+
119
+ # of basename
120
+
121
+ #
122
+ def dirname
123
+ self.class.new(@adapter, @path.dirname)
124
+ end
125
+
126
+ # of basename
127
+
128
+ #
129
+ def extname
130
+ @path.nil? ? '' : @path.extname
131
+ end
132
+
133
+ # of extname
134
+
135
+ #
136
+ def to_s
137
+ cleanpath.to_s
138
+ end
139
+
140
+ def to_prefix_s
141
+ prefix_s = cleanpath.to_s
142
+ if prefix_s == '/'
143
+ return ''
144
+ elsif prefix_s[0] == '/'
145
+ prefix_s[0] = ''
146
+ end
147
+
148
+ if prefix_s[prefix_s.size-1] != '/'
149
+ prefix_s = prefix_s + '/'
150
+ end
151
+ return prefix_s
152
+ end
153
+
154
+ # of to_s
155
+ alias_method :to_str, :to_s
156
+
157
+ #
158
+ def child_directories(with_directory=true)
159
+ adapter.children(self, with_directory).select { |child| child.directory? }.map { |e| self.class.new(@adapter, e) }
160
+ end
161
+
162
+ #
163
+ def files(with_directory=true)
164
+ adapter.children(self, with_directory).select { |child| child.file? }.map { |e| self.class.new(@adapter, e) }
165
+ end
166
+
167
+
168
+ #
169
+ def children(with_directory=true)
170
+ adapter.children(self, with_directory).map { |e| self.class.new(@adapter, e) }
171
+ end
172
+
173
+ #
174
+ def touch(options = {})
175
+ adapter.touch(cleanpath, options)
176
+ end
177
+
178
+ #
179
+ def relative_to(other)
180
+ @path.relative_path_from(other)
181
+ end
182
+
183
+ #
184
+ def unique
185
+ return self.dup unless fullpath.file?
186
+ copy = 1
187
+ begin
188
+ new_file = self.class.new(@adapter, dirname + "#{basename_sans_extension} #{copy}#{extname}")
189
+ copy += 1
190
+ end while new_file.exist?
191
+ new_file
192
+ end
193
+
194
+ # of unique
195
+
196
+ #
197
+ def duplicate
198
+ _basename = basename_sans_extension
199
+ copy = 1
200
+ if _basename.to_s =~ /^(.*) copy (\d+)$/
201
+ _basename = $1
202
+ copy = $2.to_i
203
+ end
204
+ begin
205
+ new_file = self.class.new(@adapter, dirname + "#{_basename} copy #{copy}#{extname}")
206
+ copy += 1
207
+ end while new_file.exist?
208
+ new_file
209
+ end
210
+
211
+ # of duplicate
212
+
213
+ #
214
+ def rename(to)
215
+ to = self.class.new(@adapter, to)
216
+ realpath.rename(to.fullpath.to_s)
217
+ to
218
+ end
219
+
220
+ # of rename
221
+
222
+ {
223
+ 'directory?' => {:path => 'realpath', :rescue => true},
224
+ 'exist?' => {:path => 'realpath', :rescue => true},
225
+ 'file?' => {:path => 'realpath', :rescue => true},
226
+ 'ftype' => {:path => 'realpath', },
227
+ 'mkdir' => {:path => 'fullpath', :args => '(*args)'},
228
+ 'mtime' => {:path => 'realpath', },
229
+ 'open' => {:path => 'fullpath', :args => '(*args, &block)'},
230
+ 'read' => {:path => 'fullpath', :args => '(*args)'},
231
+ 'write' => {:path => 'fullpath', :args => '(*args)'},
232
+ 'readlink' => {:path => 'fullpath', },
233
+ 'readable?' => {:path => 'realpath', :rescue => true},
234
+ 'size' => {:path => 'realpath', },
235
+ 'symlink?' => {:path => 'fullpath', },
236
+ 'unlink' => {:path => 'realpath', },
237
+ 'writable?' => {:path => 'realpath', :rescue => true},
238
+ }.each_pair do |meth, opts|
239
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
240
+ def #{meth}#{opts[:args]}
241
+ #{opts[:path]}.#{meth}#{opts[:args]}
242
+ #{"rescue Errno::ENOENT\nfalse" if opts[:rescue]}
243
+ end
244
+ METHOD
245
+ end
246
+
247
+
248
+ end # of class Pathname
249
+
250
+ end # of module ElFinderS3
@@ -0,0 +1,7 @@
1
+ module ElFinderS3
2
+ class Railties < ::Rails::Railtie
3
+ initializer 'Rails logger' do
4
+ ElFinderS3::Connector.logger = Rails.logger
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,89 @@
1
+ require 'aws-sdk'
2
+
3
+ module ElFinderS3
4
+ class S3Connector
5
+ :s3_client
6
+ :bucket_name
7
+
8
+ def initialize(server)
9
+ Aws.config.update(
10
+ {
11
+ region: server[:region],
12
+ credentials: Aws::Credentials.new(server[:access_key_id], server[:secret_access_key])
13
+ }
14
+ )
15
+ @bucket_name = server[:bucket_name]
16
+ @s3_client = Aws::S3::Client.new
17
+ end
18
+
19
+ # @param [ElFinderS3::Pathname] pathname
20
+ def ls_la(pathname, with_directory)
21
+ prefix = pathname.to_prefix_s
22
+ query = {
23
+ bucket: @bucket_name,
24
+ delimiter: '/',
25
+ encoding_type: 'url',
26
+ max_keys: 100,
27
+ prefix: prefix
28
+ }
29
+
30
+ response = @s3_client.list_objects(query)
31
+ result = []
32
+ #Files
33
+ response.contents.each { |e|
34
+ if e.key != prefix
35
+ e.key = e.key.gsub(prefix, '')
36
+ if with_directory
37
+ result.push(pathname.fullpath + ::ElFinderS3::S3Pathname.new(self, e))
38
+ else
39
+ result.push(::ElFinderS3::S3Pathname.new(self, e))
40
+ end
41
+ end
42
+ }
43
+ #Folders
44
+ response.common_prefixes.each { |f|
45
+ if f.prefix != '' && f.prefix != prefix && f.prefix != '/'
46
+ f.prefix = f.prefix.split('/').last
47
+ result.push(pathname.fullpath + ::ElFinderS3::S3Pathname.new(self, f))
48
+ end
49
+ }
50
+ return result
51
+ end
52
+
53
+ # @param [ElFinderS3::Pathname] pathname
54
+ def exist?(pathname)
55
+ query = {
56
+ bucket: @bucket_name,
57
+ key: pathname.to_prefix_s
58
+ }
59
+ begin
60
+ @s3_client.head_object(query)
61
+ true
62
+ rescue Aws::S3::Errors::NotFound
63
+ false
64
+ end
65
+ end
66
+
67
+ def mkdir(folder_name)
68
+ begin
69
+ @s3_client.put_object(bucket: @bucket_name, key: folder_name)
70
+ true
71
+ rescue
72
+ false
73
+ end
74
+ end
75
+
76
+ def touch(filename)
77
+ begin
78
+ @s3_client.put_object(bucket: @bucket_name, key: filename)
79
+ true
80
+ rescue
81
+ false
82
+ end
83
+ end
84
+
85
+ def store(filename, content)
86
+ @s3_client.put_object(bucket: @bucket_name, key: filename, body: content, acl: 'public-read')
87
+ end
88
+ end
89
+ end