~haakan/do-plugins/sshfix

« back to all changes in this revision

Viewing changes to xmms2/src/xmms2.cs

  • Committer: Jason Smith
  • Date: 2008-12-24 04:37:17 UTC
  • mto: This revision was merged to the branch mainline in revision 337.
  • Revision ID: jassmith@gmail.com-20081224043717-9yq3uhajlmnyyg5k
Merge community into official

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  xmms2.cs
 
2
//
 
3
//  GNOME Do is the legal property of its developers, whose names are too numerous
 
4
//  to list here.  Please refer to the COPYRIGHT file distributed with this
 
5
//  source distribution.
 
6
//
 
7
//  This program is free software: you can redistribute it and/or modify
 
8
//  it under the terms of the GNU General Public License as published by
 
9
//  the Free Software Foundation, either version 3 of the License, or
 
10
//  (at your option) any later version.
 
11
//
 
12
//  This program is distributed in the hope that it will be useful,
 
13
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
//  GNU General Public License for more details.
 
16
//
 
17
//  You should have received a copy of the GNU General Public License
 
18
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
using System;
 
21
using System.IO;
 
22
using System.Threading;
 
23
using System.Text.RegularExpressions;
 
24
using System.Diagnostics;
 
25
using System.Collections.Generic;
 
26
 
 
27
using Do.Universe;
 
28
 
 
29
namespace Do.Addins.xmms2 {
 
30
 
 
31
        public static class xmms2 {
 
32
                //coverart to be added later
 
33
                //static readonly string MusicLibraryFile;
 
34
                //static readonly string CoverArtDirectory;
 
35
 
 
36
                public static List<SongMusicItem> songs;
 
37
                public static List<PlaylistItem> playlists;
 
38
                
 
39
                static Timer clearSongsTimer;
 
40
                static Timer clearPlaylistsTimer;
 
41
                const int SecondsSongsCached = 45;
 
42
 
 
43
                static xmms2 (){
 
44
                        //string home;
 
45
 
 
46
                        //home =  Environment.GetFolderPath (Environment.SpecialFolder.Personal);
 
47
                        //not needed and not implemented, respectively
 
48
                        //MusicLibraryFile = "~/.gnome2/rhythmbox/rhythmdb.xml".Replace("~", home);
 
49
                        //CoverArtDirectory = "~/.gnome2/rhythmbox/covers".Replace("~", home);
 
50
 
 
51
                        clearSongsTimer = new Timer (ClearSongs);
 
52
                        clearPlaylistsTimer = new Timer (ClearPlaylists);
 
53
                        playlists = new List<PlaylistItem>();
 
54
                        songs = new List<SongMusicItem> ();
 
55
                }
 
56
 
 
57
                public static void LoadAlbumsAndArtists (out List<AlbumMusicItem> albums_out, out List<ArtistMusicItem> artists_out)
 
58
                {
 
59
                        Dictionary<string, AlbumMusicItem> albums;
 
60
                        Dictionary<string, ArtistMusicItem> artists;
 
61
 
 
62
                        albums_out = new List<AlbumMusicItem> ();
 
63
                        artists_out = new List<ArtistMusicItem> ();
 
64
 
 
65
                        albums = new Dictionary<string, AlbumMusicItem> ();
 
66
                        artists = new Dictionary<string, ArtistMusicItem> ();
 
67
                        foreach (SongMusicItem song in LoadAllSongs ()) {       //this is genius, Mr. Siegel.
 
68
                                // Don't let null covers replace non-null covers.
 
69
                                if (!artists.ContainsKey (song.Artist) || artists[song.Artist].Cover == null) {
 
70
                                        artists[song.Artist] = new ArtistMusicItem (song.Artist, song.Cover);
 
71
                                }
 
72
                                if (!albums.ContainsKey (song.Album) || albums[song.Album].Cover == null) {
 
73
                                        albums[song.Album] = new AlbumMusicItem (song.Album, song.Artist, song.Cover);  
 
74
                                }
 
75
                        }
 
76
                        albums_out.AddRange (albums.Values);
 
77
                        artists_out.AddRange (artists.Values);
 
78
                }
 
79
 
 
80
                public static List<SongMusicItem> LoadSongsFor (MusicItem item)
 
81
                {
 
82
                        if(item is SongMusicItem) {
 
83
                                List<SongMusicItem> single = new List<SongMusicItem> ();
 
84
                                single.Add (item as SongMusicItem);
 
85
                                return single;
 
86
                        }else if(item is AlbumMusicItem){
 
87
                                List<SongMusicItem> songs = search(string.Format("album:\"{0}\"*", item.Name)); //cuts down on extraneous search results, more efficient
 
88
                                songs.Sort();
 
89
                                return songs;
 
90
                        }else if(item is ArtistMusicItem){
 
91
                                List<SongMusicItem> songs = search(string.Format("artist:\"{0}\"*", item.Name));
 
92
                                songs.Sort();
 
93
                                return songs;
 
94
                        }
 
95
                        return new List<SongMusicItem>();
 
96
 
 
97
//                      songs = new SortedList<SongMusicItem, SongMusicItem> ();
 
98
//                      foreach (SongMusicItem song in LoadAllSongs ()) { //this is slowish, and causes O(songs) complexity, instead of O(albumlength) or O(SongsbyArtist) 
 
99
//                              switch (item.GetType ().Name) {
 
100
//                                      case "AlbumMusicItem":
 
101
//                                              if (item.Name != song.Album) continue;
 
102
//                                      break;
 
103
//                                      case "ArtistMusicItem":
 
104
//                                              if (item.Name != song.Artist) continue;
 
105
//                                      break;
 
106
//                              }
 
107
//                              try {
 
108
//                                      songs.Add (song, song);
 
109
//                              } catch { }
 
110
//                      }
 
111
//                      return new List<SongMusicItem> (songs.Values);
 
112
                }
 
113
                
 
114
                public static List<SongMusicItem> LoadSongsFor (PlaylistItem list){
 
115
                        string line;
 
116
                        string[] delimarr = new string[] {" - ",};
 
117
                        string[] data;
 
118
                        int id;
 
119
                        SongMusicItem entry;
 
120
                        List<SongMusicItem> entries = new List<SongMusicItem>();
 
121
                        
 
122
                        System.Diagnostics.Process getList;
 
123
                        getList = new System.Diagnostics.Process();
 
124
                        getList.StartInfo.FileName = "xmms2";
 
125
                        getList.StartInfo.Arguments = string.Format("list {0}", list.Name); //Warning: does not guard against improperly formatted queries
 
126
                        getList.StartInfo.RedirectStandardOutput = true;
 
127
                        getList.StartInfo.UseShellExecute = false;
 
128
                        getList.Start();
 
129
                        while(null != (line = getList.StandardOutput.ReadLine())){
 
130
                                try{
 
131
                                        if(line.Substring(2,1) == "["){
 
132
                                                line = Regex.Replace(line, "..\\[.+?\\/", ""); //clears out beginning of line format
 
133
                                                line = Regex.Replace(line, "\\]", " -"); //clears the other ]
 
134
                                                data = line.Split(delimarr, StringSplitOptions.None);
 
135
                                                id = int.Parse(data[0]);
 
136
                                                data[2] = Regex.Replace(data[2], "[^\\w\\s\\d].+$", "");
 
137
                                                entry = new SongMusicItem(id, data[1], "", data[2]); //blank album to match default output.  phooey.
 
138
                                         entries.Add(entry);
 
139
                                        }
 
140
                                }catch(Exception e){
 
141
                                        Console.Error.WriteLine("failed to load playlist: " + e.Message + " at " + line);
 
142
                                }
 
143
                        }
 
144
                        return entries;
 
145
                        
 
146
                }
 
147
 
 
148
                private static void ClearSongs (object state)
 
149
                {
 
150
                        lock (songs) {
 
151
                                songs.Clear ();
 
152
                        }
 
153
                }
 
154
 
 
155
                public static List<SongMusicItem> LoadAllSongs ()
 
156
                {
 
157
                        List<SongMusicItem> songsCopy;
 
158
                        
 
159
                        lock(songs){
 
160
                                // Begin a new timer to clear the songs SecondsSongsCached seconds from now.
 
161
                                clearSongsTimer.Change (SecondsSongsCached*1000, Timeout.Infinite);
 
162
                                
 
163
                                if (songs.Count == 0) {
 
164
                                        // Song list is not cached. Load songs from output of the search
 
165
                                        songs = search("title:*");
 
166
                                }
 
167
                                songsCopy = new List<SongMusicItem> (songs);
 
168
                        }
 
169
                        return songsCopy;
 
170
                }
 
171
                
 
172
                private static void ClearPlaylists (object state)
 
173
                {
 
174
                        lock(playlists){
 
175
                                playlists.Clear();
 
176
                        }
 
177
                }
 
178
                
 
179
                public static List<PlaylistItem> LoadAllPlaylists(){
 
180
                        string line;
 
181
                        List<PlaylistItem> playlistsCopy;
 
182
                        PlaylistItem item;
 
183
                        System.Diagnostics.Process getPla;
 
184
                        getPla = new System.Diagnostics.Process();
 
185
                        getPla.StartInfo.FileName = "xmms2";
 
186
                        getPla.StartInfo.Arguments = "playlist list";
 
187
                        getPla.StartInfo.RedirectStandardOutput = true;
 
188
                        getPla.StartInfo.UseShellExecute = false;
 
189
                        getPla.Start();
 
190
                        lock(playlists){
 
191
                                if (playlists.Count == 0) {
 
192
                                        clearPlaylistsTimer.Change (SecondsSongsCached*1000, Timeout.Infinite);
 
193
                                        while(null != (line = getPla.StandardOutput.ReadLine())){
 
194
                                                item = new PlaylistItem(line.Substring(2));
 
195
                                                if(line.Substring(0,2) == "->"){
 
196
                                                        item.current = true;
 
197
                                                }
 
198
                                                playlists.Add(item);
 
199
                                        }
 
200
                                }
 
201
                                playlistsCopy = new List<PlaylistItem>(playlists);
 
202
                        }
 
203
                        return playlistsCopy;
 
204
                }
 
205
                
 
206
                public static List<SongMusicItem> search(string query){ //queries should be in the form <field>:\"<name>\"
 
207
                        
 
208
                        List<SongMusicItem> songs = new List<SongMusicItem>();
 
209
                        
 
210
                        string line;
 
211
                        string[] data;
 
212
                        string[] delimarr = new string[] {"| ",};
 
213
                        SongMusicItem song;
 
214
                
 
215
                        try{
 
216
 
 
217
                                System.Diagnostics.Process getLib;
 
218
                                getLib = new System.Diagnostics.Process();
 
219
                                getLib.StartInfo.FileName = "xmms2";
 
220
                                getLib.StartInfo.Arguments = string.Format("mlib search {0}", query);
 
221
                                getLib.StartInfo.RedirectStandardOutput = true;
 
222
                                getLib.StartInfo.UseShellExecute = false;
 
223
                                getLib.Start();
 
224
                                getLib.StandardOutput.ReadLine(); //get rid of extraneous
 
225
                                getLib.StandardOutput.ReadLine(); //lines at the top
 
226
                                while(null != (line = getLib.StandardOutput.ReadLine())){
 
227
                                        if(line.Substring(0,1) != "-"){
 
228
                                                data = line.Split(delimarr, StringSplitOptions.RemoveEmptyEntries);
 
229
                                                int id = int.Parse(data[0]);
 
230
                                                for(int i = 1; i <= 3; i++){
 
231
                                                        data[i] = Regex.Replace(data[i], " +$", "");//keeps formatting right, also ensures searches actually work!
 
232
                                                }
 
233
                                                song = new SongMusicItem(id, data[1], data[2], data[3]);
 
234
                                                songs.Add(song);
 
235
                                        }
 
236
                                }
 
237
                        
 
238
                        } catch (Exception e) {
 
239
                                Console.Error.WriteLine ("xmms2 mlib search failed: " + e.Message + " query was " + query);
 
240
                        }
 
241
                        return songs;
 
242
                }
 
243
                
 
244
                public static void StartIfNeccessary ()
 
245
                {
 
246
                        if (!InstanceIsRunning) {
 
247
                                Process.Start ("xmms2d");
 
248
                                System.Threading.Thread.Sleep (3 * 1000);
 
249
                        }
 
250
                }
 
251
 
 
252
                public static bool InstanceIsRunning
 
253
                {
 
254
                        get {
 
255
                                Process pidof;
 
256
 
 
257
                                try {
 
258
                                        // Use pidof command to look for xmms2d process. Exit
 
259
                                        // status is 0 if at least one matching process is found.
 
260
                                        // If there's any error, just assume some it's running.
 
261
                                        pidof = Process.Start ("pidof", "xmms2d");
 
262
                                        pidof.WaitForExit ();
 
263
                                        return pidof.ExitCode == 0;
 
264
                                } catch {
 
265
                                        return true;
 
266
                                }
 
267
                        }
 
268
                }
 
269
 
 
270
                public static void Client (string command)
 
271
                {
 
272
                        Client (command, false);
 
273
                }
 
274
 
 
275
                public static void Client (string command, bool wait)
 
276
                {
 
277
                        Process client;
 
278
                        try {
 
279
                                client = Process.Start ("xmms2", command);
 
280
                                if (wait)
 
281
                                        client.WaitForExit ();
 
282
                        } catch {
 
283
                        }
 
284
                }
 
285
        }
 
286
}