author | Fabien Ninoles <fabien@tzone.org> |
Sun, 07 Dec 2008 16:05:33 -0500 | |
branch | immsview |
changeset 39 | a26e907b8022 |
parent 33 | ad808d18c693 |
permissions | -rw-r--r-- |
31 | 1 |
import dircache, os.path |
2 |
from sys import stderr |
|
3 |
import readline |
|
4 |
||
33
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
5 |
def sql_quote(str): |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
6 |
return str.replace("'", "''") |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
7 |
|
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
8 |
def get_song_info(path): |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
9 |
"Return (artist, title) pair from path." |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
10 |
artist, title = None, None |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
11 |
if os.path.isfile(path): |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
12 |
if path[-4:] == '.mp3': |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
13 |
from ID3 import ID3 |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
14 |
id3 = ID3(path) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
15 |
try: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
16 |
artist = id3['ARTIST'] |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
17 |
except: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
18 |
pass |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
19 |
try: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
20 |
title = id3['TITLE'] |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
21 |
except: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
22 |
pass |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
23 |
elif path[-4:] == '.ogg': |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
24 |
from ogg.vorbis import VorbisFile |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
25 |
vf = VorbisFile(path) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
26 |
vc = vf.comment() |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
27 |
try: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
28 |
artist = vc['ARTIST'][0] |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
29 |
except: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
30 |
pass |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
31 |
try: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
32 |
title = vc['TITLE'][0] |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
33 |
except: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
34 |
pass |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
35 |
return artist, title |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
36 |
|
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
37 |
def strdelay(seconds): |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
38 |
secs = abs(round(seconds)) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
39 |
minutes = secs / 60; |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
40 |
hours = minutes / 60; |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
41 |
days = hours / 24; |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
42 |
secs = secs % 60; |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
43 |
minutes %= 60; |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
44 |
hours %= 24; |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
45 |
|
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
46 |
if seconds < 0: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
47 |
s = "-" |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
48 |
else: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
49 |
s = "" |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
50 |
if days >= 1: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
51 |
s += "%dd %dh" % (days, hours) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
52 |
elif hours >= 1: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
53 |
s += "%dh%02d" % (hours, minutes) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
54 |
elif minutes >= 1: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
55 |
s += "%d'%02d\"" % (minutes, secs) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
56 |
else: |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
57 |
s += "%d\"" % (secs) |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
58 |
return s |
ad808d18c693
[svn] Many cleanup, both architecture (division of interface), encoding
fabien
parents:
31
diff
changeset
|
59 |
|
31 | 60 |
def set_file_completer(): |
61 |
readline.set_completer_delims('') |
|
62 |
readline.set_completer(_file_completer) |
|
63 |
||
64 |
def _file_completer(text, state): |
|
65 |
dirname, filename = os.path.split(text) |
|
66 |
if not os.path.isdir(dirname): |
|
67 |
return None |
|
68 |
paths = dircache.listdir(dirname) |
|
69 |
tlen = len(filename) |
|
70 |
checkpaths = [] |
|
71 |
if tlen > 0: |
|
72 |
for fn in paths: |
|
73 |
if fn[:len(filename)] == filename: |
|
74 |
checkpaths.append(fn) |
|
75 |
else: |
|
76 |
checkpaths = paths |
|
77 |
if len(checkpaths) > state: |
|
78 |
return os.path.join(dirname, checkpaths[state]) |
|
79 |
return None |
|
80 |
||
81 |
def copy_file(origname, copyname): |
|
82 |
orig = file(origname, 'r') |
|
83 |
new = file(copyname, 'w') |
|
84 |
new.write(orig.read()) |
|
85 |
new.flush() |
|
86 |
return new |
|
87 |
||
88 |
def unique(s): |
|
89 |
"""Return a list of the elements in s, but without duplicates. |
|
90 |
||
91 |
For example, unique([1,2,3,1,2,3]) is some permutation of [1,2,3], |
|
92 |
unique("abcabc") some permutation of ["a", "b", "c"], and |
|
93 |
unique(([1, 2], [2, 3], [1, 2])) some permutation of |
|
94 |
[[2, 3], [1, 2]]. |
|
95 |
||
96 |
For best speed, all sequence elements should be hashable. Then |
|
97 |
unique() will usually work in linear time. |
|
98 |
||
99 |
If not possible, the sequence elements should enjoy a total |
|
100 |
ordering, and if list(s).sort() doesn't raise TypeError it's |
|
101 |
assumed that they do enjoy a total ordering. Then unique() will |
|
102 |
usually work in O(N*log2(N)) time. |
|
103 |
||
104 |
If that's not possible either, the sequence elements must support |
|
105 |
equality-testing. Then unique() will usually work in quadratic |
|
106 |
time. |
|
107 |
""" |
|
108 |
||
109 |
n = len(s) |
|
110 |
if n == 0: |
|
111 |
return [] |
|
112 |
||
113 |
# Try using a dict first, as that's the fastest and will usually |
|
114 |
# work. If it doesn't work, it will usually fail quickly, so it |
|
115 |
# usually doesn't cost much to *try* it. It requires that all the |
|
116 |
# sequence elements be hashable, and support equality comparison. |
|
117 |
u = {} |
|
118 |
try: |
|
119 |
for x in s: |
|
120 |
u[x] = 1 |
|
121 |
except TypeError: |
|
122 |
del u # move on to the next method |
|
123 |
else: |
|
124 |
return u.keys() |
|
125 |
||
126 |
# We can't hash all the elements. Second fastest is to sort, |
|
127 |
# which brings the equal elements together; then duplicates are |
|
128 |
# easy to weed out in a single pass. |
|
129 |
# NOTE: Python's list.sort() was designed to be efficient in the |
|
130 |
# presence of many duplicate elements. This isn't true of all |
|
131 |
# sort functions in all languages or libraries, so this approach |
|
132 |
# is more effective in Python than it may be elsewhere. |
|
133 |
try: |
|
134 |
t = list(s) |
|
135 |
t.sort() |
|
136 |
except TypeError: |
|
137 |
del t # move on to the next method |
|
138 |
else: |
|
139 |
assert n > 0 |
|
140 |
last = t[0] |
|
141 |
lasti = i = 1 |
|
142 |
while i < n: |
|
143 |
if t[i] != last: |
|
144 |
t[lasti] = last = t[i] |
|
145 |
lasti += 1 |
|
146 |
i += 1 |
|
147 |
return t[:lasti] |
|
148 |
||
149 |
# Brute force is all that's left. |
|
150 |
u = [] |
|
151 |
for x in s: |
|
152 |
if x not in u: |
|
153 |
u.append(x) |
|
154 |
return u |
|
155 |
||
156 |