summaryrefslogtreecommitdiff
path: root/sync-music-to-n900
blob: 9ca85bbb7a7f8a42a8a5b577916710516edfac56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/python
# Copyright 2010  Lars Wirzenius
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import os
import re
import shutil
import sys
import ttystatus


def parse_playlist(filename):
    pat = re.compile(r'^File\d+=(?P<filename>.*)$')
    f = open(filename)
    for line in f:
        m = pat.match(line)
        if m:
            yield m.group('filename')
    f.close()


class Playlist(object):
    
    def __init__(self, filename):
        self.media_filenames = list(parse_playlist(filename))
        prefix = os.path.commonprefix(self.media_filenames)
        i = prefix.rfind('/')
        if i >= 0:
            self.dirname = prefix[:i]
            self.media_filenames = [x[i+1:] for x in self.media_filenames]
        else:
            self.dirname = '.'
        self.dirname = os.path.join(os.path.dirname(filename), self.dirname)


def identical(source, target):
    source_st = os.lstat(source)
    
    try:
        target_st = os.lstat(target)
    except OSError:
        return False
    
    return source_st.st_size == target_st.st_size


def cleanup(pathname):
    badchars = ':?*[]'
    for c in badchars:
        pathname = '_'.join(pathname.split(c))
    return pathname


def main():
    ts = ttystatus.TerminalStatus()

    target_dir = '/media/Nokia N900/music'

    playlists = []
    ts['done'] = 0
    ts['total'] = 0
    for filename in sys.argv[1:]:
        playlist = Playlist(filename)
        playlists.append(playlist)
        for x in playlist.media_filenames:
            xx = os.path.join(playlist.dirname, x)
            ts['total'] += os.path.getsize(xx)
    
    ts.add(ttystatus.ElapsedTime())
    ts.add(ttystatus.Literal(' '))
    ts.add(ttystatus.RemainingTime('done', 'total'))
    ts.add(ttystatus.Literal(' '))
    ts.add(ttystatus.ByteSize('done'))
    ts.add(ttystatus.Literal('/'))
    ts.add(ttystatus.ByteSize('total'))
    ts.add(ttystatus.Literal(' '))
    ts.add(ttystatus.ProgressBar('done', 'total'))

    for playlist in playlists:
        for relative_name in playlist.media_filenames:
            source = os.path.join(playlist.dirname, relative_name)
            target = os.path.join(target_dir, cleanup(relative_name))
            if not identical(source, target):
                x = os.path.dirname(target)
                if not os.path.exists(x):
                    os.makedirs(x)
                source_f = open(source)
                target_f = file(target, 'wb')
                while True:
                    data = source_f.read(4096)
                    if not data:
                        break
                    target_f.write(data)
                    ts['done'] += len(data)
                source_f.close()
                target_f.close()
            else:
                ts['done'] += os.path.getsize(source)

    ts.finish()

if __name__ == '__main__':
    main()