gtk2mp3 0.0.0

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.
data/README.txt ADDED
@@ -0,0 +1,5 @@
1
+ = Gtk2MP3
2
+ == DESCRIPTION:
3
+ a "Next!" button gui for mpg123
4
+ == FEATURES:
5
+ pause and a trigger safe delete button (via checkbutton).
data/bin/gtk2mp3 ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ gem 'gtk2applib', '~> 9.2'
4
+ require 'gtk2applib'
5
+ include Gtk2AppLib
6
+ include Configuration
7
+
8
+ Lock.lock_mode
9
+ program = Program.new( {
10
+ 'name' => 'Ruby-Gnome MP3',
11
+ 'authors' => ['carlosjhr64@gmail.com'],
12
+ 'website' => 'http://ruby-gnome-apps.blogspot.com/search/label/MP3',
13
+ 'website-label' => 'Ruby-Gnome MP3',
14
+ 'license' => 'GPL',
15
+ 'copyright' => '2010-10-07 17:34:04',
16
+ } )
17
+
18
+ IO.popen(PLAYER,'w+') do |pipe|
19
+ begin
20
+ require 'gtk2mp3'
21
+ Gtk2MP3::Couple.load
22
+ program.window{|window| Gtk2MP3::GUI.new(window,pipe,program)}
23
+ rescue Exception
24
+ $!.puts_bang!
25
+ ensure
26
+ Gtk2MP3::Couple.dump
27
+ program.finalize
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ module Gtk2AppLib
2
+ module Configuration
3
+ directory = nil # '/path/to/mp3s' # give it a good default, dude!
4
+ dialog = Gtk::FileChooserDialog.new("Choose Mp3 Directory", nil, Gtk::FileChooser::ACTION_SELECT_FOLDER, nil,
5
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
6
+ [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
7
+ dialog.filename = directory if directory
8
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
9
+ directory = dialog.filename
10
+ end
11
+ dialog.destroy
12
+ DIRECTORY = directory
13
+
14
+ WINDOW_DEFAULT_SIZE[0],WINDOW_DEFAULT_SIZE[1] = 0,0
15
+ OPTIONS = {:modify_font => FONT[:Large]}.freeze
16
+
17
+ SPACER1 =
18
+ SPACER2 =
19
+ SPACER3 =
20
+ SPACER4 = [' ', OPTIONS].freeze
21
+ INFO = {:modify_font => FONT[:Small]}.freeze
22
+
23
+
24
+ RELOAD = '_Reload'
25
+
26
+ CLICKED = 'clicked' # Signal (should be no need to edit)
27
+ NEXT = ['Next!', OPTIONS, CLICKED].freeze
28
+ PAUSE = ['Pause', OPTIONS, CLICKED].freeze
29
+ DELETE = ['Delete', OPTIONS, CLICKED].freeze
30
+
31
+ SELECT_A_FILE = [['Select a file', Gtk::FileChooser::ACTION_OPEN],HNIL].freeze
32
+
33
+ PLAYER = 'mpg123 -q -a hw:0,0 -R'
34
+ # mpg123 commands
35
+ C_PAUSE = 'P'
36
+ C_SILENCE = 'SILENCE'
37
+ C_LOAD = 'L'
38
+ C_QUIT = 'Q'
39
+
40
+ ### Unused ####
41
+ # C_LOADPAUSED = 'LP'
42
+ # C_STOP = 'S'
43
+ # C_VOLUME = 'V'
44
+ # C_TAG = 'T'
45
+
46
+ MENU[:dock] = '_Dock'
47
+ end
48
+ end
@@ -0,0 +1,94 @@
1
+ module Gtk2MP3
2
+ class Couple
3
+ BASE = Hash.new(1.0)
4
+ BASE_DUMP = USERDIR + '/base.dump'
5
+
6
+ COUPLE = Hash.new(1.0)
7
+ COUPLE_DUMP = USERDIR + '/couple.dump'
8
+
9
+ LEARNING = Math.sqrt(2.0)
10
+ SEP = '/'
11
+ SEPX = Regexp.new(SEP)
12
+
13
+ def self._load(dump,hash)
14
+ File.open(dump,'r'){|fh|
15
+ fh.each{|line|
16
+ if line=~/^(.*)\s([\d\.]+)\s*$/ then
17
+ hash[$1.strip] = $2.to_f
18
+ end
19
+ }
20
+ } if File.exist?(dump)
21
+ end
22
+ def self.load
23
+ Couple._load(BASE_DUMP,BASE)
24
+ Couple._load(COUPLE_DUMP,COUPLE)
25
+ end
26
+
27
+ def self.delete(current)
28
+ key = File.basename(current,MP3)
29
+ BASE.delete(key)
30
+ COUPLE.delete_if{|k| k.split(SEPX).include?(key)}
31
+ end
32
+
33
+ def self._dump(dump,hash)
34
+ # Note that the default value is 1.0, so no need to save 1.0 values.
35
+ File.open(dump,'w'){|fh| hash.each{|k,v| fh.puts "#{k}\t#{v}" if v < 1.0 } }
36
+ end
37
+ def self.dump
38
+ Couple._dump(BASE_DUMP,BASE)
39
+ Couple._dump(COUPLE_DUMP,COUPLE)
40
+ end
41
+
42
+ def keys!
43
+ @base = File.basename(@candidate,MP3)
44
+ @couple = @base + SEP + File.basename(@previous,MP3)
45
+ end
46
+
47
+ def keys
48
+ return @base, @couple
49
+ end
50
+
51
+ def threshold!
52
+ @threshold = BASE[@base] * COUPLE[@couple]
53
+ end
54
+
55
+ def treshold
56
+ @threshold
57
+ end
58
+
59
+ def initialize(candidate,previous)
60
+ @candidate = candidate
61
+ @previous = previous
62
+ self.keys!
63
+ self.threshold!
64
+ end
65
+
66
+ def promote
67
+ BASE[@base] *= LEARNING
68
+ COUPLE[@couple] *= LEARNING
69
+ BASE[@base] = 1.0 if BASE[@base] > 1.0
70
+ COUPLE[@couple] = 1.0 if COUPLE[@couple] > 1.0
71
+ end
72
+
73
+ def promote!
74
+ self.promote
75
+ self.threshold!
76
+ end
77
+
78
+ def demote
79
+ BASE[@base] /= LEARNING
80
+ COUPLE[@couple] /= LEARNING
81
+ BASE[@base] = 0.25 if BASE[@base] < 0.25
82
+ COUPLE[@couple] = 0.25 if COUPLE[@couple] < 0.25
83
+ end
84
+
85
+ def demote!
86
+ self.demote
87
+ self.threshold!
88
+ end
89
+
90
+ def play?
91
+ return rand < @threshold
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,22 @@
1
+ module Gtk2MP3
2
+ class Playlist < Array
3
+ IS_MP3 = Regexp.new(/\.mp3$/)
4
+
5
+ def reload
6
+ self.clear
7
+ Find.find(@directory){|fn| self.push(fn) if fn=~IS_MP3 }
8
+ raise 'no mp3s found' if self.length < 1
9
+ end
10
+
11
+ def initialize(directory)
12
+ super()
13
+ @directory = directory
14
+ self.reload
15
+ $stderr.puts "Playlist length #{self.length}" if $trace
16
+ end
17
+
18
+ def random
19
+ self[ rand(self.length) ]
20
+ end
21
+ end
22
+ end
data/lib/gtk2mp3.rb ADDED
@@ -0,0 +1,93 @@
1
+ require 'gtk2mp3/playlist'
2
+ require 'gtk2mp3/couple'
3
+
4
+ module Gtk2MP3
5
+ MP3 = '.mp3'
6
+
7
+ class GUI
8
+ include Configuration
9
+ def random_song
10
+ plays = false
11
+ while !plays do
12
+ @current = @playlist.random
13
+ $stderr.puts @current if $trace
14
+ @couple = Gtk2MP3::Couple.new(@current,@previous)
15
+ $stderr.puts "#{@couple.keys.last} #{@couple.treshold}" if $trace
16
+ plays = @couple.play?
17
+ end
18
+ end
19
+
20
+ def load_song
21
+ self.random_song
22
+ @info.text = File.basename(@current,MP3)
23
+ @pipe.puts "#{C_LOAD} #{@current}"
24
+ end
25
+
26
+ def skip_song
27
+ @couple.demote
28
+ self.load_song
29
+ end
30
+
31
+ def pause_song
32
+ @pipe.puts C_PAUSE
33
+ end
34
+
35
+ def delete_song
36
+ File.unlink(@current)
37
+ @playlist.delete(@current)
38
+ @couple.delete(@current)
39
+ self.load_song
40
+ end
41
+
42
+ def initialize(window,pipe,program)
43
+ pipe.puts C_SILENCE
44
+ window.signal_connect('destroy'){ pipe.puts C_QUIT }
45
+
46
+ @pipe = pipe
47
+ @playlist = Gtk2MP3::Playlist.new(DIRECTORY)
48
+ @current = ''
49
+ @previous = ''
50
+
51
+ vbox = Widgets::VBox.new(window)
52
+
53
+ hbox = Widgets::HBox.new(vbox)
54
+ @info = Widgets::Label.new('Gtk2 MP3 Next!!!!', INFO, hbox)
55
+
56
+ hbox = Widgets::HBox.new(vbox)
57
+ Widgets::Label.new(*SPACER1, hbox) # Spacer
58
+ Widgets::Button.new(*NEXT, hbox){ self.skip_song }
59
+ Widgets::Label.new(*SPACER2, hbox) # Spacer
60
+ Widgets::Button.new(*PAUSE, hbox){ self.pause_song }
61
+ Widgets::Label.new(*SPACER3, hbox) # Spacer
62
+ Widgets.define_composite(:CheckButton,:Button)
63
+ Widgets::CheckButtonButton.new(*DELETE, hbox){|is,*dummies|
64
+ if is.checkbutton.active? then
65
+ self.delete_song
66
+ is.checkbutton.active = false
67
+ end
68
+ }
69
+ Widgets::Label.new(*SPACER4, hbox) # Spacer
70
+
71
+ self.load_song
72
+ Thread.new do
73
+ pipe.each do |line|
74
+ line.strip!
75
+ $stderr.puts line if $trace
76
+ if line =~ /^\@I\s+(\S.*)$/ then
77
+ # :-??
78
+ elsif line == '@P 0' then
79
+ @couple.promote
80
+ @previous = @current
81
+ self.load_song
82
+ end
83
+ end
84
+ false
85
+ end
86
+
87
+ program.append_app_menu(RELOAD){ @playlist.reload }
88
+ program.append_dock_menu(PAUSE.first){ self.pause_song }
89
+ program.append_dock_menu(NEXT.first){ self.skip_song }
90
+
91
+ end
92
+ end
93
+ end
data/pngs/icon.png ADDED
Binary file
data/pngs/logo.png ADDED
Binary file
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gtk2mp3
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ version: 0.0.0
11
+ platform: ruby
12
+ authors:
13
+ - carlosjhr64@gmail.com
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-07 00:00:00 -07:00
19
+ default_executable: gtk2mp3
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: gtk2applib
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 43
30
+ segments:
31
+ - 9
32
+ - 2
33
+ version: "9.2"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description: a "Next!" button gui for mpg123
37
+ email: carlosjhr64@gmail.com
38
+ executables:
39
+ - gtk2mp3
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - README.txt
44
+ files:
45
+ - ./lib/gtk2mp3/playlist.rb
46
+ - ./lib/gtk2mp3/couple.rb
47
+ - ./lib/gtk2mp3/appconfig.rb
48
+ - ./lib/gtk2mp3.rb
49
+ - ./pngs/logo.png
50
+ - ./pngs/icon.png
51
+ - ./README.txt
52
+ - README.txt
53
+ - bin/gtk2mp3
54
+ has_rdoc: true
55
+ homepage: http://ruby-gnome-apps.blogspot.com/search/label/MP3
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --main
61
+ - README.txt
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ hash: 3
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ requirements:
83
+ - mpg123
84
+ rubyforge_project: gtk2mp3
85
+ rubygems_version: 1.3.7
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Gtk2MP3
89
+ test_files: []
90
+