tmsu_file_db 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 87c86606a333c58a62d8d6c1d6db1cdee4da35dc
4
+ data.tar.gz: fbae0484413b490c0e1c98f5a415b95e7ef46b0f
5
+ SHA512:
6
+ metadata.gz: 220887318854f6a1a9037bf265edc70f547384f8acc44b4d75b7b3a5f00026fdf0c75c913e453c7d6800446f857cb357ac40d9ed2526817b185a42f7f39f6d11
7
+ data.tar.gz: f5fc16da123e6a2c8eb1eec9f476905e7d4a85193125298efac7e42119f41d2b33ea762da7902a8fbffaf1519599b83d22ce87a76c02c374beefe109b418aa5a
data/bin/tmsu_file_db ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ require 'tmsu_file_db'
3
+ class TmsuFileDb::CLI < Thor
4
+ desc "test", "run tests"
5
+ def test
6
+ puts "No tests have been wrritten"
7
+ exit
8
+ end
9
+ end
10
+ TmsuFileDb::CLI.start ARGV
@@ -0,0 +1,270 @@
1
+ require 'securerandom'
2
+ require 'gemmy'
3
+
4
+ module TmsuFileDb
5
+ def self.start
6
+ ::TmsuRuby.start
7
+ end
8
+ end
9
+
10
+ class TmsuModel
11
+ Config = { root_path: "." }
12
+ Validations = Hash.new { |h,k| h[k] = [] }
13
+ Callbacks = {}
14
+
15
+ def self.query_glob
16
+ "#{Config[:root_path] || "."}/*"
17
+ end
18
+
19
+ def self.configure(root_path:)
20
+ Config[:root_path] = root_path || "./db".tap do |path|
21
+ `mkdir #{path}`
22
+ end
23
+ end
24
+
25
+ def self.validate(attribute=nil, &blk)
26
+ if attribute
27
+ Validations[:generic] << blk
28
+ else
29
+ Validations[attribute] << blk
30
+ end
31
+ end
32
+
33
+ def self.add_callback name, &blk
34
+ Callbacks[name] = blk
35
+ end
36
+
37
+ def self.opts_to_query opts
38
+ case opts
39
+ when Array
40
+ opts.join " "
41
+ when Hash
42
+ opts.map { |k,v| "#{k}={v}" }.join(" ")
43
+ end
44
+ end
45
+
46
+ def self.find_by opts
47
+ where(opts).first
48
+ end
49
+
50
+ def self.where opts={}
51
+ query opts_to_query opts
52
+ end
53
+
54
+ def self.query string
55
+ TmsuFile.new(query_glob).paths_query(query)
56
+ end
57
+
58
+ def self.update_all opts={}
59
+ Dir.glob(query_glob).each { |path| new(path).update(opts) }
60
+ end
61
+
62
+ def self.destroy_all opts={}
63
+ Dir.glob(query_glob).each { |path| `rm #{path}` }
64
+ end
65
+
66
+ attr_reader :attributes, :errors, :path
67
+
68
+ def initialize(attrs={})
69
+ attrs = attrs.with_indifferent_access
70
+ @path = build_id(attrs.delete :id)
71
+ @attributes = attrs
72
+ @persisted = File.exists? @path
73
+ @errors = []
74
+ end
75
+
76
+ def build_id(given=nil)
77
+ rand_id = given || SecureRandom.urlsafe_base64
78
+ prefix = "#{self.class::Config[:root_path]}"
79
+ if prefix
80
+ "#{prefix}/#{rand_id}"
81
+ else
82
+ "#{rand_id}"
83
+ end
84
+ end
85
+
86
+ def []=(k,v)
87
+ attributes[k] = v
88
+ end
89
+
90
+ def [](k)
91
+ attributes[k]
92
+ end
93
+
94
+ def method_missing(sym, *arguments, &blk)
95
+ if attributes.keys.include? sym
96
+ attributes[sym]
97
+ else
98
+ super
99
+ end
100
+ end
101
+
102
+ def write(text, append: false)
103
+ return unless text
104
+ File.open(path, "w#{"a" if append}") { |f| f.write text }
105
+ self
106
+ end
107
+
108
+ def append(text)
109
+ write(text, append: true)
110
+ self
111
+ end
112
+
113
+ def valid?
114
+ @errors = []
115
+ Validations.each do |type, procs|
116
+ procs.each do |proc|
117
+ some_errors = if type.eql?(:generic)
118
+ proc.call self
119
+ else
120
+ proc.call self[type], self
121
+ end
122
+ raise(
123
+ ArgumentError, "validations must return arrays"
124
+ ) unless some_errors.is_a?(Array)
125
+ @errors.concat some_errors
126
+ end
127
+ end
128
+ @errors.empty?
129
+ end
130
+
131
+ def persisted?
132
+ !!@persisted
133
+ end
134
+
135
+ def ensure_persisted
136
+ `touch #{path}` unless persisted?
137
+ end
138
+
139
+ def save
140
+ ensure_persisted
141
+ tag attributes
142
+ self
143
+ end
144
+
145
+ def update attrs={}
146
+ attrs.each_key { |k| self[k] = attrs[k] }
147
+ save
148
+ self
149
+ end
150
+
151
+ def destroy
152
+ `rm #{path}`
153
+ self
154
+ end
155
+
156
+ end
157
+
158
+ module SystemPatch
159
+ refine Object do
160
+ def system string
161
+ `#{string}`.tap &method(:puts)
162
+ end
163
+ end
164
+ end
165
+
166
+ module TmsuRubyInitializer
167
+ using SystemPatch
168
+ def start
169
+ init_tmsu
170
+ end
171
+ def init_tmsu
172
+ puts "initializing tmsu"
173
+ puts system "tmsu init"
174
+ puts "making vfs_path #{vfs_path}"
175
+ puts system "mkdir #{vfs_path}"
176
+ puts "mounting vfs path"
177
+ puts system "tmsu mount #{vfs_path}"
178
+ end
179
+ def vfs_path
180
+ "/home/max/tmsu_vfs"
181
+ end
182
+ end
183
+
184
+ module TmsuFileAPI
185
+
186
+ using SystemPatch
187
+
188
+ def tags
189
+ ensure_persisted
190
+ system("tmsu tags #{path}").split(" ")[1..-1].reduce({}) do |res, tag|
191
+ key, val = tag.split("=")
192
+ res.tap { res[key] = val }
193
+ end
194
+ end
195
+
196
+ def paths_query(query)
197
+ query_root = "#{vfs_path}/queries/#{query}"
198
+ system("ls #{query_root}").split("\n").map do |filename|
199
+ system("readlink #{query_root}/#{filename}").chomp
200
+ end
201
+ end
202
+
203
+ def untag tag_list
204
+ `touch #{path}` unless persisted?
205
+ attributes.delete
206
+ system "tmsu untag #{path} #{tag_list}"
207
+ tags
208
+ end
209
+
210
+ def tag tag_obj
211
+ `touch #{path}` unless persisted?
212
+ system "tmsu tag #{path} #{build_tag_arg tag_obj}"
213
+ tags
214
+ end
215
+
216
+ def build_tag_arg obj
217
+ case obj
218
+ when String
219
+ obj
220
+ when Array
221
+ obj.join " "
222
+ when Hash
223
+ obj.map {|k,v| "#{k}=#{v}" }.join " "
224
+ else
225
+ obj
226
+ end
227
+ end
228
+
229
+ def tag_selector(tag_obj)
230
+ system "tmsu tag --tags '#{build_tag_arg tag_obj}' #{path}"
231
+ files tag_obj
232
+ end
233
+
234
+ def merge_tag(source, dest)
235
+ source_files = files source
236
+ dest_files = files dest
237
+ raise(ArgumentError, "#{source} tag not found") if source_files.empty?
238
+ raise(ArgumentError, "#{dest} tag not found") if dest_files.empty?
239
+ system("tmsu merge #{source} #{dest}")
240
+ source_files
241
+ end
242
+
243
+ def files(tag_obj)
244
+ system("tmsu files #{build_tag_arg tag_obj }").split("\n")
245
+ end
246
+
247
+ end
248
+
249
+ class TmsuRuby
250
+ extend TmsuRubyInitializer
251
+
252
+ def self.file(path=nil)
253
+ TmsuRuby::TmsuFile.new path, vfs_path
254
+ end
255
+
256
+ def self.model(path=nil)
257
+ record = TmsuModel.new id: path
258
+ end
259
+
260
+ class TmsuFile
261
+ include TmsuFileAPI
262
+ attr_reader :path, :vfs_path
263
+ def initialize path, vfs_path
264
+ @path = path
265
+ @vfs_path = vfs_path
266
+ end
267
+ end
268
+ end
269
+
270
+ TmsuModel.include TmsuFileAPI
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module TmsuFileDb
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tmsu_file_db
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - maxpleaner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gemmyrb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: ''
28
+ email: maxpleaner@gmail.com
29
+ executables:
30
+ - tmsu_file_db
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/tmsu_file_db
35
+ - lib/tmsu_file_db.rb
36
+ - lib/version.rb
37
+ homepage: http://github.com/maxpleaner/tmsu_file_db
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.3'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.5.1
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.5.1
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: a 'database' using TMSU file tagging system
61
+ test_files: []