mbrew 0.1.0.pre.dev.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/README.md +2 -17
- data/bin/mbrew +31 -9
- data/lib/mbrew/mbrew.rb +319 -27
- data/lib/mbrew/version.rb +2 -2
- data/mbrew.gemspec +2 -1
- data/mbrew.sublime-project +6 -0
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fbae6a20b39530ec7a35b85b250dec35668e4ec
|
4
|
+
data.tar.gz: 566246f43f9ce9df0885818e10109c2b2ca4751e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54507e3b48b10e006aa566622161f45d74db92e2ed48c192c325028e7e48b4f9453eefcdb313df500a7a65e6ce11e5288f5edeae03b5758a0b523856d3c71e10
|
7
|
+
data.tar.gz: 1a663e9ac363135037a8d6c8623ec4667f6dd22e288538513f64546e34581b96a30c797d1458a8127e0e9923809c37189e785b95161ff23c582613282cb100f7
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mbrew (0.1.0.pre.dev.
|
4
|
+
mbrew (0.1.0.pre.dev.3)
|
5
5
|
git (~> 1.2)
|
6
|
+
highline (~> 1.7)
|
6
7
|
id3lib-ruby (~> 0.6)
|
7
8
|
rainbow (~> 2.0)
|
8
9
|
thefox-ext (~> 1.0)
|
@@ -11,6 +12,7 @@ GEM
|
|
11
12
|
remote: https://rubygems.org/
|
12
13
|
specs:
|
13
14
|
git (1.2.9.1)
|
15
|
+
highline (1.7.8)
|
14
16
|
id3lib-ruby (0.6.0)
|
15
17
|
rainbow (2.0.0)
|
16
18
|
thefox-ext (1.1.0)
|
data/README.md
CHANGED
@@ -1,25 +1,10 @@
|
|
1
1
|
# MusicBrew
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
## Install
|
6
|
-
|
7
|
-
The preferred method of installation is via RubyGems.org:
|
8
|
-
<https://rubygems.org/gems/mbrew>
|
9
|
-
|
10
|
-
gem install mbrew
|
11
|
-
|
12
|
-
or via `Gemfile`:
|
13
|
-
|
14
|
-
gem 'mbrew', '~>0.1.0'
|
15
|
-
|
16
|
-
Use it in your sources:
|
17
|
-
|
18
|
-
require 'mbrew'
|
3
|
+
MusicBrew is a combination of Spotify and [Homebrew](http://brew.sh/). Like a [package manager](https://en.wikipedia.org/wiki/Package_manager) for software but for music. It's made to use it via [comand-line](https://en.wikipedia.org/wiki/Command-line_interface). You can install all songs by a specified band, for example from ABBA via `music install ABBA`. The .mp3 files will be downloaded from a central server to your local music collection. The search acts like on a traditional package manager, for example via `music search AC/DC`. Like on Homebrew, each song file gets a *formula*/meta file. These files will be searched locally when the search command is used. On `music update` all meta files will be updated through Git. The `music upgrade` command is used to upgrade all existing artists. New songs will be downloaded. Since it's not legal in most of the countries on earth to copy and distribute copyright protected music it's highly recommended to encrypt the .mp3 files. This will be done with the best encryption software ever been made: [GnuPG](https://gnupg.org/). Beside the aspect of the copyright there is also the aspect to encrypt your files when using blanc HTTP (instead of HTTPS).
|
19
4
|
|
20
5
|
## Documentation
|
21
6
|
|
22
|
-
|
7
|
+
For all kinds of documentation see [`mbrew(1)`](http://mbrew.fox21.at/man/mbrew.1.html).
|
23
8
|
|
24
9
|
## License
|
25
10
|
Copyright (C) 2015 Christian Mayer <http://fox21.at>
|
data/bin/mbrew
CHANGED
@@ -17,14 +17,17 @@ if ARGV.count == 0
|
|
17
17
|
puts 'Commands:'
|
18
18
|
puts "\t clone"
|
19
19
|
puts "\t init"
|
20
|
+
#puts "\t push"
|
20
21
|
puts "\t add"
|
21
22
|
puts "\t commit"
|
22
23
|
puts "\t status"
|
23
24
|
puts "\t list"
|
24
|
-
puts "\t search"
|
25
25
|
puts "\t info"
|
26
|
+
puts "\t search"
|
26
27
|
puts "\t install"
|
27
28
|
puts "\t uninstall"
|
29
|
+
puts "\t update"
|
30
|
+
puts "\t upgrade"
|
28
31
|
puts
|
29
32
|
exit 3
|
30
33
|
end
|
@@ -84,6 +87,7 @@ when 'init'
|
|
84
87
|
dir = args.shift || '.'
|
85
88
|
|
86
89
|
mbrew.init(dir)
|
90
|
+
when 'push'
|
87
91
|
when 'add'
|
88
92
|
options = {
|
89
93
|
:recursive => false,
|
@@ -135,11 +139,29 @@ when 'status'
|
|
135
139
|
|
136
140
|
mbrew.status
|
137
141
|
when 'list'
|
138
|
-
|
142
|
+
options = {
|
143
|
+
:files => false,
|
144
|
+
}
|
145
|
+
opts = OptionParser.new do |opts|
|
146
|
+
opts.banner = "Usage: mbrew #{command1}"
|
147
|
+
opts.separator('')
|
148
|
+
|
149
|
+
opts.on('-f', '--files', 'List files are available by the index.') do |v|
|
150
|
+
options[:files] = true
|
151
|
+
end
|
152
|
+
|
153
|
+
opts.on_tail('-h', '--help', 'Show this message.') do
|
154
|
+
puts opts
|
155
|
+
puts
|
156
|
+
exit 3
|
157
|
+
end
|
158
|
+
end
|
159
|
+
#ARGV << '-h' if ARGV.count == 0
|
160
|
+
opts.parse(ARGV)
|
161
|
+
|
162
|
+
list = mbrew.list(options[:files])
|
139
163
|
|
140
164
|
if list.count > 0
|
141
|
-
puts 'Available artists:'
|
142
|
-
puts
|
143
165
|
puts list
|
144
166
|
end
|
145
167
|
when 'info'
|
@@ -157,7 +179,7 @@ when 'info'
|
|
157
179
|
artist_names = opts.parse(ARGV)
|
158
180
|
|
159
181
|
mbrew.info(artist_names).each do |search_name, artist|
|
160
|
-
if artist[:songs]
|
182
|
+
if artist[:songs] > 0
|
161
183
|
puts "Artist: '#{search_name}'"
|
162
184
|
puts "\t Name: #{artist[:name]}"
|
163
185
|
puts "\t Songs: #{artist[:songs]}"
|
@@ -233,8 +255,8 @@ when 'update'
|
|
233
255
|
exit 3
|
234
256
|
end
|
235
257
|
end
|
236
|
-
ARGV << '-h' if ARGV.count == 0
|
237
|
-
|
258
|
+
# ARGV << '-h' if ARGV.count == 0
|
259
|
+
opts.parse(ARGV)
|
238
260
|
|
239
261
|
mbrew.update
|
240
262
|
when 'upgrade'
|
@@ -248,8 +270,8 @@ when 'upgrade'
|
|
248
270
|
exit 3
|
249
271
|
end
|
250
272
|
end
|
251
|
-
ARGV << '-h' if ARGV.count == 0
|
252
|
-
|
273
|
+
# ARGV << '-h' if ARGV.count == 0
|
274
|
+
opts.parse(ARGV)
|
253
275
|
|
254
276
|
mbrew.upgrade
|
255
277
|
end
|
data/lib/mbrew/mbrew.rb
CHANGED
@@ -6,6 +6,8 @@ require 'yaml'
|
|
6
6
|
require 'yaml/store'
|
7
7
|
require 'digest/sha1'
|
8
8
|
require 'id3lib'
|
9
|
+
require 'highline/import'
|
10
|
+
require 'net/http'
|
9
11
|
require 'thefox-ext'
|
10
12
|
|
11
13
|
module TheFox
|
@@ -17,11 +19,14 @@ module TheFox
|
|
17
19
|
|
18
20
|
@working_dir = File.realpath(working_dir)
|
19
21
|
@working_dir_pn = Pathname.new(@working_dir)
|
22
|
+
@dotmbrew_dir = "#{@working_dir}/.mbrew"
|
23
|
+
@config = YAML.load_file("#{@dotmbrew_dir}/config.yml")
|
20
24
|
|
21
25
|
# puts "working_dir: '#{@working_dir}'"
|
26
|
+
# puts "config: '#{@config}'"
|
22
27
|
end
|
23
28
|
|
24
|
-
def clone(
|
29
|
+
def clone(url, dir = nil)
|
25
30
|
url = URI(url)
|
26
31
|
dir = dir ||
|
27
32
|
"#{url.host} #{url.path}"
|
@@ -107,6 +112,18 @@ module TheFox
|
|
107
112
|
|
108
113
|
grepo.commit('Initial commit.')
|
109
114
|
end
|
115
|
+
|
116
|
+
config_yml = YAML::Store.new('config.yml')
|
117
|
+
config_yml.transaction do
|
118
|
+
config_yml['mbrew'] = {
|
119
|
+
'release_id' => TheFox::MBrew::RELEASE_ID,
|
120
|
+
'version' => TheFox::MBrew::VERSION,
|
121
|
+
}
|
122
|
+
config_yml['origin'] = {
|
123
|
+
'downstream' => nil,
|
124
|
+
'upstream' => nil,
|
125
|
+
}
|
126
|
+
end
|
110
127
|
end
|
111
128
|
else
|
112
129
|
raise "Directory '#{dir}' is already a mbrew library."
|
@@ -114,6 +131,10 @@ module TheFox
|
|
114
131
|
end
|
115
132
|
end
|
116
133
|
|
134
|
+
def push
|
135
|
+
|
136
|
+
end
|
137
|
+
|
117
138
|
def add(paths, recursive = false)
|
118
139
|
check_is_a_mbrew_lib
|
119
140
|
check_staged_file
|
@@ -166,12 +187,17 @@ module TheFox
|
|
166
187
|
|
167
188
|
Dir.chdir(@working_dir) do
|
168
189
|
Dir.chdir('.mbrew') do
|
190
|
+
grepo = Git.open('index')
|
191
|
+
grepo.config('user.name', 'Mr. Robot')
|
192
|
+
grepo.config('user.email', 'robot@example.com')
|
193
|
+
|
169
194
|
files_staged = YAML.load_file('staged.yml')['files']
|
170
195
|
if files_staged.count >= 0
|
171
196
|
files_staged.each do |src_file_path|
|
172
197
|
if File.exist?(src_file_path)
|
173
198
|
|
174
199
|
src_file_relative_path = Pathname.new(src_file_path).relative_path_from(@working_dir_pn).to_s
|
200
|
+
src_file_relative_dir = File.dirname(src_file_relative_path)
|
175
201
|
src_file_basename = File.basename(src_file_path)
|
176
202
|
src_file_basename_hex = Digest::SHA256.hexdigest(src_file_basename)
|
177
203
|
src_file_relative_path_hex = Digest::SHA256.hexdigest(src_file_relative_path)
|
@@ -182,17 +208,18 @@ module TheFox
|
|
182
208
|
|
183
209
|
src_file_content_hex = Digest::SHA256.file(clone_file_path).hexdigest
|
184
210
|
|
185
|
-
dst_dir_path = "#{src_file_relative_path_hex[0
|
186
|
-
dst_file_name = src_file_relative_path_hex[6
|
211
|
+
dst_dir_path = "#{src_file_relative_path_hex[0..1]}/#{src_file_relative_path_hex[2..3]}/#{src_file_relative_path_hex[4..5]}"
|
212
|
+
dst_file_name = src_file_relative_path_hex[6..-1]
|
187
213
|
gpg_file_name = "#{dst_file_name}.gpg"
|
188
214
|
gpg_file_path = "#{dst_dir_path}/#{gpg_file_name}"
|
189
215
|
yml_file_name = "#{dst_file_name}.yml"
|
190
216
|
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}'"
|
217
|
+
gpg_exec = "LC_ALL=C gpg --no-tty --batch --passphrase supersecret2015 --cipher-algo AES256 -c -o '#{gpg_file_name}' '#{clone_file_basename}'"
|
192
218
|
|
193
219
|
puts "src_file_path: '#{src_file_path}'"
|
194
220
|
puts "src_file_relative_path: '#{src_file_relative_path}'"
|
195
221
|
puts "src_file_relative_path_hex: '#{src_file_relative_path_hex}'"
|
222
|
+
puts "src_file_relative_dir: '#{src_file_relative_dir}'"
|
196
223
|
|
197
224
|
puts "src_file_basename: '#{src_file_basename}'"
|
198
225
|
puts "src_file_basename_hex: '#{src_file_basename_hex}'"
|
@@ -245,9 +272,7 @@ module TheFox
|
|
245
272
|
mp3_tag_title = mp3_tag.title.to_s.to_utf8
|
246
273
|
mp3_tag_year = mp3_tag.year.to_s.to_utf8
|
247
274
|
|
248
|
-
|
249
|
-
grepo.config('user.name', 'Mr. Robot')
|
250
|
-
grepo.config('user.email', 'robot@example.com')
|
275
|
+
|
251
276
|
|
252
277
|
yml = YAML::Store.new(yml_file_path)
|
253
278
|
yml.transaction do
|
@@ -256,6 +281,7 @@ module TheFox
|
|
256
281
|
'path' => src_file_relative_path,
|
257
282
|
'path_hash' => src_file_relative_path_hex,
|
258
283
|
'name' => src_file_basename,
|
284
|
+
'dir' => src_file_relative_dir,
|
259
285
|
'content_hash' => src_file_content_hex,
|
260
286
|
},
|
261
287
|
}
|
@@ -277,17 +303,9 @@ module TheFox
|
|
277
303
|
|
278
304
|
begin
|
279
305
|
grepo.add(yml_file_path)
|
280
|
-
grepo.commit("
|
306
|
+
grepo.commit("Yml file: '#{yml_file_path}' ('#{mp3_tag_artist}' - '#{mp3_tag_title}')")
|
281
307
|
rescue Exception => e
|
282
308
|
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
309
|
end
|
292
310
|
end
|
293
311
|
else
|
@@ -296,6 +314,16 @@ module TheFox
|
|
296
314
|
end
|
297
315
|
end
|
298
316
|
|
317
|
+
Dir.chdir('index') do
|
318
|
+
begin
|
319
|
+
grepo.add('.')
|
320
|
+
grepo.commit('Misc changes.')
|
321
|
+
rescue Exception => e
|
322
|
+
end
|
323
|
+
|
324
|
+
system('git update-server-info')
|
325
|
+
end
|
326
|
+
|
299
327
|
staged_yml = YAML::Store.new('staged.yml')
|
300
328
|
staged_yml.transaction do
|
301
329
|
staged_yml['files'] = []
|
@@ -337,15 +365,22 @@ module TheFox
|
|
337
365
|
end
|
338
366
|
end
|
339
367
|
|
340
|
-
def list
|
368
|
+
def list(files = false)
|
341
369
|
check_is_a_mbrew_lib
|
342
370
|
|
343
371
|
Dir.chdir(@working_dir) do
|
344
372
|
Dir.chdir('.mbrew/index') do
|
345
|
-
|
346
|
-
yml
|
347
|
-
|
348
|
-
|
373
|
+
if files
|
374
|
+
Dir.glob('**/*.yml').map{ |yml_file_path|
|
375
|
+
yml = YAML.load_file(yml_file_path)
|
376
|
+
yml['src']['file']['path']
|
377
|
+
}.sort
|
378
|
+
else
|
379
|
+
Dir.glob('**/*.yml').map{ |yml_file_path|
|
380
|
+
yml = YAML.load_file(yml_file_path)
|
381
|
+
yml['id3']['artist']
|
382
|
+
}.uniq.sort
|
383
|
+
end
|
349
384
|
end
|
350
385
|
end
|
351
386
|
end
|
@@ -371,7 +406,7 @@ module TheFox
|
|
371
406
|
if artist_found.count >= 1
|
372
407
|
infos[artist_name] = {
|
373
408
|
:name => artist_found.keys.join,
|
374
|
-
:songs => artist_found.values.join,
|
409
|
+
:songs => artist_found.values.join.to_i,
|
375
410
|
}
|
376
411
|
else
|
377
412
|
infos[artist_name] = {
|
@@ -411,13 +446,35 @@ module TheFox
|
|
411
446
|
|
412
447
|
def install(artist_names)
|
413
448
|
check_is_a_mbrew_lib
|
449
|
+
check_installed_file
|
414
450
|
|
415
451
|
Dir.chdir(@working_dir) do
|
416
|
-
Dir.chdir('.mbrew
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
452
|
+
Dir.chdir('.mbrew') do
|
453
|
+
Dir.mkdir('tmp') if !Dir.exist?('tmp')
|
454
|
+
|
455
|
+
Dir.chdir('index') do
|
456
|
+
file_paths = Dir.glob('**/*.yml')
|
457
|
+
yml_files = file_paths
|
458
|
+
.map{ |yml_file_path|
|
459
|
+
yml = YAML.load_file(yml_file_path)
|
460
|
+
[yml_file_path, {
|
461
|
+
'path' => yml['src']['file']['path'],
|
462
|
+
'artist' => yml['id3']['artist'],
|
463
|
+
}]
|
464
|
+
}
|
465
|
+
.to_h
|
466
|
+
.keep_if{ |yml_file_path, yml| artist_names.include?(yml['artist']) }
|
467
|
+
|
468
|
+
puts "The following files will be INSTALLED (#{yml_files.count}):"
|
469
|
+
puts
|
470
|
+
puts yml_files.values.map{ |yml| yml['path'] }.sort
|
471
|
+
puts
|
472
|
+
res = ask('Do it? [Yn] ').strip.downcase
|
473
|
+
res = 'y' if res == ''
|
474
|
+
if res == 'y'
|
475
|
+
install_files(yml_files.keys)
|
476
|
+
end
|
477
|
+
end
|
421
478
|
end
|
422
479
|
end
|
423
480
|
end
|
@@ -425,16 +482,123 @@ module TheFox
|
|
425
482
|
def uninstall(artist_names)
|
426
483
|
check_is_a_mbrew_lib
|
427
484
|
|
485
|
+
Dir.chdir(@working_dir) do
|
486
|
+
Dir.chdir('.mbrew') do
|
487
|
+
installed_artists = YAML.load_file('installed.yml')['artists']
|
488
|
+
|
489
|
+
Dir.chdir('index') do
|
490
|
+
file_paths = Dir.glob('**/*.yml')
|
491
|
+
yml_files = file_paths
|
492
|
+
.map{ |yml_file_path| YAML.load_file(yml_file_path) }
|
493
|
+
.keep_if{ |yml| artist_names.include?(yml['id3']['artist']) }
|
494
|
+
|
495
|
+
puts 'The following files will be REMOVED:'
|
496
|
+
puts
|
497
|
+
puts yml_files.map{ |yml| yml['src']['file']['path'] }.sort
|
498
|
+
puts
|
499
|
+
res = ask('Do it? [yN] ').strip.downcase
|
500
|
+
if res == 'y'
|
501
|
+
puts
|
502
|
+
|
503
|
+
Dir.chdir('../..') do
|
504
|
+
printf 'Deleting file ...'
|
505
|
+
yml_files.map{ |yml| yml['src']['file']['path'] }.uniq.sort{ |d| d.length }.reverse.each do |path|
|
506
|
+
begin
|
507
|
+
FileUtils.rm(path)
|
508
|
+
rescue Exception => e
|
509
|
+
begin
|
510
|
+
FileUtils.rm(path)
|
511
|
+
rescue Exception => e
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
puts ' done'
|
516
|
+
|
517
|
+
dirs = yml_files.map{ |yml| yml['src']['file']['dir'] }.uniq.sort{ |d| d.length }.reverse
|
518
|
+
|
519
|
+
printf 'Deleting directories ...'
|
520
|
+
dirs.each do |path|
|
521
|
+
begin
|
522
|
+
FileUtils.rm("#{path}/.DS_Store")
|
523
|
+
rescue Exception => e
|
524
|
+
end
|
525
|
+
|
526
|
+
FileUtils.rmdir(path)
|
527
|
+
end
|
528
|
+
puts ' done'
|
529
|
+
|
530
|
+
end
|
531
|
+
|
532
|
+
installed_artists -= yml_files.map{ |yml| yml['id3']['artist'] }.uniq
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
printf 'Update index ...'
|
537
|
+
installed_yml = YAML::Store.new('installed.yml')
|
538
|
+
installed_yml.transaction do
|
539
|
+
installed_yml['artists'] = installed_artists.uniq
|
540
|
+
end
|
541
|
+
puts ' done'
|
542
|
+
end
|
543
|
+
end
|
428
544
|
end
|
429
545
|
|
430
546
|
def update
|
431
547
|
check_is_a_mbrew_lib
|
432
548
|
|
549
|
+
Dir.chdir(@working_dir) do
|
550
|
+
Dir.chdir('.mbrew/index') do
|
551
|
+
printf 'Index update ...'
|
552
|
+
grepo = Git.open('.')
|
553
|
+
grepo.pull
|
554
|
+
puts ' done'
|
555
|
+
end
|
556
|
+
end
|
433
557
|
end
|
434
558
|
|
435
559
|
def upgrade
|
436
560
|
check_is_a_mbrew_lib
|
437
561
|
|
562
|
+
Dir.chdir(@working_dir) do
|
563
|
+
Dir.chdir('.mbrew') do
|
564
|
+
|
565
|
+
installed_artists = YAML.load_file('installed.yml')['artists']
|
566
|
+
|
567
|
+
Dir.chdir('index') do
|
568
|
+
file_paths = Dir.glob('**/*.yml')
|
569
|
+
yml_files = file_paths
|
570
|
+
.map{ |yml_file_path|
|
571
|
+
yml = YAML.load_file(yml_file_path)
|
572
|
+
[yml_file_path, {
|
573
|
+
'path' => yml['src']['file']['path'],
|
574
|
+
'artist' => yml['id3']['artist'],
|
575
|
+
}]
|
576
|
+
}
|
577
|
+
.to_h
|
578
|
+
.keep_if{ |yml_file_path, yml| installed_artists.include?(yml['artist']) }
|
579
|
+
.keep_if{ |yml_file_path, yml|
|
580
|
+
Dir.chdir('../..') do
|
581
|
+
!File.exist?(yml['path'])
|
582
|
+
end
|
583
|
+
}
|
584
|
+
|
585
|
+
if yml_files.count > 0
|
586
|
+
puts "The following files will be INSTALLED (#{yml_files.count}):"
|
587
|
+
puts
|
588
|
+
puts yml_files.values.map{ |yml| yml['path'] }.sort
|
589
|
+
puts
|
590
|
+
res = ask('Do it? [Yn] ').strip.downcase
|
591
|
+
res = 'y' if res == ''
|
592
|
+
if res == 'y'
|
593
|
+
install_files(yml_files.keys)
|
594
|
+
end
|
595
|
+
else
|
596
|
+
puts 'No new files.'
|
597
|
+
end
|
598
|
+
|
599
|
+
end
|
600
|
+
end
|
601
|
+
end
|
438
602
|
end
|
439
603
|
|
440
604
|
private
|
@@ -456,6 +620,134 @@ module TheFox
|
|
456
620
|
end
|
457
621
|
end
|
458
622
|
|
623
|
+
def check_installed_file
|
624
|
+
Dir.chdir(@working_dir) do
|
625
|
+
Dir.chdir('.mbrew') do
|
626
|
+
if !File.exist?('installed.yml')
|
627
|
+
installed_yml = YAML::Store.new('installed.yml')
|
628
|
+
installed_yml.transaction do
|
629
|
+
installed_yml['artists'] = []
|
630
|
+
end
|
631
|
+
end
|
632
|
+
end
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
def install_files(file_paths)
|
637
|
+
check_is_a_mbrew_lib
|
638
|
+
check_installed_file
|
639
|
+
|
640
|
+
downstream_url = @config['origin']['downstream']
|
641
|
+
downstream_data_url = "#{downstream_url}/data"
|
642
|
+
|
643
|
+
#p file_paths
|
644
|
+
|
645
|
+
Dir.chdir(@working_dir) do
|
646
|
+
Dir.chdir('.mbrew') do
|
647
|
+
installed_artists = YAML.load_file('installed.yml')['artists']
|
648
|
+
|
649
|
+
yml_files = []
|
650
|
+
Dir.chdir('index') do
|
651
|
+
yml_files = file_paths
|
652
|
+
.map{ |yml_file_path| YAML.load_file(yml_file_path) }
|
653
|
+
end
|
654
|
+
|
655
|
+
Dir.mkdir('tmp') if !Dir.exist?('tmp')
|
656
|
+
Dir.chdir('tmp') do
|
657
|
+
Dir.mkdir('install') if !Dir.exist?('install')
|
658
|
+
Dir.chdir('install') do
|
659
|
+
|
660
|
+
yml_files.each do |yml|
|
661
|
+
src_file_relative_path = yml['src']['file']['path']
|
662
|
+
src_file_relative_path_hex = yml['src']['file']['path_hash']
|
663
|
+
src_file_content_hex = yml['src']['file']['content_hash']
|
664
|
+
src_file_basename = yml['src']['file']['name']
|
665
|
+
|
666
|
+
dst_dir_path = "#{src_file_relative_path_hex[0..1]}/#{src_file_relative_path_hex[2..3]}/#{src_file_relative_path_hex[4..5]}"
|
667
|
+
dst_file_name = src_file_relative_path_hex[6..-1]
|
668
|
+
|
669
|
+
gpg_file_name = "#{dst_file_name}.gpg"
|
670
|
+
gpg_file_path = "#{dst_dir_path}/#{gpg_file_name}"
|
671
|
+
gpg_file_url = "#{downstream_data_url}/#{gpg_file_path}"
|
672
|
+
tmp_mp3_file_name = "#{src_file_relative_path_hex}.mp3"
|
673
|
+
|
674
|
+
puts "src_file_basename: '#{src_file_basename}'"
|
675
|
+
|
676
|
+
puts "gpg_file_name: '#{gpg_file_name}'"
|
677
|
+
puts "gpg_file_path: '#{gpg_file_path}'"
|
678
|
+
puts "gpg_file_url: '#{gpg_file_url}'"
|
679
|
+
|
680
|
+
printf "Downloading '#{src_file_relative_path}' ..."
|
681
|
+
if !File.exist?(gpg_file_name)
|
682
|
+
gpg_file_uri = URI(gpg_file_url)
|
683
|
+
Net::HTTP.start(gpg_file_uri.host, gpg_file_uri.port) do |http|
|
684
|
+
request = Net::HTTP::Get.new(gpg_file_uri)
|
685
|
+
http.request(request) do |response|
|
686
|
+
open(gpg_file_name, 'w') do |io|
|
687
|
+
response.read_body do |chunk|
|
688
|
+
io.write(chunk)
|
689
|
+
printf '.'
|
690
|
+
end
|
691
|
+
end
|
692
|
+
end
|
693
|
+
end
|
694
|
+
end
|
695
|
+
puts ' done'
|
696
|
+
|
697
|
+
gpg_exec = "LC_ALL=C gpg --no-tty --batch --passphrase supersecret2015 -d -o #{tmp_mp3_file_name} #{gpg_file_name}"
|
698
|
+
puts "gpg_exec: '#{gpg_exec}'"
|
699
|
+
|
700
|
+
if !system(gpg_exec).nil?
|
701
|
+
tmp_file_content_hex = Digest::SHA256.file(tmp_mp3_file_name).hexdigest
|
702
|
+
puts "tmp_file_content_hex: '#{tmp_file_content_hex}'"
|
703
|
+
puts "src_file_content_hex: '#{src_file_content_hex}'"
|
704
|
+
|
705
|
+
if src_file_content_hex == tmp_file_content_hex
|
706
|
+
puts Rainbow('Hash OK.').green
|
707
|
+
else
|
708
|
+
puts Rainbow('Hash INVALID.').red
|
709
|
+
end
|
710
|
+
puts
|
711
|
+
|
712
|
+
FileUtils.rm(gpg_file_name)
|
713
|
+
else
|
714
|
+
FileUtils.rm(gpg_file_name)
|
715
|
+
raise 'FATAL ERROR: gpg failed.'
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
719
|
+
puts 'Installing files ...'
|
720
|
+
yml_files.each do |yml|
|
721
|
+
src_file_relative_path = yml['src']['file']['path']
|
722
|
+
src_file_relative_dir = yml['src']['file']['dir']
|
723
|
+
src_file_relative_path_hex = yml['src']['file']['path_hash']
|
724
|
+
tmp_mp3_file_name = "#{src_file_relative_path_hex}.mp3"
|
725
|
+
|
726
|
+
puts src_file_relative_path
|
727
|
+
# p Dir.pwd
|
728
|
+
# puts "src_file_relative_path: '#{src_file_relative_path}'"
|
729
|
+
# puts "src_file_relative_dir: '#{src_file_relative_dir}'"
|
730
|
+
# puts "tmp_mp3_file_name: '#{tmp_mp3_file_name}'"
|
731
|
+
|
732
|
+
Dir.chdir('../../..') do
|
733
|
+
FileUtils.mkdir_p(src_file_relative_dir) if !Dir.exist?(src_file_relative_dir)
|
734
|
+
end
|
735
|
+
FileUtils.mv(tmp_mp3_file_name, "../../../#{src_file_relative_path}")
|
736
|
+
|
737
|
+
installed_artists << yml['id3']['artist']
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
installed_yml = YAML::Store.new('installed.yml')
|
743
|
+
installed_yml.transaction do
|
744
|
+
installed_yml['artists'] = installed_artists.uniq
|
745
|
+
end
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
end
|
750
|
+
|
459
751
|
end
|
460
752
|
end
|
461
753
|
end
|
data/lib/mbrew/version.rb
CHANGED
data/mbrew.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.email = 'christian@fox21.at'
|
14
14
|
|
15
15
|
spec.summary = %q{MusicBrew}
|
16
|
-
spec.description = %q{A
|
16
|
+
spec.description = %q{A Package Manager for Music.}
|
17
17
|
spec.homepage = TheFox::MBrew::HOMEPAGE
|
18
18
|
spec.license = 'GPL-3.0'
|
19
19
|
|
@@ -31,5 +31,6 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency 'rainbow', '~>2.0'
|
32
32
|
spec.add_dependency 'git', '~>1.2'
|
33
33
|
spec.add_dependency 'id3lib-ruby', '~>0.6'
|
34
|
+
spec.add_dependency 'highline', '~>1.7'
|
34
35
|
spec.add_dependency 'thefox-ext', '~>1.0'
|
35
36
|
end
|
data/mbrew.sublime-project
CHANGED
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
|
4
|
+
version: 0.1.0
|
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-
|
11
|
+
date: 2015-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: highline
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.7'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.7'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: thefox-ext
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,7 +94,7 @@ dependencies:
|
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '1.0'
|
83
|
-
description: A
|
97
|
+
description: A Package Manager for Music.
|
84
98
|
email: christian@fox21.at
|
85
99
|
executables:
|
86
100
|
- mbrew
|
@@ -115,9 +129,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
129
|
version: 2.2.0
|
116
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
131
|
requirements:
|
118
|
-
- - "
|
132
|
+
- - ">="
|
119
133
|
- !ruby/object:Gem::Version
|
120
|
-
version:
|
134
|
+
version: '0'
|
121
135
|
requirements:
|
122
136
|
- GPG
|
123
137
|
- Git
|