Mercurial > audlegacy
comparison contrib/lap.py @ 3255:3c3a3f3c2269
- Added my "Locate and Play" script to contrib.
- Added a few commented-out lines to my G15 LCD script to help anyone who wants to tweak it.
author | "Stephan Sokolow <http://www.ssokolow.com/ContactMe>" |
---|---|
date | Sun, 05 Aug 2007 21:26:56 -0400 |
parents | |
children | 7a4fcf84a34f |
comparison
equal
deleted
inserted
replaced
3254:4f4e07f06801 | 3255:3c3a3f3c2269 |
---|---|
1 #!/usr/bin/env python | |
2 """Locate and Play | |
3 Author: Stephan Sokolow (deitarion/SSokolow) | |
4 License: GNU GPL-2 | |
5 Version: 1.0 | |
6 | |
7 Description: | |
8 - A quick wrapper to make playing songs via the local command quick and easy. | |
9 - Works with any player which implements the MPRIS standard for remote control via D-Bus. | |
10 - Accepts multiple space- and/or comma-separated choices after presenting the results. | |
11 - Can enqueue or enqueue and play. | |
12 - Can show full paths or just filenames. | |
13 - Will behave in a sane fashion when asked to enqueue and play multiple files. | |
14 | |
15 TODO: | |
16 - Complete the list of extensions for ModPlug, Embedded MPlayer (plugins-ugly), and UADE (3rd-party) | |
17 - Support sticking a 'q' in the result to choose enqueue on the fly | |
18 - Support an "all" keyword and an alternative to Ctrl+C for cancelling. (maybe 0) | |
19 """ | |
20 | |
21 ADLIB_EXTS = ['.a2m', '.adl', '.adlib', '.amd', '.bam', '.cff', '.cmf', '.d00', '.dfm', '.dmo', '.dro', '.dtm', '.hsc', '.hsp', | |
22 '.jbm', '.ksm', '.laa', '.lds', '.m', '.mad', '.mkj', '.msc', '.mtk', '.rad', '.raw', '.rix', '.rol', '.sat', | |
23 '.sa2', '.sci', '.sng', '.imf', '.wlf', '.xad', '.xsm'] | |
24 CONSOLE_EXTS = ['.adx', '.ay', '.gbs', '.gym', '.hes', '.kss', '.minipsf', '.nsf', '.nsfe', '.psf', '.sap', '.sid', '.spc', | |
25 '.vgm', '.vgz', '.vtx', '.ym'] | |
26 MIDI_EXTS = ['.mid', '.midi', '.rmi'] | |
27 MODULE_EXTS = [ '.it', ',mod', '.s3m', '.stm', '.xm'] | |
28 PLAYLIST_EXTS = ['.cue', '.m3u', '.pls', '.xspf'] | |
29 WAVEFORM_EXTS = ['.aac', '.aif', '.aiff', '.au', '.flac', '.m4a', '.mp2', '.mp3', '.mpc', '.ogg', '.snd', '.tta', '.voc', '.wav', | |
30 '.wma', '.wv'] | |
31 | |
32 # Edit these lines to choose the kind of files to be filtered for. By default, playlist extensions are excluded. | |
33 OK_EXTS = WAVEFORM_EXTS + MODULE_EXTS + CONSOLE_EXTS + MIDI_EXTS + ADLIB_EXTS | |
34 # If you want true format filtering, YOU write the mimetype cache. | |
35 USE_PAGER = False # Should we page output if it's more than a screenful? | |
36 | |
37 locate_command = ['locate', '-i'] | |
38 | |
39 # ========== Configuration Ends ========== | |
40 | |
41 import fnmatch, optparse, os, subprocess | |
42 from dbus import Bus, DBusException | |
43 | |
44 # Use readline if available but don't depend on it | |
45 try: import readline | |
46 except ImportError: pass | |
47 | |
48 # connect to DBus | |
49 bus = Bus(Bus.TYPE_SESSION) | |
50 | |
51 def get_results(query): | |
52 """Given a query or series of queries for the locate command, run them.""" | |
53 results, cmd = [], locate_command + (isinstance(query, basestring) and [query] or query) | |
54 for line in subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout: | |
55 result = line.strip() | |
56 if os.path.splitext(result)[1] in OK_EXTS: | |
57 results.append(result) | |
58 results.sort() | |
59 return results | |
60 | |
61 def filter(results, filters): | |
62 for filter in filters: | |
63 results = [x for x in results if fnmatch.fnmatch(x.lower(), '*%s*' % filter.lower())] | |
64 return results | |
65 | |
66 def makeMenu(results, strip_path=True): | |
67 for pos, val in enumerate(results): | |
68 val = strip_path and os.path.split(val)[1] or val | |
69 print "%3d) %s" % (pos+1, val) | |
70 | |
71 def addTrack(path, play=False): | |
72 try: | |
73 mp = bus.get_object('org.freedesktop.MediaPlayer', '/TrackList') | |
74 mp.AddTrack('file://' + path, play) | |
75 except DBusException: | |
76 print "ERROR: Unable to contact media player." | |
77 | |
78 def parseChoice(inString): | |
79 try: | |
80 return [int(inString)] | |
81 except ValueError: | |
82 choices = [] | |
83 for x in inString.replace(',',' ').split(): | |
84 try: choices.append(int(x)) | |
85 except ValueError: print "Not an integer: %s" % x | |
86 return choices | |
87 | |
88 if __name__ == '__main__': | |
89 try: | |
90 op = optparse.OptionParser() | |
91 op.add_option("-q", "--enqueue", action="store_true", dest="enqueue", default=False, | |
92 help="Don't start the song playing after enqueueing it.") | |
93 op.add_option("-p", "--show_path", action="store_true", dest="show_path", default=False, | |
94 help="Show the full path to each result.") | |
95 | |
96 (opts, args) = op.parse_args() | |
97 | |
98 results = (len(args) > 0) and get_results(args.pop(0)) or [] | |
99 results = filter(results, args) | |
100 | |
101 def takeChoice(index, play=False): | |
102 index = index - 1 | |
103 if index >= 0 and index < len(results): | |
104 addTrack(results[index], play) | |
105 else: | |
106 print "Invalid result index: %s" % (index + 1) | |
107 | |
108 if len(results): | |
109 makeMenu(results, not opts.show_path) | |
110 choices = parseChoice(raw_input("Choice(s) (Ctrl+C to cancel): ")) | |
111 | |
112 if len(choices): | |
113 takeChoice(choices.pop(0), not opts.enqueue) | |
114 for item in choices: | |
115 takeChoice(item, False) # This ensures proper behaviour with no --enqueue and multiple choices. | |
116 else: | |
117 print "No Results" | |
118 except KeyboardInterrupt: | |
119 pass |