1 /*
2  * handlers_playlist.c
3  * Copyright 2005-2013 George Averill, Ariadne Conill, Yoshiki Yazawa,
4  *                     Matti Hämäläinen, and John Lindgren
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  *    this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions, and the following disclaimer in the documentation
14  *    provided with the distribution.
15  *
16  * This software is provided "as is" and without any warranty, express or
17  * implied. In no event shall the authors be liable for any damages arising from
18  * the use of this software.
19  */
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "audtool.h"
25 #include "wrappers.h"
26 
select_displayed(int argc,char ** argv)27 void select_displayed (int argc, char * * argv)
28 {
29     obj_audacious_call_select_displayed_playlist_sync (dbus_proxy, NULL, NULL);
30 }
31 
select_playing(int argc,char ** argv)32 void select_playing (int argc, char * * argv)
33 {
34     obj_audacious_call_select_playing_playlist_sync (dbus_proxy, NULL, NULL);
35 }
36 
playlist_reverse(int argc,char ** argv)37 void playlist_reverse (int argc, char * * argv)
38 {
39     obj_audacious_call_reverse_sync (dbus_proxy, NULL, NULL);
40 }
41 
playlist_reverse_album(int argc,char ** argv)42 void playlist_reverse_album (int argc, char * * argv)
43 {
44     obj_audacious_call_reverse_album_sync (dbus_proxy, NULL, NULL);
45 }
46 
playlist_advance(int argc,char ** argv)47 void playlist_advance (int argc, char * * argv)
48 {
49     obj_audacious_call_advance_sync (dbus_proxy, NULL, NULL);
50 }
51 
playlist_advance_album(int argc,char ** argv)52 void playlist_advance_album (int argc, char * * argv)
53 {
54     obj_audacious_call_advance_album_sync (dbus_proxy, NULL, NULL);
55 }
56 
playlist_auto_advance_status(int argc,char ** argv)57 void playlist_auto_advance_status (int argc, char * * argv)
58 {
59     gboolean advance = FALSE;
60     obj_audacious_call_auto_advance_sync (dbus_proxy, & advance, NULL, NULL);
61     audtool_report (advance ? "on" : "off");
62 }
63 
playlist_auto_advance_toggle(int argc,char ** argv)64 void playlist_auto_advance_toggle (int argc, char * * argv)
65 {
66     obj_audacious_call_toggle_auto_advance_sync (dbus_proxy, NULL, NULL);
67 }
68 
playlist_stop_after_status(int argc,char ** argv)69 void playlist_stop_after_status (int argc, char * * argv)
70 {
71     gboolean stop_after = FALSE;
72     obj_audacious_call_stop_after_sync (dbus_proxy, & stop_after, NULL, NULL);
73     audtool_report (stop_after ? "on" : "off");
74 }
75 
playlist_stop_after_toggle(int argc,char ** argv)76 void playlist_stop_after_toggle (int argc, char * * argv)
77 {
78     obj_audacious_call_toggle_stop_after_sync (dbus_proxy, NULL, NULL);
79 }
80 
check_args_playlist_pos(int argc,char ** argv)81 int check_args_playlist_pos (int argc, char * * argv)
82 {
83     int pos;
84 
85     if (argc < 2 || (pos = atoi (argv[1])) < 1)
86     {
87         audtool_whine_args (argv[0], "<position>");
88         exit (1);
89     }
90 
91     return pos;
92 }
93 
construct_uri(char * string)94 static char * construct_uri (char * string)
95 {
96     char * filename = g_strdup (string);
97     char * tmp, * path;
98     char * uri = NULL;
99 
100     // case 1: filename is raw full path or uri
101     if (filename[0] == '/' || strstr (filename, "://"))
102     {
103         uri = g_filename_to_uri (filename, NULL, NULL);
104 
105         if (! uri)
106             uri = g_strdup (filename);
107 
108         g_free (filename);
109     }
110     // case 2: filename is not raw full path nor uri.
111     // make full path with pwd. (using g_build_filename)
112     else
113     {
114         path = g_get_current_dir();
115         tmp = g_build_filename (path, filename, NULL);
116         g_free (path);
117         g_free (filename);
118         uri = g_filename_to_uri (tmp, NULL, NULL);
119         g_free (tmp);
120     }
121 
122     return uri;
123 }
124 
playlist_add_url_string(int argc,char ** argv)125 void playlist_add_url_string (int argc, char * * argv)
126 {
127     char * uri;
128 
129     if (argc < 2)
130     {
131         audtool_whine_args (argv[0], "<url>");
132         exit (1);
133     }
134 
135     uri = construct_uri (argv[1]);
136 
137     if (! uri)
138         exit (1);
139 
140     obj_audacious_call_add_sync (dbus_proxy, uri, NULL, NULL);
141     g_free (uri);
142 }
143 
playlist_delete(int argc,char ** argv)144 void playlist_delete (int argc, char * * argv)
145 {
146     int pos = check_args_playlist_pos (argc, argv);
147     obj_audacious_call_delete_sync (dbus_proxy, pos - 1, NULL, NULL);
148 }
149 
playlist_length(int argc,char ** argv)150 void playlist_length (int argc, char * * argv)
151 {
152     audtool_report ("%d", get_playlist_length ());
153 }
154 
playlist_song(int argc,char ** argv)155 void playlist_song (int argc, char * * argv)
156 {
157     int pos = check_args_playlist_pos (argc, argv);
158     char * title = get_entry_title (pos - 1);
159     audtool_report ("%s", title);
160     g_free (title);
161 }
162 
number_of_playlists(int argc,char ** argv)163 void number_of_playlists (int argc, char * * argv)
164 {
165     int playlists = 0;
166     obj_audacious_call_number_of_playlists_sync (dbus_proxy, & playlists, NULL, NULL);
167     audtool_report ("%d", playlists);
168 }
169 
current_playlist(int argc,char ** argv)170 void current_playlist (int argc, char * * argv)
171 {
172     int playlist = -1;
173     obj_audacious_call_get_active_playlist_sync (dbus_proxy, & playlist, NULL, NULL);
174     audtool_report ("%d", playlist + 1);
175 }
176 
set_current_playlist(int argc,char ** argv)177 void set_current_playlist (int argc, char * * argv)
178 {
179     if (argc < 2)
180     {
181         audtool_whine_args (argv[0], "<number>");
182         exit (1);
183     }
184 
185     obj_audacious_call_set_active_playlist_sync (dbus_proxy, atoi (argv[1]) - 1, NULL, NULL);
186 }
187 
playlist_title(int argc,char ** argv)188 void playlist_title (int argc, char * * argv)
189 {
190     char * title = NULL;
191     obj_audacious_call_get_active_playlist_name_sync (dbus_proxy, & title, NULL, NULL);
192 
193     if (! title)
194         exit (1);
195 
196     audtool_report ("%s", title);
197     g_free (title);
198 }
199 
set_playlist_title(int argc,char ** argv)200 void set_playlist_title (int argc, char * * argv)
201 {
202     if (argc < 2)
203     {
204         audtool_whine_args (argv[0], "<title>");
205         exit (1);
206     }
207 
208     obj_audacious_call_set_active_playlist_name_sync (dbus_proxy, argv[1], NULL, NULL);
209 }
210 
new_playlist(int argc,char ** argv)211 void new_playlist (int argc, char * * argv)
212 {
213     obj_audacious_call_new_playlist_sync (dbus_proxy, NULL, NULL);
214 }
215 
delete_current_playlist(int argc,char ** argv)216 void delete_current_playlist (int argc, char * * argv)
217 {
218     obj_audacious_call_delete_active_playlist_sync (dbus_proxy, NULL, NULL);
219 }
220 
play_current_playlist(int argc,char ** argv)221 void play_current_playlist (int argc, char * * argv)
222 {
223     obj_audacious_call_play_active_playlist_sync (dbus_proxy, NULL, NULL);
224 }
225 
playlist_song_length(int argc,char ** argv)226 void playlist_song_length (int argc, char * * argv)
227 {
228     int pos = check_args_playlist_pos (argc, argv);
229     int length = get_entry_length (pos - 1) / 1000;
230     audtool_report ("%d:%.2d", length / 60, length % 60);
231 }
232 
playlist_song_length_seconds(int argc,char ** argv)233 void playlist_song_length_seconds (int argc, char * * argv)
234 {
235     int pos = check_args_playlist_pos (argc, argv);
236     int length = get_entry_length (pos - 1) / 1000;
237     audtool_report ("%d", length);
238 }
239 
playlist_song_length_frames(int argc,char ** argv)240 void playlist_song_length_frames (int argc, char * * argv)
241 {
242     int pos = check_args_playlist_pos (argc, argv);
243     int length = get_entry_length (pos - 1);
244     audtool_report ("%d", length);
245 }
246 
playlist_display(int argc,char ** argv)247 void playlist_display (int argc, char * * argv)
248 {
249     int entries = get_playlist_length ();
250 
251     audtool_report ("%d track%s.", entries, entries != 1 ? "s" : "");
252 
253     int total = 0;
254 
255     for (int entry = 0; entry < entries; entry ++)
256     {
257         char * title = get_entry_title (entry);
258         int length = get_entry_length (entry) / 1000;
259 
260         total += length;
261 
262         /* adjust width for multi byte characters */
263         int column = 60;
264 
265         for (const char * p = title; * p; p = g_utf8_next_char (p))
266         {
267             int stride = g_utf8_next_char (p) - p;
268 
269             if (g_unichar_iswide (g_utf8_get_char (p)) ||
270              g_unichar_iswide_cjk (g_utf8_get_char (p)))
271                 column += (stride - 2);
272             else
273                 column += (stride - 1);
274         }
275 
276         char * fmt = g_strdup_printf ("%%4d | %%-%ds | %%d:%%.2d", column);
277         audtool_report (fmt, entry + 1, title, length / 60, length % 60);
278 
279         g_free (fmt);
280         g_free (title);
281     }
282 
283     audtool_report ("Total length: %d:%.2d", total / 60, total % 60);
284 }
285 
playlist_position(int argc,char ** argv)286 void playlist_position (int argc, char * * argv)
287 {
288     audtool_report ("%d", get_current_entry () + 1);
289 }
290 
playlist_song_filename(int argc,char ** argv)291 void playlist_song_filename (int argc, char * * argv)
292 {
293     int pos = check_args_playlist_pos (argc, argv);
294     char * filename = get_entry_filename (pos - 1);
295     audtool_report ("%s", filename);
296     g_free (filename);
297 }
298 
playlist_jump(int argc,char ** argv)299 void playlist_jump (int argc, char * * argv)
300 {
301     int pos = check_args_playlist_pos (argc, argv);
302     obj_audacious_call_jump_sync (dbus_proxy, pos - 1, NULL, NULL);
303 }
304 
playlist_clear(int argc,char ** argv)305 void playlist_clear (int argc, char * * argv)
306 {
307     obj_audacious_call_clear_sync (dbus_proxy, NULL, NULL);
308 }
309 
playlist_repeat_status(int argc,char ** argv)310 void playlist_repeat_status (int argc, char * * argv)
311 {
312     gboolean repeat = FALSE;
313     obj_audacious_call_repeat_sync (dbus_proxy, & repeat, NULL, NULL);
314     audtool_report (repeat ? "on" : "off");
315 }
316 
playlist_repeat_toggle(int argc,char ** argv)317 void playlist_repeat_toggle (int argc, char * * argv)
318 {
319     obj_audacious_call_toggle_repeat_sync (dbus_proxy, NULL, NULL);
320 }
321 
playlist_shuffle_status(int argc,char ** argv)322 void playlist_shuffle_status (int argc, char * * argv)
323 {
324     gboolean shuffle = FALSE;
325     obj_audacious_call_shuffle_sync (dbus_proxy, & shuffle, NULL, NULL);
326     audtool_report (shuffle ? "on" : "off");
327 }
328 
playlist_shuffle_toggle(int argc,char ** argv)329 void playlist_shuffle_toggle (int argc, char * * argv)
330 {
331     obj_audacious_call_toggle_shuffle_sync (dbus_proxy, NULL, NULL);
332 }
333 
playlist_tuple_field_data(int argc,char ** argv)334 void playlist_tuple_field_data (int argc, char * * argv)
335 {
336     int pos;
337 
338     if (argc < 3 || (pos = atoi (argv[2])) < 1)
339     {
340         audtool_whine_args (argv[0], "<fieldname> <position>");
341         audtool_whine_tuple_fields ();
342         exit (1);
343     }
344 
345     char * str = get_entry_field (pos - 1, argv[1]);
346     audtool_report ("%s", str);
347     g_free (str);
348 }
349 
playlist_ins_url_string(int argc,char ** argv)350 void playlist_ins_url_string (int argc, char * * argv)
351 {
352     int pos;
353 
354     if (argc < 3 || (pos = atoi (argv[2])) < 1)
355     {
356         audtool_whine_args (argv[0], "<url> <position>");
357         exit (1);
358     }
359 
360     char * uri = construct_uri (argv[1]);
361 
362     if (! uri)
363         exit (1);
364 
365     obj_audacious_call_playlist_ins_url_string_sync (dbus_proxy, uri, pos - 1, NULL, NULL);
366 
367     g_free (uri);
368 }
369 
playlist_enqueue_to_temp(int argc,char ** argv)370 void playlist_enqueue_to_temp (int argc, char * * argv)
371 {
372     if (argc < 2)
373     {
374         audtool_whine_args (argv[0], "<url>");
375         exit (1);
376     }
377 
378     char * uri = construct_uri (argv[1]);
379 
380     if (! uri)
381         exit (1);
382 
383     obj_audacious_call_playlist_enqueue_to_temp_sync (dbus_proxy, uri, NULL, NULL);
384 
385     g_free (uri);
386 }
387