progstr-filer 0.8.7 → 0.8.8

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/Gemfile CHANGED
@@ -12,14 +12,14 @@ group :development do
12
12
  gem "libnotify"
13
13
  gem "shoulda", ">= 0"
14
14
  #gem "rspec", "~> 2.3.0"
15
- gem "bundler", "~> 1.0.0"
15
+ gem "bundler", ">= 1.0.0"
16
16
  gem "jeweler", "~> 1.6.4"
17
- gem "rcov", ">= 0"
18
17
  gem "rdoc", ">= 0"
19
18
  end
20
19
 
21
20
  gem "activerecord", ">=3.0.0"
22
21
  gem "activemodel", ">=3.0.0"
22
+ gem "actionpack", ">=3.0.0"
23
23
  gem "uuid"
24
24
  gem "rest-client"
25
25
  gem "multi_json"
data/Gemfile.lock CHANGED
@@ -1,68 +1,94 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activemodel (3.1.3)
5
- activesupport (= 3.1.3)
4
+ actionpack (3.2.3)
5
+ activemodel (= 3.2.3)
6
+ activesupport (= 3.2.3)
6
7
  builder (~> 3.0.0)
7
- i18n (~> 0.6)
8
- activerecord (3.1.3)
9
- activemodel (= 3.1.3)
10
- activesupport (= 3.1.3)
11
- arel (~> 2.2.1)
8
+ erubis (~> 2.7.0)
9
+ journey (~> 1.0.1)
10
+ rack (~> 1.4.0)
11
+ rack-cache (~> 1.2)
12
+ rack-test (~> 0.6.1)
13
+ sprockets (~> 2.1.2)
14
+ activemodel (3.2.3)
15
+ activesupport (= 3.2.3)
16
+ builder (~> 3.0.0)
17
+ activerecord (3.2.3)
18
+ activemodel (= 3.2.3)
19
+ activesupport (= 3.2.3)
20
+ arel (~> 3.0.2)
12
21
  tzinfo (~> 0.3.29)
13
- activesupport (3.1.3)
22
+ activesupport (3.2.3)
23
+ i18n (~> 0.6)
14
24
  multi_json (~> 1.0)
15
- arel (2.2.1)
25
+ arel (3.0.2)
16
26
  builder (3.0.0)
27
+ erubis (2.7.0)
17
28
  ffi (1.0.11)
18
29
  git (1.2.5)
19
- guard (0.10.0)
30
+ guard (1.0.1)
20
31
  ffi (>= 0.5.0)
21
32
  thor (~> 0.14.6)
22
33
  guard-test (0.4.3)
23
34
  guard (>= 0.4)
24
35
  test-unit (~> 2.2)
36
+ hike (1.2.1)
25
37
  i18n (0.6.0)
26
38
  jeweler (1.6.4)
27
39
  bundler (~> 1.0)
28
40
  git (>= 1.2.5)
29
41
  rake
30
- json (1.6.4)
31
- libnotify (0.7.1)
42
+ journey (1.0.3)
43
+ json (1.6.6)
44
+ libnotify (0.7.2)
32
45
  macaddr (1.5.0)
33
46
  systemu (>= 2.4.0)
34
- mime-types (1.17.2)
35
- multi_json (1.0.4)
47
+ mime-types (1.18)
48
+ multi_json (1.3.0)
49
+ rack (1.4.1)
50
+ rack-cache (1.2)
51
+ rack (>= 0.4)
52
+ rack-test (0.6.1)
53
+ rack (>= 1.0)
36
54
  rake (0.9.2.2)
37
55
  rb-inotify (0.8.8)
38
56
  ffi (>= 0.5.0)
39
- rcov (0.9.11)
40
57
  rdoc (3.12)
41
58
  json (~> 1.4)
42
59
  rest-client (1.6.7)
43
60
  mime-types (>= 1.16)
44
- shoulda (2.11.3)
61
+ shoulda (3.0.1)
62
+ shoulda-context (~> 1.0.0)
63
+ shoulda-matchers (~> 1.0.0)
64
+ shoulda-context (1.0.0)
65
+ shoulda-matchers (1.0.0)
66
+ sprockets (2.1.2)
67
+ hike (~> 1.2)
68
+ rack (~> 1.0)
69
+ tilt (~> 1.1, != 1.3.0)
45
70
  sqlite3 (1.3.5)
46
- systemu (2.4.2)
47
- test-unit (2.4.4)
71
+ systemu (2.5.0)
72
+ test-unit (2.4.8)
48
73
  thor (0.14.6)
49
- tzinfo (0.3.31)
50
- uuid (2.3.4)
74
+ tilt (1.3.3)
75
+ tzinfo (0.3.33)
76
+ uuid (2.3.5)
51
77
  macaddr (~> 1.0)
52
78
 
53
79
  PLATFORMS
54
80
  ruby
55
81
 
56
82
  DEPENDENCIES
83
+ actionpack (>= 3.0.0)
57
84
  activemodel (>= 3.0.0)
58
85
  activerecord (>= 3.0.0)
59
- bundler (~> 1.0.0)
86
+ bundler (>= 1.0.0)
60
87
  guard-test
61
88
  jeweler (~> 1.6.4)
62
89
  libnotify
63
90
  multi_json
64
91
  rb-inotify
65
- rcov
66
92
  rdoc
67
93
  rest-client
68
94
  shoulda
data/Rakefile CHANGED
@@ -38,18 +38,6 @@ Rake::TestTask.new(:test) do |test|
38
38
  test.verbose = true
39
39
  end
40
40
 
41
- #RSpec::Core::RakeTask.new(:rcov) do |spec|
42
- #spec.pattern = 'spec/**/*_spec.rb'
43
- #spec.rcov = true
44
- #end
45
- require 'rcov/rcovtask'
46
- Rcov::RcovTask.new do |test|
47
- test.libs << 'test'
48
- test.pattern = 'test/**/test_*.rb'
49
- test.verbose = true
50
- test.rcov_opts << '--exclude "gems/*"'
51
- end
52
-
53
41
  task :default => :spec
54
42
 
55
43
  require 'rdoc/task'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.7
1
+ 0.8.8
@@ -46,24 +46,35 @@ module Progstr
46
46
  def _get_attachment(attribute)
47
47
  if _attachments[attribute].nil?
48
48
  id = read_attribute(attribute)
49
+ uploader_class = self.class._uploaders[attribute].class
49
50
  if id.nil?
50
- _attachments[attribute] = Attachment.empty
51
+ _attachments[attribute] = Attachment.empty(uploader_class)
51
52
  else
52
- _attachments[attribute] = Attachment.from_id(attribute, id)
53
+ _attachments[attribute] = Attachment.from_id(uploader_class, attribute, id)
53
54
  end
54
55
  else
55
56
  _attachments[attribute]
56
57
  end
57
58
  end
58
59
 
59
- def _set_attachment(attribute, file)
60
+ def _set_attachment(attribute, value)
60
61
  old_attachment = _get_attachment(attribute)
61
62
  unless old_attachment.blank?
62
63
  _attachments_to_delete << old_attachment
63
64
  end
64
65
 
65
- unless file.nil?
66
- attachment = Attachment.from_file(attribute, file)
66
+ uploader_class = self.class._uploaders[attribute].class
67
+ if value.kind_of?(String)
68
+ attachment = nil
69
+ if value.include?("{")
70
+ attachment = Attachment.from_json(uploader_class, attribute, value)
71
+ else
72
+ attachment = Attachment.from_id(uploader_class, attribute, value)
73
+ end
74
+ _attachments[attribute] = attachment
75
+ write_attribute(attribute, attachment.id)
76
+ elsif !value.nil? #file-like
77
+ attachment = Attachment.from_file(uploader_class, attribute, value)
67
78
  _attachments[attribute] = attachment
68
79
  write_attribute(attribute, attachment.id)
69
80
  else
@@ -81,7 +92,7 @@ module Progstr
81
92
 
82
93
  def _upload_attachment(attribute)
83
94
  attachment = _get_attachment(attribute)
84
- if (!attachment.blank?) && (!attachment.file.nil?)
95
+ if attachment.need_upload?
85
96
  uploader = self.class._uploaders[attribute]
86
97
  uploader.upload_attachment(attachment) unless uploader.nil?
87
98
  end
@@ -1,7 +1,25 @@
1
1
  module Progstr
2
2
  module Filer
3
+ class FileLike
4
+ def initialize(json)
5
+ @values = MultiJson.decode(json)
6
+ end
7
+
8
+ def id
9
+ @values["id"]
10
+ end
11
+
12
+ def path
13
+ @values["name"]
14
+ end
15
+
16
+ def size
17
+ @values["size"]
18
+ end
19
+ end
20
+
3
21
  class Attachment
4
- attr_accessor :id, :attribute, :file, :pre_validated
22
+ attr_accessor :id, :uploader_class, :attribute, :file, :pre_validated
5
23
 
6
24
  @@id_generator = ::UUID.new
7
25
 
@@ -9,34 +27,58 @@ module Progstr
9
27
  def blank?
10
28
  true
11
29
  end
12
-
13
30
  def size
14
31
  0
15
32
  end
16
-
17
33
  def path
18
34
  ""
19
35
  end
20
-
21
36
  def extension
22
37
  ""
23
38
  end
39
+ def display_hash
40
+ nil
41
+ end
42
+ def display_json
43
+ nil
44
+ end
45
+ def need_upload?
46
+ false
47
+ end
24
48
  end
25
49
 
26
- def self.empty
27
- EmptyAttachment.new
50
+ def self.empty(uploader_class)
51
+ result = EmptyAttachment.new
52
+ result.uploader_class = uploader_class
53
+ result
28
54
  end
29
55
 
30
- def self.from_file(attribute, file)
56
+ def self.from_json(uploader_class, attribute, json)
57
+ file = FileLike.new(json)
58
+ result = from_file(uploader_class, attribute, file)
59
+ result.pre_validated = true
60
+ return result
61
+ end
62
+
63
+ def self.from_file(uploader_class, attribute, file)
31
64
  result = Attachment.new
32
- result.id = generate_id
65
+ result.id = file_id(file)
33
66
  result.attribute = attribute
67
+ result.uploader_class = uploader_class
34
68
 
35
69
  result.file = file
36
70
  result.pre_validated = false
37
71
  result
38
72
  end
39
73
 
74
+ def self.file_id(file)
75
+ if file.respond_to?(:id)
76
+ file.id
77
+ else
78
+ generate_id
79
+ end
80
+ end
81
+
40
82
  def self.generate_id
41
83
  uuid = @@id_generator.generate
42
84
  uuid.gsub("-", "")
@@ -56,10 +98,11 @@ module Progstr
56
98
  from_file.sub(".", "")
57
99
  end
58
100
 
59
- def self.from_id(attribute, id)
101
+ def self.from_id(uploader_class, attribute, id)
60
102
  result = Attachment.new
61
103
  result.id = id
62
104
  result.attribute = attribute
105
+ result.uploader_class = uploader_class
63
106
 
64
107
  result.pre_validated = true
65
108
  result
@@ -71,7 +114,7 @@ module Progstr
71
114
 
72
115
  def url
73
116
  if !blank?
74
- token = Progstr::Filer.generate_file_auth_token(id)
117
+ token = Progstr::Filer.generate_download_auth_token(id)
75
118
  "#{Progstr::Filer.url_prefix}files/data/#{Progstr::Filer.access_key}/#{id}?auth=#{token}"
76
119
  else
77
120
  ""
@@ -85,6 +128,28 @@ module Progstr
85
128
  ""
86
129
  end
87
130
  end
131
+
132
+ def display_json
133
+ MultiJson.encode(display_hash)
134
+ end
135
+
136
+ def display_hash
137
+ {
138
+ "name" => path,
139
+ "size" => size,
140
+ "id" => id
141
+ }
142
+ end
143
+
144
+ def need_upload?
145
+ if file.nil?
146
+ false
147
+ elsif file.kind_of?(FileLike)
148
+ false
149
+ else
150
+ true
151
+ end
152
+ end
88
153
  end
89
154
  end
90
155
  end
data/lib/filer/config.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  module Progstr
3
3
  module Filer
4
4
  class << self
5
- attr_accessor :host, :port, :path_prefix, :session_timeout
5
+ attr_accessor :host, :port, :path_prefix, :session_timeout, :asset_url_prefix, :upload_url, :use_ssl
6
6
  attr_writer :access_key, :secret_key
7
7
 
8
8
  def access_key
@@ -16,6 +16,21 @@ module Progstr
16
16
  def host
17
17
  @host ||= "filer-api.progstr.com"
18
18
  end
19
+
20
+ def default_asset_url_prefix
21
+ insecure_prefix = "http://cdn.progstr.com/upload/"
22
+ secure_prefix = "https://s3.amazonaws.com/cdn.progstr.com/upload/"
23
+ javascript_version = "1.0"
24
+
25
+ prefix = insecure_prefix
26
+ prefix = secure_prefix if use_ssl
27
+ prefix + javascript_version
28
+ end
29
+
30
+ def default_upload_url
31
+ "http://#{Progstr::Filer.host}/upload/new"
32
+ end
33
+
19
34
  def port
20
35
  @port || 80
21
36
  end
@@ -23,7 +38,7 @@ module Progstr
23
38
  @path_prefix ||= '/'
24
39
  end
25
40
  def session_timeout
26
- @http_read_timeout ||= 30 * 60 # 30 minutes
41
+ @session_timeout ||= 30 * 60 # 30 minutes
27
42
  end
28
43
 
29
44
  def generate_auth_token
@@ -33,13 +48,20 @@ module Progstr
33
48
  "#{access_key}-#{expiration}-#{signature}"
34
49
  end
35
50
 
36
- def generate_file_auth_token(file_id)
51
+ def generate_download_auth_token(file_id)
37
52
  expiration = expiration_time
38
53
  to_sign = "#{access_key}-#{file_id}-#{expiration}-#{secret_key}"
39
54
  signature = Digest::SHA1.hexdigest(to_sign)
40
55
  "#{access_key}-#{expiration}-#{signature}"
41
56
  end
42
57
 
58
+ def generate_upload_auth_token(uploader)
59
+ expiration = expiration_time
60
+ to_sign = "#{access_key}-#{uploader}-#{expiration}-#{secret_key}"
61
+ signature = Digest::SHA1.hexdigest(to_sign)
62
+ "#{access_key}-#{expiration}-#{signature}"
63
+ end
64
+
43
65
  def url_prefix
44
66
  prefix = "http://#{Progstr::Filer.host}:#{Progstr::Filer.port}#{Progstr::Filer.path_prefix}"
45
67
  if prefix.end_with? "/"
@@ -12,9 +12,6 @@ class FileInfo
12
12
  def content_type
13
13
  @values["contentType"]
14
14
  end
15
- def property
16
- @values["property"]
17
- end
18
15
  def uploader
19
16
  @values["uploader"]
20
17
  end
@@ -30,7 +30,6 @@ module Progstr
30
30
  response = RestClient.post(url, {
31
31
  :upload1 => attachment.file,
32
32
  :authToken => Progstr::Filer.generate_auth_token,
33
- :property => attachment.attribute,
34
33
  :uploader => self.class.name,
35
34
  :id => attachment.id
36
35
  }, json_headers)
@@ -0,0 +1,23 @@
1
+ module Progstr
2
+ module Filer
3
+ module FormHtml
4
+
5
+ def filer_upload_field(method, options = {})
6
+ unless options.key? :file_input_name
7
+ sanitized_method_name = method.to_s.sub(/\?$/,"")
8
+ input_name = "#{@object_name}[#{sanitized_method_name}]"
9
+ options[:file_input_name] = input_name
10
+ end
11
+ attachment = @object.send(method)
12
+
13
+ @template.filer_upload(attachment, options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ require "action_view"
20
+ form_builder = ActionView::Base.default_form_builder
21
+ form_builder.class_eval do
22
+ include Progstr::Filer::FormHtml
23
+ end
@@ -0,0 +1,69 @@
1
+ module Progstr
2
+ module Filer
3
+ module Html
4
+ def filer_upload(attachment, options = {})
5
+ client_id = generate_container_id
6
+ register_scripts
7
+
8
+ client_options = prepare_client_options(attachment, options)
9
+ client_options_json = MultiJson.encode(client_options)
10
+
11
+ init_script = <<EOJSON
12
+ $(function(){
13
+ $('\##{client_id}').filerUpload(#{client_options_json})
14
+ })
15
+ EOJSON
16
+
17
+ tag("div", "id" => client_id) +
18
+ javascript_tag(init_script)
19
+ end
20
+
21
+
22
+ def filer_scripts
23
+ prefix = Progstr::Filer.asset_url_prefix || Progstr::Filer.default_asset_url_prefix
24
+
25
+ scripts = [
26
+ "/upload.js",
27
+ "/pl/flash.support.js",
28
+ ]
29
+ tags = scripts.map do |script|
30
+ javascript_include_tag (prefix + script)
31
+ end
32
+ tags.join("\r\n").html_safe
33
+ end
34
+
35
+ private
36
+ def generate_container_id
37
+ request.env["PROGSTR_FILER_UPLOAD_INSTANCES"] ||= 1
38
+ instances = request.env["PROGSTR_FILER_UPLOAD_INSTANCES"]
39
+ request.env["PROGSTR_FILER_UPLOAD_INSTANCES"] += 1
40
+ "filer_upload_container_#{instances}"
41
+ end
42
+
43
+ def prepare_client_options(attachment, options)
44
+ client_options = {}
45
+ options.each do |k, v|
46
+ client_options[k.to_s.camelize(:lower)] = v
47
+ end
48
+ uploader_name = attachment.uploader_class.name
49
+ client_options["uploader"] = uploader_name
50
+ client_options["initialFiles"] = [attachment.display_hash] unless attachment.blank?
51
+ client_options["authToken"] = Progstr::Filer.generate_upload_auth_token(uploader_name)
52
+ client_options["uploadUrl"] = Progstr::Filer.upload_url unless Progstr::Filer.upload_url.nil?
53
+
54
+ client_options
55
+ end
56
+
57
+ def register_scripts
58
+ unless request.env.key? "PROGSTR_FILER_SCRIPTS_INCLUDED"
59
+ request.env["PROGSTR_FILER_SCRIPTS_INCLUDED"] = true
60
+
61
+ content_for :filer_scripts, filer_scripts
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ require "action_controller"
69
+ ActionController::Base.helper(Progstr::Filer::Html)
data/lib/progstr-filer.rb CHANGED
@@ -10,6 +10,8 @@ require 'filer/attachment'
10
10
  require 'filer/file_info'
11
11
  require 'filer/validation'
12
12
  require 'filer/activerecord'
13
+ require 'filer/views/html'
14
+ require 'filer/views/form_html'
13
15
 
14
16
  class ApiError < StandardError
15
17
  attr_accessor :server_response
@@ -1,4 +1,4 @@
1
- class FileLike
1
+ class FileMock
2
2
  attr_accessor :size, :path
3
3
 
4
4
  def read
@@ -6,7 +6,7 @@ class FileLike
6
6
  end
7
7
  end
8
8
 
9
- class UploadedFileLike
9
+ class UploadedFileMock
10
10
  attr_accessor :size, :original_filename
11
11
 
12
12
  def read
@@ -2,10 +2,21 @@ require 'test_helper'
2
2
 
3
3
  class TestIdGeneration < Test::Unit::TestCase
4
4
  should "generate file URLs using accessKey and file ID" do
5
- a = Progstr::Filer::Attachment.from_id(:avatar, "some-attachment-id")
5
+ a = Progstr::Filer::Attachment.from_id(MockUploader, :avatar, "some-attachment-id")
6
6
 
7
7
  assert_match "/files/data/DEMO/some-attachment-id", a.url
8
8
  assert_match Progstr::Filer.host, a.url
9
9
  assert_match Progstr::Filer.host, a.url
10
10
  end
11
+
12
+ should "roundtrip from and to JSON" do
13
+ json = '{"id":"7933ad9a0f93457ab625a070fec3544f","name":"test.png","size":100}'
14
+ a = Progstr::Filer::Attachment.from_json(MockUploader, :avatar, json)
15
+
16
+ new_json = a.display_json
17
+
18
+ assert_match "7933ad9a0f93457ab625a070fec3544f", new_json
19
+ assert_match "test.png", new_json
20
+ assert_match "100", new_json
21
+ end
11
22
  end
@@ -8,20 +8,38 @@ class TestFileMount < UserTest
8
8
 
9
9
  should "create an uploader when given a file" do
10
10
  non_empty = User.new
11
- non_empty.avatar = FileLike.new
11
+ non_empty.avatar = FileMock.new
12
12
  assert_false non_empty.avatar.blank?
13
13
  end
14
14
 
15
- should "save persist attachment id only" do
15
+ should "create an uploader when given an id string" do
16
+ non_empty = User.new
17
+ non_empty.avatar = "some-string-id"
18
+ assert_false non_empty.avatar.blank?
19
+ assert_equal "some-string-id", non_empty.avatar.id
20
+ end
21
+
22
+ should "create an uploader when given file info JSON string" do
23
+ json = '{"id":"7933ad9a0f93457ab625a070fec3544f","name":"test.png","size":100}'
24
+
25
+ non_empty = User.new
26
+ non_empty.avatar = json
27
+ assert_false non_empty.avatar.blank?
28
+ assert_equal "7933ad9a0f93457ab625a070fec3544f", non_empty.avatar.id
29
+ assert_equal "test.png", non_empty.avatar.path
30
+ assert_equal 100, non_empty.avatar.size
31
+ end
32
+
33
+ should "persist attachment id only" do
16
34
  u = User.new
17
- u.avatar = FileLike.new
35
+ u.avatar = FileMock.new
18
36
  assert_not_nil u.avatar.id, "attachment id generated"
19
37
  assert_equal u.read_attribute(:avatar), u.avatar.id, "attachment id saved to db"
20
38
  end
21
39
 
22
40
  should "save and load attachment id to db" do
23
41
  u = User.new
24
- u.avatar = FileLike.new
42
+ u.avatar = FileMock.new
25
43
  u.save!
26
44
 
27
45
  loaded = User.find(u.id)
data/test/test_helper.rb CHANGED
@@ -5,7 +5,7 @@ require 'progstr-filer'
5
5
 
6
6
  require 'test/unit'
7
7
  require 'shoulda'
8
- require 'file_like'
8
+ require 'file_mock'
9
9
  require 'user_data'
10
10
  require 'pp'
11
11
 
@@ -6,12 +6,11 @@ end
6
6
  class TestHttpUpload < Test::Unit::TestCase
7
7
  # The mother of all tests calling the real API
8
8
  test "upload attachment" do
9
- attachment = Progstr::Filer::Attachment.from_file(:version, File.open("VERSION"))
9
+ attachment = Progstr::Filer::Attachment.from_file(MockUploader, :version, File.open("VERSION"))
10
10
  uploader = DemoUploader.new
11
11
  response = uploader.upload_attachment attachment
12
12
 
13
13
  assert_equal response.name, "VERSION"
14
- assert_equal response.success, true
15
14
  assert_equal response.message, "OK"
16
15
 
17
16
  info = uploader.file_info attachment
@@ -19,7 +18,6 @@ class TestHttpUpload < Test::Unit::TestCase
19
18
  assert_equal info.name, "VERSION"
20
19
  assert_equal info.id, attachment.id
21
20
  assert_equal info.content_type, "text/plain"
22
- assert_equal info.property, "version"
23
21
  assert_equal info.uploader, "DemoUploader"
24
22
  assert_true info.size > 0
25
23
 
@@ -31,7 +29,7 @@ class TestHttpUpload < Test::Unit::TestCase
31
29
  begin
32
30
  Progstr::Filer.secret_key = "BROKEN"
33
31
 
34
- attachment = Progstr::Filer::Attachment.from_file(:version, File.open("VERSION"))
32
+ attachment = Progstr::Filer::Attachment.from_file(MockUploader, :version, File.open("VERSION"))
35
33
  uploader = DemoUploader.new
36
34
  begin
37
35
  response = uploader.upload_attachment attachment
@@ -2,8 +2,8 @@ require 'test_helper'
2
2
 
3
3
  class TestIdGeneration < Test::Unit::TestCase
4
4
  should "use UUIDs for attachment IDs" do
5
- a = Progstr::Filer::Attachment.from_file(:avatar, FileLike.new)
6
- b = Progstr::Filer::Attachment.from_file(:avatar, FileLike.new)
5
+ a = Progstr::Filer::Attachment.from_file(MockUploader, :avatar, FileMock.new)
6
+ b = Progstr::Filer::Attachment.from_file(MockUploader, :avatar, FileMock.new)
7
7
 
8
8
  assert_not_nil a.id
9
9
  assert_not_nil b.id
@@ -11,7 +11,7 @@ class TestIdGeneration < Test::Unit::TestCase
11
11
  end
12
12
 
13
13
  should "have attachment IDs with no hyphens" do
14
- a = Progstr::Filer::Attachment.from_file(:avatar, FileLike.new)
14
+ a = Progstr::Filer::Attachment.from_file(MockUploader, :avatar, FileMock.new)
15
15
  assert_match /^[^-]+$/, a.id, "IDs should contain no hyphens"
16
16
  end
17
17
  end
@@ -3,20 +3,41 @@ require 'test_helper'
3
3
  class TestUploadOnSave < UserTest
4
4
  should "upload file on record save" do
5
5
  u = User.new
6
- f = FileLike.new
6
+ f = FileMock.new
7
7
  u.avatar = f
8
8
 
9
9
  u.save!
10
10
  assert_same $lastUploadedAtachment.file, f, "avatar file sent to uploader"
11
11
  end
12
12
 
13
+ should "not upload JSON-created attachments" do
14
+ $lastUploadedAtachment = nil
15
+
16
+ u = User.new
17
+ json = '{"id":"7933ad9a0f93457ab625a070fec3544f","name":"test.png","size":100}'
18
+ u.avatar = json
19
+
20
+ u.save!
21
+ assert_nil $lastUploadedAtachment
22
+ end
23
+
24
+ should "save id only when JSON-created" do
25
+ $lastUploadedAtachment = nil
26
+
27
+ u = User.new
28
+ json = '{"id":"7933ad9a0f93457ab625a070fec3544f","name":"test.png","size":100}'
29
+ u.avatar = json
30
+ saved_id = u.read_attribute(:avatar)
31
+ assert_equal "7933ad9a0f93457ab625a070fec3544f", saved_id
32
+ end
33
+
13
34
  should "delete the previous attachment on save" do
14
35
  u = User.new
15
- f1 = FileLike.new
36
+ f1 = FileMock.new
16
37
  u.avatar = f1
17
38
  u.save!
18
39
 
19
- f2 = FileLike.new
40
+ f2 = FileMock.new
20
41
  u.avatar = f2
21
42
 
22
43
  u.save!
@@ -25,7 +46,7 @@ class TestUploadOnSave < UserTest
25
46
 
26
47
  should "delete previous attachment and null attribute if set to nil" do
27
48
  u = User.new
28
- f1 = FileLike.new
49
+ f1 = FileMock.new
29
50
  u.avatar = f1
30
51
  u.save!
31
52
 
@@ -39,7 +60,7 @@ class TestUploadOnSave < UserTest
39
60
 
40
61
  should "delete attachments on record delete" do
41
62
  u = User.new
42
- f1 = FileLike.new
63
+ f1 = FileMock.new
43
64
  u.avatar = f1
44
65
  u.save!
45
66
 
@@ -8,7 +8,7 @@ class TestValidation < UserTest
8
8
 
9
9
  test "don't store if size greater than 2MB" do
10
10
  u = ValidatedUser.new
11
- too_big = FileLike.new
11
+ too_big = FileMock.new
12
12
  too_big.path = "too_big.png"
13
13
  too_big.size = 5 * 1024 * 1024
14
14
  u.avatar = too_big
@@ -18,7 +18,7 @@ class TestValidation < UserTest
18
18
 
19
19
  test "don't store if extension not allowed" do
20
20
  u = ValidatedUser.new
21
- exe = FileLike.new
21
+ exe = FileMock.new
22
22
  exe.path = "virus_infected.exe"
23
23
  u.avatar = exe
24
24
 
@@ -28,7 +28,7 @@ class TestValidation < UserTest
28
28
 
29
29
  test "use original_filename on file objects if present" do
30
30
  u = ValidatedUser.new
31
- exe = UploadedFileLike.new
31
+ exe = UploadedFileMock.new
32
32
  exe.original_filename = "virus_infected.exe"
33
33
  u.avatar = exe
34
34
 
@@ -38,7 +38,7 @@ class TestValidation < UserTest
38
38
 
39
39
  test "don't store files without an extension" do
40
40
  u = ValidatedUser.new
41
- exe = FileLike.new
41
+ exe = FileMock.new
42
42
  exe.path = "noextension"
43
43
  u.avatar = exe
44
44
 
@@ -62,7 +62,7 @@ class TestValidation < UserTest
62
62
 
63
63
  test "validation passes" do
64
64
  u = ValidatedUser.new
65
- jpg = FileLike.new
65
+ jpg = FileMock.new
66
66
  jpg.path = "avatar.jpg"
67
67
  u.avatar = jpg
68
68
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: progstr-filer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-02 00:00:00.000000000Z
12
+ date: 2012-05-10 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &23855440 !ruby/object:Gem::Requirement
16
+ requirement: &24236220 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *23855440
24
+ version_requirements: *24236220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activemodel
27
- requirement: &23854620 !ruby/object:Gem::Requirement
27
+ requirement: &24235640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,21 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *23854620
35
+ version_requirements: *24235640
36
+ - !ruby/object:Gem::Dependency
37
+ name: actionpack
38
+ requirement: &24235040 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 3.0.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *24235040
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: uuid
38
- requirement: &23853940 !ruby/object:Gem::Requirement
49
+ requirement: &24234320 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '0'
44
55
  type: :runtime
45
56
  prerelease: false
46
- version_requirements: *23853940
57
+ version_requirements: *24234320
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: rest-client
49
- requirement: &23853000 !ruby/object:Gem::Requirement
60
+ requirement: &24233600 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: '0'
55
66
  type: :runtime
56
67
  prerelease: false
57
- version_requirements: *23853000
68
+ version_requirements: *24233600
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: multi_json
60
- requirement: &23852420 !ruby/object:Gem::Requirement
71
+ requirement: &24227220 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :runtime
67
78
  prerelease: false
68
- version_requirements: *23852420
79
+ version_requirements: *24227220
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: sqlite3
71
- requirement: &23851860 !ruby/object:Gem::Requirement
82
+ requirement: &24226500 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *23851860
90
+ version_requirements: *24226500
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: guard-test
82
- requirement: &23847260 !ruby/object:Gem::Requirement
93
+ requirement: &24225800 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *23847260
101
+ version_requirements: *24225800
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: rb-inotify
93
- requirement: &23846440 !ruby/object:Gem::Requirement
104
+ requirement: &24224980 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,10 +109,10 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *23846440
112
+ version_requirements: *24224980
102
113
  - !ruby/object:Gem::Dependency
103
114
  name: libnotify
104
- requirement: &23845420 !ruby/object:Gem::Requirement
115
+ requirement: &24224220 !ruby/object:Gem::Requirement
105
116
  none: false
106
117
  requirements:
107
118
  - - ! '>='
@@ -109,10 +120,10 @@ dependencies:
109
120
  version: '0'
110
121
  type: :development
111
122
  prerelease: false
112
- version_requirements: *23845420
123
+ version_requirements: *24224220
113
124
  - !ruby/object:Gem::Dependency
114
125
  name: shoulda
115
- requirement: &23844760 !ruby/object:Gem::Requirement
126
+ requirement: &24223540 !ruby/object:Gem::Requirement
116
127
  none: false
117
128
  requirements:
118
129
  - - ! '>='
@@ -120,21 +131,21 @@ dependencies:
120
131
  version: '0'
121
132
  type: :development
122
133
  prerelease: false
123
- version_requirements: *23844760
134
+ version_requirements: *24223540
124
135
  - !ruby/object:Gem::Dependency
125
136
  name: bundler
126
- requirement: &23844080 !ruby/object:Gem::Requirement
137
+ requirement: &24222840 !ruby/object:Gem::Requirement
127
138
  none: false
128
139
  requirements:
129
- - - ~>
140
+ - - ! '>='
130
141
  - !ruby/object:Gem::Version
131
142
  version: 1.0.0
132
143
  type: :development
133
144
  prerelease: false
134
- version_requirements: *23844080
145
+ version_requirements: *24222840
135
146
  - !ruby/object:Gem::Dependency
136
147
  name: jeweler
137
- requirement: &23843180 !ruby/object:Gem::Requirement
148
+ requirement: &24222200 !ruby/object:Gem::Requirement
138
149
  none: false
139
150
  requirements:
140
151
  - - ~>
@@ -142,21 +153,10 @@ dependencies:
142
153
  version: 1.6.4
143
154
  type: :development
144
155
  prerelease: false
145
- version_requirements: *23843180
146
- - !ruby/object:Gem::Dependency
147
- name: rcov
148
- requirement: &23842540 !ruby/object:Gem::Requirement
149
- none: false
150
- requirements:
151
- - - ! '>='
152
- - !ruby/object:Gem::Version
153
- version: '0'
154
- type: :development
155
- prerelease: false
156
- version_requirements: *23842540
156
+ version_requirements: *24222200
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: rdoc
159
- requirement: &23841900 !ruby/object:Gem::Requirement
159
+ requirement: &24221480 !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements:
162
162
  - - ! '>='
@@ -164,7 +164,7 @@ dependencies:
164
164
  version: '0'
165
165
  type: :development
166
166
  prerelease: false
167
- version_requirements: *23841900
167
+ version_requirements: *24221480
168
168
  description: Progstr Filer is a developer-friendly file and attachment hosting service
169
169
  that lets you easily build apps that store and share files.
170
170
  email: hristo@deshev.com
@@ -189,9 +189,11 @@ files:
189
189
  - lib/filer/file_info.rb
190
190
  - lib/filer/uploader.rb
191
191
  - lib/filer/validation.rb
192
+ - lib/filer/views/form_html.rb
193
+ - lib/filer/views/html.rb
192
194
  - lib/progstr-filer.rb
193
195
  - test/adium-green-duckling.png
194
- - test/file_like.rb
196
+ - test/file_mock.rb
195
197
  - test/test_attachment_url.rb
196
198
  - test/test_file_mount.rb
197
199
  - test/test_helper.rb
@@ -215,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
215
217
  version: '0'
216
218
  segments:
217
219
  - 0
218
- hash: 651641532922132160
220
+ hash: -4458103190430304874
219
221
  required_rubygems_version: !ruby/object:Gem::Requirement
220
222
  none: false
221
223
  requirements: