acts_as_file 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5a692309dc92a0a6668370bdf0d1a750c41372dd
4
+ data.tar.gz: 7a8957cf252f0d825fad043b8a2235f9561ef97f
5
+ SHA512:
6
+ metadata.gz: 6ddfc4ad98004d6ab638aa198abaca8d0b7aec385d4cd6f0a7af4148921b0dd22a9065cdb6b38e00ffd71566134463b7082cf18d4a97e285b89641ce007702be
7
+ data.tar.gz: dd63c176af3007665c0dec56812d108749ce3ab2bd042303c8786c47d6c79ab5999b75e99ab2d1fdf4763f749892dda7e3d546a5c6921951ad1214847bbca30b
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ Gemfile.lock
2
+ .bundle
3
+ .yardoc
4
+ *.rbc
5
+ .rbx/
6
+ doc/
7
+ .DS_Store
8
+ tags
9
+ pkg/*
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.0
5
+ - rbx
6
+ - jruby-19mode
7
+ gemfile:
8
+ - Gemfile
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+ gem 'coveralls', :require => false
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Naotoshi Seo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # Acts as file
2
+
3
+ `acts_as_file` makes your field act as a file.
4
+ The content of the field is stored into a file on calling `#save` method,
5
+ and is loaded from the file on calling its accessor method.
6
+
7
+ [![Build Status](https://travis-ci.org/sonots/acts_as_file.svg)](https://travis-ci.org/sonots/acts_as_file)
8
+ [![Coverage Status](https://coveralls.io/repos/sonots/acts_as_file/badge.png)](https://coveralls.io/r/sonots/acts_as_file)
9
+
10
+ ## Installation
11
+
12
+ Add the following to your `Gemfile`:
13
+
14
+ ```ruby
15
+ gem 'acts_as_file'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ ```plain
21
+ $ bundle
22
+ ```
23
+
24
+ ## Examples
25
+
26
+ ActiveRecord is not required, but let me write an example for it.
27
+
28
+ ```ruby
29
+ class Post < ActiveRecord::Base
30
+ include ActsAsFile
31
+ def filename
32
+ "posts/#{self.id}_body.txt"
33
+ end
34
+ acts_as_file :body => self.instance_method(:filename)
35
+ end
36
+
37
+ post = Post.new
38
+ post.body = 'content'
39
+ post.save # save the content into the file of `#filename`
40
+ loaded = Post.find(post.id)
41
+ puts loaded.body # load the content from the file of `#filename`
42
+ loaded.destroy # remove the file
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
52
+
53
+ ## Copyright
54
+
55
+ * Copyright (c) 2014 Naotoshi Seo. See [LICENSE](LICENSE) for details.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec) do |t|
6
+ t.rspec_opts = ["-c", "-f progress"] # '--format specdoc'
7
+ t.pattern = 'spec/**/*_spec.rb'
8
+ end
9
+ task :test => :spec
10
+ task :default => :spec
11
+
12
+ desc 'Open an irb session preloaded with the gem library'
13
+ task :console do
14
+ sh 'irb -rubygems -I lib -r acts_as_file'
15
+ end
16
+ task :c => :console
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env gem build
2
+ # encoding: utf-8
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "acts_as_file"
6
+ s.authors = ["Naotoshi Seo"]
7
+ s.email = ["sonots@gmail.com"]
8
+ s.homepage = "https://github.com/sonots/acts_as_file"
9
+ s.summary = "Make your field act as a file"
10
+ s.description = "Make your field act as a file. Save the content to a file, and load the content from a file."
11
+ s.version = '0.0.1'
12
+ s.date = Time.now.strftime("%Y-%m-%d")
13
+
14
+ s.extra_rdoc_files = Dir["*.rdoc"]
15
+ s.files = `git ls-files`.split($\)
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+ s.rdoc_options = ["--charset=UTF-8"]
20
+
21
+ s.add_development_dependency 'rspec'
22
+ s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'pry'
24
+ s.add_development_dependency 'pry-nav'
25
+ end
@@ -0,0 +1,74 @@
1
+ module ActsAsFile
2
+ def self.included(klass)
3
+ klass.extend(ClassMethods)
4
+ end
5
+
6
+ # ToDo: rename if filename is changed
7
+ module ClassMethods
8
+ # acts_as_file :field => self.instance_method(:filename)
9
+ def acts_as_file(params = {})
10
+ self.class_eval do
11
+ unless method_defined?(:save_with_file)
12
+ define_method(:save_with_file) do |*args|
13
+ params.each do |field, filename_instance_method|
14
+ field_name = :"@#{field}"
15
+ filename = filename_instance_method.bind(self).call
16
+ content = self.instance_variable_get(field_name)
17
+ File.open(filename, 'w') do |f|
18
+ f.flock(File::LOCK_EX) # inter-process locking
19
+ f.sync = true
20
+ f.write(content)
21
+ f.flush
22
+ end if filename and content
23
+ end
24
+ save_without_file(*args)
25
+ end
26
+ alias_method :save_without_file, :save
27
+ alias_method :save, :save_with_file
28
+
29
+ params.each do |field, filename_instance_method|
30
+ field_name = :"@#{field}"
31
+ define_method("#{field}=") do |content|
32
+ self.instance_variable_set(field_name, content)
33
+ end
34
+ end
35
+
36
+ params.each do |field, filename_instance_method|
37
+ field_name = :"@#{field}"
38
+ define_method(field) do |offset = nil, length = nil|
39
+ if offset || length
40
+ # does not cache in this way
41
+ filename = filename_instance_method.bind(self).call
42
+ return nil unless filename
43
+ return nil unless File.exist?(filename)
44
+ File.open(filename) do |file|
45
+ file.seek(offset) if offset
46
+ file.read(length)
47
+ end
48
+ else
49
+ content = self.instance_variable_get(field_name)
50
+ return content if content
51
+ # if (self.updated_at.nil? or File.mtime(filename) > self.updated_at)
52
+ filename = filename_instance_method.bind(self).call
53
+ return nil unless filename
54
+ return nil unless File.exist?(filename)
55
+ self.instance_variable_set(field_name, File.read(filename))
56
+ end
57
+ end
58
+ end
59
+
60
+ define_method(:destroy_with_file) do
61
+ params.each do |field, filename_instance_method|
62
+ field_name = :"@#{field}"
63
+ filename = filename_instance_method.bind(self).call
64
+ File.unlink(filename) if File.exist?(filename)
65
+ end
66
+ destroy_without_file
67
+ end
68
+ alias_method :destroy_without_file, :destroy
69
+ alias_method :destroy, :destroy_with_file
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,82 @@
1
+ require_relative 'spec_helper'
2
+ require 'acts_as_file'
3
+
4
+ class Post
5
+ def initialize(params)
6
+ @name = params[:name]
7
+ end
8
+ attr_accessor :name
9
+ def save; end
10
+ def destroy; end
11
+ def self.delete_all; end
12
+ end
13
+
14
+ class TestPost < Post
15
+ include ActsAsFile
16
+ def filename
17
+ @filename ||= Tempfile.open(self.name) {|f| f.path }.tap {|name| File.unlink(name) }
18
+ end
19
+ acts_as_file :body => self.instance_method(:filename)
20
+ end
21
+
22
+ describe ActsAsFile do
23
+ let(:subject) { TestPost.new(name: 'name') }
24
+ after { TestPost.delete_all }
25
+ after { File.unlink(subject.filename) if File.exist?(subject.filename) }
26
+
27
+ context '#body=' do
28
+ it { expect { subject.body = 'aaaa' }.not_to raise_error }
29
+ end
30
+
31
+ context '#body' do
32
+ context 'get from instance variable' do
33
+ before { subject.body = 'aaaa' }
34
+ its(:body) { should == 'aaaa' }
35
+ end
36
+
37
+ context 'get from file' do
38
+ before { subject.body = nil }
39
+ before { File.write(subject.filename, 'aaaa') }
40
+ its(:body) { should == 'aaaa' }
41
+ end
42
+
43
+ context 'seek' do
44
+ before { File.write(subject.filename, 'abcd') }
45
+ it { subject.body(1, 2).should == 'bc' }
46
+ end
47
+
48
+ context 'file does not exit' do
49
+ before { File.unlink(subject.filename) if File.exist?(subject.filename) }
50
+ it { subject.body.should be_nil }
51
+ it { subject.body(1, 2).should be_nil }
52
+ end
53
+ end
54
+
55
+ context '#save_with_file' do
56
+ context 'save if body exists' do
57
+ before { subject.body = 'aaaa' }
58
+ before { subject.save }
59
+ it { expect(File.read(subject.filename)).to eql('aaaa') }
60
+ end
61
+
62
+ context 'does not save if body does not exist' do
63
+ before { subject.body = nil }
64
+ before { subject.save }
65
+ it { expect(File.exist?(subject.filename)).to be_false }
66
+ end
67
+ end
68
+
69
+ context '#destroy_with_file' do
70
+ context 'delete if file exists' do
71
+ before { subject.save }
72
+ before { subject.destroy }
73
+ it { expect(File.exist?(subject.filename)).to be_false }
74
+ end
75
+
76
+ context 'fine even if file does not exist' do
77
+ before { subject.destroy }
78
+ it { expect(File.exist?(subject.filename)).to be_false }
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'pry'
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
5
+
6
+ if ENV['TRAVIS']
7
+ require 'coveralls'
8
+ Coveralls.wear!
9
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acts_as_file
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Naotoshi Seo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-nav
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Make your field act as a file. Save the content to a file, and load the
70
+ content from a file.
71
+ email:
72
+ - sonots@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - LICENSE
81
+ - README.md
82
+ - Rakefile
83
+ - acts_as_file.gemspec
84
+ - lib/acts_as_file.rb
85
+ - spec/acts_as_file_spec.rb
86
+ - spec/spec_helper.rb
87
+ homepage: https://github.com/sonots/acts_as_file
88
+ licenses: []
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options:
92
+ - "--charset=UTF-8"
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.2.2
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Make your field act as a file
111
+ test_files:
112
+ - spec/acts_as_file_spec.rb
113
+ - spec/spec_helper.rb