mbrew 0.1.0.pre.dev.1 → 0.1.0.pre.dev.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d45f7c902432ff4773ad0948623b47ca2a97ffa1
4
- data.tar.gz: bfad59bbb9d52702783c6e9c3bb2223d2487429a
3
+ metadata.gz: a4a3e5518911c2ec8802c6f6b15e88292335a8dd
4
+ data.tar.gz: 2f6657372b73dde1a06864c99637848f8a6c684d
5
5
  SHA512:
6
- metadata.gz: d0d8d527d34a34f648ba669339311fd98e004477c3b4d931854a392ebe843028506f81c5789ec55988800b4b387589a6e6c5718b499416182b402a89bf68c0a8
7
- data.tar.gz: 9ee8375a483366532a53da418489b18407c92939301ace0fa2e040683f5314d40a71f808de437baa3b2db92e626d9973768bcc4b63e09bfd9d8af7444d3787fb
6
+ metadata.gz: e8e665e53ee44ebc0dd264644113fba65262bcc3b1ce9d22b9e7209dde4d5f43c52534ded959987b98bb96d851051a5157f1775fa31b68d6a2c579d6e67c746c
7
+ data.tar.gz: 24a4e975798e6890b846461d880e5ce23f18932357c6a159728761c4fc08ae6b7c91b7bcb18216a4aedd5752efbe9a724914b3f9f1f9b6773075e7834e428e4b
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  .setup
2
- CHANGELOG-*.txt
2
+ CHANGELOG-*.txt
3
+ /releases/
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mbrew (0.1.0.pre.dev.1)
4
+ mbrew (0.1.0.pre.dev.2)
5
5
  git (~> 1.2)
6
6
  id3lib-ruby (~> 0.6)
7
7
  rainbow (~> 2.0)
data/README.md CHANGED
@@ -17,6 +17,10 @@ Use it in your sources:
17
17
 
18
18
  require 'mbrew'
19
19
 
20
+ ## Documentation
21
+
22
+ See [`mbrew(1)`](http://thefox.github.io/mbrew/man/mbrew.1.html).
23
+
20
24
  ## License
21
25
  Copyright (C) 2015 Christian Mayer <http://fox21.at>
22
26
 
data/bin/dev ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir(File.expand_path('..', __dir__)) do
4
+ require 'bundler/setup'
5
+ #require 'lib/mbrew'
6
+ end
7
+
8
+ load Gem.bin_path('mbrew', 'mbrew')
data/bin/mbrew CHANGED
@@ -4,25 +4,15 @@
4
4
  raise 'Ruby >=2.2 required' unless RUBY_VERSION.to_f >= 2.2
5
5
 
6
6
  require 'optparse'
7
- require 'fileutils'
8
- require 'uri'
9
- require 'git'
10
- require 'yaml'
11
- require 'yaml/store'
12
- require 'digest/sha1'
13
7
  require 'rainbow'
14
- require 'id3lib'
15
- require 'thefox-ext'
16
-
17
-
18
- lib = '/Users/thefox/work/dev/homemusic/lib'
19
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
20
8
  require 'mbrew'
21
9
 
22
10
 
23
11
  if ARGV.count == 0
24
- puts "Usage: mbrew <command>"
25
- puts "Version: #{TheFox::MBrew::VERSION}"
12
+ puts "MBrew #{TheFox::MBrew::VERSION}"
13
+ puts TheFox::MBrew::HOMEPAGE
14
+ puts
15
+ puts "Usage: mbrew <command> [-h] [<args>]"
26
16
  puts
27
17
  puts 'Commands:'
28
18
  puts "\t clone"
@@ -31,10 +21,33 @@ if ARGV.count == 0
31
21
  puts "\t commit"
32
22
  puts "\t status"
33
23
  puts "\t list"
24
+ puts "\t search"
25
+ puts "\t info"
26
+ puts "\t install"
27
+ puts "\t uninstall"
34
28
  puts
35
29
  exit 3
36
30
  end
37
31
 
32
+ def get_working_dir
33
+ if Dir.exist?('.mbrew')
34
+ Dir.pwd
35
+ else
36
+ if Dir.pwd == '/'
37
+ nil
38
+ else
39
+ Dir.chdir('..') do
40
+ get_working_dir
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ working_dir = get_working_dir
47
+ is_a_mbrew_lib = !working_dir.nil?
48
+
49
+ mbrew = TheFox::MBrew::MBrew.new(working_dir)
50
+
38
51
  command1 = ARGV.shift
39
52
  case command1
40
53
  when 'clone'
@@ -49,34 +62,13 @@ when 'clone'
49
62
  end
50
63
  end
51
64
  ARGV << '-h' if ARGV.count == 0
52
- opts.parse(ARGV)
65
+ args = opts.parse(ARGV)
66
+ url = args.shift
67
+ dir = args.shift
53
68
 
54
- url = URI(ARGV.shift)
55
- dir = ARGV.shift ||
56
- "#{url.host} #{url.path}"
57
- .gsub('.', '-')
58
- .gsub('/', ' ')
59
- .strip
60
- .gsub(/ +/, '-')
69
+ puts "Cloning library '#{url}' ..."
61
70
 
62
- puts "url: '#{url}'"
63
- puts "dir: '#{dir}'"
64
-
65
- if !Dir.exist?(dir)
66
- puts "Cloning into library '#{dir}'..."
67
-
68
- Dir.mkdir(dir)
69
- Dir.chdir(dir) do
70
- Dir.mkdir('.mbrew')
71
- Dir.chdir('.mbrew') do
72
- grepo = Git.clone(URI, NAME, :path => 'index')
73
- grepo.config('user.name', 'Mr. Robot')
74
- grepo.config('user.email', 'robot@example.com')
75
- end
76
- end
77
- else
78
- raise "Directory '#{dir}' already exist."
79
- end
71
+ mbrew.clone(url, dir)
80
72
  when 'init'
81
73
  opts = OptionParser.new do |opts|
82
74
  opts.banner = "Usage: mbrew #{command1} <dir>"
@@ -88,59 +80,11 @@ when 'init'
88
80
  exit 3
89
81
  end
90
82
  end
91
- opts.parse(ARGV)
83
+ args = opts.parse(ARGV)
84
+ dir = args.shift || '.'
92
85
 
93
- dir = ARGV.shift || '.'
94
- Dir.chdir(dir) do
95
- puts Dir.pwd
96
- if !Dir.exist?('.mbrew')
97
- Dir.mkdir('.mbrew')
98
- Dir.chdir('.mbrew') do
99
- Dir.mkdir('data')
100
- Dir.mkdir('bin')
101
- Dir.mkdir('index')
102
-
103
- Dir.chdir('bin') do
104
- File.open('push', 'w') do |file|
105
- file.chmod(0755)
106
-
107
- file.puts('#!/usr/bin/env bash')
108
- file.puts
109
- file.puts('SCRIPT_BASEDIR=$(dirname $0)')
110
- file.puts('RSYNC_BIN="rsync"')
111
- file.puts('RSYNC_OPTIONS="-vucr --delete --delete-excluded -h --progress --exclude=.DS_Store"')
112
- file.puts('RSYNC_REMOTE="user@remote:/path/to/public"')
113
- file.puts
114
- file.puts
115
- file.puts('cd $SCRIPT_BASEDIR/..')
116
- file.puts
117
- file.puts('# $RSYNC_BIN $RSYNC_OPTIONS index data $RSYNC_REMOTE')
118
- end
119
- end
120
-
121
- Dir.chdir('index') do
122
- grepo = Git.init('.')
123
- grepo.config('user.name', 'Mr. Robot')
124
- grepo.config('user.email', 'robot@example.com')
125
-
126
- File.write('.gitkeep', 'keep')
127
- grepo.add('.gitkeep')
128
-
129
- grepo.commit('Initial commit.')
130
- end
131
-
132
- staged_yaml = YAML::Store.new('staged.yml')
133
- staged_yaml.transaction do
134
- staged_yaml['files'] = []
135
- end
136
- end
137
- else
138
- raise "Directory '#{dir}' is already a mbrew library."
139
- end
140
- end
86
+ mbrew.init(dir)
141
87
  when 'add'
142
- raise 'FATAL ERROR: not a mbrew library.' if !Dir.exist?('.mbrew')
143
-
144
88
  options = {
145
89
  :recursive => false,
146
90
  }
@@ -161,46 +105,70 @@ when 'add'
161
105
  ARGV << '-h' if ARGV.count == 0
162
106
  paths = opts.parse(ARGV)
163
107
 
164
- file_pattern = '*.mp3'
165
- file_pattern = File.join('**', '*.mp3') if options[:recursive]
166
-
167
- files_staged = []
168
- Dir.chdir('.mbrew') do
169
- files_staged = YAML.load_file('staged.yml')['files']
108
+ mbrew.add(paths, options[:recursive])
109
+ when 'commit'
110
+ opts = OptionParser.new do |opts|
111
+ opts.banner = "Usage: mbrew #{command1}"
112
+ opts.separator('')
113
+
114
+ opts.on_tail('-h', '--help', 'Show this message.') do
115
+ puts opts
116
+ puts
117
+ exit 3
118
+ end
170
119
  end
120
+ opts.parse(ARGV)
171
121
 
172
- paths.each do |path|
173
- if File.exist?(path)
174
- if File.directory?(path)
175
- Dir.chdir(path) do
176
- Dir.glob(file_pattern).sort.each do |file_path|
177
- full_path = File.join(path, file_path)
178
- puts "Adding file '#{full_path}'"
179
- files_staged << full_path
180
- end
181
- end
182
- else
183
- puts "Adding file '#{path}'"
184
- files_staged << path
185
- end
186
- else
187
- $stderr.puts "WARNING: '#{path}' no such file or directory."
122
+ mbrew.commit
123
+ when 'status'
124
+ opts = OptionParser.new do |opts|
125
+ opts.banner = "Usage: mbrew #{command1}"
126
+ opts.separator('')
127
+
128
+ opts.on_tail('-h', '--help', 'Show this message.') do
129
+ puts opts
130
+ puts
131
+ exit 3
188
132
  end
189
133
  end
134
+ opts.parse(ARGV)
190
135
 
191
- files_staged.sort!.uniq!
136
+ mbrew.status
137
+ when 'list'
138
+ list = mbrew.list
192
139
 
193
- Dir.chdir('.mbrew') do
194
- staged_yaml = YAML::Store.new('staged.yml')
195
- staged_yaml.transaction do
196
- staged_yaml['files'] = files_staged
140
+ if list.count > 0
141
+ puts 'Available artists:'
142
+ puts
143
+ puts list
144
+ end
145
+ when 'info'
146
+ opts = OptionParser.new do |opts|
147
+ opts.banner = "Usage: mbrew #{command1} <names...>"
148
+ opts.separator('')
149
+
150
+ opts.on_tail('-h', '--help', 'Show this message.') do
151
+ puts opts
152
+ puts
153
+ exit 3
197
154
  end
198
155
  end
199
- when 'commit'
200
- raise 'FATAL ERROR: not a mbrew library.' if !Dir.exist?('.mbrew')
156
+ ARGV << '-h' if ARGV.count == 0
157
+ artist_names = opts.parse(ARGV)
201
158
 
159
+ mbrew.info(artist_names).each do |search_name, artist|
160
+ if artist[:songs] >= 1
161
+ puts "Artist: '#{search_name}'"
162
+ puts "\t Name: #{artist[:name]}"
163
+ puts "\t Songs: #{artist[:songs]}"
164
+ puts
165
+ else
166
+ puts "Artist: '#{search_name}' not found."
167
+ end
168
+ end
169
+ when 'search'
202
170
  opts = OptionParser.new do |opts|
203
- opts.banner = "Usage: mbrew #{command1}"
171
+ opts.banner = "Usage: mbrew #{command1} <names...>"
204
172
  opts.separator('')
205
173
 
206
174
  opts.on_tail('-h', '--help', 'Show this message.') do
@@ -209,142 +177,52 @@ when 'commit'
209
177
  exit 3
210
178
  end
211
179
  end
212
- opts.parse(ARGV)
180
+ ARGV << '-h' if ARGV.count == 0
181
+ artist_names = opts.parse(ARGV)
213
182
 
214
- files_staged = []
215
- Dir.chdir('.mbrew') do
216
- files_staged = YAML.load_file('staged.yml')['files']
217
- end
183
+ mbrew.search
218
184
 
219
- if files_staged.count >= 0
220
- files_staged.each do |src_file_path|
221
- if File.exist?(src_file_path)
222
-
223
-
224
- src_file_basename = File.basename(src_file_path)
225
- src_file_basename_hex = Digest::SHA256.hexdigest(src_file_basename)
226
- clone_file_basename = "#{src_file_basename_hex}.mp3"
227
- clone_file_path = ".mbrew/data/#{clone_file_basename}"
228
-
229
- FileUtils.cp(src_file_path, clone_file_path)
230
-
231
- src_file_hex = Digest::SHA256.file(clone_file_path).hexdigest
232
-
233
- dst_dir_path = "#{src_file_hex[0,2]}/#{src_file_hex[2,2]}/#{src_file_hex[4,2]}"
234
- dst_file_name = src_file_hex[6,58]
235
- gpg_file_name = "#{dst_file_name}.gpg"
236
- gpg_file_path = "#{dst_dir_path}/#{gpg_file_name}"
237
- yml_file_name = "#{dst_file_name}.yml"
238
- yml_file_path = "#{dst_dir_path}/#{yml_file_name}"
239
- gpg_exec = "gpg --no-tty --batch --passphrase supersecret2015 --cipher-algo AES256 -c -o '#{gpg_file_name}' '#{clone_file_basename}'"
240
-
241
- puts "src_file_basename: '#{src_file_basename}'"
242
- puts "src_file_basename_hex: '#{src_file_basename_hex}'"
243
- puts "clone_file_basename: '#{clone_file_basename}'"
244
- puts "clone_file_path: '#{clone_file_path}'"
245
- puts
246
- puts "src_file_hex: '#{src_file_hex}'"
247
- puts "dst_dir_path: '#{dst_dir_path}'"
248
- puts "dst_file_name: '#{dst_file_name}'"
249
- puts "gpg_file_name: '#{gpg_file_name}'"
250
- puts "gpg_file_path: '#{gpg_file_path}'"
251
- puts "yml_file_name: '#{yml_file_name}'"
252
- puts "yml_file_path: '#{yml_file_path}'"
253
- puts
254
- puts "gpg_exec: '#{gpg_exec}'"
255
- puts
256
-
257
- Dir.chdir('.mbrew') do
258
- mp3_tag = nil
259
-
260
- Dir.chdir('data') do
261
- FileUtils.mkdir_p(dst_dir_path) if !Dir.exist?(dst_dir_path)
262
- FileUtils.rm(gpg_file_path) if File.exist?(gpg_file_path)
263
-
264
- if !File.exist?(gpg_file_path)
265
- FileUtils.mv(clone_file_basename, dst_dir_path)
266
- Dir.chdir(dst_dir_path) do
267
- if !system(gpg_exec).nil?
268
- mp3_tag = ID3Lib::Tag.new(clone_file_basename)
269
- FileUtils.rm(clone_file_basename)
270
- else
271
- FileUtils.rm(clone_file_basename)
272
- raise 'FATAL ERROR: gpg failed.'
273
- end
274
- end
275
- else
276
- FileUtils.rm(clone_file_basename)
277
- raise "FATAL ERROR: '#{gpg_file_path}' file already exist."
278
- end
279
- end
280
-
281
- if !mp3_tag.nil?
282
- Dir.chdir('index') do
283
- FileUtils.mkdir_p(dst_dir_path) if !Dir.exist?(dst_dir_path)
284
-
285
- mp3_tag_artist = mp3_tag.artist.to_s.to_utf8
286
- mp3_tag_band = mp3_tag.band.to_s.to_utf8
287
- mp3_tag_composer = mp3_tag.composer.to_s.to_utf8
288
- mp3_tag_album = mp3_tag.album.to_s.to_utf8
289
-
290
- mp3_tag_title = mp3_tag.title
291
- mp3_tag_year = mp3_tag.year.to_i
292
-
293
- grepo = Git.open('.')
294
- grepo.config('user.name', 'Mr. Robot')
295
- grepo.config('user.email', 'robot@example.com')
296
-
297
- yaml_store = YAML::Store.new(yml_file_path)
298
- yaml_store.transaction do
299
- yaml_store['src'] = {
300
- 'file_path' => src_file_path,
301
- 'file_name' => src_file_basename,
302
- 'hash' => src_file_hex,
303
- }
304
- yaml_store['id3'] = {
305
- 'artist' => "#{mp3_tag_artist}",
306
- 'band' => "#{mp3_tag_band}",
307
- 'composer' => "#{mp3_tag_composer}",
308
- 'album' => "#{mp3_tag_album}",
309
- 'title' => "#{mp3_tag_title}",
310
- 'year' => mp3_tag_year,
311
- }
312
- end
313
-
314
- puts "composer: '#{mp3_tag_composer}'"
315
- puts "album: '#{mp3_tag_album}'"
316
-
317
- puts "Committing file '#{src_file_path}' ('#{mp3_tag_artist}' - '#{mp3_tag_title}')."
318
-
319
- begin
320
- grepo.add(yml_file_path)
321
- grepo.commit("New file: '#{yml_file_path}' ('#{mp3_tag_artist}' - '#{mp3_tag_title}')")
322
- rescue Exception => e
323
- end
324
-
325
- begin
326
- grepo.add('.')
327
- grepo.commit('Misc changes.')
328
- rescue Exception => e
329
- end
330
- end
331
- end
332
- end
333
- else
334
- $stderr.puts "WARNING: '#{file_path}' no such file."
335
- end
185
+ printf 'Search ...'
186
+ found_names = mbrew.search(artist_names)
187
+ puts ' done'
188
+ puts
189
+ if found_names.count > 0
190
+ puts 'Found:'
191
+ puts found_names
192
+ else
193
+ puts 'Nothing found.'
194
+ end
195
+ when 'install'
196
+ opts = OptionParser.new do |opts|
197
+ opts.banner = "Usage: mbrew #{command1} <names...>"
198
+ opts.separator('')
199
+
200
+ opts.on_tail('-h', '--help', 'Show this message.') do
201
+ puts opts
202
+ puts
203
+ exit 3
336
204
  end
337
205
  end
206
+ ARGV << '-h' if ARGV.count == 0
207
+ artist_names = opts.parse(ARGV)
338
208
 
339
- Dir.chdir('.mbrew') do
340
- staged_yaml = YAML::Store.new('staged.yml')
341
- staged_yaml.transaction do
342
- staged_yaml['files'] = []
209
+ mbrew.install(artist_names)
210
+ when 'uninstall'
211
+ opts = OptionParser.new do |opts|
212
+ opts.banner = "Usage: mbrew #{command1} <names...>"
213
+ opts.separator('')
214
+
215
+ opts.on_tail('-h', '--help', 'Show this message.') do
216
+ puts opts
217
+ puts
218
+ exit 3
343
219
  end
344
220
  end
345
- when 'status'
346
- raise 'FATAL ERROR: not a mbrew library.' if !Dir.exist?('.mbrew')
221
+ ARGV << '-h' if ARGV.count == 0
222
+ artist_names = opts.parse(ARGV)
347
223
 
224
+ mbrew.uninstall(artist_names)
225
+ when 'update'
348
226
  opts = OptionParser.new do |opts|
349
227
  opts.banner = "Usage: mbrew #{command1}"
350
228
  opts.separator('')
@@ -355,16 +233,23 @@ when 'status'
355
233
  exit 3
356
234
  end
357
235
  end
358
- opts.parse(ARGV)
236
+ ARGV << '-h' if ARGV.count == 0
237
+ artist_names = opts.parse(ARGV)
359
238
 
360
- Dir.chdir('.mbrew') do
361
- files_staged = YAML.load_file('staged.yml')['files']
362
- if files_staged.count > 0
363
- puts "Files staged for commit: #{files_staged.count}"
364
- puts
365
- puts Rainbow("\t" + (files_staged.join("\n\t"))).red
239
+ mbrew.update
240
+ when 'upgrade'
241
+ opts = OptionParser.new do |opts|
242
+ opts.banner = "Usage: mbrew #{command1}"
243
+ opts.separator('')
244
+
245
+ opts.on_tail('-h', '--help', 'Show this message.') do
246
+ puts opts
366
247
  puts
248
+ exit 3
367
249
  end
368
250
  end
369
- when 'list'
251
+ ARGV << '-h' if ARGV.count == 0
252
+ artist_names = opts.parse(ARGV)
253
+
254
+ mbrew.upgrade
370
255
  end
@@ -1,2 +1,3 @@
1
1
 
2
2
  require 'mbrew/version'
3
+ require 'mbrew/mbrew'
@@ -0,0 +1,461 @@
1
+
2
+ require 'uri'
3
+ require 'fileutils'
4
+ require 'git'
5
+ require 'yaml'
6
+ require 'yaml/store'
7
+ require 'digest/sha1'
8
+ require 'id3lib'
9
+ require 'thefox-ext'
10
+
11
+ module TheFox
12
+ module MBrew
13
+ class MBrew
14
+
15
+ def initialize(working_dir = '.')
16
+ working_dir = working_dir || '.'
17
+
18
+ @working_dir = File.realpath(working_dir)
19
+ @working_dir_pn = Pathname.new(@working_dir)
20
+
21
+ # puts "working_dir: '#{@working_dir}'"
22
+ end
23
+
24
+ def clone(ourl, dir = nil)
25
+ url = URI(url)
26
+ dir = dir ||
27
+ "#{url.host} #{url.path}"
28
+ .gsub('.', '-')
29
+ .gsub('/', ' ')
30
+ .strip
31
+ .gsub(/ +/, '-')
32
+
33
+ puts "url: '#{url}'"
34
+ puts "dir: '#{dir}'"
35
+
36
+ url_index = "#{url}/index"
37
+ url_index_git = "#{url_index}/.git"
38
+
39
+ if !Dir.exist?(dir)
40
+ puts "Cloning into library '#{dir}'..."
41
+
42
+ Dir.mkdir(dir)
43
+ Dir.chdir(dir) do
44
+ Dir.mkdir('.mbrew')
45
+ Dir.chdir('.mbrew') do
46
+ grepo = Git.clone(url_index_git, 'index')
47
+ grepo.config('user.name', 'Mr. Robot')
48
+ grepo.config('user.email', 'robot@example.com')
49
+
50
+ config_yml = YAML::Store.new('config.yml')
51
+ config_yml.transaction do
52
+ config_yml['mbrew'] = {
53
+ 'release_id' => TheFox::MBrew::RELEASE_ID,
54
+ 'version' => TheFox::MBrew::VERSION,
55
+ }
56
+ config_yml['origin'] = {
57
+ 'downstream' => "#{url}",
58
+ 'upstream' => nil,
59
+ }
60
+ end
61
+
62
+ installed_yml = YAML::Store.new('installed.yml')
63
+ installed_yml.transaction do
64
+ installed_yml['artists'] = []
65
+ end
66
+ end
67
+ end
68
+ else
69
+ raise "Directory '#{dir}' already exist."
70
+ end
71
+ end
72
+
73
+ def init(dir = '.')
74
+ Dir.chdir(dir) do
75
+ if !Dir.exist?('.mbrew')
76
+ Dir.mkdir('.mbrew', 0700)
77
+ Dir.chdir('.mbrew') do
78
+ Dir.mkdir('data')
79
+ Dir.mkdir('bin')
80
+ Dir.mkdir('index')
81
+
82
+ Dir.chdir('bin') do
83
+ File.open('push', 'w') do |file|
84
+ file.chmod(0755)
85
+
86
+ file.puts('#!/usr/bin/env bash')
87
+ file.puts
88
+ file.puts('SCRIPT_BASEDIR=$(dirname $0)')
89
+ file.puts('RSYNC_BIN="rsync"')
90
+ file.puts('RSYNC_OPTIONS="-vucr --delete --delete-excluded -h --progress --exclude=.DS_Store"')
91
+ file.puts('RSYNC_REMOTE="user@remote:/path/to/public"')
92
+ file.puts
93
+ file.puts
94
+ file.puts('cd $SCRIPT_BASEDIR/..')
95
+ file.puts
96
+ file.puts('# $RSYNC_BIN $RSYNC_OPTIONS index data $RSYNC_REMOTE')
97
+ end
98
+ end
99
+
100
+ Dir.chdir('index') do
101
+ grepo = Git.init('.')
102
+ grepo.config('user.name', 'Mr. Robot')
103
+ grepo.config('user.email', 'robot@example.com')
104
+
105
+ File.write('.gitkeep', 'keep')
106
+ grepo.add('.gitkeep')
107
+
108
+ grepo.commit('Initial commit.')
109
+ end
110
+ end
111
+ else
112
+ raise "Directory '#{dir}' is already a mbrew library."
113
+ end
114
+ end
115
+ end
116
+
117
+ def add(paths, recursive = false)
118
+ check_is_a_mbrew_lib
119
+ check_staged_file
120
+
121
+ file_pattern = '*.mp3'
122
+ file_pattern = File.join('**', '*.mp3') if recursive
123
+
124
+ files_staged = []
125
+ Dir.chdir(@working_dir) do
126
+ Dir.chdir('.mbrew') do
127
+ files_staged = YAML.load_file('staged.yml')['files']
128
+ end
129
+ end
130
+
131
+ paths.each do |path|
132
+ if File.exist?(path)
133
+ if File.directory?(path)
134
+ Dir.glob(File.join(path, file_pattern)).sort.each do |file_path|
135
+ real_path = File.realpath(file_path)
136
+ files_staged << real_path
137
+
138
+ puts "Adding file '#{file_path}'."
139
+ end
140
+ else
141
+ real_path = File.realpath(path)
142
+ files_staged << real_path
143
+
144
+ puts "Adding file '#{path}'."
145
+ end
146
+ else
147
+ $stderr.puts "WARNING: '#{path}' no such file or directory."
148
+ end
149
+ end
150
+
151
+ files_staged.sort!.uniq!
152
+
153
+ Dir.chdir(@working_dir) do
154
+ Dir.chdir('.mbrew') do
155
+ staged_yml = YAML::Store.new('staged.yml')
156
+ staged_yml.transaction do
157
+ staged_yml['files'] = files_staged
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ def commit
164
+ check_is_a_mbrew_lib
165
+ check_staged_file
166
+
167
+ Dir.chdir(@working_dir) do
168
+ Dir.chdir('.mbrew') do
169
+ files_staged = YAML.load_file('staged.yml')['files']
170
+ if files_staged.count >= 0
171
+ files_staged.each do |src_file_path|
172
+ if File.exist?(src_file_path)
173
+
174
+ src_file_relative_path = Pathname.new(src_file_path).relative_path_from(@working_dir_pn).to_s
175
+ src_file_basename = File.basename(src_file_path)
176
+ src_file_basename_hex = Digest::SHA256.hexdigest(src_file_basename)
177
+ src_file_relative_path_hex = Digest::SHA256.hexdigest(src_file_relative_path)
178
+ clone_file_basename = "#{src_file_basename_hex}.mp3"
179
+ clone_file_path = "data/#{clone_file_basename}"
180
+
181
+ FileUtils.cp(src_file_path, clone_file_path)
182
+
183
+ src_file_content_hex = Digest::SHA256.file(clone_file_path).hexdigest
184
+
185
+ dst_dir_path = "#{src_file_relative_path_hex[0,2]}/#{src_file_relative_path_hex[2,2]}/#{src_file_relative_path_hex[4,2]}"
186
+ dst_file_name = src_file_relative_path_hex[6,58]
187
+ gpg_file_name = "#{dst_file_name}.gpg"
188
+ gpg_file_path = "#{dst_dir_path}/#{gpg_file_name}"
189
+ yml_file_name = "#{dst_file_name}.yml"
190
+ yml_file_path = "#{dst_dir_path}/#{yml_file_name}"
191
+ gpg_exec = "gpg --no-tty --batch --passphrase supersecret2015 --cipher-algo AES256 -c -o '#{gpg_file_name}' '#{clone_file_basename}'"
192
+
193
+ puts "src_file_path: '#{src_file_path}'"
194
+ puts "src_file_relative_path: '#{src_file_relative_path}'"
195
+ puts "src_file_relative_path_hex: '#{src_file_relative_path_hex}'"
196
+
197
+ puts "src_file_basename: '#{src_file_basename}'"
198
+ puts "src_file_basename_hex: '#{src_file_basename_hex}'"
199
+
200
+ puts "clone_file_basename: '#{clone_file_basename}'"
201
+ puts "clone_file_path: '#{clone_file_path}'"
202
+ puts
203
+ puts "src_file_content_hex: '#{src_file_content_hex}'"
204
+ puts "dst_dir_path: '#{dst_dir_path}'"
205
+ puts "dst_file_name: '#{dst_file_name}'"
206
+ puts "gpg_file_name: '#{gpg_file_name}'"
207
+ puts "gpg_file_path: '#{gpg_file_path}'"
208
+ puts "yml_file_name: '#{yml_file_name}'"
209
+ puts "yml_file_path: '#{yml_file_path}'"
210
+ puts
211
+ puts "gpg_exec: '#{gpg_exec}'"
212
+ puts
213
+
214
+ mp3_tag = nil
215
+
216
+ Dir.chdir('data') do
217
+ FileUtils.mkdir_p(dst_dir_path) if !Dir.exist?(dst_dir_path)
218
+ FileUtils.rm(gpg_file_path) if File.exist?(gpg_file_path)
219
+
220
+ if !File.exist?(gpg_file_path)
221
+ FileUtils.mv(clone_file_basename, dst_dir_path)
222
+ Dir.chdir(dst_dir_path) do
223
+ if !system(gpg_exec).nil?
224
+ mp3_tag = ID3Lib::Tag.new(clone_file_basename)
225
+ FileUtils.rm(clone_file_basename)
226
+ else
227
+ FileUtils.rm(clone_file_basename)
228
+ raise 'FATAL ERROR: gpg failed.'
229
+ end
230
+ end
231
+ else
232
+ FileUtils.rm(clone_file_basename)
233
+ raise "FATAL ERROR: '#{gpg_file_path}' file already exist."
234
+ end
235
+ end
236
+
237
+ if !mp3_tag.nil?
238
+ Dir.chdir('index') do
239
+ FileUtils.mkdir_p(dst_dir_path) if !Dir.exist?(dst_dir_path)
240
+
241
+ mp3_tag_artist = mp3_tag.artist.to_s.to_utf8
242
+ mp3_tag_band = mp3_tag.band.to_s.to_utf8
243
+ mp3_tag_composer = mp3_tag.composer.to_s.to_utf8
244
+ mp3_tag_album = mp3_tag.album.to_s.to_utf8
245
+ mp3_tag_title = mp3_tag.title.to_s.to_utf8
246
+ mp3_tag_year = mp3_tag.year.to_s.to_utf8
247
+
248
+ grepo = Git.open('.')
249
+ grepo.config('user.name', 'Mr. Robot')
250
+ grepo.config('user.email', 'robot@example.com')
251
+
252
+ yml = YAML::Store.new(yml_file_path)
253
+ yml.transaction do
254
+ yml['src'] = {
255
+ 'file' => {
256
+ 'path' => src_file_relative_path,
257
+ 'path_hash' => src_file_relative_path_hex,
258
+ 'name' => src_file_basename,
259
+ 'content_hash' => src_file_content_hex,
260
+ },
261
+ }
262
+ yml['id3'] = {
263
+ 'artist' => mp3_tag_artist,
264
+ 'band' => mp3_tag_band,
265
+ 'composer' => mp3_tag_composer,
266
+ 'album' => mp3_tag_album,
267
+ 'title' => mp3_tag_title,
268
+ 'year' => mp3_tag_year,
269
+ }
270
+ end
271
+
272
+ # puts "composer: '#{mp3_tag_composer}'"
273
+ # puts "album: '#{mp3_tag_album}'"
274
+
275
+ puts "Committing file '#{src_file_relative_path}'."
276
+ puts "\t'#{mp3_tag_artist}' - '#{mp3_tag_title}'"
277
+
278
+ begin
279
+ grepo.add(yml_file_path)
280
+ grepo.commit("New file: '#{yml_file_path}' ('#{mp3_tag_artist}' - '#{mp3_tag_title}')")
281
+ rescue Exception => e
282
+ end
283
+
284
+ begin
285
+ grepo.add('.')
286
+ grepo.commit('Misc changes.')
287
+ rescue Exception => e
288
+ end
289
+
290
+ system('git update-server-info')
291
+ end
292
+ end
293
+ else
294
+ $stderr.puts "WARNING: '#{file_path}' no such file."
295
+ end
296
+ end
297
+ end
298
+
299
+ staged_yml = YAML::Store.new('staged.yml')
300
+ staged_yml.transaction do
301
+ staged_yml['files'] = []
302
+ end
303
+ end
304
+ end
305
+ end
306
+
307
+ def status
308
+ check_is_a_mbrew_lib
309
+ check_staged_file
310
+
311
+ cwd = Dir.pwd
312
+ cwd_pn = Pathname.new(cwd)
313
+
314
+ Dir.chdir(@working_dir) do
315
+ Dir.chdir('.mbrew') do
316
+ files_staged = YAML.load_file('staged.yml')['files']
317
+ if files_staged.count > 0
318
+ paths_s = files_staged
319
+ .map{ |p| Pathname.new(p).relative_path_from(cwd_pn).to_s }
320
+ .join("\n\t")
321
+
322
+ puts "Files staged for commit: #{files_staged.count}"
323
+ puts
324
+ puts Rainbow("\t" + (paths_s)).red
325
+ puts
326
+ end
327
+
328
+ Dir.chdir('index') do
329
+ # grepo = Git.open('.')
330
+ # grepo.config('user.name', 'Mr. Robot')
331
+ # grepo.config('user.email', 'robot@example.com')
332
+ # grepo.update_server_info
333
+
334
+ system('git update-server-info')
335
+ end
336
+ end
337
+ end
338
+ end
339
+
340
+ def list
341
+ check_is_a_mbrew_lib
342
+
343
+ Dir.chdir(@working_dir) do
344
+ Dir.chdir('.mbrew/index') do
345
+ Dir.glob('**/*.yml').map{ |yml_file_path|
346
+ yml = YAML.load_file(yml_file_path)
347
+ yml['id3']['artist']
348
+ }.uniq.sort
349
+ end
350
+ end
351
+ end
352
+
353
+ def info(artist_names = [])
354
+ check_is_a_mbrew_lib
355
+
356
+ Dir.chdir(@working_dir) do
357
+ Dir.chdir('.mbrew/index') do
358
+ infos = {}
359
+
360
+ artist_names.each do |artist_name|
361
+ artist_name_dc = artist_name.downcase
362
+ artist_found = Dir.glob('**/*.yml').map{ |yml_file_path|
363
+ yml = YAML.load_file(yml_file_path)
364
+ yml['id3']['artist']
365
+ }
366
+ .keep_if{ |a| a.downcase == artist_name_dc}
367
+ .group_by{ |a| a }
368
+ .map{ |a,v| [a, v.count] }
369
+ .to_h
370
+
371
+ if artist_found.count >= 1
372
+ infos[artist_name] = {
373
+ :name => artist_found.keys.join,
374
+ :songs => artist_found.values.join,
375
+ }
376
+ else
377
+ infos[artist_name] = {
378
+ :name => nil,
379
+ :songs => 0,
380
+ }
381
+ end
382
+ end
383
+
384
+ infos
385
+ end
386
+ end
387
+ end
388
+
389
+ def search(artist_names = [])
390
+ check_is_a_mbrew_lib
391
+
392
+ Dir.chdir(@working_dir) do
393
+ Dir.chdir('.mbrew/index') do
394
+
395
+ found_names = []
396
+ artist_names.each do |artist_name|
397
+ artist_name_rx = Regexp.new(artist_name, Regexp::IGNORECASE)
398
+
399
+ found_names += Dir.glob('**/*.yml').map{ |yml_file_path|
400
+ yml = YAML.load_file(yml_file_path)
401
+ yml['id3']['artist']
402
+ }
403
+ .grep(artist_name_rx)
404
+ .uniq
405
+ end
406
+
407
+ found_names.uniq.sort
408
+ end
409
+ end
410
+ end
411
+
412
+ def install(artist_names)
413
+ check_is_a_mbrew_lib
414
+
415
+ Dir.chdir(@working_dir) do
416
+ Dir.chdir('.mbrew/index') do
417
+ p Dir.glob('**/*.yml').map{ |yml_file_path|
418
+ yml = YAML.load_file(yml_file_path)
419
+ yml['id3']['artist']
420
+ }
421
+ end
422
+ end
423
+ end
424
+
425
+ def uninstall(artist_names)
426
+ check_is_a_mbrew_lib
427
+
428
+ end
429
+
430
+ def update
431
+ check_is_a_mbrew_lib
432
+
433
+ end
434
+
435
+ def upgrade
436
+ check_is_a_mbrew_lib
437
+
438
+ end
439
+
440
+ private
441
+
442
+ def check_is_a_mbrew_lib
443
+ raise 'not a mbrew library.' if @working_dir.nil?
444
+ end
445
+
446
+ def check_staged_file
447
+ Dir.chdir(@working_dir) do
448
+ Dir.chdir('.mbrew') do
449
+ if !File.exist?('staged.yml')
450
+ staged_yml = YAML::Store.new('staged.yml')
451
+ staged_yml.transaction do
452
+ staged_yml['files'] = []
453
+ end
454
+ end
455
+ end
456
+ end
457
+ end
458
+
459
+ end
460
+ end
461
+ end
@@ -1,7 +1,9 @@
1
1
 
2
2
  module TheFox
3
3
  module MBrew
4
- VERSION = '0.1.0-dev.1'
5
- DATE = '2015-12-07'
4
+ RELEASE_ID = 0
5
+ VERSION = '0.1.0-dev.2'
6
+ DATE = '2015-12-09'
7
+ HOMEPAGE = 'https://github.com/TheFox/mbrew'
6
8
  end
7
9
  end
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
 
15
15
  spec.summary = %q{MusicBrew}
16
16
  spec.description = %q{A combination of Spotify and Homebrew.}
17
- spec.homepage = 'https://github.com/TheFox/homemusic'
17
+ spec.homepage = TheFox::MBrew::HOMEPAGE
18
18
  spec.license = 'GPL-3.0'
19
19
 
20
20
  spec.files = `git ls-files -z`.split("\x0").reject{ |f| f.match(%r{^(test|spec|features)/}) }
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.required_ruby_version = '>=2.2.0'
25
25
 
26
26
  spec.requirements << 'GPG'
27
+ spec.requirements << 'Git'
27
28
 
28
29
  spec.add_development_dependency 'bundler', '~>1.10'
29
30
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mbrew
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.dev.1
4
+ version: 0.1.0.pre.dev.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-07 00:00:00.000000000 Z
11
+ date: 2015-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -93,12 +93,14 @@ files:
93
93
  - Makefile
94
94
  - Makefile.common
95
95
  - README.md
96
+ - bin/dev
96
97
  - bin/mbrew
97
98
  - lib/mbrew.rb
99
+ - lib/mbrew/mbrew.rb
98
100
  - lib/mbrew/version.rb
99
101
  - mbrew.gemspec
100
102
  - mbrew.sublime-project
101
- homepage: https://github.com/TheFox/homemusic
103
+ homepage: https://github.com/TheFox/mbrew
102
104
  licenses:
103
105
  - GPL-3.0
104
106
  metadata: {}
@@ -118,6 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
120
  version: 1.3.1
119
121
  requirements:
120
122
  - GPG
123
+ - Git
121
124
  rubyforge_project:
122
125
  rubygems_version: 2.4.7
123
126
  signing_key: