snapimage 0.1.1 → 0.2.0
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.
- data/README.md +2 -2
- data/bin/snapimage_generate_config +40 -7
- data/lib/snapimage.rb +5 -13
- data/lib/snapimage/adapters/cloudinary/config.rb +13 -0
- data/lib/snapimage/adapters/cloudinary/storage.rb +22 -0
- data/lib/snapimage/adapters/local/config.rb +14 -0
- data/lib/snapimage/adapters/local/storage.rb +48 -0
- data/lib/snapimage/config.rb +3 -1
- data/lib/snapimage/exceptions.rb +0 -6
- data/lib/snapimage/middleware.rb +2 -1
- data/lib/snapimage/rack/request.rb +1 -1
- data/lib/snapimage/rack/response.rb +2 -10
- data/lib/snapimage/server.rb +12 -17
- data/lib/snapimage/storage.rb +10 -0
- data/lib/snapimage/version.rb +1 -1
- data/snapimage.gemspec +0 -1
- data/spec/acceptance/upload_spec.rb +45 -3
- data/spec/snapimage/adapters/local/storage_spec.rb +44 -0
- data/spec/snapimage/middleware_spec.rb +2 -0
- data/spec/snapimage/rack/request_spec.rb +3 -9
- data/spec/snapimage/server_spec.rb +27 -11
- data/spec/support/assets/config.json +2 -0
- data/spec/support/assets/config.yml +2 -0
- metadata +9 -34
- data/lib/snapimage/image/image.rb +0 -103
- data/lib/snapimage/image/image_name_utils.rb +0 -131
- data/lib/snapimage/server_actions/server_actions.authorize.rb +0 -69
- data/lib/snapimage/server_actions/server_actions.delete_resource_images.rb +0 -23
- data/lib/snapimage/server_actions/server_actions.generate_image.rb +0 -169
- data/lib/snapimage/server_actions/server_actions.list_resource_images.rb +0 -23
- data/lib/snapimage/server_actions/server_actions.sync_resource.rb +0 -78
- data/lib/snapimage/storage/storage.rb +0 -120
- data/lib/snapimage/storage/storage_server.local.rb +0 -120
- data/lib/snapimage/storage/storage_server.rb +0 -110
@@ -1,120 +0,0 @@
|
|
1
|
-
module SnapImage
|
2
|
-
module StorageServer
|
3
|
-
class Local < SnapImage::StorageServer::Base
|
4
|
-
def validate_config
|
5
|
-
super
|
6
|
-
raise InvalidStorageConfig, 'Missing "local_root"' unless @config["local_root"]
|
7
|
-
end
|
8
|
-
|
9
|
-
def store_file(file, type, resource_id)
|
10
|
-
image = SnapImage::Image.from_blob(file.read)
|
11
|
-
name = SnapImage::ImageNameUtils.generate_image_name(image.width, image.height, type)
|
12
|
-
store(image, name, resource_id)
|
13
|
-
end
|
14
|
-
|
15
|
-
def store_url(url, type, resource_id)
|
16
|
-
image = SnapImage::Image.from_blob(URI.parse(url).read)
|
17
|
-
name = SnapImage::ImageNameUtils.generate_image_name(image.width, image.height, type)
|
18
|
-
store(image, name, resource_id)
|
19
|
-
end
|
20
|
-
|
21
|
-
def store_image(image, name, resource_id)
|
22
|
-
store(image, name, resource_id)
|
23
|
-
end
|
24
|
-
|
25
|
-
def get(url)
|
26
|
-
path = public_url_to_local_path(url)
|
27
|
-
raise SnapImage::FileDoesNotExist, "Missing file: #{path}" unless File.exists?(path)
|
28
|
-
SnapImage::Image.from_path(path, url)
|
29
|
-
end
|
30
|
-
|
31
|
-
def get_resource_urls(resource_id, timestamp = nil)
|
32
|
-
urls = []
|
33
|
-
get_resource_filenames(resource_id).each do |filename|
|
34
|
-
urls.push(local_path_to_public_url(filename)) if file_modified_before_timestamp?(filename, timestamp)
|
35
|
-
end
|
36
|
-
urls
|
37
|
-
end
|
38
|
-
|
39
|
-
def delete(url)
|
40
|
-
path = public_url_to_local_path(url)
|
41
|
-
raise SnapImage::FileDoesNotExist, "Missing file: #{path}" unless File.exists?(path)
|
42
|
-
File.delete(path)
|
43
|
-
end
|
44
|
-
|
45
|
-
def delete_resource_images(resource_id)
|
46
|
-
deleted_urls = get_resource_urls(resource_id)
|
47
|
-
FileUtils.rm_rf(File.join(root, resource_id)) if deleted_urls.size > 0
|
48
|
-
deleted_urls
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# Stores the image and returns a SnapImage::Image object.
|
54
|
-
# If the image does not fit within the server max width/height, the image
|
55
|
-
# is resized and the modified image is returned.
|
56
|
-
# Arguments:
|
57
|
-
# * image:: SnapImage::Image to store
|
58
|
-
# * name:: Suggested name to use
|
59
|
-
# * resource_id:: Resource identifier
|
60
|
-
def store(image, name, resource_id)
|
61
|
-
result = resize_to_fit(image, name)
|
62
|
-
image = result[:image]
|
63
|
-
name = result[:name]
|
64
|
-
|
65
|
-
# Generate the filename and public url.
|
66
|
-
local_path = File.join(resource_id, name)
|
67
|
-
image.public_url = "#{File.join(@config["public_url"], local_path)}"
|
68
|
-
|
69
|
-
# Store the file.
|
70
|
-
path = File.join(root, local_path)
|
71
|
-
# Ensure the directory exists accounting for the resource_id.
|
72
|
-
dir = File.dirname(path)
|
73
|
-
FileUtils.mkdir_p(dir)
|
74
|
-
# Write the file to the storage.
|
75
|
-
File.open(path, "wb") { |f| f.write(image.blob) }
|
76
|
-
|
77
|
-
# Return the image.
|
78
|
-
image
|
79
|
-
end
|
80
|
-
|
81
|
-
def root
|
82
|
-
unless @root_exists
|
83
|
-
FileUtils.mkdir_p(@config["local_root"]) unless File.directory?(@config["local_root"])
|
84
|
-
@root_exists = true
|
85
|
-
end
|
86
|
-
@config["local_root"]
|
87
|
-
end
|
88
|
-
|
89
|
-
def get_local_path_parts(path)
|
90
|
-
match = path.match(/#{root}\/(.+)\/([^\/]+\.(png|jpg|gif))/)
|
91
|
-
return match && {
|
92
|
-
resource_id: match[1],
|
93
|
-
filename: match[2]
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
def local_path_to_public_url(path)
|
98
|
-
parts = get_local_path_parts(path)
|
99
|
-
"#{File.join(@config["public_url"], parts[:resource_id], parts[:filename])}"
|
100
|
-
end
|
101
|
-
|
102
|
-
def public_url_to_local_path(url)
|
103
|
-
parts = get_url_parts(url)
|
104
|
-
path = File.join(root, parts[:path])
|
105
|
-
end
|
106
|
-
|
107
|
-
def get_resource_filenames(resource_id)
|
108
|
-
Dir.glob(File.join(root, resource_id, "/**/*.{png,jpg,gif}"))
|
109
|
-
end
|
110
|
-
|
111
|
-
# Returns true if no timestamp is given or the file was modified before
|
112
|
-
# the timestamp.
|
113
|
-
def file_modified_before_timestamp?(filename, timestamp = nil)
|
114
|
-
# File.mtime returns a Time object. Convert it to a DateTime because
|
115
|
-
# timestamp is a DateTime.
|
116
|
-
!timestamp || File.mtime(filename).to_datetime < timestamp
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
module SnapImage
|
2
|
-
module StorageServer
|
3
|
-
class Base
|
4
|
-
# Config:
|
5
|
-
# * name:: Name of the storage.
|
6
|
-
# * public_url:: URL to acces the storage.
|
7
|
-
def initialize(config)
|
8
|
-
@config = config
|
9
|
-
validate_config
|
10
|
-
end
|
11
|
-
|
12
|
-
def name
|
13
|
-
@config["name"]
|
14
|
-
end
|
15
|
-
|
16
|
-
# Returns a regular expression for matching urls handled by this storage
|
17
|
-
# server.
|
18
|
-
def url_regexp
|
19
|
-
@url_regexp ||= /#{@config["public_url"]}\/.+?\.(png|gif|jpg)/
|
20
|
-
end
|
21
|
-
|
22
|
-
def local?(url)
|
23
|
-
!!url.match(url_regexp)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Stores the file in the storage and returns a SnapImage::Image object.
|
27
|
-
# Arguments:
|
28
|
-
# * file:: File object representing the file to store.
|
29
|
-
# * type:: File type
|
30
|
-
# * resource_id:: Resource identifier.
|
31
|
-
def store_file(file, type, resource_id)
|
32
|
-
raise "#store_file needs to be overridden."
|
33
|
-
end
|
34
|
-
|
35
|
-
# Downloads the file and adds it to the storage and returns a
|
36
|
-
# SnapImage::Image object.
|
37
|
-
# Arguments:
|
38
|
-
# * url:: Url to get the image
|
39
|
-
# * type:: File type
|
40
|
-
# * resource_id:: Resource identifier.
|
41
|
-
def store_url(url, type, resource_id)
|
42
|
-
raise "#store_url needs to be overridden."
|
43
|
-
end
|
44
|
-
|
45
|
-
# Adds the image to the storage. Overwrites existing file.
|
46
|
-
# Arguments:
|
47
|
-
# * image:: SnapImage::Image object
|
48
|
-
# * name:: Name of the image
|
49
|
-
# * resource_id:: Resource identifier
|
50
|
-
def store_image(image, name, resource_id)
|
51
|
-
raise "#store_image needs to be overridden."
|
52
|
-
end
|
53
|
-
|
54
|
-
# Returns the SnapImage:Image object from the url.
|
55
|
-
def get(url)
|
56
|
-
raise "#get needs to be overriden."
|
57
|
-
end
|
58
|
-
|
59
|
-
# Returns all the image urls for the given resource in the storage.
|
60
|
-
# Arguments:
|
61
|
-
# * resource_id:: Filter by resource identifier
|
62
|
-
# * timestamp:: Only images that were updated before the DateTime
|
63
|
-
def get_resource_urls(resource_id, timestamp = nil)
|
64
|
-
raise "#get_all_urls needs to be overriden."
|
65
|
-
end
|
66
|
-
|
67
|
-
# Deletes the given url.
|
68
|
-
def delete(url)
|
69
|
-
raise "#delete needs to be overridden."
|
70
|
-
end
|
71
|
-
|
72
|
-
# Deletes the given resource images.
|
73
|
-
def delete_resource_images(resource_id)
|
74
|
-
raise "#delete_resource needs to be overridden."
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
# Validates the config. Subclasses should add to this.
|
80
|
-
def validate_config
|
81
|
-
raise InvalidStorageConfig, 'Missing "name"' unless @config["name"]
|
82
|
-
raise InvalidStorageConfig, 'Missing "public_url"' unless @config["public_url"]
|
83
|
-
raise InvalidStorageConfig, 'Missing "max_width"' unless @config["max_width"]
|
84
|
-
raise InvalidStorageConfig, 'Missing "max_height"' unless @config["max_height"]
|
85
|
-
end
|
86
|
-
|
87
|
-
def get_url_parts(url)
|
88
|
-
match = url.match(/^(([a-z]+):|)(#{@config["public_url"]})\/(.+)$/)
|
89
|
-
return match && {
|
90
|
-
protocol: match[2],
|
91
|
-
public_url: match[3],
|
92
|
-
path: match[4]
|
93
|
-
}
|
94
|
-
end
|
95
|
-
|
96
|
-
# Resizes the image if it doesn't fit on the server. Updates the name if
|
97
|
-
# needed.
|
98
|
-
# Returns { image: resized_image, name: resized_name }.
|
99
|
-
def resize_to_fit(image, name)
|
100
|
-
# Resize the image if it's larger than the max width/height.
|
101
|
-
if image.width > @config["max_width"] || image.height > @config["max_height"]
|
102
|
-
image.resize([image.width, @config["max_width"]].min, [image.height, @config["max_height"]].min)
|
103
|
-
# Generate a new name.
|
104
|
-
name = SnapImage::ImageNameUtils.get_resized_image_name(name, image.width, image.height)
|
105
|
-
end
|
106
|
-
{ image: image, name: name }
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|