filestore 0.0.2

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/lib/action.rb ADDED
@@ -0,0 +1,56 @@
1
+ #
2
+ # action.rb
3
+ # @author Thomas Stätter
4
+ # @date 09.07.2012
5
+ # @description Library using a file system as storage for arbitrary files
6
+ #
7
+ $:.unshift('.')
8
+
9
+ require 'filestore.rb'
10
+
11
+ module FileStore
12
+
13
+ class Action
14
+ @@DATE_FORMAT = '%d.%m.%Y %H:%M:%S:%L'
15
+
16
+ @@STATUS_NOT_STARTED = "NOT STARTED"
17
+ @@STATUS_SUCCESS = "SUCCESS"
18
+ @@STATUS_FAILURE = "FAILURE"
19
+
20
+ @type = 'UNDEFINED'
21
+
22
+ def initialize(id)
23
+ raise FileStoreException, "No identifier given for action" if id.nil?
24
+ raise FileStoreException, "Identifier can only be of type String or Numeric" if (not id.is_a?(String) and not id.is_a?(Numeric))
25
+ raise FileStoreException, "Identifier can't be empty" if id.is_a?(String) and id == ''
26
+
27
+ @identifier = id
28
+ @status = @@STATUS_NOT_STARTED
29
+ end
30
+
31
+ def execute(&block)
32
+ @start = Date.today.strftime @@DATE_FORMAT
33
+
34
+ begin
35
+ block.call
36
+ @end = Date.today.strftime @@DATE_FORMAT
37
+ rescue Exception => e
38
+ @status = @@STATUS_FAILURE
39
+ raise FileStoreException, 'Caught exception while executing action', e.backtrace
40
+ else
41
+ @status = @@STATUS_SUCCESS
42
+ end
43
+ end
44
+
45
+ def to_s
46
+ "#{@status} - #{@start} - #{self.class.name} - #{@msg} - #{@end} - #{@identifier}"
47
+ end
48
+ end
49
+
50
+ class AddAction < Action
51
+ end
52
+
53
+ class DeleteAction < Action
54
+ end
55
+
56
+ end
data/lib/filestore.rb ADDED
@@ -0,0 +1,108 @@
1
+ #
2
+ # filestore.rb
3
+ # @author Thomas Stätter
4
+ # @date 09.07.2012
5
+ # @description Library using a file system as storage for arbitrary files
6
+ #
7
+
8
+ $:.unshift('.')
9
+
10
+ require 'uuidtools'
11
+ require 'fileutils'
12
+ require 'action.rb'
13
+ require 'log.rb'
14
+ require 'meta.rb'
15
+
16
+ module FileStore
17
+
18
+ class FileStoreException < Exception
19
+ end
20
+
21
+ class FileStore
22
+ @@STORE_ROOT = 'filestore'
23
+ @@DELETED_ROOT = 'deleted'
24
+
25
+ def initialize(basePath = ".", metaManager)
26
+ raise FileStoreException, "Invalid base path given" if (basePath.nil? or
27
+ not File.exists?(basePath) or
28
+ not File.directory?(basePath) or
29
+ not basePath.is_a?(String) or
30
+ basePath == '')
31
+
32
+ @storePath = File.join(basePath, @@STORE_ROOT)
33
+ @deletedPath = File.join(basePath, @@DELETED_ROOT)
34
+
35
+ begin
36
+ FileUtils.mkdir_p(@storePath) if not Dir.exists?(@storePath)
37
+ FileUtils.mkdir_p(@deletedPath) if not Dir.exists?(@deletedPath)
38
+ rescue StandardError => e
39
+ raise FileStoreException, "Couldn't create store directories", e.backtrace
40
+ end
41
+
42
+ # needs no specific exception handling dew to the fact, that the directories
43
+ # could be created
44
+ @logger = Log.new(basePath)
45
+
46
+ raise FileStoreException, "No meta manager given" if not metaManager.is_a? MetaManager
47
+ @metaManager = metaManager
48
+ end
49
+
50
+ def <<(path)
51
+ id = ''
52
+
53
+ if File.exists?(path) and File.readable?(path) then
54
+ id = UUIDTools::UUID.random_create.to_s
55
+ action = AddAction.new(id)
56
+
57
+ action.execute {
58
+ dstPath = move(@storePath, id, path)
59
+
60
+ raise "Couldn't move file" if dstPath == ''
61
+
62
+ @metaManager << MetaData.new(id, { MetaData::FIELD_PATH => dstPath })
63
+ }
64
+
65
+ @logger << action
66
+ else
67
+ raise FileStoreException, "File is not readable"
68
+ end
69
+
70
+ id
71
+ end
72
+
73
+ def -(id)
74
+ if @metaManager[id] != nil then
75
+ action = DeleteAction.new(id)
76
+
77
+ action.execute {
78
+ raise "Couldn't move file" if move(@deletedPath, id, @metaManager[id].path) == ''
79
+ @metaManager - id
80
+ }
81
+
82
+ @logger << action
83
+ else
84
+ raise FileStoreException, "Key not found"
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ def move(basePath, id, srcPath)
91
+ dstPath = ''
92
+
93
+ begin
94
+ date = Date.today
95
+ dstPath = File.join(basePath, date.year.to_s, date.month.to_s, date.day.to_s, id)
96
+ dstDir = File.dirname(dstPath)
97
+
98
+ (FileUtils.mkdir_p(dstDir) and puts "creating #{dstDir}") if not Dir.exists?(dstDir)
99
+ FileUtils.mv(srcPath, dstPath)
100
+ rescue Exception => e
101
+ raise FileStoreException, "Couldn't move file", e.backtrace
102
+ ensure
103
+ return dstPath
104
+ end
105
+ end
106
+ end
107
+
108
+ end
data/lib/log.rb ADDED
@@ -0,0 +1,40 @@
1
+ #
2
+ # log.rb
3
+ # @author Thomas Stätter
4
+ # @date 09.07.2012
5
+ # @description Library using a file system as storage for arbitrary files
6
+ #
7
+ $:.unshift('.')
8
+
9
+ require 'filestore.rb'
10
+
11
+ module FileStore
12
+
13
+ class Log
14
+ FILE = 'filestore-actions.log'
15
+
16
+ def initialize(path = '.')
17
+ begin
18
+ @logPath = File.join(path, FILE)
19
+ @logFile = File.new(@logPath, 'a+')
20
+ rescue StandardError => e
21
+ raise FileStoreException, "Initialization of logger failed", e.backtrace
22
+ end
23
+ end
24
+
25
+ def <<(action)
26
+ return if not action.is_a? Action
27
+
28
+ @logFile.puts action.to_s
29
+ end
30
+
31
+ def close
32
+ begin
33
+ @logFile.close
34
+ rescue StandardError => e
35
+ raise FileStoreException, "Couldn't properly close the logger", e.backtrace
36
+ end
37
+ end
38
+ end
39
+
40
+ end
data/lib/meta.rb ADDED
@@ -0,0 +1,81 @@
1
+ #
2
+ # meta.rb
3
+ # @author Thomas Stätter
4
+ # @date 10.07.2012
5
+ # @description Library using a file system as storage for arbitrary files
6
+ #
7
+ $:.unshift('.')
8
+
9
+ require 'filestore.rb'
10
+
11
+ module FileStore
12
+
13
+ class MetaManager
14
+
15
+ def initialize
16
+ yield
17
+ end
18
+
19
+ def <<(md)
20
+ end
21
+
22
+ def -(id)
23
+ end
24
+
25
+ end
26
+
27
+ class MemoryMetaManager < MetaManager
28
+
29
+ def initialize
30
+ # must be a hash object
31
+ @mgmt = super
32
+
33
+ raise FileStoreException, "MemoryMetamanager needs a not nil hash object for initialization" if not @mgmt.is_a?(Hash) or @mgmt.nil?
34
+ end
35
+
36
+ def <<(md)
37
+ raise FileStoreException, "Can't add 'nil' to the store" if md.nil?
38
+ raise FileStoreException, "Only objects of type 'FileStore::MetaData' can be added to the store" if not md.instance_of?(MetaData)
39
+
40
+ @mgmt[md.key] = md
41
+ end
42
+
43
+ def -(id)
44
+ raise FileStoreException, "Can't remove 'nil' from the store" if id.nil?
45
+
46
+ @mgmt.delete(id) if @mgmt.has_key?(id)
47
+ end
48
+
49
+ def [](id)
50
+ raise FileStoreException, "Can't read 'nil' from the store" if id.nil?
51
+
52
+ return @mgmt[id] if @mgmt.has_key?(id)
53
+ nil
54
+ end
55
+
56
+ end
57
+
58
+ class MetaData
59
+ FIELD_PATH = 'path'
60
+ FIELD_FILENAME = 'filename'
61
+
62
+ attr_reader :key, :data
63
+
64
+ def initialize(key, data)
65
+ raise FileStoreException, "No identifier given for meta data" if key.nil?
66
+ raise FileStoreException, "Identifier can only be of type String or Numeric" if (not key.is_a?(String) and not key.is_a?(Numeric))
67
+ raise FileStoreException, "No data given" if data.nil?
68
+ raise FileStoreException, "Data can only be of type Hash" if not data.is_a?(Hash)
69
+ raise FileStoreException, "Identifier can't be empty" if key.is_a?(String) and key == ''
70
+
71
+ @key = key
72
+ @data = data
73
+ end
74
+
75
+ def path
76
+ @data[FIELD_PATH]
77
+ end
78
+
79
+ end
80
+
81
+ end
File without changes
data/test/tc_action.rb ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # tc_action.rb
4
+ # @author Thomas Stätter
5
+ # @date 10.07.2012
6
+ # @description Unit test for classes in meta.rb
7
+ #
8
+
9
+ # execute test using: ruby -I ../lib/ tc_action.rb
10
+
11
+ require "test/unit"
12
+ require "../lib/filestore.rb"
13
+
14
+ class TestAction < Test::Unit::TestCase
15
+
16
+ def test_init
17
+ # initialization of an instance of FileStore::Action should raise an
18
+ # exception if no identifier is given or the identifier is not a string or
19
+ # numeric
20
+ assert_raise(FileStore::FileStoreException, ArgumentError) { FileStore::Action.new }
21
+ assert_raise(FileStore::FileStoreException, ArgumentError) { FileStore::Action.new(nil) }
22
+ assert_raise(FileStore::FileStoreException, ArgumentError) { FileStore::Action.new([]) }
23
+ # identifier can't be an empty string if it's a String
24
+ assert_raise(FileStore::FileStoreException) { FileStore::Action.new('') }
25
+ assert_nothing_raised(Exception) { FileStore::Action.new("asdf") }
26
+ assert_nothing_raised(Exception) { FileStore::Action.new(213123) }
27
+ end
28
+
29
+ def test_execute
30
+ # execution should fail if no block is given
31
+ assert_raise(TypeError, FileStore::FileStoreException) {
32
+ action = FileStore::Action.new("asdf")
33
+ action.execute
34
+ }
35
+ end
36
+
37
+ def test_string
38
+ # execution shouldn't fail in any case
39
+ assert_nothing_raised(Exception) { FileStore::Action.new("asdf").to_s }
40
+ assert_nothing_raised(Exception) { FileStore::Action.new(123).to_s }
41
+ assert_nothing_raised(Exception) {
42
+ action = FileStore::Action.new("asdf")
43
+ action.execute {}
44
+ action.to_s
45
+ }
46
+ end
47
+
48
+ end
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # tc_filestore.rb
4
+ # @author Thomas Stätter
5
+ # @date 10.07.2012
6
+ # @description Unit test for classes in filestore.rb
7
+ #
8
+ # execute test using: ruby -I ../lib/ tc_filestore.rb
9
+
10
+ require "test/unit"
11
+ require '../lib/filestore.rb'
12
+
13
+ class TestFileStore < Test::Unit::TestCase
14
+ BASE_PATH = "./data"
15
+
16
+ def test_init
17
+ # should work
18
+ assert_nothing_raised { FileStore::FileStore.new(BASE_PATH, FileStore::MemoryMetaManager.new {{}}) }
19
+ # shouldn't work, invalid path
20
+ assert_raise(FileStore::FileStoreException) { FileStore::FileStore.new("/some/invalid/path", FileStore::MemoryMetaManager.new {{}}) }
21
+ assert_raise(FileStore::FileStoreException) { FileStore::FileStore.new("", FileStore::MemoryMetaManager.new {{}}) }
22
+ assert_raise(FileStore::FileStoreException) { FileStore::FileStore.new(nil, FileStore::MemoryMetaManager.new {{}}) }
23
+ # shouldn't work, invalid MetaManager
24
+ assert_raise(FileStore::FileStoreException) { FileStore::FileStore.new(BASE_PATH, {}) }
25
+ assert_raise(FileStore::FileStoreException) { FileStore::FileStore.new(BASE_PATH, nil) }
26
+ end
27
+
28
+ def test_add
29
+ mm = FileStore::MemoryMetaManager.new {
30
+ data = {}
31
+
32
+ Dir.glob(File.join(BASE_PATH, "**", "*")).each { |f|
33
+ if not File.directory?(f) and File.basename(f) != FileStore::Log::FILE then
34
+ data[File.basename(f)] = File.absolute_path(f)
35
+ end
36
+ }
37
+
38
+ data
39
+ }
40
+ fs = FileStore::FileStore.new(BASE_PATH, mm)
41
+ id = fs << './move_from/test-file-to-move'
42
+
43
+ assert_not_nil(id, "Returned ID can't be nil")
44
+ assert_not_same(id, '', "Returned ID can't be empty")
45
+ assert_instance_of(String, id, "Weird ID returned: #{id}")
46
+ # should raise an exception
47
+ assert_raise(FileStore::FileStoreException) { fs << '/some/invalid/file' }
48
+
49
+ # restore the test file
50
+ `touch ./move_from/test-file-to-move`
51
+ end
52
+
53
+ def test_remove
54
+ fs = FileStore::FileStore.new(BASE_PATH, FileStore::MemoryMetaManager.new {{}})
55
+
56
+ # should raise an exception
57
+ assert_raise(FileStore::FileStoreException) { fs - 'adsfasdf' }
58
+ end
59
+
60
+ end
data/test/tc_log.rb ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # tc_log.rb
4
+ # @author Thomas Stätter
5
+ # @date 10.07.2012
6
+ # @description Unit test for classes in log.rb
7
+ #
8
+
9
+ # execute test using: ruby -I ../lib/ tc_log.rb
10
+
11
+ require "test/unit"
12
+ require "../lib/filestore.rb"
13
+
14
+ class TestLog < Test::Unit::TestCase
15
+
16
+ def test_init
17
+ # should be working, default path would be '.'
18
+ assert_nothing_raised { FileStore::Log.new }
19
+ # should raise an error, because the path is invalid
20
+ assert_raise(FileStore::FileStoreException){ FileStore::Log.new('/some/invalid/path') }
21
+ end
22
+
23
+ def test_log
24
+ # shouldn't raise any error (but nothing will happen to the log)
25
+ logger = FileStore::Log.new
26
+
27
+ assert_nothing_raised {
28
+ logger << "asdf"
29
+ logger << 2343
30
+ logger << []
31
+ logger << FileStore::DeleteAction.new("asdf")
32
+ }
33
+ end
34
+
35
+ def test_close
36
+ logger = FileStore::Log.new
37
+
38
+ assert_nothing_raised { logger.close }
39
+ end
40
+ end
data/test/tc_meta.rb ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # tc_meta.rb
4
+ # @author Thomas Stätter
5
+ # @date 10.07.2012
6
+ # @description Unit test for classes in meta.rb
7
+ #
8
+
9
+ # execute test using: ruby -I ../lib/ tc_meta.rb
10
+
11
+ require "test/unit"
12
+ require "../lib/filestore.rb"
13
+
14
+ # Test cases for FileStore::MetaData
15
+ class TestMetaData < Test::Unit::TestCase
16
+ def test_init
17
+ # arguments 'key' and 'data' must be provided
18
+ assert_raise(ArgumentError) { FileStore::MetaData.new }
19
+ # argument 'key' must be of type String or Numeric
20
+ assert_raise(FileStore::FileStoreException) { FileStore::MetaData.new({},{}) }
21
+ assert_nothing_raised(FileStore::FileStoreException) { FileStore::MetaData.new('asdf',{}) }
22
+ assert_nothing_raised(FileStore::FileStoreException) { FileStore::MetaData.new(234,{}) }
23
+ # identifier may not be an empty string
24
+ assert_raise(FileStore::FileStoreException) { FileStore::MetaData.new('',{}) }
25
+ # data argument may not be nil
26
+ assert_raise(FileStore::FileStoreException) { FileStore::MetaData.new('asdf',nil) }
27
+ end
28
+
29
+ def test_accessors
30
+ # attr_readers for key and data may not return nil
31
+ md = FileStore::MetaData.new(234,{})
32
+
33
+ assert_not_nil(md.key, "Key can't be nil")
34
+ assert_not_nil(md.data, "Key can't be nil")
35
+ end
36
+
37
+ def test_path
38
+ md = FileStore::MetaData.new(234,{ FileStore::MetaData::FIELD_PATH => '/some/path' })
39
+ # path may only return a string
40
+ assert_instance_of(String, md.path, "Path can only be of type string")
41
+
42
+ md = FileStore::MetaData.new(234,{})
43
+ # path may be nil
44
+ assert_nil(md.path, "Path is not given although it should be there")
45
+ end
46
+ end
47
+
48
+ # Test cases for FileStore::MetaManager
49
+ class TestMetaManager < Test::Unit::TestCase
50
+ def test_init
51
+ # should raise a type error if no initialize code is given
52
+ assert_raise(LocalJumpError) { FileStore::MetaManager.new }
53
+ assert_nothing_raised(Exception) { FileStore::MetaManager.new {} }
54
+ end
55
+ end
56
+
57
+ # Test cases for FileStore::MemoryMetaManager
58
+ class TestMemoryMetaManager < Test::Unit::TestCase
59
+ def test_init
60
+ # the init block may only return a not nil hash object
61
+ assert_raise(FileStore::FileStoreException){ FileStore::MemoryMetaManager.new {""} }
62
+ assert_raise(FileStore::FileStoreException){ FileStore::MemoryMetaManager.new { } }
63
+ assert_nothing_raised(FileStore::FileStoreException){ FileStore::MemoryMetaManager.new {{}} }
64
+ end
65
+
66
+ def test_add
67
+ mm = FileStore::MemoryMetaManager.new {{}}
68
+
69
+ assert_raise(FileStore::FileStoreException){ mm << nil }
70
+ assert_raise(FileStore::FileStoreException){ mm << "asdfasdf" }
71
+ assert_nothing_raised(FileStore::FileStoreException){
72
+ md = FileStore::MetaData.new(234,{})
73
+ mm << md
74
+ }
75
+ end
76
+
77
+ def test_remove
78
+ mm = FileStore::MemoryMetaManager.new {{}}
79
+
80
+ assert_raise(FileStore::FileStoreException){ mm - nil }
81
+ assert_nothing_raised(Exception){
82
+ mm - "asdf"
83
+ mm - 123123
84
+ mm - []
85
+ mm - {}
86
+ mm - FileStore::MetaData.new(234,{})
87
+ }
88
+ end
89
+
90
+ def test_read
91
+ mm = FileStore::MemoryMetaManager.new {{}}
92
+
93
+ assert_raise(FileStore::FileStoreException){ mm[nil] }
94
+ assert_nothing_raised(Exception){
95
+ mm[[]]
96
+ mm["asdf"]
97
+ mm[2421]
98
+ }
99
+ assert_nil(mm[2343], "Nil wasn't returned althought the given key wasn't existing")
100
+ end
101
+ end
data/test/ts_gem.rb ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # ts_gem.rb
4
+ # @author Thomas Stätter
5
+ # @date 10.07.2012
6
+ # @description Test suite for the complete gem
7
+ #
8
+
9
+ # execute test using: ruby -I../lib/ -I. ts_gem.rb
10
+ $:.unshift('.')
11
+ $:.unshift('../lib')
12
+
13
+ require "test/unit"
14
+ require 'tc_action.rb'
15
+ require 'tc_meta.rb'
16
+ require 'tc_log.rb'
17
+ require 'tc_filestore.rb'
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: filestore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Stätter
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: uuidtools
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.1.2
22
+ - - ! '>='
23
+ - !ruby/object:Gem::Version
24
+ version: '2.0'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.1.2
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '2.0'
36
+ description: Organizes a file storage using the file system and some meta data
37
+ email: thomas.staetter@gmail.com
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - lib/filestore.rb
43
+ - lib/action.rb
44
+ - lib/log.rb
45
+ - lib/meta.rb
46
+ - test/ts_gem.rb
47
+ - test/tc_action.rb
48
+ - test/tc_log.rb
49
+ - test/tc_meta.rb
50
+ - test/tc_filestore.rb
51
+ - test/move_from/test-file-to-move
52
+ homepage: https://www.xing.com/profile/thomas.staetter
53
+ licenses: []
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: 1.9.3
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements:
71
+ - gem uuidtools
72
+ rubyforge_project:
73
+ rubygems_version: 1.8.21
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Simple file storage
77
+ test_files:
78
+ - test/ts_gem.rb
79
+ - test/tc_action.rb
80
+ - test/tc_log.rb
81
+ - test/tc_meta.rb
82
+ - test/tc_filestore.rb
83
+ - test/move_from/test-file-to-move