what_cd 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57e94a9b268eda29b46fedb523c52213a55c6168
4
- data.tar.gz: 1ff28ee6644868e2e6dbfc0054957f0b685cafbe
3
+ metadata.gz: b0780f43cbdc8861be4195ee4812dcc80b7b9d8b
4
+ data.tar.gz: 618d617b22d2fef1d5f465ff1c75d1d068f45ade
5
5
  SHA512:
6
- metadata.gz: 8c10517ee6d31ef8508cb25930d0495054a9c58fbd342d88f899947ac8557bdedd1ec787a5611192714b35a5e3bef9ea79ce6bfd87b3d47dfb152683e3b09f0d
7
- data.tar.gz: 14bf5c332cfe9405bd532091727f8802c94a0474b1435267fcee2af835729b945dd755e1ff542c7589b23a25448a39fd5b3b3f3c475637374b6e259514598780
6
+ metadata.gz: 99d5643b3da74e5db694b6b3cf01289429782db57006b4556cb08d01d8ebeb0c331ae5aef9e65f4d94eb9732912900f61c9951c1046bc15dc0227c5fbf6ed6e1
7
+ data.tar.gz: a75af750dbe7330b7c588541b869d1e8cc8d14718636889836b14d28adf48e24503b2c5daa0324b0db6b22c3be4b2c01df18f2cad28d2de881702c63724db0e7
data/README.md CHANGED
@@ -1,4 +1,26 @@
1
- what.cd-tools
2
- =============
1
+ # what_cd
2
+ What.CD uploader toolkit that makes your uploads squeaky clean.
3
3
 
4
- Making contributing to what.cd less tedious.
4
+ ## Installation
5
+ ```bash
6
+ gem install what_cd
7
+ ```
8
+ Create a default config file
9
+ ```bash
10
+ cp what_cd/etc/.what_cd ~/.what_cd
11
+ ```
12
+
13
+ ## Usage
14
+ ```bash
15
+ what_cd sanitize [dir]
16
+ ```
17
+ Sanitizing a release will iterate over a number of plugins under lib/what_cd/sanitize_plugins. Each plugin may modify the files themselves, the file names, or the directory name to adhere to What.CD guidelines. They may also throw errors if there is an issue with the upload ie. a mutt rip.
18
+
19
+ ```bash
20
+ what_cd metadata [dir]
21
+ ```
22
+ The metadata command will generate metadata about the release information that makes it easy to fill out the upload form.
23
+
24
+ ## License
25
+
26
+ Please see LICENSE at the top level of the repository.
@@ -1,40 +1,67 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- begin
4
- require 'rubygems'
5
- rescue LoadError
6
- # no rubygems to load, so we fail silently
3
+ require 'rubygems'
4
+ require 'commander/import'
5
+ require 'logging'
6
+ require 'pathname'
7
+
8
+ require '../lib/what_cd'
9
+ require '../lib/what_cd/version'
10
+ require '../lib/what_cd/sanitize'
11
+ require '../lib/what_cd/better'
12
+ require '../lib/what_cd/metadata'
13
+
14
+ # :name is optional, otherwise uses the basename of this executable
15
+ program :name, 'WHAT.CD'
16
+ program :version, WhatCD::VERSION
17
+ program :description, 'WHAT.CD tools'
18
+
19
+ global_option('--verbose') { $verbose = true }
20
+
21
+ command :sanitize do |c|
22
+ c.syntax = 'what_cd sanitize [dir]'
23
+ c.description = 'Sanitizes releases'
24
+ c.action do |args, options|
25
+ # Preconditions
26
+ raise ArgumentError.new("dir argument required") unless args.count > 0
27
+ path = sanitize_path(args[0])
28
+ Sanitize.run(path)
29
+ end
7
30
  end
8
31
 
9
- require 'optparse'
10
- require 'what_cd'
11
-
12
- OPTIONS = {}
13
- MANDATORY_OPTIONS = %w[]
14
-
15
- parser = OptionParser.new do |opts|
16
- opts.banner = <<BANNER
17
- Usage: #{File.basename($0)} [directory]
18
-
19
- Options are:
20
- BANNER
21
- opts.separator ''
22
- opts.on('-v', '--version',
23
- "Show the #{File.basename($0)} version number and exit") { require 'what-cd/version'; puts "what-cd #{WhatCD::VERSION}"; exit }
24
- opts.on('-t', '--tracker',
25
- "Create torrent file with tracker") { |tracker| OPTIONS[:tracker] = tracker }
26
- opts.on('-e', '--encoding', String,
27
- "Set lame encoding options", "Default: #{WhatCD.default_encoding}") { |encoding| OPTIONS[:encoding] = encoding }
28
- opts.on('-h', '--help',
29
- 'Show this help message.') { puts opts; exit }
30
- opts.parse!(ARGV)
31
-
32
- if MANDATORY_OPTIONS && MANDATORY_OPTIONS.find { |option| OPTIONS[option.to_sym].nil? }
33
- puts opts; exit
32
+ command :metadata do |c|
33
+ c.syntax = 'what_cd metadata [dir]'
34
+ c.description = 'Gets release metadata for uploading'
35
+ c.action do |args, options|
36
+ # Preconditions
37
+ raise ArgumentError.new("dir argument required") unless args.count > 0
38
+ path = sanitize_path(args[0])
39
+ Metadata.run(path)
34
40
  end
41
+ end
35
42
 
36
- # do stuff
37
- dir = ARGV[0]
43
+ command :better do |c|
44
+ c.syntax = 'what_cd better [args] [dir]'
45
+ c.description = 'Converts FLAC releases to MP3'
46
+ c.option '--quality [320/V0]', String, 'Specifies what quality MP3 to convert to'
47
+ c.action do |args, options|
48
+ # Preconditions
49
+ raise ArgumentError.new("dir argument required") unless args.count > 0
50
+ raise ArgumentError.new("quality option required") unless options.quality
51
+ raise ArgumentError.new("specified quality invalid. Must be 320 or V0") unless options.quality == "320" || options.quality == "V0"
52
+ path = sanitize_path(args[0])
53
+ Better.run(path, options.quality, $verbose)
54
+ end
55
+ end
38
56
 
39
- #WhatCD.convert(dir, OPTIONS)
57
+ def sanitize_path(path)
58
+ # Force add a trailing '/'
59
+ #path = path.chomp('/')
60
+ #path << '/'
61
+
62
+ if (Pathname.new(path).absolute?)
63
+ return path
64
+ else
65
+ return Dir.pwd + '/' + path
66
+ end
40
67
  end
@@ -1,14 +1,10 @@
1
- #$:.unshift File.dirname(__FILE__)
1
+ $:.unshift File.dirname(__FILE__)
2
2
 
3
- class WhatCD
3
+ require 'logging'
4
4
 
5
- def initialize(options = {})
6
- end
5
+ module WhatCD
6
+
7
+ # YAML config
8
+ CONFIG = "#{Dir.home}/.what_cd"
7
9
 
8
- class << self
9
- # V0
10
- def default_encoding
11
- '--preset extreme'
12
- end
13
- end
14
10
  end
@@ -0,0 +1,73 @@
1
+ require 'logging'
2
+ require 'active_support/all'
3
+ require 'yaml'
4
+
5
+ '''
6
+ This tool is primarily for working through better.php with ease.
7
+ Essentially this tool will look at an existing release directory with
8
+ FLAC files and create a matching release with MP3 files. A best attempt
9
+ is made to create an appropriate folder name. Any non-flac files are moved
10
+ over and then flac files are converted to an MP3.
11
+
12
+ '''
13
+
14
+ module Better
15
+
16
+ @log = Logging.logger[self]
17
+ @log.appenders = Logging.appenders.stdout
18
+
19
+ def self. setup_log(verbose)
20
+ if verbose
21
+ @log.level = :debug
22
+ else
23
+ @log.level = :info
24
+ end
25
+ end
26
+
27
+ # Load from config file
28
+ def self.run(path, quality, verbose=false)
29
+ setup_log(verbose)
30
+
31
+ # Load configured plugins
32
+ begin
33
+ # Get config
34
+ config = YAML.load_file(WhatCD::CONFIG)
35
+ # Get configured plugins
36
+ configured_plugins = config['commands']['better']['plugins']
37
+
38
+ if configured_plugins
39
+ # Run them
40
+ self.run_plugins(path, configured_plugins, quality)
41
+ else
42
+ @log.info "No plugins to run. Edit your config to enable plugins."
43
+ end
44
+ rescue Errno::ENOENT
45
+ @log.error "Missing gem config file '~/.what_cd'"
46
+ end
47
+ end
48
+
49
+ def self.run_plugins(path, configured_plugins, quality)
50
+ # Get this directory
51
+ current_dir = File.dirname(__FILE__)
52
+
53
+ # Set the context to be passed around between plugins
54
+ context = {}
55
+ context[:path] = path
56
+ context[:quality] = quality
57
+
58
+ # Iterate over the configured plugins and dynamically execute them
59
+ configured_plugins.each do |configured_plugin|
60
+ file = "#{current_dir}/better_plugins/#{configured_plugin}.rb"
61
+ require file
62
+ file_name = File.basename(file, '.rb')
63
+ # using ActiveSupport for camelcase and constantize
64
+ plugin = file_name.camelcase.constantize
65
+ # Check to ensure ruby file defines a class
66
+ if plugin.class == Class
67
+ @log.info "Bettering with plugin #{plugin}"
68
+ context = plugin.new.better(context)
69
+ @log.debug "context returned as #{context}"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ module BetterPlugin
2
+
3
+ def better(context)
4
+ raise 'This method should be implemented by every better plugin and return the context, modified or not'
5
+ end
6
+
7
+ def description
8
+ raise 'This method should be implemented by every better plugin and describe the plugin'
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ require 'logging'
2
+
3
+ require File.expand_path("../better_plugin", __FILE__)
4
+
5
+ class Convert
6
+
7
+ include BetterPlugin
8
+
9
+ def initialize
10
+ @log = Logging.logger[self]
11
+ @log.appenders = Logging.appenders.stdout
12
+ if $verbose
13
+ @log.level = :debug
14
+ else
15
+ @log.level = :info
16
+ end
17
+ end
18
+
19
+ def better(context)
20
+ path = context[:path]
21
+ quality = context[:quality]
22
+
23
+ if quality == "320"
24
+ convert(path, "insane")
25
+ elsif quality == "V0"
26
+ convert(path, "extreme")
27
+ else
28
+ # rage
29
+ end
30
+
31
+ # Remove old flac files
32
+ cleanup(path)
33
+
34
+ return context
35
+ end
36
+
37
+ def convert(path, preset)
38
+
39
+ files = Dir.chdir(path) { Dir["*.flac"] }
40
+
41
+ files.each do |flac_file|
42
+ @log.info "Converting #{flac_file}"
43
+ cmd = "cd #{Shellwords.escape(path)}; flac2mp3 #{Shellwords.escape(flac_file)} --encoding='--preset #{preset}' > /dev/null 2>&1"
44
+ output = system "bash -c \"#{cmd}\""
45
+ end
46
+ end
47
+
48
+ def cleanup(path)
49
+ files = Dir.chdir(path) { Dir["*.flac"] }
50
+
51
+ files.each do |flac_file|
52
+ @log.info "Deleting #{flac_file}"
53
+ FileUtils.rm_rf(path + flac_file)
54
+ end
55
+ end
56
+
57
+ def description
58
+ "Creates a new directory for the MP3 files that will be converted from FLAC"
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ require 'logging'
2
+
3
+ require File.expand_path("../better_plugin", __FILE__)
4
+
5
+ class NewDir
6
+
7
+ include BetterPlugin
8
+
9
+ def initialize
10
+ @log = Logging.logger[self]
11
+ @log.appenders = Logging.appenders.stdout
12
+ if $verbose
13
+ @log.level = :debug
14
+ else
15
+ @log.level = :info
16
+ end
17
+ end
18
+
19
+ def better(context)
20
+ path = context[:path]
21
+ quality = context[:quality]
22
+ new_path = determine_new_dir_name(path, quality)
23
+
24
+ @log.info "Creating path for MP3 files at #{new_path} and copying files over"
25
+ # Create the new directory if it does not exist
26
+ FileUtils.cp_r path, new_path unless File.exists?(new_path)
27
+
28
+ context[:path] = new_path
29
+ return context
30
+ end
31
+
32
+ # Intelligently decide on a new directory name
33
+ def determine_new_dir_name(path, quality)
34
+ if path.include? 'FLAC'
35
+ return path.gsub 'FLAC', "MP3 #{quality}"
36
+ elsif path.include? 'flac'
37
+ return path.gsub! 'flac', "MP3 #{quality}"
38
+ else
39
+ return path.gsub! '/', " [MP3 #{quality}]"
40
+ end
41
+ end
42
+
43
+ def description
44
+ "Creates a new directory for the MP3 files that will be converted from FLAC"
45
+ end
46
+ end
@@ -0,0 +1,135 @@
1
+ require 'logging'
2
+ require 'active_support/all'
3
+ require 'yaml'
4
+ require 'mp3info'
5
+
6
+ module Metadata
7
+
8
+ @log = Logging.logger[self]
9
+ @log.appenders = Logging.appenders.stdout
10
+ if $verbose
11
+ @log.level = :debug
12
+ else
13
+ @log.level = :info
14
+ end
15
+
16
+ # Load from config file
17
+ def self.run(path)
18
+
19
+ metadata = {}
20
+ metadata['album_title'] = self.get_album_title(path)
21
+ metadata['artists'] = self.get_artists(path)
22
+ metadata['year'] = self.get_year(path)
23
+ # We only handle MP3 files at the moment
24
+ metadata['format'] = 'MP3'
25
+ metadata ['bitrate'] = self.get_bitrate(path)
26
+
27
+
28
+ puts metadata
29
+ end
30
+
31
+ def self.get_artists(path)
32
+ artists = []
33
+
34
+ Dir.entries(path).each do |f|
35
+ if !File.directory? f
36
+ # Fix Tags
37
+ if File.extname(f) == ".mp3"
38
+ filename = File.basename(f, File.extname(f))
39
+ file_path = path + f
40
+
41
+ Mp3Info.open(file_path) do |mp3|
42
+ if mp3.tag.artist
43
+ artists.push(mp3.tag.artist)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ return artists
51
+ end
52
+
53
+ def self.get_year(path)
54
+ file_path = self.get_first_mp3(path)
55
+
56
+ if file_path
57
+ Mp3Info.open(file_path) do |mp3|
58
+ return mp3.tag.year
59
+ end
60
+ end
61
+ end
62
+
63
+ def self.get_album_title(path)
64
+ file_path = self.get_first_mp3(path)
65
+
66
+ if file_path
67
+ Mp3Info.open(file_path) do |mp3|
68
+ return mp3.tag.album
69
+ end
70
+ end
71
+ end
72
+
73
+ def self.get_first_mp3(path)
74
+ Dir.entries(path).each do |f|
75
+ if !File.directory? f
76
+ # Fix Tags
77
+ if File.extname(f) == ".mp3"
78
+ filename = File.basename(f, File.extname(f))
79
+ file_path = path + f
80
+ return file_path
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ def self.get_bitrate(path)
87
+ files = Dir.chdir(path) { Dir["*.mp3"] }
88
+ return if files.empty?
89
+
90
+ bitrates = {}
91
+
92
+ files.each do |file_name|
93
+ file_path = path + file_name
94
+ Mp3Info.open(file_path) do |mp3|
95
+ hash = {:bitrate => mp3.bitrate, :vbr => mp3.vbr}
96
+ bitrates[file_name] = hash
97
+ end
98
+ end
99
+
100
+ vbr_list = bitrates.values.map{|value| value[:vbr] }
101
+ # Will only have 1-2 count (true & false)
102
+ if vbr_list.uniq.count > 1
103
+ raise BitrateError.new("Release has both constant and variable bitrate tracks!")
104
+ else
105
+ vbr = vbr_list.first
106
+ end
107
+
108
+ bitrate_list = bitrates.values.map{|value| value[:bitrate] }
109
+ # Remove duplicates
110
+ uniq_bitrate_list = bitrate_list.uniq
111
+
112
+ # If the only vbr value is false, this is CBR
113
+ if not vbr and uniq_bitrate_list.uniq.count > 1
114
+ raise BitrateError.new("Release tracks are constant bit rate but multiple bitrates found!")
115
+ elsif vbr
116
+ puts "Calculating average bitrate"
117
+ # Determine average VBR of release
118
+ avg_bitrate = bitrate_list.inject(:+) / bitrate_list.length
119
+ if avg_bitrate > 220
120
+ return 'V0 (VBR)'
121
+ elsif avg_bitrate > 192
122
+ return 'V2 (VBR)'
123
+ else
124
+ raise BitrateError.new("Release average bit rate is too low")
125
+ end
126
+ else
127
+ return bitrate_list.first
128
+ end
129
+ end
130
+
131
+ class BitrateError < StandardError
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,57 @@
1
+ require 'logging'
2
+ require 'active_support/all'
3
+ require 'yaml'
4
+
5
+ module Sanitize
6
+
7
+ @log = Logging.logger[self]
8
+ @log.appenders = Logging.appenders.stdout
9
+ if $verbose
10
+ @log.level = :debug
11
+ else
12
+ @log.level = :info
13
+ end
14
+
15
+ # Load from config file
16
+ def self.run(path)
17
+
18
+ # Load configured plugins
19
+ begin
20
+ # Get config
21
+ config = YAML.load_file(WhatCD::CONFIG)
22
+ # Get configured plugins
23
+ configured_plugins = config['commands']['sanitize']['plugins']
24
+ # Run them
25
+ self.run_plugins(path, configured_plugins)
26
+ rescue Errno::ENOENT
27
+ @log.error "Missing gem config file '~/.what_cd'"
28
+ end
29
+ end
30
+
31
+ def self.run_plugins(path, configured_plugins)
32
+ @log.info "Sanitizing release located at #{path}"
33
+ # Get this directory
34
+ current_dir = File.dirname(__FILE__)
35
+
36
+ # Set the context to be passed around between plugins
37
+ context = {}
38
+ context[:path] = path
39
+
40
+ # Iterate over the configured plugins and dynamically execute them
41
+ configured_plugins.each do |configured_plugin|
42
+ file = "#{current_dir}/sanitize_plugins/#{configured_plugin}.rb"
43
+ require file
44
+ file_name = File.basename(file, '.rb')
45
+ # using ActiveSupport for camelcase and constantize
46
+ plugin = file_name.camelcase.constantize
47
+ # Check to ensure ruby file defines a class
48
+ if plugin.class == Class
49
+ @log.info "Sanitizing with plugin #{plugin}"
50
+ context = plugin.new.sanitize(context)
51
+ @log.debug "Context returned as #{context}"
52
+ end
53
+ end
54
+
55
+ @log.info "Sanitization finished. Sanitized release located at #{context[:path]}"
56
+ end
57
+ end
@@ -0,0 +1,66 @@
1
+ require 'logging'
2
+ require 'mp3info'
3
+
4
+ require File.expand_path("../sanitize_plugin", __FILE__)
5
+
6
+ class Bitrate
7
+
8
+ include SanitizePlugin
9
+
10
+ def initialize
11
+ @log = Logging.logger[self]
12
+ @log.appenders = Logging.appenders.stdout
13
+ if $verbose
14
+ @log.level = :debug
15
+ else
16
+ @log.level = :info
17
+ end
18
+ end
19
+
20
+ def sanitize(context)
21
+ path = context[:path]
22
+ files = Dir.chdir(path) { Dir["*.mp3"] }
23
+ return if files.empty?
24
+
25
+ bitrates = {}
26
+
27
+ files.each do |file_name|
28
+ file_path = path + file_name
29
+ Mp3Info.open(file_path) do |mp3|
30
+ hash = {:bitrate => mp3.bitrate, :vbr => mp3.vbr}
31
+ bitrates[file_name] = hash
32
+ end
33
+ end
34
+
35
+ # TODO: Improve this to print out the violating file name
36
+ vbr_list = bitrates.values.map{|value| value[:vbr] }
37
+ if vbr_list.uniq.count > 1
38
+ raise BitrateError.new("Release has both constant and variable bitrate tracks!")
39
+ else
40
+ vbr = vbr_list.first
41
+ end
42
+
43
+ bitrate_list = bitrates.values.map{|value| value[:bitrate] }
44
+ # Remove duplicates
45
+ bitrate_list = bitrate_list.uniq
46
+
47
+ # If the only vbr value is false, this is CBR
48
+ if not vbr and bitrate_list.uniq.count > 1
49
+ raise BitrateError.new("Release tracks are constant bit rate but multiple bitrates found!")
50
+ else
51
+ bitrate = bitrate_list.first
52
+ end
53
+
54
+ if vbr
55
+ @log.info "Variable bitrate detected"
56
+ else
57
+ @log.info "Constant bitrate detected at #{bitrate} kbps"
58
+ end
59
+
60
+ return context
61
+ end
62
+ end
63
+
64
+ class BitrateError < StandardError
65
+
66
+ end
@@ -0,0 +1,36 @@
1
+ require 'logging'
2
+
3
+ require File.expand_path("../sanitize_plugin", __FILE__)
4
+
5
+ class Cover
6
+
7
+ include SanitizePlugin
8
+
9
+ def initialize
10
+ @log = Logging.logger[self]
11
+ @log.appenders = Logging.appenders.stdout
12
+ if $verbose
13
+ @log.level = :debug
14
+ else
15
+ @log.level = :info
16
+ end
17
+ end
18
+
19
+ def sanitize(context)
20
+ path = context[:path]
21
+ images = Dir.chdir(path) { Dir["*.jpg"] }
22
+
23
+ if images.count == 1
24
+ file_name = images[0]
25
+ file_path = path + file_name
26
+ new_file_path = path + '00. cover.jpg'
27
+ File.rename(file_path, new_file_path)
28
+ elsif images.count > 1
29
+ @log.info "Several .jpg files in release directory. Unable to determine cover art."
30
+ else
31
+ @log.debug "No .jpg files found in release directory."
32
+ end
33
+
34
+ return context
35
+ end
36
+ end
@@ -0,0 +1,76 @@
1
+ require 'mp3info'
2
+ require 'logging'
3
+
4
+ require File.expand_path("../sanitize_plugin", __FILE__)
5
+
6
+ class DirName
7
+ include SanitizePlugin
8
+
9
+ def initialize
10
+ @log = Logging.logger[self]
11
+ @log.appenders = Logging.appenders.stdout
12
+ if $verbose
13
+ @log.level = :debug
14
+ else
15
+ @log.level = :info
16
+ end
17
+ end
18
+
19
+ def sanitize(context)
20
+ path = context[:path]
21
+ # To get release info we need to look at an mp3
22
+ file_path = get_first_mp3_path(path)
23
+
24
+ if file_path
25
+ @log.debug "Opening file_path #{file_path}"
26
+ Mp3Info.open(file_path) do |mp3|
27
+ if mp3.tag.album
28
+ new_dir = mp3.tag.album
29
+
30
+ # Add year if available
31
+ if mp3.tag.year
32
+ new_dir = new_dir + " [#{mp3.tag.year}]"
33
+ end
34
+
35
+ quality = get_quality_string(mp3.bitrate, mp3.vbr)
36
+ new_dir = new_dir + " #{quality}"
37
+
38
+ parts = path.split("/")
39
+ parts[-1] = new_dir
40
+ new_path = parts.join("/")
41
+ # Add trailing '/' that was removed from splitting
42
+ new_path << '/'
43
+ if new_dir != path.chomp("/")
44
+ @log.debug "Renaming directory to #{new_dir}"
45
+ File.rename(path, new_path)
46
+ context[:path] = new_path
47
+ end
48
+ end
49
+ end
50
+ end
51
+ return context
52
+ end
53
+
54
+ def get_first_mp3_path(path)
55
+ Dir.entries(path).each do |f|
56
+ if !File.directory?(f) and File.extname(f) == ".mp3"
57
+ file_path = path + f
58
+ return file_path
59
+ end
60
+ end
61
+
62
+ return nil
63
+ end
64
+
65
+ def get_quality_string(bitrate, vbr)
66
+ if vbr
67
+ if bitrate > 230
68
+ return "[MP3 V0]"
69
+ elsif bitrate > 190
70
+ return "[MP3 V2]"
71
+ end
72
+ else
73
+ return "[MP3 #{bitrate}]"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,70 @@
1
+ require 'mp3info'
2
+ require 'logging'
3
+ require 'active_support/all'
4
+
5
+ require File.expand_path("../sanitize_plugin", __FILE__)
6
+
7
+ class FileName
8
+ include SanitizePlugin
9
+
10
+ def initialize
11
+ @log = Logging.logger[self]
12
+ @log.appenders = Logging.appenders.stdout
13
+ if $verbose
14
+ @log.level = :debug
15
+ else
16
+ @log.level = :info
17
+ end
18
+ end
19
+
20
+ def sanitize(context)
21
+ path = context[:path]
22
+ Dir.chdir(path) { Dir["*.mp3"] }.each do |f|
23
+ file_name = f
24
+ file_path = path + file_name
25
+
26
+ new_file_name = get_fixed_file_name(file_path)
27
+
28
+ if new_file_name != file_name
29
+ new_file_path = path + new_file_name
30
+ File.rename(file_path, new_file_path)
31
+ end
32
+ end
33
+
34
+ return context
35
+ end
36
+
37
+ def get_fixed_file_name(file_path)
38
+ # Return the original file_path by default
39
+ new_file_path = file_path
40
+
41
+ Mp3Info.open(file_path) do |mp3|
42
+ if mp3.tag.title and mp3.tag.artist and mp3.tag.tracknum
43
+ @log.debug "Reconstructing file name for #{file_path}"
44
+ title = mp3.tag.title
45
+ artist = mp3.tag.artist
46
+ tracknum = mp3.tag.tracknum.to_s
47
+ # Append a 0 to tracknum if necessary
48
+ if tracknum.length == 1
49
+ tracknum = "0" + tracknum
50
+ end
51
+
52
+ # Append a period to the trackname
53
+ tracknum = tracknum + "."
54
+
55
+ # Handle any remix parenthesis
56
+ title_parts = title.split('-')
57
+ if title_parts.length > 1
58
+ title_part = title_parts[0].strip
59
+ remix_part = title_parts[1].strip
60
+
61
+ title = title_part + " (#{remix_part})"
62
+ end
63
+
64
+ new_file_path = "#{tracknum} #{artist} - #{title}" + File.extname(file_path)
65
+ end
66
+ end
67
+
68
+ return new_file_path
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ require 'mp3info'
2
+ require 'logging'
3
+ require 'active_support/all'
4
+
5
+ require File.expand_path("../sanitize_plugin", __FILE__)
6
+
7
+ class Hidden
8
+ include SanitizePlugin
9
+
10
+ def initialize
11
+ @log = Logging.logger[self]
12
+ @log.appenders = Logging.appenders.stdout
13
+ if $verbose
14
+ @log.level = :debug
15
+ else
16
+ @log.level = :info
17
+ end
18
+ end
19
+
20
+ def sanitize(context)
21
+ path = context[:path]
22
+ Dir.entries(path).each do |entry|
23
+ # We only want to remove hidden files... not directories. ASK ME HOW I KNOW!
24
+ if !File.directory? entry
25
+ # Remove hidden files
26
+ if entry.start_with? "."
27
+ @log.debug "Deleting hidden file #{path + entry}"
28
+ FileUtils.rm_rf(path + entry)
29
+ end
30
+ end
31
+ end
32
+
33
+ return context
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ module SanitizePlugin
2
+
3
+ def sanitize(path)
4
+ raise 'This method should be implemented by every sanitization plugin and return the context regardless of whether it has been modified or not'
5
+ end
6
+ end
@@ -0,0 +1,40 @@
1
+ require 'mp3info'
2
+ require 'logging'
3
+
4
+ require File.expand_path("../sanitize_plugin", __FILE__)
5
+
6
+ class Tags
7
+
8
+ include SanitizePlugin
9
+
10
+ def initialize
11
+ @log = Logging.logger[self]
12
+ @log.appenders = Logging.appenders.stdout
13
+ if $verbose
14
+ @log.level = :debug
15
+ else
16
+ @log.level = :info
17
+ end
18
+ end
19
+
20
+ def sanitize(context)
21
+ path = context[:path]
22
+
23
+ Dir.entries(path).each do |f|
24
+ if !File.directory?(f) and File.extname(f) == ".mp3"
25
+ file_path = path + f
26
+ Mp3Info.open(file_path) do |mp3|
27
+ # Remove all comments
28
+ if not mp3.tag.comments.nil? or not mp3.tag2.COMM.nil?
29
+ mp3.tag.comments = nil
30
+ mp3.tag2.COMM = nil
31
+ end
32
+
33
+ # Handle publisher tag
34
+ mp3.tag2.TPUB = nil
35
+ end
36
+ end
37
+ end
38
+ return context
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
- class WhatCD
2
- VERSION = "0.0.4"
1
+ module WhatCD
2
+ VERSION = "0.0.5"
3
3
  end
metadata CHANGED
@@ -1,41 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: what_cd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Parraga
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-11 00:00:00.000000000 Z
11
+ date: 2015-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: flac2mp3
14
+ name: commander
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mp3info
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: mktorrent
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - '>='
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '0'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - '>='
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  description: Useful CLI tools for What.cd
@@ -47,10 +61,22 @@ extensions: []
47
61
  extra_rdoc_files: []
48
62
  files:
49
63
  - README.md
50
- - lib/better.rb
51
- - lib/what_cd/version.rb
52
- - lib/what_cd.rb
53
64
  - bin/what_cd
65
+ - lib/what_cd.rb
66
+ - lib/what_cd/better.rb
67
+ - lib/what_cd/better_plugins/better_plugin.rb
68
+ - lib/what_cd/better_plugins/convert.rb
69
+ - lib/what_cd/better_plugins/new_dir.rb
70
+ - lib/what_cd/metadata.rb
71
+ - lib/what_cd/sanitize.rb
72
+ - lib/what_cd/sanitize_plugins/bitrate.rb
73
+ - lib/what_cd/sanitize_plugins/cover.rb
74
+ - lib/what_cd/sanitize_plugins/dir_name.rb
75
+ - lib/what_cd/sanitize_plugins/file_name.rb
76
+ - lib/what_cd/sanitize_plugins/hidden.rb
77
+ - lib/what_cd/sanitize_plugins/sanitize_plugin.rb
78
+ - lib/what_cd/sanitize_plugins/tags.rb
79
+ - lib/what_cd/version.rb
54
80
  homepage: https://github.com/Sovietaced/what-cd
55
81
  licenses: []
56
82
  metadata: {}
@@ -60,17 +86,17 @@ require_paths:
60
86
  - lib
61
87
  required_ruby_version: !ruby/object:Gem::Requirement
62
88
  requirements:
63
- - - '>='
89
+ - - ">="
64
90
  - !ruby/object:Gem::Version
65
91
  version: '0'
66
92
  required_rubygems_version: !ruby/object:Gem::Requirement
67
93
  requirements:
68
- - - '>='
94
+ - - ">="
69
95
  - !ruby/object:Gem::Version
70
96
  version: '0'
71
97
  requirements: []
72
98
  rubyforge_project:
73
- rubygems_version: 2.1.11
99
+ rubygems_version: 2.4.6
74
100
  signing_key:
75
101
  specification_version: 4
76
102
  summary: Useful CLI tools for What.cd
@@ -1,122 +0,0 @@
1
- #!/usr/bin/ruby
2
- require 'shellwords'
3
- require 'mktorrent'
4
-
5
- '''
6
- This tool is primarily for working through better.php with ease.
7
- Essentially this tool will look at an existing release directory with
8
- FLAC files and create a matching release with MP3 V0 files. A best attempt
9
- is made to create an appropriate folder name. Any non-flac files are moved
10
- over and then flac files are converted to MP3 V0.
11
-
12
- Dependencies:
13
- flac2mp3: https://github.com/ymendel/flac2mp3
14
-
15
- '''
16
-
17
- class Better
18
-
19
- attr_reader :dir, :dir_name, :new_dir, :files, :tracker
20
-
21
- def initialize(dir_name, tracker)
22
- # dir will be modified later
23
- @dir = dir_name
24
- @dir_name = dir_name.chomp("/")
25
- @tracker = tracker
26
- @files = []
27
-
28
- run
29
- end
30
-
31
- def run
32
-
33
- handle_dirs
34
-
35
- load_flac_files
36
-
37
- puts @files
38
-
39
- copy_files(@dir, @new_dir)
40
-
41
- # Finally, convert to MP3 V0 if necessary
42
- convert(@dir, @new_dir)
43
-
44
- #create_torrent
45
-
46
- puts "Woot! Conversion successful!"
47
- puts "Find your files in #{new_dir}"
48
- end
49
-
50
- def load_flac_files
51
- flac_files = Dir.entries(dir).select { |e| e.include? '.flac' }
52
-
53
- if flac_files.empty?
54
- puts "No flac files found. Exiting..."
55
- exit
56
- end
57
-
58
- flac_files.each do | flac_file|
59
- @files.push(dir + flac_file)
60
- end
61
- end
62
-
63
-
64
- def handle_dirs
65
- # clear up inconsistencies
66
- if @dir.chars.last != '/'
67
- @dir = @dir + '/'
68
- end
69
-
70
- # Since mutable
71
- @new_dir = @dir.dup
72
-
73
- determine_new_dir_name(@new_dir)
74
-
75
- # Attach to full path
76
- @dir = Dir.pwd + "/" + @dir
77
- @new_dir = Dir.pwd + "/" + @new_dir
78
-
79
- # Create the new directory if it does not exist
80
- Dir.mkdir(@new_dir) unless File.exists?(@new_dir)
81
- end
82
-
83
- # Intelligently decide on a new directory name
84
- def determine_new_dir_name(new_dir)
85
- if new_dir.include? 'FLAC'
86
- new_dir.gsub! 'FLAC', 'MP3 V0'
87
- elsif new_dir.include? 'flac'
88
- new_dir.gsub! 'flac', 'MP3 V0'
89
- else
90
- new_dir.gsub! '/', ' [MP3 V0]/'
91
- end
92
- end
93
-
94
- def convert(dir, new_dir)
95
-
96
- @files.each do |flac_file|
97
- puts "Converting #{flac_file}"
98
- cmd = "cd #{Shellwords.escape(new_dir)}; flac2mp3 #{Shellwords.escape(flac_file)} --encoding='--preset extreme' > /dev/null 2>&1"
99
- output = system "bash -c \"#{cmd}\""
100
- end
101
- end
102
-
103
- def copy_files(dir, new_dir)
104
- # Copy all files from dir to new_dir
105
- cmd = "cp -r #{Shellwords.escape(dir)}/* #{Shellwords.escape(new_dir)}"
106
- system "bash -c \"#{cmd}\""
107
-
108
- # Remove any flac files, as they will be replaced by MP#s
109
- cmd = "rm #{Shellwords.escape(new_dir)}*.flac"
110
- system "bash -c \"#{cmd}\""
111
- end
112
-
113
- def create_torrent
114
- t = Torrent.new(@tracker)
115
- @files.each do |flac_file|
116
- t.add_file(flac_file)
117
- end
118
- t.defaultdir = @dir_name
119
- t.set_private
120
- t.write_torrent("#{@dir_name}.torrent")
121
- end
122
- end