rwdschedule 0.96 → 0.97

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/Readme.txt +5 -0
  2. data/bin/rwdschedule +18 -18
  3. data/code/dd0viewphoto/dd0viewphoto.rb +4 -0
  4. data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +4 -1
  5. data/code/superant.com.rwdtinkerbackwindow/installapplet.rb +5 -3
  6. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +10 -6
  7. data/code/superant.com.schedule/loadconfigurationrecord.rb +11 -0
  8. data/configuration/language.dist +7 -0
  9. data/configuration/rwdapplicationidentity.dist +3 -0
  10. data/configuration/rwdcalendar.dist +10 -0
  11. data/configuration/rwdschedule.dist +15 -0
  12. data/configuration/{rwdtinker.cnf → rwdtinker.dist} +3 -4
  13. data/configuration/{tinkerwin2variables.cnf → tinkerwin2variables.dist} +6 -1
  14. data/extras/cmdline_parse +47 -0
  15. data/extras/config_file +69 -0
  16. data/extras/errorMsg +19 -0
  17. data/extras/makePlaylist +34 -0
  18. data/extras/mp3controld +289 -0
  19. data/extras/playlist +186 -0
  20. data/extras/rconftool.rb +380 -0
  21. data/extras/showHelp +18 -0
  22. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/67viewconfiguration.rwd +11 -1
  23. data/init.rb +42 -37
  24. data/rwd_files/HowTo_Schedule.txt +5 -0
  25. data/rwd_files/HowTo_Tinker.txt +16 -0
  26. data/rwdconfig.dist +6 -0
  27. data/tests/checkdepends.sh +4 -0
  28. data/tests/cleancnf.sh +5 -0
  29. data/tests/makedist.rb +29 -0
  30. data/tests/rdep.rb +354 -0
  31. metadata +26 -23
  32. data/configuration/language.cnf +0 -5
  33. data/configuration/rwdapplicationidentity.cnf +0 -3
  34. data/configuration/rwdcalendar.cnf +0 -4
  35. data/configuration/rwdcalendarversion.cnf +0 -4
  36. data/configuration/rwdschedule.cnf +0 -7
  37. data/configuration/rwdscheduleversion.cnf +0 -3
  38. data/configuration/rwdtinkerversion.cnf +0 -2
  39. data/configuration/tinkerwin2version.cnf +0 -3
  40. data/lang/alanguagehashbegin.rb +0 -4
  41. data/lang/languagehash.rb +0 -4
  42. data/lang/templangfile.rb +0 -22
  43. data/lang/vlanguagehashend.rb +0 -6
  44. data/lang/wlocallangstart.rb +0 -5
  45. data/lang/xlocallangfile.rb +0 -22
  46. data/lang/zlocallangend.rb +0 -2
  47. data/rwdschedule-0.96.gem +0 -0
data/Readme.txt CHANGED
@@ -154,6 +154,11 @@ Steven Gibson
154
154
  steven@superant.com
155
155
 
156
156
  == Changelog
157
+ version 0.97
158
+ added rconftool use to update configuration files
159
+ changed applet removal to not use external rm
160
+ removed version number from directory name
161
+
157
162
  version 0.96
158
163
  added export ics record
159
164
  added end time for ics create record
data/bin/rwdschedule CHANGED
@@ -1,19 +1,19 @@
1
- #!/usr/bin/env ruby
2
- #--
3
- # Copyright 2004 Steven Gibson <steven@superant.com>
4
- # RwdTinker application
5
- #
6
- # This program is free software. It may be redistributed and/or modified under
7
- # the terms of the GPL version 2 (or later), or the
8
- # Ruby licence.
9
- #
10
- #++
11
-
12
-
13
- $progdir = File::expand_path( File.dirname(__FILE__))
14
-
15
- Dir.chdir($progdir)
16
-
17
- Dir.chdir("..")
18
-
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004 Steven Gibson <steven@superant.com>
4
+ # RwdTinker application
5
+ #
6
+ # This program is free software. It may be redistributed and/or modified under
7
+ # the terms of the GPL version 2 (or later), or the
8
+ # Ruby licence.
9
+ #
10
+ #++
11
+
12
+
13
+ $progdir = File::expand_path( File.dirname(__FILE__))
14
+
15
+ Dir.chdir($progdir)
16
+
17
+ Dir.chdir("..")
18
+
19
19
  `ruby init.rb`
@@ -0,0 +1,4 @@
1
+ def viewphoto
2
+ @rwd_window = "photo"
3
+
4
+ end
@@ -9,6 +9,7 @@
9
9
 
10
10
  rwdtinker applets packaged as RubyGems can be used if you have RubyGems installed.
11
11
  You can download rwdtinker gems at the 'Install Remote Applets' tab
12
+ to install applets you need the ruby zlib library installed
12
13
  ",
13
14
  :applet_viewing => "You can get a list of all installed applets by clicking the 'listfiles button'
14
15
  To see the text of a install file
@@ -32,7 +33,9 @@
32
33
  chose the applet you want\n
33
34
  click on 'install applet'\n
34
35
  If all goes well the applet should be installed.\n
35
- You will need to restart rwdtinker to see the new screens",
36
+ You will need to restart rwdtinker to see the new screens
37
+ to install applets you need the ruby zlib library installed",
38
+
36
39
  :applet_tinkerbackeditconfiguration => " You can edit the configuration
37
40
 
38
41
  Remember to reload the configuration variables if you want your
@@ -1,10 +1,12 @@
1
1
  # code in install rwdtinker applets - now uses ruby.zip module
2
2
  def installapplet
3
- require 'fileutils'
4
- require 'extras/zip/zip'
3
+
5
4
  nametext = "%s" % [@a_installapplet]
6
-
5
+
7
6
  begin # exception trapped block
7
+
8
+
9
+ require 'extras/zip/zip'
8
10
  fullname = nametext + ".zip"
9
11
  fileName = File.join($zipslocation,fullname)
10
12
 
@@ -10,19 +10,23 @@
10
10
 
11
11
  fd.each { |oneline|
12
12
  if count == 1
13
- commandline = "rm -r " + oneline
14
- system( commandline+' > temp.output' )
13
+ if File.exist?(oneline.chop)
14
+ FileUtils.rm_rf( oneline.chop)
15
+ end
16
+
15
17
  end
16
18
  count = 1
17
19
  }
18
20
  fd.close
19
- commandline = "rm " + fileName
21
+
22
+ FileUtils.rm_rf( fileName)
23
+
20
24
 
21
- system(commandline)
22
25
  @removeapplettext = "applet files removed! - restart rwd to finish uninstalling"
23
26
 
24
27
  rescue
25
- @removeapplettext = "\n" + "error"
26
- end # exception rescue
28
+ @removeapplettext = "\n" + "error"
29
+
30
+ end # exception rescue
27
31
 
28
32
  end
@@ -22,6 +22,17 @@
22
22
  @a_schconfigline7 =fd.readline.chomp
23
23
  @a_schconfigline8 = fd.readline.chomp
24
24
  @a_schconfigline9 = fd.readline.chomp
25
+ @a_schconfigline10= fd.readline.chomp
26
+ @a_schconfigline10= fd.readline.chomp
27
+ @a_schconfigline11= fd.readline.chomp
28
+ @a_schconfigline12= fd.readline.chomp
29
+ @a_schconfigline13= fd.readline.chomp
30
+ @a_schconfigline14= fd.readline.chomp
31
+ @a_schconfigline15= fd.readline.chomp
32
+ @a_schconfigline16= fd.readline.chomp
33
+ @a_schconfigline17= fd.readline.chomp
34
+ @a_schconfigline18= fd.readline.chomp
35
+
25
36
 
26
37
  while ! fd.eof?
27
38
  @extraschconfigdatadisplay = fd.readline
@@ -0,0 +1,7 @@
1
+ ##VERSION:1.57
2
+ #language selection file
3
+ ##NAME:$lang:0
4
+ #$lang = "jp"
5
+ $lang= "en"
6
+ #$lang= "nl"
7
+ #$lang= "es"
@@ -0,0 +1,3 @@
1
+ ##VERSION:1.57
2
+ $rwdapplicationidentity = "rwdtinker main application"
3
+
@@ -0,0 +1,10 @@
1
+ ##VERSION:0.97
2
+ # rwdcalendar
3
+ ##NAME:$extras_directory:0
4
+ $extras_directory = "extras"
5
+
6
+
7
+
8
+
9
+
10
+
@@ -0,0 +1,15 @@
1
+ ##VERSION:0.97
2
+ ##NAME:$rwdschedule_directory:0
3
+ $rwdschedule_directory = "schedules"
4
+ ##NAME:$rwdschedule_ftpsite:0
5
+ $rwdschedule_ftpsite = "ftp.mysite.com"
6
+ ##NAME:$rwdschedule_ftplogin:0
7
+ $rwdschedule_ftplogin = "mylogin"
8
+ ##NAME:$rwdschedule_ftppassword:0
9
+ $rwdschedule_ftppassword = "mypassword"
10
+ ##NAME:$rwdschedule_ftpdirectory:0
11
+ $rwdschedule_ftpdirectory = "/incoming/rwdschedules/"
12
+ ##NAME:$rwdschedule_updatedirectory:0
13
+ $rwdschedule_updatedirectory = "updates"
14
+ RwdScheduleVersion = "0.97"
15
+
@@ -1,12 +1,9 @@
1
-
1
+ ##VERSION:1.58
2
2
  ConfigurationDir = "configuration" # for use in program - init.rb has this value without using this constant
3
3
  CodeName = "rwdtinker"
4
4
  CodeNameFile = CodeName + ".rb"
5
- LangNameFile = "rwdlanguage.rb"
6
5
  RWDFile = "rwdtinker.rwd"
7
6
  LangDir = "lang"
8
- TempLangHashFile = LangDir + "/" + "templangfile.rb"
9
- LocalLangHashFile = LangDir + "/" + "xlocallangfile.rb"
10
7
  CodeDir = "code"
11
8
  GuiDir = "gui"
12
9
  $help_topic = "general_help"
@@ -14,3 +11,5 @@ LocalLangHashFile = LangDir + "/" + "xlocallangfile.rb"
14
11
  $prevouswindow ="main"
15
12
  $rwdcontrolports =["13713","13714","13715","13716","13717","13718"]
16
13
  $port = 7705
14
+
15
+ RwdTinkerVersion = "1.58"
@@ -1,12 +1,17 @@
1
-
1
+ ##VERSION:1.57
2
2
  TinkerWin2ConfigurationFileName = "tinkerwin2variables.cnf" # this file name - do not change
3
+ ##NAME:$zipslocation:0
3
4
  $zipslocation = "zips" # location of applets to add
4
5
  $zipsarray = [""] ; $zipsarraylocal = [""]
6
+ ##NAME:$xpcommand:0
5
7
  $xpcommand = " " # Linux machines
6
8
  # $xpcommand = "cmd /C " # XP machines with cmd shell
9
+ ##NAME:$gemdirectory_withgemfiles:0
7
10
  $gemdirectory_withgemfiles = "/usr/lib/ruby/gems/1.8/gems"
8
11
  # $gemdirectory_withgemfiles = "c:\\ruby\\lib\\ruby\\gems\\1.8\\gems" # XP machine
12
+ ##NAME:$geminstalled_directory:0
9
13
  # $geminstalled_directory = "/ruby/lib/ruby/gems/1.8/gems" # XP machine
10
14
  $geminstalled_directory = "/usr/lib/ruby/gems/1.8/gems" # Debian Linux
11
15
 
16
+ RwdTinkerWin2Version = "0.8"
12
17
 
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/ruby
2
+ # --- Parse command line ---
3
+ #
4
+ # Author: Magnus Engstr�m
5
+ # Email: magnus@gisab.se
6
+ # File: cmdline_parse
7
+ #
8
+ # Description
9
+ # -----------
10
+ # Parses the commandline and
11
+ # returns a hash with the
12
+ # switch as key and the
13
+ # value as value :)
14
+ # --------------------------
15
+
16
+ class Commandline
17
+ def Commandline::parse()
18
+
19
+ params = Hash::new() # Could be useful to have something to put the commandline in ;)
20
+ key = false # Just a really ugly hack to keep track on if we're reading key or value
21
+ foo = '' # Keeps the key name
22
+
23
+ # Iterate through the command line ($*) and put it in the params hash
24
+ $*.each { |param|
25
+ key = ( key == true ? false : true ) # Negate the value of key
26
+ if(key)
27
+ foo = param
28
+ else
29
+ params[foo] = param
30
+ end
31
+ }
32
+
33
+ # Validate the command line.
34
+ # Every key should begin with at least one '-' and have a value
35
+ if( !key ) # If key equals true, then the user should enter one more parameter
36
+ passed = true
37
+ params.each { |key, value| # Iterate through all parameters
38
+ passed = false if(key[0].chr() != '-') # Doesn't it start with a '-'? Not passed...
39
+ passed = false if(value == '') # I really want a value here, not just an empty string
40
+ }
41
+ end
42
+
43
+ # Return params if check passed, else return -1
44
+ passed ? params : -1
45
+
46
+ end
47
+ end
@@ -0,0 +1,69 @@
1
+ #!ruby
2
+ require 'ftools'
3
+ require 'tempfile'
4
+
5
+ class ConfigFile
6
+
7
+ def ConfigFile::parse(filename)
8
+ # Make sure this file exists and is readable
9
+ if( FileTest::readable_real?(filename) )
10
+ new(filename) # Return the class instance
11
+ else
12
+ -1 # Return -1 on failure
13
+ end
14
+ end
15
+
16
+ def initialize(filename)
17
+ @filename = filename
18
+ @config = Hash::new() # The class internal variable that holds the config data
19
+ section = ''
20
+
21
+ # Parse the configuration file (and in only TWO rows, God I love Ruby! =)
22
+ IO::foreach(@filename) { |configLine| @config[section = $1] = Hash::new() if(configLine.gsub(/\s*#.*$/, '') =~ /\s*(\S+)\s*\{/)
23
+ @config[section].update({$1 => $2}) if(configLine.gsub(/\s*#.*$/, '') =~ /\s*(\S+)\s*=\s*(.*)/) }
24
+ end
25
+
26
+ # Return the requested parameter
27
+ def getParam(section, parameter)
28
+ @config[section][parameter] if(@config[section].type == Hash)
29
+ end
30
+
31
+ # Set the provided parameter
32
+ def setParam(section, parameter, value)
33
+ # Create a temp file
34
+ temp = Tempfile::new('config')
35
+
36
+ current_section = ''
37
+ # Loop through the config file
38
+ IO::foreach(@filename) { |line|
39
+ current_section = $1 if( line =~ /^\s*(\S+)\s*{\s*(#.*)?$/ ) # Handle the section stuff
40
+ # Is this a correct parameter entry?
41
+ if( line =~ /^\s*(\S+)\s*=\s*\S+\s*(#.*)?$/ )
42
+
43
+ if( current_section == section && $1 == parameter ) # This is the line we want to change!
44
+ line.gsub!( /^(\s*\S+\s*=\s*)\S+(\s*(#.*)?)$/, "\\1#{value}\\2" ) # Change the parameter value to the one the user supplied
45
+ end
46
+
47
+ end
48
+
49
+ temp.puts(line) # Write the line to the tempfile
50
+ }
51
+
52
+ temp.close() # Close the file
53
+ File::copy(temp.path, @filename) # Copy the tempfile to overwrite the old one
54
+ temp.close(true) # Remove the file
55
+ end
56
+
57
+ # Loop through all sections
58
+ def each_section()
59
+ @config.each { |key,value| yield(key) }
60
+ end
61
+
62
+ # Loop through all parameters in a section
63
+ def each_parameter(section)
64
+ @config[section].each { |key,value| yield(key) }
65
+ end
66
+
67
+ attr_reader :filename
68
+
69
+ end
data/extras/errorMsg ADDED
@@ -0,0 +1,19 @@
1
+ #!ruby
2
+
3
+ # --- errorMsg ---
4
+ #
5
+ # Author: Magnus Engstr�m
6
+ # Email: magnus@gisab.se
7
+ # File: errorWrite
8
+ #
9
+ # Description
10
+ # -----------
11
+ # Outputs an error message to the administrator
12
+ # ------------------
13
+
14
+ def errorMsg(message, exitapp = false)
15
+ STDERR.puts(message)
16
+ MP3Control::exit_mpg123() if(exitapp)
17
+ Kernel::exit(exitapp) if(exitapp) # Terminate application and return the exitapp value if it isn't falsew
18
+
19
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/ruby
2
+ require 'mp3tag'
3
+
4
+ def getList(dir)
5
+ Dir::chdir(dir)
6
+
7
+ # Find the files in this directory
8
+ Dir['*mp3'].each { |file|
9
+ if(FileTest::file?(file))
10
+ mp3tag = Mp3Tag::new(Dir::getwd()+"/"+file)
11
+ if(mp3tag.songname.length > 0)
12
+ puts("#{Dir::getwd()+"/"+file}||#{mp3tag.songname}||#{mp3tag.artist}||#{mp3tag.album}||#{mp3tag.year}||#{mp3tag.comment}||#{mp3tag.tracknum}||#{mp3tag.genre_id}||#{mp3tag.genre}")
13
+ else
14
+ name = Dir::getwd()+"/"+file
15
+ name =~ /([^\/]+)\.mp3$/
16
+ puts("#{Dir::getwd()+"/"+file}||#{$1}||#{mp3tag.artist}||#{mp3tag.album}||#{mp3tag.year}||#{mp3tag.comment}||#{mp3tag.tracknum}||#{mp3tag.genre_id}||#{mp3tag.genre}")
17
+ end
18
+ end
19
+ }
20
+
21
+ Dir['*'].each { |entry|
22
+ if(FileTest::directory?(entry))
23
+ getList(entry)
24
+ end
25
+ }
26
+ Dir::chdir('..')
27
+ end
28
+
29
+ # Change current directory to user supplied one
30
+ Dir::chdir(ARGV[0])
31
+ getList(ARGV[0])
32
+
33
+ #song = Mp3Tag::new(ARGV[0])
34
+ #puts song.songname()
@@ -0,0 +1,289 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # --- MP3 Control ---
4
+ #
5
+ # Author: Magnus Engstr�m
6
+ # Email: magnus@gisab.se
7
+ # File: mp3controld
8
+ #
9
+ # Description
10
+ # -----------
11
+ # An application which manages
12
+ # mp3 songs on the poor users
13
+ # computer.
14
+ # -------------------------
15
+
16
+ # --- External files ---
17
+ # Change directory to find all functions
18
+ #Dir::chdir("/usr/lib/mp3control")
19
+
20
+ load "extras/config_file" # Handles the mp3controld.conf configuration file
21
+ load "extras/cmdline_parse" # Provides the Commandline::parse which returns an hash of the commandline
22
+ load "extras/showHelp" # Hmmm... guess what? This function shows the help message =)
23
+ load "extras/errorMsg" # Outputs error messages to the admin
24
+ load "extras/playlist" # Core playlist functionality
25
+
26
+ # --- MP3Control - the main class ---
27
+ class MP3Control
28
+ # --- Core functions ---
29
+ # initialize() reads the config files and daemonizes!
30
+ def initialize()
31
+ # Parse the commandline
32
+ $commandline = Commandline::parse()
33
+
34
+ # Display help if the commandline sucks
35
+ if($commandline == -1)
36
+ showHelp()
37
+ Kernel::exit(-1)
38
+ end
39
+
40
+ # Make this class instance a background daemon
41
+ daemonize() if($commandline["--daemon"] != 'no' && $commandline["-D"] != 'no')
42
+
43
+ # Read the configuration file
44
+ configfile = ( $commandline["--configfile"] ? $commandline["--configfile"] : 'configuration/mp3controld.conf' ) # Use the --configfile if supplied, else use the default /etc/mp3controld/mp3controld.conf
45
+ $configFile = ConfigFile::parse(configfile) # Create an new config file object
46
+ errorMsg("Configuration file #{configfile} isn't readable or doesn't exist!", 137) if($configFile == -1)
47
+
48
+ # Find the default playlist (or use the user supplied one from the commandline)
49
+ defaultPlaylist = $configFile.getParam("programConfig", "defaultPlaylist")
50
+ defaultPlaylist = $commandline["--playlist"] if($commandline["--playlist"])
51
+ if( $configFile.getParam(defaultPlaylist, 'listFile').type == String) # Make sure the listFile contains a value
52
+ if(FileTest.readable_real?( $configFile.getParam(defaultPlaylist, 'listFile') )) # Make sure this file is readable
53
+ # Cool. Everything looks alright. Lets create a playlist!
54
+ errorMsg("Loading playlist '#{defaultPlaylist}' from #{$configFile.getParam(defaultPlaylist, 'listFile')}...") if($commandline['--verbose'] == 'on')
55
+ $current_playlist = Playlist::create_from_file($configFile.getParam(defaultPlaylist, 'listFile'))
56
+ $current_playlist_name = defaultPlaylist
57
+
58
+ # Errorhandling
59
+ errorMsg("Playlist creation from #{$current_playlist.filename} failed.", 1) if($current_playlist == -1) # Quit and complain if it didn't work
60
+ errorMsg("Playlist #{defaultPlaylist} (#{$current_playlist.filename}) doesn't contain any entries.", 1) if($current_playlist.length() < 1)
61
+ errorMsg("Playlist '#{defaultPlaylist}' loaded successfully.") if($commandline["--verbose"] == 'on')
62
+
63
+ # Fix wrap/repeat and shuffle the playlist if the configfile says so
64
+ $current_playlist.wrap = true if($configFile.getParam(defaultPlaylist, 'repeat') == 'true')
65
+ $current_playlist.shuffle() if($configFile.getParam(defaultPlaylist, 'random') == 'true')
66
+ $current_playlist.goto(0) # Rewind the playlist
67
+ else
68
+ errorMsg("The default playlist doesn't appear to exist, or has the wrong permissions. That's not good.", 1)
69
+ end
70
+ else # listFile returns other than string, that's baaaaad
71
+ errorMsg("the listFile value for '#{defaultPlaylist}' doesn't appear to exist in your #{$configFile.filename}. That's not good.", 1)
72
+ end
73
+
74
+ # Check for the existence of our mpg123 instance
75
+ errorMsg("Trying to find the mp3 player...") if($commandline["--verbose"] == 'on')
76
+ @mpg123 = $configFile.getParam('programConfig', 'application') # Get the application name, path, and possible arguments
77
+ mpg123_application = @mpg123.scan(/^\S+/)
78
+ if(mpg123_application.type == Array)
79
+ mpg123_application = mpg123_application[0]
80
+ else
81
+ errorMsg("Please check your ProgramConfig/application setting in the configuration file. It seems weird.", 1)
82
+ end
83
+
84
+ # Do some nice errorhandling
85
+ if( !FileTest::executable_real?(mpg123_application) )
86
+ errorMsg("#{mpg123_application} doesn't appear to exist. Please do something about it (no, not \"touch #{mpg123_application}\"! Stupid!).", 1)
87
+ else
88
+ errorMsg("Found #{mpg123_application}!") if($commandline["--verbose"] == 'on')
89
+ end
90
+
91
+ # Open an instance of mpg123, our high-performance mp3 player
92
+ @@mpg123 = IO::popen("#{@mpg123} -R -", 'r+')
93
+
94
+ # Start all plugins
95
+ load_plugins()
96
+
97
+ # Start the mp3 player
98
+ mpg123_control()
99
+
100
+ end
101
+
102
+ # mpg123_control() gets the input from the mpg123 process and handles it hopefully correctly :)
103
+ def mpg123_control()
104
+
105
+ # Initialize class variables
106
+ @@stopped = false
107
+
108
+ # Start playing if the configfile says so
109
+ if( $configFile.getParam('programConfig', 'playOnStartup') == 'true' )
110
+ MP3Control::play()
111
+ else
112
+ puts("Dont want to play!")
113
+ end
114
+
115
+ # The infinite 5 second loop =)
116
+ while(true)
117
+ begin
118
+ input = @@mpg123.readline.chop()
119
+ rescue EOFError
120
+ errorMsg("mpg123 error! Probably just a file that didn't exist (#{$current_playlist.song_info["filename"]}).")
121
+ @@mpg123 = IO::popen("#{@mpg123} -R -", 'r+') # Just start it again...
122
+ MP3Control::next_song() # Next song, so it doesn't die again...
123
+ end
124
+
125
+ # Song stopped
126
+ MP3Control::next_song() if(input == '@P 0' && @@stopped != true) # Change to the next song if current song stops and the user didn't told it to
127
+ @@stopped = false if(input == '@P 0' && @@stopped == true) # Reset the stop-flag if the user ordered the stop
128
+
129
+ # Time left
130
+ if(input[0,2] == '@F')
131
+ input =~ /^@F\s+\S+\s+\S+\s+(\S+)\s+(\S+)$/
132
+ @@time = $1
133
+ @@timeleft = $2
134
+ end
135
+
136
+ end
137
+ end
138
+
139
+ # start() creates a new instance. Just like .new, but a nicer name.
140
+ def MP3Control::start()
141
+ MP3Control::new()
142
+ end
143
+
144
+ # daemonize() daemonizes this process. Cool =)
145
+ def daemonize()
146
+ if(child_pid = fork) # Parent code
147
+ puts("PID #{child_pid}")
148
+ Kernel::exit(0) # We dont want this parent process any more. Too bad.
149
+ end
150
+
151
+ # Child code. And child wants to be free from parent
152
+ Process.setsid()
153
+ end
154
+
155
+ # load_plugins() loads all plugins that can be found in the plugins directory
156
+ def load_plugins()
157
+ Dir::entries('extras/plugins/').each { |plugin|
158
+ # Try to load every plugin except all files that begins with a dot
159
+ if(plugin[0].chr() != '.')
160
+ retval = 0
161
+ # Do some errorhandling
162
+ begin
163
+ load("extras/plugins/#{plugin}") # Load the files
164
+ errorMsg("Loaded plugin '#{plugin}'") if($commandline['--verbose'] == 'no')
165
+ rescue SyntaxError
166
+ errorMsg("Plugin '#{plugin}' has syntax errors.")
167
+ end
168
+
169
+ # Run the plugin in a separate thread
170
+ # Try to start the class with the same name as the plugin
171
+ eval("
172
+ Thread::new() {
173
+ start_again = true
174
+ while(start_again)
175
+ puts(\"Plugin starting...\")
176
+ begin
177
+ retval = #{plugin}::start()
178
+ rescue
179
+ error = $!
180
+ puts(error)
181
+ puts(error.backtrace)
182
+ puts(\"Error in plugin #{plugin}! Waiting for 5 seconds before attempting to start again...\")
183
+ sleep(5)
184
+ end
185
+ if(retval == -1)
186
+ errorMsg(\"Plugin 'plugins/#{plugin}' failed to load...\")
187
+ start_again = false
188
+ end
189
+ end
190
+ }
191
+ ")
192
+
193
+ end
194
+ }
195
+ end
196
+
197
+ # exit_mpg123() terminates the current mpg123 session
198
+ def MP3Control::exit_mpg123()
199
+ #system("kill `pidof mpg123`") # Yes, I know this isn't a nice way to do it in, please fix this and send me a patch :)
200
+ end
201
+
202
+ # mpg123_command() sends a command to mpg123
203
+ def MP3Control::mpg123_command(command)
204
+ errorMsg("mpg123 command: '#{command}'") if($commandline['--verbose'] == 'on')
205
+ @@mpg123.write("#{command}\n")
206
+ @@mpg123.flush()
207
+ end
208
+
209
+
210
+ # --- play functions ---
211
+ # play() plays the current index of the current playlist
212
+ def MP3Control::play()
213
+ @@stopped = false
214
+ mpg123_command("LOAD #{$current_playlist.song_info["filename"]}")
215
+ end
216
+
217
+ # stop() stops playing
218
+ def MP3Control::stop()
219
+ mpg123_command("PAUSE")
220
+ @@stopped = true # Set the stop-status to true
221
+ end
222
+
223
+ # pause() pauses playing
224
+ def MP3Control::pause()
225
+ @@stopped = false
226
+ mpg123_command("PAUSE")
227
+ end
228
+
229
+ # next_song() loads the next song. Yay...
230
+ def MP3Control::next_song()
231
+ retval = $current_playlist.next()
232
+ if(retval == -1)
233
+ errorMsg("Error while changing to the next song.") # Tell him/her
234
+ else
235
+ MP3Control::play() if(@@stopped == false)
236
+ end
237
+ end
238
+
239
+ # prev_song() loads the previous song. Yay...
240
+ def MP3Control::prev_song()
241
+ retval = $current_playlist.prev()
242
+ if(retval == -1)
243
+ errorMsg("Error while changing to the previous song.") # Tell him/her
244
+ else
245
+ MP3Control::play() if(@@stopped == false)
246
+ end
247
+ end
248
+
249
+ # forward(sec) jumps sec seconds forward
250
+ def MP3Control::forward(sec)
251
+ mpg123_command("JUMP +#{sec*38}")
252
+ end
253
+
254
+ # backward(sec) jumps sec seconds backward
255
+ def MP3Control::backward(sec)
256
+ mpg123_command("JUMP -#{sec*38}")
257
+ end
258
+
259
+
260
+ # --- Misc functions ---
261
+ # getTime() - Get the current song time information. getTime(true) for time left
262
+ def MP3Control::getTime(whichTime = 'elapsed')
263
+ case whichTime
264
+ when 'elapsed'
265
+ parsed = Time::at(@@time.to_i)
266
+ when 'left'
267
+ parsed = Time::at(@@timeleft.to_i)
268
+ when 'total'
269
+ parsed = Time::at( (@@time.to_f + @@timeleft.to_f).to_i )
270
+ end
271
+
272
+ hour = (parsed.hour - 1).to_s
273
+ min = parsed.min.to_s
274
+ sec = parsed.sec.to_s
275
+
276
+ hour = "0#{hour}" if(hour.length == 1)
277
+ min = "0#{min}" if(min.length == 1)
278
+ sec = "0#{sec}" if(sec.length == 1)
279
+
280
+ hour = (hour == '00' ? '' : "#{hour}:")
281
+
282
+ # Return the now formatted time
283
+ "#{hour}#{min}:#{sec}"
284
+ end
285
+
286
+ end
287
+
288
+ # Create an instance of the MP3Control class and start the application
289
+ MP3Control::start()