1
2
3
4 """
5 Clear mp3-player memory and put random music in
6 """
7
8 import os, sys, stat, operator, statvfs, time, random
9 from optparse import OptionParser
10
11 def get_list(path):
12 cur_list=[]
13 for curpath, paths, files in os.walk(path):
14 if curpath != path:
15 file_list = [(fn,
16 os.path.getsize(os.path.join(curpath,
17 fn)))
18 for fn in files]
19 size=reduce(operator.add, [x[1] for x in file_list])
20 cur_list.append((curpath, size, file_list))
21 return cur_list
22
23 def pick_album(maxsize, albums):
24 albums=[x for x in albums if x[1]<=maxsize]
25 if not albums: return None, []
26 choice = random.choice(albums)
27 albums.remove(choice)
28 return choice, albums
29
30 def get_freespace(path):
31 s=os.statvfs(path)
32 return s[statvfs.F_BSIZE]*s[statvfs.F_BAVAIL]
33
34 def is_mountpoint(path):
35 return os.stat(path)[stat.ST_INO]==1
36
37 def humanize(amount):
38 for ex, prefix in ((3, "G"), (2, "M"), (1, "K"), (0, "")):
39 if amount > 1024.0**ex:
40 amount /= 1024**ex
41 return "%.1f%s"%(amount, prefix)
42
43 def copying(starttime, left, total):
44 now=time.time()
45 elapsed=now-starttime
46 helap = int(elapsed / 3600)
47 minelap=int((elapsed-helap*3600)/60)
48 secelap=elapsed%60
49 if left>0:
50 timeleft = elapsed / ((total - left) / float(left) )
51 else:
52 timeleft = 0
53 hleft = int(timeleft/3600)
54 minleft = int((timeleft-hleft*3600)/60)
55 secleft = timeleft%60
56 percd = 100.0 * (total - left) / total
57 return "Copying: %.1f%% done, %02d:%02d:%02d (%sB) left, "\
"%02d:%02d:%02d elapsed..."%(percd, hleft, minleft,
58 secleft, humanize(left), helap, minelap, secelap)
59
60 def status(line=""):
61 if options.verbose:
62 sys.stdout.write(line.ljust(78))
63 sys.stdout.write("\r")
64 sys.stdout.flush()
65
66 parser=OptionParser(version="%prog 0.1")
67 parser.add_option("-d", "--dest", dest="destination", default="/mnt/sda1",
68 help="destination PATH [/mnt/sda1]", metavar="PATH")
69 parser.add_option("-s", "--source", dest="source", default="/media/lowbitrate",
70 help="source PATH [/media/lowbitrate]", metavar="PATH")
71 parser.add_option("-n", "--no-mount",
72 action="store_false", dest="mount", default=True,
73 help="Do not mount destination PATH")
74 parser.add_option("-q", "--quiet",
75 action="store_false", dest="verbose", default=True,
76 help="don't print status messages to stdout")
77
78 global options
79 (options, args) = parser.parse_args()
80
81 if options.destination[:5]!="/mnt/":
82 sys.stderr.write("Destination must be under /mnt/\n")
83 sys.exit(1)
84
85 if options.mount:
86 status("Mounting %s..."%options.destination)
87 os.system("mount %s"%options.destination)
88
89 status("Erasing %s..."%options.destination)
90 for root, dirs, files in os.walk(options.destination, topdown=False):
91 for name in files:
92 os.remove(os.path.join(root, name))
93 for name in dirs:
94 os.rmdir(os.path.join(root, name))
95
96 spaceleft=totalsize=get_freespace(options.destination)
97 albums=get_list(options.source)
98
99 playlist=[]
100 while spaceleft>0 and albums:
101 status("Choosing, space left %d bytes"%spaceleft)
102 choice, albums = pick_album(spaceleft, albums)
103 if not choice: break
104 playlist.append(choice)
105 spaceleft -= choice[1]
106
107 status("Copying %d albums..."%len(playlist))
108 playsize=bytesleft=reduce(operator.add, [x[1] for x in playlist])
109 start=time.time()
110
111 for root, dsize, files in playlist:
112 targetdir=os.path.join(options.destination, os.path.basename(root))
113 os.mkdir(targetdir)
114 for name, size in files:
115 targetfile=os.path.join(targetdir, name)
116 sourcefile=os.path.join(root, name)
117 sf=file(sourcefile)
118 of=file(targetfile, "w+")
119 data=sf.read(1024*1024)
120 while data:
121 of.write(data)
122 bytes=len(data)
123 bytesleft-=bytes
124 status(copying(start, bytesleft, playsize))
125 data=sf.read(1024*1024)
126 sf.close()
127 of.close()
128
129 if options.mount:
130 status("Unmounting %s..."%options.destination)
131 os.system("umount %s"%options.destination)
132 now=time.time()
133 tput=playsize/float(now-start)
134 status("Copied %d albums (%sB), avg thruput %sBps"%(
135 len(playlist), humanize(playsize), humanize(tput)
136 ))
137 print