mingle-storage 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTliODIxMzIzMDNmMTYzOTNmNmZiOWEyYTY5YmEwMTUwNDVkZjAyMg==
5
+ data.tar.gz: !binary |-
6
+ M2UzMGQ5MjNkNTE0MDk0YmIwZmY3Njc3OWU4ZTVlM2U0NDdmNzhlMA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NTdjNGFkYjEzODllMzFlNGUyZWM4YzA4ZmJjMDljNmI3MGY5MTYzY2M3NDA1
10
+ MTNkYTFmZTMyMjY4ZjkzMWNiNGEwYTY2NzY3Y2UyM2QyNzdhYmU3MmZkNjNk
11
+ NzUzZTczZmNmYmZhZWNjNTQ0Nzk5NTI0NjhkMzMzMThiYmI0MzQ=
12
+ data.tar.gz: !binary |-
13
+ OTZkYTEwMzYyZjMwOTZmOGEwYTg1MjgwNzJkMTJiYWY3ZjNhMmI1NTgxMDU2
14
+ YTQxZjBlMTNkOTk5NWMwMzI3OWJhM2JhMGY2ZmY0Y2NkMmIzMjZjMmE4OTYx
15
+ Njg5YzJlYTQyMWNjYTg0NWFkMDA4ZTYwMDVkYmJmMDI0MmM2ODk=
@@ -0,0 +1,47 @@
1
+ module Storage
2
+ class FilesystemStore
3
+ def initialize(path_prefix, options={})
4
+ @dir = options[:root_path] || raise('Must define root path for file system store')
5
+ @path_prefix = path_prefix
6
+ FileUtils.mkdir_p File.join(@dir, @path_prefix)
7
+ end
8
+
9
+ def copy(path, to_local_path)
10
+ raise "File(#{path}) does not exist" unless File.exists?(absolute_path(path))
11
+ FileUtils.cp(absolute_path(path), to_local_path)
12
+ end
13
+
14
+ def read(path)
15
+ File.read(absolute_path(path))
16
+ end
17
+
18
+ def upload(path, local_file)
19
+ FileUtils.mkdir_p(absolute_path(path))
20
+ FileUtils.mv(local_file, absolute_path(path))
21
+ end
22
+
23
+ def upload_dir(path, local_dir)
24
+ FileUtils.rm_rf(absolute_path(path))
25
+ Dir[File.join(local_dir, "*")].each do |f|
26
+ upload(path, f)
27
+ end
28
+ end
29
+
30
+ #todo: this should be interface that retrive a lazy file object
31
+ def absolute_path(*relative_paths)
32
+ File.join(@dir, @path_prefix, *relative_paths)
33
+ end
34
+
35
+ def exists?(path)
36
+ File.exists?(absolute_path(path))
37
+ end
38
+
39
+ def delete(path)
40
+ FileUtils.rm_rf(absolute_path(path))
41
+ end
42
+
43
+ def clear
44
+ FileUtils.rm_rf File.join(@dir, @path_prefix)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,105 @@
1
+ module Storage
2
+ class S3Store
3
+
4
+ HALF_AN_HOUR = 30 * 60
5
+
6
+ def initialize(path_prefix, options)
7
+ @path_prefix = path_prefix
8
+ @url_expires = options[:url_expires] || HALF_AN_HOUR
9
+ @bucket_name = options[:bucket_name]
10
+ end
11
+
12
+ def upload(path, local_file)
13
+ local_file_name = File.basename(local_file)
14
+ bucket.objects.create(
15
+ s3_path(path, local_file_name),
16
+ File.read(local_file),
17
+ { :content_type => derive_content_type(local_file_name) }
18
+ )
19
+ end
20
+
21
+ def upload_dir(path, local_dir)
22
+ bucket.objects.with_prefix(s3_path(path)).delete_all
23
+ Dir[File.join(local_dir, "*")].each do |f|
24
+ upload(path, f)
25
+ end
26
+ end
27
+
28
+ def content_type(path)
29
+ object(path).content_type
30
+ end
31
+
32
+ def copy(path, to_local_path)
33
+ obj = object(path)
34
+ raise "File(#{path}) does not exist in the bucket #{bucket.name}" unless obj.exists?
35
+ File.open(to_local_path, 'w') do |f|
36
+ obj.read do |c|
37
+ f.write(c)
38
+ end
39
+ end
40
+ end
41
+
42
+ def write_to_file(path, content)
43
+ object(path).write(content)
44
+ end
45
+
46
+ def read(path)
47
+ object(path).read
48
+ end
49
+
50
+ def exists?(path)
51
+ object(path).exists?
52
+ end
53
+
54
+ def url_for(path)
55
+ object(path).url_for(:read, :expires => @url_expires).to_s
56
+ end
57
+
58
+ #todo: this should be interface that retrive a lazy file object
59
+ def absolute_path(*relative_paths)
60
+ File.join("s3:#{bucket_name}://", *relative_paths)
61
+ end
62
+
63
+ def delete(path)
64
+ bucket.objects.with_prefix(s3_path(path)).delete_all
65
+ end
66
+
67
+ def clear
68
+ if s3_path.blank?
69
+ bucket.clear
70
+ else
71
+ bucket.objects.with_prefix(s3_path).delete_all
72
+ end
73
+ end
74
+
75
+ def objects(path)
76
+ bucket.objects.with_prefix(s3_path(path))
77
+ end
78
+
79
+ private
80
+ def derive_content_type(file_name)
81
+ file_extension = file_name.split(".").last
82
+ Storage::CONTENT_TYPES[file_extension]
83
+ end
84
+
85
+ def s3
86
+ AWS::S3.new
87
+ end
88
+
89
+ def object(path)
90
+ bucket.objects[s3_path(path)]
91
+ end
92
+
93
+ def s3_path(*paths)
94
+ File.join(*([@path_prefix, *paths].compact))
95
+ end
96
+
97
+ def bucket
98
+ @bucket ||= s3.buckets[bucket_name]
99
+ end
100
+
101
+ def bucket_name
102
+ @bucket_name.is_a?(String) ? @bucket_name : @bucket_name[@path_prefix]
103
+ end
104
+ end
105
+ end
data/lib/storage.rb ADDED
@@ -0,0 +1,124 @@
1
+ require 'rubygems'
2
+ require 'aws-sdk'
3
+ require 'storage/filesystem_store.rb'
4
+ require 'storage/s3_store.rb'
5
+
6
+ module Storage
7
+
8
+ CONTENT_TYPES = {
9
+ "html" => "text/html",
10
+ "htm" => "text/html",
11
+ "shtml" => "text/html",
12
+ "css" => "text/css",
13
+ "xml" => "text/xml",
14
+ "gif" => "image/gif",
15
+ "jpeg" => "image/jpeg",
16
+ "jpg" => "image/jpeg",
17
+ "js" => "application/x-javascript",
18
+ "atom" => "application/atom+xml",
19
+ "rss" => "application/rss+xml",
20
+ "json" => "application/json",
21
+ "mml" => "text/mathml",
22
+ "txt" => "text/plain",
23
+ "jad" => "text/vnd.sun.j2me.app-descriptor",
24
+ "wml" => "text/vnd.wap.wml",
25
+ "htc" => "text/x-component",
26
+ "png" => "image/png",
27
+ "tif" => "image/tiff",
28
+ "tiff" => "image/tiff",
29
+ "wbmp" => "image/vnd.wap.wbmp",
30
+ "ico" => "image/x-icon",
31
+ "jng" => "image/x-jng",
32
+ "bmp" => "image/x-ms-bmp",
33
+ "svg" => "image/svg+xml",
34
+ "jar" => "application/java-archive",
35
+ "war" => "application/java-archive",
36
+ "ear" => "application/java-archive",
37
+ "hqx" => "application/mac-binhex40",
38
+ "doc" => "application/msword",
39
+ "pdf" => "application/pdf",
40
+ "ps" => "application/postscript",
41
+ "eps" => "application/postscript",
42
+ "ai" => "application/postscript",
43
+ "rtf" => "application/rtf",
44
+ "xls" => "application/vnd.ms-excel",
45
+ "ppt" => "application/vnd.ms-powerpoint",
46
+ "wmlc" => "application/vnd.wap.wmlc",
47
+ "xhtml" => "application/vnd.wap.xhtml+xml",
48
+ "kml" => "application/vnd.google-earth.kml+xml",
49
+ "kmz" => "application/vnd.google-earth.kmz",
50
+ "7z" => "application/x-7z-compressed",
51
+ "cco" => "application/x-cocoa",
52
+ "jardiff" => "application/x-java-archive-diff",
53
+ "jnlp" => "application/x-java-jnlp-file",
54
+ "run" => "application/x-makeself",
55
+ "pl" => "application/x-perl",
56
+ "pm" => "application/x-perl",
57
+ "prc" => "application/x-pilot",
58
+ "pdb" => "application/x-pilot",
59
+ "rar" => "application/x-rar-compressed",
60
+ "rpm" => "application/x-redhat-package-manager",
61
+ "sea" => "application/x-sea",
62
+ "swf" => "application/x-shockwave-flash",
63
+ "sit" => "application/x-stuffit",
64
+ "tcl" => "application/x-tcl",
65
+ "tk" => "application/x-tcl",
66
+ "der" => "application/x-x509-ca-cert",
67
+ "pem" => "application/x-x509-ca-cert",
68
+ "crt" => "application/x-x509-ca-cert",
69
+ "xpi" => "application/x-xpinstall",
70
+ "zip" => "application/zip",
71
+ "bin" => "application/octet-stream",
72
+ "exe" => "application/octet-stream",
73
+ "dll" => "application/octet-stream",
74
+ "deb" => "application/octet-stream",
75
+ "dmg" => "application/octet-stream",
76
+ "eot" => "application/octet-stream",
77
+ "iso" => "application/octet-stream",
78
+ "img" => "application/octet-stream",
79
+ "msi" => "application/octet-stream",
80
+ "msp" => "application/octet-stream",
81
+ "msm" => "application/octet-stream",
82
+ "mid" => "audio/midi",
83
+ "midi" => "audio/midi",
84
+ "kar" => "audio/midi",
85
+ "mp3" => "audio/mpeg",
86
+ "ra" => "audio/x-realaudio",
87
+ "3gpp" => "video/3gpp",
88
+ "3gp" => "video/3gpp",
89
+ "mpeg" => "video/mpeg",
90
+ "mpg" => "video/mpeg",
91
+ "mov" => "video/quicktime",
92
+ "flv" => "video/x-flv",
93
+ "mng" => "video/x-mng",
94
+ "asx" => "video/x-ms-asf",
95
+ "asf" => "video/x-ms-asf",
96
+ "wmv" => "video/x-ms-wmv",
97
+ "avi" => "video/x-msvideo"
98
+ }
99
+
100
+ class Builder
101
+ def initialize(type)
102
+ @type = type
103
+ end
104
+
105
+ def build(path_prefix, options={})
106
+ store_class.new(path_prefix, options)
107
+ end
108
+
109
+ private
110
+
111
+ def store_class
112
+ {
113
+ :filesystem => Storage::FilesystemStore,
114
+ :s3 => Storage::S3Store
115
+ }[@type.to_sym]
116
+ end
117
+ end
118
+
119
+ def self.store(type, path_prefix, options={})
120
+ builder = Builder.new(type)
121
+ builder.build(path_prefix, options)
122
+ end
123
+
124
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mingle-storage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - ThoughtWorks Studios
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.11.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.11.3
27
+ description: Mingle storage API to support filesystem and AWS S3 backed storage
28
+ email: mingle-dev@thoughtworks.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/storage/filesystem_store.rb
34
+ - lib/storage/s3_store.rb
35
+ - lib/storage.rb
36
+ homepage: http://www.thoughtworks.com/products
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.0.7
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Mingle storage API to support filesystem and AWS S3 backed storage
60
+ test_files: []