jackfs 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ v0.1.0. Released with tests passing.
2
+
3
+ v0.0.1. Initial release.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jackfs.gemspec
4
+ gemspec
data/Manifest ADDED
@@ -0,0 +1,16 @@
1
+ CHANGELOG
2
+ Manifest
3
+ README.md
4
+ Rakefile
5
+ init.rb
6
+ lib/jackfs/file_store.rb
7
+ lib/jackfs/adapters/db_adapter.rb
8
+ lib/jackfs/adapters/s3_adapter.rb
9
+ lib/jackfs/adapters/file_adapter.rb
10
+ spec/adapters/db_adapter_spec.rb
11
+ spec/adapters/file_adapter_spec.rb
12
+ spec/adapters/s3_adapter_spec.rb
13
+
14
+ jackfs.gemspec
15
+ spec/jackfs.rb
16
+ spec/spec_helper.rb
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Jackfs
2
+
3
+ Is a rails 3 file store plugin, that allows you to create a simple file store system
4
+ that can point to disk, s3, or database based on your configuration file.
5
+
6
+ This allows you to implement the storage using a simple api. The plugin is
7
+ adapter driven, so you can create additional adapters to use for this Jackfs
8
+ system.
9
+
10
+ ## Install
11
+
12
+ rails plugin install git://github.com/jackhq/jackfs.git
13
+
14
+ ## Configure
15
+
16
+ * If File Adapter your config/filestore.yml would look like this
17
+
18
+ production:
19
+ location: tmp
20
+ adapter: file
21
+
22
+
23
+ * If Db Adapter your config/filestore.yml would look like this
24
+
25
+ production:
26
+ connection: sqlite://production.db
27
+ adapter: db
28
+ table_name: jackfs
29
+
30
+ ** It is important to note that it uses the sequel toolkit to connect to the database. The connection setting must be a valid sequel toolkit connection string.
31
+
32
+ * If S3 Adapter your config/filestore.yml would look like this
33
+
34
+ production:
35
+ adapter: s3
36
+ bucket: jackhq
37
+ access_key: ACCESS KEY
38
+ secret_key: SECRET KEY
39
+
40
+ ---
41
+
42
+ # Report any problems to team@jackrussellsoftware.com
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'jackfs'
2
+
data/jackfs.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "jackfs/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jackfs"
7
+ s.version = Jackfs::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jack Russell Software"]
10
+ s.email = ["team@jackrussellsoftware.com"]
11
+ s.homepage = ""
12
+ s.summary = 'This is a fs gem we use'
13
+ s.description = 'This is an description for the fs gem we use'
14
+
15
+ s.rubyforge_project = "jackfs"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency 'sequel'
23
+ s.add_runtime_dependency 'aws-s3'
24
+ end
@@ -0,0 +1,72 @@
1
+ require 'base64'
2
+ require 'fileutils'
3
+
4
+ begin
5
+ require 'sequel'
6
+ rescue LoadError
7
+ puts 'sequel gem is required to use file store'
8
+ end
9
+
10
+
11
+ module Jackfs
12
+ class DbAdapter
13
+ TEMP_PATH = File.join('tmp','fs_cache')
14
+
15
+ attr_accessor :connection, :table_name, :dbase, :app_root, :app_env
16
+
17
+ def initialize(app_root, app_env)
18
+ @app_root = app_root
19
+ @app_env = app_env
20
+
21
+ FileUtils.mkdir_p temp_file_path
22
+
23
+ yml = YAML.load_file(config_file)[@app_env.to_s]
24
+ @connection = yml["connection"]
25
+ @table_name = yml["table_name"]
26
+
27
+ # Clean up temp files
28
+ FileUtils.remove_file(File.join(temp_file_path,'/*'), true)
29
+ end
30
+
31
+ def store(f, name)
32
+ body = Base64.encode64(f.read)
33
+ data << { :name => name, :body => body, :created_at => Time.now, :updated_at => Time.now }
34
+ end
35
+
36
+ def get(name)
37
+ record = data.where(:name => name).order(:name).first
38
+ unique_name = UUIDTools::UUID.random_create.to_s
39
+ # Write Body to generated tmp file
40
+ f = temp_file_path + unique_name
41
+ open(File.join(f), 'wb') { |file| file.write Base64.decode64(record[:body]) }
42
+ f
43
+ end
44
+
45
+ def data
46
+ db = Sequel.connect(@connection)
47
+ make_table(db) unless db.tables.include?(@table_name.to_sym)
48
+ db[@table_name.to_sym]
49
+ end
50
+
51
+ def make_table(db)
52
+ db.create_table @table_name do
53
+ primary_key :id
54
+ string :name
55
+ text :body
56
+ timestamp :created_at
57
+ timestamp :updated_at
58
+ end
59
+ rescue
60
+ # table exists
61
+ end
62
+
63
+ def temp_file_path
64
+ File.join(@app_root, TEMP_PATH)
65
+ end
66
+
67
+ def config_file
68
+ File.join(@app_root, Jackfs::FileStore::CONFIG_FILE)
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,25 @@
1
+ module Jackfs
2
+ class FileAdapter
3
+ attr_accessor :location, :app_root, :app_env
4
+
5
+ def initialize(app_root, app_env)
6
+ @app_root = app_root
7
+ @app_env = app_env
8
+ begin
9
+ @location = YAML.load_file(File.join(@app_root, Jackfs::FileStore::CONFIG_FILE))[@app_env.to_s]["location"]
10
+ rescue
11
+ raise InvalidFileStore
12
+ end
13
+ end
14
+
15
+ def store(this_file, name)
16
+ File.open(File.join(@app_root, @location, name), 'w') { |file| file.write this_file.read }
17
+ name
18
+ end
19
+
20
+ def get(name)
21
+ File.open(File.join(app_root, @location, name), 'r')
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,72 @@
1
+ require 'fileutils'
2
+
3
+ begin
4
+ require 'aws/s3'
5
+ rescue LoadError
6
+ puts 'aws-s3 gem is required to use file store'
7
+ end
8
+
9
+ module Jackfs
10
+ class S3Adapter
11
+
12
+ TEMP_PATH = File.join('tmp','fs_cache')
13
+
14
+ attr_accessor :access_key, :secret_key, :bucket, :app_root, :app_env
15
+
16
+ def initialize(app_root, app_env)
17
+ @app_root = app_root
18
+ @app_env = app_env
19
+
20
+ FileUtils.mkdir_p(full_temp_path)
21
+
22
+ yml = YAML.load_file(config_file)[@app_env.to_s]
23
+ @access_key = yml["access_key"]
24
+ @secret_key = yml["secret_key"]
25
+ @bucket = yml["bucket"]
26
+
27
+ # Clean up temp files
28
+ FileUtils.remove_file(File.join(full_temp_path,'/*'), true)
29
+
30
+ end
31
+
32
+ def store(f, name)
33
+ find_or_create_bucket
34
+ AWS::S3::S3Object.store(name, f, @bucket)
35
+ name
36
+ end
37
+
38
+ def get(name)
39
+ unique_name = UUIDTools::UUID.random_create.to_s
40
+ # Write Body to generated tmp file
41
+ open(File.join(full_temp_path, unique_name), 'wb') do |file|
42
+ AWS::S3::S3Object.stream(name, @bucket) do |chunk|
43
+ file.write chunk
44
+ end
45
+ end
46
+ # Open and return Temp File
47
+ open(File.join(full_temp_path,unique_name), 'rb')
48
+ end
49
+
50
+ def establish_connection
51
+ AWS::S3::Base.establish_connection!(
52
+ :access_key_id => @access_key,
53
+ :secret_access_key => @secret_key
54
+ )
55
+ end
56
+
57
+ def find_or_create_bucket
58
+ establish_connection
59
+ AWS::S3::Bucket.create(@bucket) unless bucket = AWS::S3::Bucket.find(@bucket)
60
+ true
61
+ end
62
+
63
+ def full_temp_path
64
+ File.join(@app_root, TEMP_PATH)
65
+ end
66
+
67
+ def config_file
68
+ File.join(@app_root, Jackfs::FileStore::CONFIG_FILE)
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ module Jackfs
2
+ class InvalidFileStore < RuntimeError; end
3
+ end
@@ -0,0 +1,49 @@
1
+ begin
2
+ require 'uuidtools'
3
+ rescue LoadError
4
+ puts 'gem uuidtools is required'
5
+ end
6
+
7
+ require File.dirname(__FILE__) + '/adapters/file_adapter'
8
+ require File.dirname(__FILE__) + '/adapters/s3_adapter'
9
+ require File.dirname(__FILE__) + '/adapters/db_adapter'
10
+
11
+ module Jackfs
12
+ class FileStore
13
+ CONFIG_FILE = File.join('config','filestore.yml')
14
+
15
+ attr_accessor :file, :guid, :adapter, :app_root, :app_env
16
+
17
+ def initialize(app_root, app_env)
18
+ @app_root = app_root
19
+ @app_env = app_env
20
+ @adapter = load_adapter
21
+ end
22
+
23
+ def store(this_file)
24
+ @file = this_file
25
+ @guid = create_guid
26
+ # call adapter passing the file and guid as file identifier
27
+ @adapter.store(this_file, @guid)
28
+ end
29
+
30
+ def get(guid)
31
+ # Need call adapter passing the guid and returning the file
32
+ @adapter.get(guid)
33
+ end
34
+
35
+ def create_guid
36
+ UUIDTools::UUID.random_create.to_s
37
+ end
38
+
39
+ def load_adapter
40
+ adapter_type = YAML.load_file(File.join(@app_root,CONFIG_FILE))[@app_env.to_s]["adapter"].to_sym
41
+ case adapter_type
42
+ when :s3 then Jackfs::S3Adapter.new(@app_root, @app_env)
43
+ when :db then Jackfs::DbAdapter.new(@app_root, @app_env)
44
+ else Jackfs::FileAdapter.new(@app_root, @app_env)
45
+ end
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,3 @@
1
+ module Jackfs
2
+ VERSION = "0.0.1"
3
+ end
data/lib/jackfs.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/jackfs/file_store'
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+
4
+ describe "Jackfs Db Adapter" do
5
+ before(:each) do
6
+ File.delete("test.db") if File.exists?("test.db")
7
+ YAML.should_receive(:load_file).and_return("test" => {
8
+ "adapter" => "db",
9
+ "connection" => 'sqlite://test.db',
10
+ "table_name" => 'jackfs'
11
+ })
12
+
13
+ root = File.dirname(__FILE__) + '/..'
14
+ @dba = Jackfs::DbAdapter.new(root, :test)
15
+ end
16
+
17
+
18
+ it "should save a file to a configured database name" do
19
+ @dba.connection.should == 'sqlite://test.db'
20
+ end
21
+
22
+
23
+ it "should save a file to a configured table name" do
24
+ @dba.table_name.should == 'jackfs'
25
+ end
26
+
27
+ it "should save the file in db using the given name" do
28
+ @dba.store(File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r'),"COOLBEANS").should == true
29
+ end
30
+
31
+ # it "should get a file from a configured from db" do
32
+ # f = File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r')
33
+ # @dba.store(f, "COOLBEANS")
34
+ # orig = File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r')
35
+ #
36
+ # @dba.get("COOLBEANS").read.length.should == orig.read.length
37
+ # end
38
+
39
+
40
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+
4
+ describe "Jackfs File Adapter" do
5
+ before(:each) do
6
+ YAML.should_receive(:load_file).and_return("test" => {
7
+ "adapter" => "file",
8
+ "location" => 'tmp'
9
+ })
10
+ root = File.dirname(__FILE__) + '/..'
11
+
12
+ @fa = Jackfs::FileAdapter.new(root, :test)
13
+ end
14
+
15
+ it "should save a file to a configured location" do
16
+ Jackfs::FileAdapter.should be_true
17
+ @fa.location.should == "tmp"
18
+ end
19
+
20
+ it "should save the file in the location using the given name" do
21
+ @fa.store(File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r'),"COOLBEANS").should == true
22
+ end
23
+
24
+ it "should get a file from a configured location" do
25
+ f = File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r')
26
+ @fa.store(File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r'),"COOLBEANS").should == true
27
+ orig = File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r')
28
+ @fa.get("COOLBEANS").read.length.should == orig.read.length
29
+ end
30
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+
5
+ describe "JackFS S3 Adapter" do
6
+ before(:each) do
7
+ root = File.dirname(__FILE__) + '/..'
8
+ YAML.should_receive(:load_file).and_return("test" => {
9
+ "adapter" => "s3",
10
+ "bucket" => 'jackhq',
11
+ "access_key" => ENV['AMAZON_ACCESS_KEY_ID'],
12
+ "secret_key" => ENV['AMAZON_SECRET_ACCESS_KEY']
13
+ })
14
+
15
+ @s3a = Jackfs::S3Adapter.new(root, :test)
16
+
17
+ end
18
+
19
+ it "should save a file to a configured access key" do
20
+ @s3a.access_key.should == ENV['AMAZON_ACCESS_KEY_ID']
21
+ end
22
+
23
+ it "should save a file to a configured secret key" do
24
+ @s3a.secret_key.should == ENV['AMAZON_SECRET_ACCESS_KEY']
25
+ end
26
+
27
+ it "should save a file to a configured secret key" do
28
+ @s3a.bucket.should == "jackhq"
29
+ end
30
+
31
+ it "should establish a connection to s3" do
32
+ AWS::S3::Base.stub!(:establish_connection!).and_return(true)
33
+ @s3a.establish_connection.should == true
34
+ end
35
+
36
+ it "should create a bucket if a bucket does not exist" do
37
+ AWS::S3::Bucket.should_receive(:find).and_return(false)
38
+ AWS::S3::Bucket.should_receive(:create).and_return(true)
39
+ @s3a.find_or_create_bucket.should be_true
40
+
41
+ end
42
+
43
+ it "should find a bucket if a bucket does exist" do
44
+ AWS::S3::Bucket.should_receive(:find).and_return(true)
45
+ @s3a.find_or_create_bucket.should be_true
46
+ end
47
+
48
+ it "should save the file in s3 using the given name" do
49
+ @s3a.should_receive(:find_or_create_bucket).and_return(true)
50
+ AWS::S3::S3Object.should_receive(:store).and_return(true)
51
+ @s3a.store(File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r'),"COOLBEANS").should == true
52
+ end
53
+
54
+ it "should get a file from a configured from s3" do
55
+ f = File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r')
56
+ #AWS::S3::S3Object.should_receive(:stream).and_return(f)
57
+ @s3a.store(File.open(File.dirname(__FILE__) + '/../fixtures/test.pdf', 'r'),"COOLBEANS").should == true
58
+ @s3a.get("COOLBEANS").read.length.should == f.read.length
59
+ end
60
+
61
+ end
Binary file
@@ -0,0 +1,43 @@
1
+ require 'rspec'
2
+ require 'fileutils'
3
+ require 'yaml'
4
+
5
+
6
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
7
+
8
+ require File.join(File.dirname(__FILE__), '..', 'init')
9
+
10
+
11
+ #TEST_DATABASE_FILE = File.join(File.dirname(__FILE__), 'test.sqlite3')
12
+
13
+ # Spec::Runner.configure do |config|
14
+ #
15
+ # end
16
+
17
+ # def setup_database
18
+ # File.unlink(TEST_DATABASE_FILE) if File.exist?(TEST_DATABASE_FILE)
19
+ # ActiveRecord::Base.establish_connection(
20
+ # "adapter" => "sqlite3", "timeout" => 5000, "database" => TEST_DATABASE_FILE
21
+ # )
22
+ # create_tables
23
+ # end
24
+ #
25
+ # def create_tables
26
+ # c = ActiveRecord::Base.connection
27
+ #
28
+ # c.create_table :sponsors, :force => true do |t|
29
+ # t.string :name
30
+ # t.string :address
31
+ # t.string :city
32
+ # t.string :state
33
+ # t.string :zip
34
+ # t.string :phone
35
+ # t.string :fax
36
+ #
37
+ # t.timestamps
38
+ # end
39
+ # end
40
+ #
41
+ # setup_database
42
+ #
43
+ # require File.join(File.dirname(__FILE__), 'models')
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jackfs
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jack Russell Software
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-16 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sequel
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: aws-s3
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ description: This is an description for the fs gem we use
49
+ email:
50
+ - team@jackrussellsoftware.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - CHANGELOG
60
+ - Gemfile
61
+ - Manifest
62
+ - README.md
63
+ - Rakefile
64
+ - init.rb
65
+ - jackfs.gemspec
66
+ - lib/jackfs.rb
67
+ - lib/jackfs/adapters/db_adapter.rb
68
+ - lib/jackfs/adapters/file_adapter.rb
69
+ - lib/jackfs/adapters/s3_adapter.rb
70
+ - lib/jackfs/errors.rb
71
+ - lib/jackfs/file_store.rb
72
+ - lib/jackfs/version.rb
73
+ - spec/adapters/db_adapter_spec.rb
74
+ - spec/adapters/file_adapter_spec.rb
75
+ - spec/adapters/s3_adapter_spec.rb
76
+ - spec/fixtures/test.pdf
77
+ - spec/spec_helper.rb
78
+ homepage: ""
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project: jackfs
107
+ rubygems_version: 1.8.10
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: This is a fs gem we use
111
+ test_files:
112
+ - spec/adapters/db_adapter_spec.rb
113
+ - spec/adapters/file_adapter_spec.rb
114
+ - spec/adapters/s3_adapter_spec.rb
115
+ - spec/fixtures/test.pdf
116
+ - spec/spec_helper.rb