activefile 0.0.0beta

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTQ1YjFmMGQ2NjI5ZWU4Y2ZjYTNhYjY2NjQwYTE1ZDcxZmI4ODM4ZQ==
5
+ data.tar.gz: !binary |-
6
+ NGZhMzQwMDY4NzVmNjMxZTY2NjFmYzhjMjliNWU5OTQwMjQ1ZjhjOQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YTFhZjEyNDZiYWE4ZTAwNTE0MGQzZWQ5NjQ0NzNmMTAwMWQ0MjYwMWM2MTRm
10
+ ZmU3ZThiODUzNzY0Yzc1N2U1YmM1YjQ4YjA2YjI2ODg5ZTE0OTkyMWQ2NWYz
11
+ MjMwZmI3ZDBlNTAyOTFhNjE4NjczZThkM2VmZDc3MjA4ZjkyNGQ=
12
+ data.tar.gz: !binary |-
13
+ OTU4ZmZjN2RmMGJmZTUxYjM1OTk4YmVjMDczNDQ5NzFkYjQ3MTEwNGY5OGQ2
14
+ MmYzNWMwNzFlNjcwZTljZDE0OTliMmMzZjM2OTI1MTJlNDczZGJmN2Q5YWIy
15
+ OTNjZWIxZDU2ODk5ZWRlNzY0NjI0ZGVjM2MyNjM3NTdmMjJhZGY=
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,35 @@
1
+ == Gem under construction. Base functionality already done, but I still need reorganize it. I work with Unit tests now.
2
+
3
+ Please, be patient! All work will be done untill May.
4
+
5
+ == Welcome to ActiveFile
6
+
7
+ ActiveFile is a lightweight file system ORM.
8
+
9
+ Build a persistent domain model by mapping file system objects to Ruby classes. It inherits ActiveRecord-similar interface.
10
+
11
+
12
+
13
+ class Shop < ActiveFile::Base
14
+ parent_to :product
15
+ end
16
+
17
+ class Product < ActiveFile::Base
18
+ child_of :shop
19
+ end
20
+
21
+ shop = Shop.new(:name => "Apple Store")
22
+ shop.save!
23
+
24
+ Shop.all.size #> 1
25
+
26
+ iPad = Product.new(:name => "iPad", :parent => shop, :data => "The iPad is a line of tablet computers designed and marketed by Apple Inc., which runs Apple's iOS operating system.")
27
+ iPad.save!
28
+
29
+ product = Product.where(:name => "iPad")[0]
30
+ product.data #> "The iPad "...
31
+ product.shop #> <Shop instance>
32
+ product.shop.name #> "Apple Store"
33
+
34
+
35
+ # In result, two persistent files were created, accessible via ORM mechanism.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+
2
+ desc "Default Task"
3
+ task default: [ :test ]
4
+
5
+ # Run the unit tests
6
+ #Rake::TestTask.new { |t|
7
+ ## t.libs << "test"
8
+ # t.pattern = 'test/**/*_test.rb'
9
+ # t.warning = true
10
+ # t.verbose = true
11
+ #}
12
+
13
+ task :test do
14
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
15
+ Dir.glob("test/**/*_test.rb").all? do |file|
16
+ sh(ruby, '-Ilib:test', file)
17
+ end or raise "Failures"
18
+ end
@@ -0,0 +1,273 @@
1
+ module ActiveFile
2
+ # Data Source Storage Adapter
3
+ module Adapter
4
+ require 'fileutils'
5
+ RAISE_TRUE = true
6
+ RAISE_FALSE = false
7
+
8
+ def initialize args
9
+ super args
10
+ end
11
+
12
+ def base_folder arg
13
+ puts "BaseFolder is #{arg}"
14
+ end
15
+
16
+
17
+ # touch file to read!
18
+ def load!
19
+ self.data
20
+ self
21
+ end
22
+
23
+ def data= data_arg
24
+ @self_data = data_arg
25
+ end
26
+
27
+ def data
28
+ if @self_data == nil
29
+ @self_data = File.read(self.get_source_path)
30
+ end
31
+ @self_data || ""
32
+ end
33
+
34
+ # Main rule to link attaches (css) with their targets (layouts, contents). Special filename format used for this purpose;
35
+ def attach_my_name!
36
+ # Is we an attached instance?
37
+ unless self.target.nil?
38
+ #@ext = CSS_EXT if self.type == SourceType::CSS
39
+ self.name = target.type.to_s + TARGET_DIVIDER + target.name #+ @ext.to_s
40
+ end
41
+ end
42
+
43
+ # Get source folder. Create, if not exists.
44
+ def get_source_folder
45
+ Adapter.get_source_folder(type)
46
+ end
47
+ def get_name
48
+ attach_my_name!
49
+ return name
50
+ end
51
+ # Get source filename
52
+ def get_filename
53
+ get_name + get_extension
54
+ end
55
+ # Alias for get_source_path
56
+ def get_filepath
57
+ get_source_path
58
+ end
59
+ # Get source path. For targeted objects, target name + '--' + target type appends
60
+ def get_source_path
61
+ raise ArgumentError, 'Name can not be blank!' if name.blank? && target.nil?
62
+ raise ArgumentError, 'Target name can not be blank!' if target && target.name.blank?
63
+ get_source_folder + get_filename
64
+ end
65
+ def get_extension
66
+ return ".scss" if type == SourceType::CSS
67
+ return extension.blank? ? "" : "."+extension
68
+
69
+ type_ext = SOURCE_TYPE_EXTENSIONS[type.to_i] || ""
70
+ return "" if type_ext == "*"
71
+ if type_ext == "*"
72
+ unless new_record?
73
+ # Custom extension, from filename
74
+ Dir.glob(dir+"*").each do |f|
75
+ name_with_extension = f.split('/').last
76
+ name, ext = name_with_extension.split('.')
77
+ if name == get_name
78
+ type_ext = ext
79
+ break
80
+ end
81
+ end
82
+ else
83
+ _name, _ext = name.split(".")
84
+ unless _name.empty? && _ext.empty?
85
+ type_ext = _ext
86
+ end
87
+ end
88
+ end
89
+ type_ext = "." + type_ext unless type_ext.empty?
90
+ type_ext
91
+ end
92
+ # Get unique id of the source
93
+ def get_id
94
+ ID_PREFIX + type.to_s + ID_DIVIDER + get_name
95
+ end
96
+ # Rename the source file, return boolean operation result
97
+ def rename(new_file_name)
98
+ raise "Source is new record, call the save! method before rename." if new_record?
99
+ # rename attached file, if present ()
100
+ attach = get_attach
101
+ # later..
102
+ old_file_path = get_source_path
103
+ new_file_path = get_source_folder + new_file_name + get_extension
104
+ b_result = !!File.rename(old_file_path, new_file_path)
105
+ raise "Unable to rename source" unless b_result
106
+ self.name = new_file_name
107
+ if attach
108
+ # to rename attach, create new copy of attached object with new target name, and delete old
109
+ attach_source = attach.clone
110
+ attach_source.target = self
111
+ b_result = attach_source.save! && attach.delete!
112
+ raise 'Attached file rename failed' unless b_result
113
+ end
114
+ b_result
115
+ end
116
+ def new_record?
117
+ p get_source_path
118
+ !File.exists?(get_source_path)
119
+ end
120
+ private
121
+ def save_method(raise_exception_on_error)
122
+ File.open(get_source_path, "w") do
123
+ |file| file.write(data.force_encoding('utf-8'))
124
+ end
125
+ rescue => e
126
+ return raise_exception_on_error == RAISE_TRUE ? raise(e) : false
127
+ end
128
+ def delete_method(raise_exception_on_error)
129
+ delete_file_name = get_source_path
130
+ File.delete(delete_file_name)
131
+ return true
132
+ rescue => e
133
+ return raise_exception_on_error == RAISE_TRUE ? raise(e) : false
134
+ end
135
+ public
136
+ # Save the source, return boolean operation result
137
+ def save
138
+ save_method(RAISE_FALSE)
139
+ end
140
+ def save!
141
+ save_method(RAISE_TRUE)
142
+ end
143
+ # Delete the source: if successful returns true, else return false
144
+ def delete
145
+ delete_method(RAISE_FALSE)
146
+ end
147
+ # Delete the source: if successful returns true, else raise an error
148
+ def delete!
149
+ raise StandardError, "Unable to delete file if object hasn't been saved yet" if new_record?
150
+ delete_method(RAISE_TRUE)
151
+ end
152
+ def get_target_type
153
+ name.split(TARGET_DIVIDER)[0]
154
+ end
155
+ def get_target_name
156
+ name.split(TARGET_DIVIDER)[1]
157
+ end
158
+ # Get target object
159
+ def get_target
160
+ return nil unless name.include?(TARGET_DIVIDER)
161
+ #target_type, target_name = name[0..-2].split(TARGET_DIVIDER)
162
+ target_type = get_target_type
163
+ target_name = get_target_name
164
+
165
+ target_type_extension = SOURCE_TYPE_EXTENSIONS[target_type.to_i]
166
+ unless target_type_extension.empty?
167
+ target_type_extension = "." + target_type_extension
168
+ end
169
+
170
+ target = Adapter.get_source_folder(target_type) + target_name + target_type_extension
171
+ return nil unless File.exists?(target)
172
+ return Source.new({ :type => target_type.to_i, :name => target_name, :data => nil })
173
+ end
174
+ # Get attached object
175
+ def get_attach attach_type=SourceType::CSS
176
+ Adapter.where(:type => attach_type, :name => get_attached_name).first
177
+ end
178
+ def get_attached_name
179
+ type.to_s + TARGET_DIVIDER + name
180
+ end
181
+ #def get_attached_filename
182
+ # attached_file_extension = SOURCE_TYPE_EXTENSIONS[attach_type.to_i]
183
+ # attached_file_extension = "." + attached_file_extension unless attached_file_extension.empty?
184
+ # type.to_s + TARGET_DIVIDER + name + attached_file_extension
185
+ #end
186
+ def get_attach_or_create attach_type=SourceType::CSS
187
+ attach = get_attach(attach_type)
188
+ if attach.nil?
189
+ attach = Source.new(:type => attach_type, :extension => SOURCE_TYPE_EXTENSIONS[attach_type])
190
+ attach.target = self
191
+ attach.save!
192
+ end
193
+ attach
194
+ end
195
+ #
196
+ # STATIC METHODS MODULE
197
+ module ClassMethods
198
+ # Creates a new source instance and saves it to disk. Returns the newly created source. If a failure has occurred or source already exists -
199
+ # an exception will be raised.
200
+ def create(attributes={})
201
+ raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
202
+ source_instance = Source.new(attributes)
203
+ raise 'Source file with such name already exists!' if File.exists?(source_instance.get_source_path)
204
+ source_instance.save!
205
+ return source_instance
206
+ end
207
+ # Get source folder for any source type. Create, if not exists.
208
+ def get_source_folder(type)
209
+ source_folder = Rails.env == 'test' ? TEST_SOURCE_FOLDERS[type.to_i || SourceType::UNDEFINED] : SOURCE_FOLDERS[type.to_i || SourceType::UNDEFINED]
210
+ FileUtils.mkpath(source_folder) unless File.exists?(source_folder)
211
+ return source_folder
212
+ end
213
+ # Get names array of all sources with specified type
214
+ def all_by_type(source_type)
215
+ files = Array.new
216
+ dir = Adapter.get_source_folder(source_type)
217
+ source_extension = SOURCE_TYPE_EXTENSIONS[source_type.to_i]
218
+
219
+ Dir.glob(dir+"*").each do |f|
220
+ name_with_extension = f.split('/').last
221
+ extension = name_with_extension.split('.').size > 1 ? name_with_extension.split('.').last : ""
222
+ name_without_extension = nil
223
+
224
+ name_without_extension = name_with_extension
225
+
226
+ if source_extension.blank?
227
+ name_without_extension = name_with_extension
228
+ else
229
+ name_without_extension = source_extension == "*" ? name_with_extension.split('.').first : name_with_extension[0..-source_extension.length-2]
230
+ end
231
+
232
+ s = Source.new({ :type => source_type, :name => name_without_extension, :extension => extension, :data => nil })
233
+ target_object = s.get_target
234
+ s.target = target_object unless target_object.nil?
235
+ files.push(s)
236
+ end
237
+ return files
238
+ end
239
+ def all
240
+ (Rails.env == 'test' ? TEST_SOURCE_FOLDERS : SOURCE_FOLDERS).map {|key_type, val| Adapter.all_by_type(key_type) }.reject { |ar| ar.empty? }.flatten
241
+ end
242
+ # Find the source
243
+ def where(attributes)
244
+ raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
245
+ Adapter.all.select do |source|
246
+ match = true
247
+ attributes.each{|key, val|
248
+ match = false if source.send(key) != val
249
+ }
250
+ match
251
+ end
252
+ end
253
+ def find_by_id(id)
254
+ id = id[ID_PREFIX.size .. -1]
255
+ type, name = id.include?(TARGET_DIVIDER) ? (id).split(ID_DIVIDER) : id.split(ID_DIVIDER)
256
+ Adapter.find_by_name_and_type(name, type.to_i).first
257
+ end
258
+ # Complex finders:
259
+ def method_missing(m, *args, &block)
260
+ if m.to_s.index("find_by_") == 0
261
+ attributes = m["find_by_".size..-1].split("_and_")
262
+ raise "Attributes count expected: #{attributes.size}, got: #{args.size}" unless attributes.size == args.size
263
+ match_hash = {}
264
+ attributes.each_with_index {|attr, index| match_hash[attr.to_sym] = args[index]}
265
+ return Adapter.where(match_hash)
266
+ else
267
+ puts "There's no method called #{m} here -- please try again with args #{args}"
268
+ end
269
+ end
270
+ end
271
+ extend ClassMethods
272
+ end
273
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveFile
2
+ require 'ostruct'
3
+ class Base < OpenStruct
4
+
5
+
6
+ include Adapter
7
+ extend Adapter::ClassMethods
8
+ def ahola
9
+ puts 'ahols here!'
10
+ end
11
+ #'a'.camelize.safe_constantize
12
+ #def child_of(parent_name)
13
+ # puts "ok, I am a child of #{parent_name}"
14
+ #end
15
+ #
16
+ #def parent_to(child_name)
17
+ # puts "OH, I am a parent to #{child_name}"
18
+ #end
19
+
20
+ end
21
+ end
data/lib/activefile.rb ADDED
@@ -0,0 +1,29 @@
1
+ #--
2
+ # Copyright (c) 2013 ariekdev
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require "active_support/dependencies/autoload"
25
+ module ActiveFile
26
+ extend ActiveSupport::Autoload
27
+ autoload :Base
28
+ autoload :Adapter
29
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activefile
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0beta
5
+ platform: ruby
6
+ authors:
7
+ - Vitaly Pestov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Build a hierarchical model of filesystem objects.
14
+ email: vitalyp@softwareplanet.uk.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/activefile.rb
20
+ - lib/active_file/adapter.rb
21
+ - lib/active_file/base.rb
22
+ - MIT-LICENSE
23
+ - Rakefile
24
+ - README.rdoc
25
+ homepage: http://www.interlink-ua.com
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.9.3
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ! '>'
41
+ - !ruby/object:Gem::Version
42
+ version: 1.3.1
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 2.0.2
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Object-relational mapper framework. Please, be patient. Under construction.
49
+ test_files: []