utils.py
author fabien
Sat, 03 Apr 2004 13:00:44 -0500
branchimmsview
changeset 38 785c66feccd3
parent 33 ad808d18c693
permissions -rw-r--r--
[svn] For sure, I almost clean the library...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
     1
import dircache, os.path
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
     2
from sys import stderr
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
     3
import readline
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
     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
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    60
def set_file_completer():
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    61
    readline.set_completer_delims('')
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    62
    readline.set_completer(_file_completer)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    63
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    64
def _file_completer(text, state):
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    65
    dirname, filename = os.path.split(text)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    66
    if not os.path.isdir(dirname):
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    67
        return None
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    68
    paths = dircache.listdir(dirname)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    69
    tlen = len(filename)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    70
    checkpaths = []
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    71
    if tlen > 0:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    72
        for fn in paths:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    73
            if fn[:len(filename)] == filename:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    74
                checkpaths.append(fn)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    75
    else:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    76
        checkpaths = paths
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    77
    if len(checkpaths) > state:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    78
        return os.path.join(dirname, checkpaths[state])
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    79
    return None
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    80
    
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    81
def copy_file(origname, copyname):
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    82
    orig = file(origname, 'r')
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    83
    new = file(copyname, 'w')
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    84
    new.write(orig.read())
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    85
    new.flush()
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    86
    return new
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    87
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    88
def unique(s):
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    89
    """Return a list of the elements in s, but without duplicates.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    90
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    91
    For example, unique([1,2,3,1,2,3]) is some permutation of [1,2,3],
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    92
    unique("abcabc") some permutation of ["a", "b", "c"], and
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    93
    unique(([1, 2], [2, 3], [1, 2])) some permutation of
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    94
    [[2, 3], [1, 2]].
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    95
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    96
    For best speed, all sequence elements should be hashable.  Then
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    97
    unique() will usually work in linear time.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    98
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
    99
    If not possible, the sequence elements should enjoy a total
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   100
    ordering, and if list(s).sort() doesn't raise TypeError it's
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   101
    assumed that they do enjoy a total ordering.  Then unique() will
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   102
    usually work in O(N*log2(N)) time.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   103
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   104
    If that's not possible either, the sequence elements must support
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   105
    equality-testing.  Then unique() will usually work in quadratic
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   106
    time.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   107
    """
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   108
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   109
    n = len(s)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   110
    if n == 0:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   111
        return []
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   112
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   113
    # Try using a dict first, as that's the fastest and will usually
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   114
    # work.  If it doesn't work, it will usually fail quickly, so it
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   115
    # usually doesn't cost much to *try* it.  It requires that all the
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   116
    # sequence elements be hashable, and support equality comparison.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   117
    u = {}
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   118
    try:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   119
        for x in s:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   120
            u[x] = 1
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   121
    except TypeError:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   122
        del u  # move on to the next method
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   123
    else:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   124
        return u.keys()
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   125
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   126
    # We can't hash all the elements.  Second fastest is to sort,
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   127
    # which brings the equal elements together; then duplicates are
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   128
    # easy to weed out in a single pass.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   129
    # NOTE:  Python's list.sort() was designed to be efficient in the
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   130
    # presence of many duplicate elements.  This isn't true of all
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   131
    # sort functions in all languages or libraries, so this approach
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   132
    # is more effective in Python than it may be elsewhere.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   133
    try:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   134
        t = list(s)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   135
        t.sort()
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   136
    except TypeError:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   137
        del t  # move on to the next method
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   138
    else:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   139
        assert n > 0
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   140
        last = t[0]
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   141
        lasti = i = 1
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   142
        while i < n:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   143
            if t[i] != last:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   144
                t[lasti] = last = t[i]
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   145
                lasti += 1
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   146
            i += 1
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   147
        return t[:lasti]
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   148
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   149
    # Brute force is all that's left.
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   150
    u = []
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   151
    for x in s:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   152
        if x not in u:
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   153
            u.append(x)
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   154
    return u
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   155
13f56bb29b96 [svn] New bestofimms, cleanimms, imms.py and utils.py.
fabien
parents:
diff changeset
   156