progstr-filer 0.8.7 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
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: