1
2 """
3 Provides a command-line interface to the SONY Reader PRS-500.
4
5 For usage information run the script.
6 """
7
8 import StringIO, sys, time, os
9 from optparse import OptionParser
10
11 from libprs500 import VERSION
12 from libprs500.communicate import PRS500Device
13 from libprs500.terminfo import TerminalController
14 from libprs500.errors import ArgumentError
15
16
17 MINIMUM_COL_WIDTH = 12
18
20 """ Convert a size in bytes into a human readle form """
21 if size < 1024: divisor, suffix = 1, ""
22 elif size < 1024*1024: divisor, suffix = 1024., "K"
23 elif size < 1024*1024*1024: divisor, suffix = 1024*1024, "M"
24 elif size < 1024*1024*1024*1024: divisor, suffix = 1024*1024, "G"
25 size = str(size/divisor)
26 if size.find(".") > -1: size = size[:size.find(".")+2]
27 return size + suffix
28
50
51 @apply
63 return property(**locals())
64
65 @apply
70 return property(**locals())
71
72 @apply
77 return property(**locals())
78
79 @apply
84 return property(**locals())
85
92
93 -def ls(dev, path, term, recurse=False, color=False, human_readable_size=False, ll=False, cols=0):
94 def col_split(l, cols):
95 rows = len(l) / cols
96 if len(l) % cols:
97 rows += 1
98 m = []
99 for i in range(rows):
100 m.append(l[i::rows])
101 return m
102
103 def row_widths(table):
104 tcols = len(table[0])
105 rowwidths = [ 0 for i in range(tcols) ]
106 for row in table:
107 c = 0
108 for item in row:
109 rowwidths[c] = len(item) if len(item) > rowwidths[c] else rowwidths[c]
110 c += 1
111 return rowwidths
112
113 output = StringIO.StringIO()
114 if path.endswith("/"): path = path[:-1]
115 dirs = dev.list(path, recurse)
116 for dir in dirs:
117 if recurse: print >>output, dir[0] + ":"
118 lsoutput, lscoloutput = [], []
119 files = dir[1]
120 maxlen = 0
121 if ll:
122 for file in files:
123 size = len(str(file.size))
124 if human_readable_size:
125 file = FileFormatter(file, term)
126 size = len(file.human_readable_size)
127 if size > maxlen: maxlen = size
128 for file in files:
129 file = FileFormatter(file, term)
130 name = file.name
131 lsoutput.append(name)
132 if color: name = file.name_in_color
133 lscoloutput.append(name)
134 if ll:
135 size = str(file.size)
136 if human_readable_size: size = file.human_readable_size
137 print >>output, file.mode_string, ("%"+str(maxlen)+"s")%size, file.modification_time, name
138 if not ll and len(lsoutput) > 0:
139 trytable = []
140 for colwidth in range(MINIMUM_COL_WIDTH, cols):
141 trycols = int(cols/colwidth)
142 trytable = col_split(lsoutput, trycols)
143 works = True
144 for row in trytable:
145 row_break = False
146 for item in row:
147 if len(item) > colwidth - 1:
148 works, row_break = False, True
149 break
150 if row_break: break
151 if works: break
152 rowwidths = row_widths(trytable)
153 trytablecol = col_split(lscoloutput, len(trytable[0]))
154 for r in range(len(trytable)):
155 for c in range(len(trytable[r])):
156 padding = rowwidths[c] - len(trytable[r][c])
157 print >>output, trytablecol[r][c], "".ljust(padding),
158 print >>output
159 print >>output
160 listing = output.getvalue().rstrip()+ "\n"
161 output.close()
162 return listing
163
165 term = TerminalController()
166 cols = term.COLS
167
168 parser = OptionParser(usage="usage: %prog [options] command args\n\ncommand is one of: info, df, ls, cp, cat or rm\n\n"+
169 "For help on a particular command: %prog command", version="libprs500 version: " + VERSION)
170 parser.add_option("--log-packets", help="print out packet stream to stdout", dest="log_packets", action="store_true", default=False)
171 parser.remove_option("-h")
172 parser.disable_interspersed_args()
173 options, args = parser.parse_args()
174
175 if len(args) < 1:
176 parser.print_help()
177 sys.exit(1)
178 command = args[0]
179 args = args[1:]
180 dev = PRS500Device(log_packets=options.log_packets)
181 if command == "df":
182 dev.open()
183 data = dev.available_space()
184 dev.close()
185 print "Filesystem\tSize \tUsed \tAvail \tUse%"
186 for datum in data:
187 total, free, used, percent = human_readable(datum[2]), human_readable(datum[1]), human_readable(datum[2]-datum[1]), \
188 str(0 if datum[2]==0 else int(100*(datum[2]-datum[1])/(datum[2]*1.)))+"%"
189 print "%-10s\t%s\t%s\t%s\t%s"%(datum[0], total, used, free, percent)
190 elif command == "ls":
191 parser = OptionParser(usage="usage: %prog ls [options] path\n\npath must begin with /,a:/ or b:/")
192 parser.add_option("--color", help="show ls output in color", dest="color", action="store_true", default=False)
193 parser.add_option("-l", help="In addition to the name of each file, print the file type, permissions, and timestamp (the modification time unless other times are selected)", dest="ll", action="store_true", default=False)
194 parser.add_option("-R", help="Recursively list subdirectories encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False)
195 parser.remove_option("-h")
196 parser.add_option("-h", "--human-readable", help="show sizes in human readable format", dest="hrs", action="store_true", default=False)
197 options, args = parser.parse_args(args)
198 if len(args) < 1:
199 parser.print_help()
200 sys.exit(1)
201 dev.open()
202 try:
203 print ls(dev, args[0], term, color=options.color, recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols),
204 except ArgumentError, e:
205 print >> sys.stderr, e
206 sys.exit(1)
207 finally:
208 dev.close()
209 elif command == "info":
210 dev.open()
211 try:
212 info(dev)
213 finally: dev.close()
214 elif command == "cp":
215 parser = OptionParser(usage="usage: %prog cp [options] source destination\n\nsource is a path on the device and must begin with /,a:/ or b:/"+
216 "\n\ndestination is a path on your computer and can point to either a file or a directory")
217 options, args = parser.parse_args(args)
218 if len(args) < 2:
219 parser.print_help()
220 sys.exit(1)
221 if args[0].endswith("/"): path = args[0][:-1]
222 else: path = args[0]
223 outfile = args[1]
224 if os.path.isdir(outfile):
225 outfile = os.path.join(outfile, path[path.rfind("/")+1:])
226 outfile = open(outfile, "w")
227 dev.open()
228 try:
229 dev.get_file(path, outfile)
230 except ArgumentError, e:
231 print >>sys.stderr, e
232 finally:
233 dev.close()
234 outfile.close()
235 elif command == "cat":
236 outfile = sys.stdout
237 parser = OptionParser(usage="usage: %prog cat path\n\npath should point to a file on the device and must begin with /,a:/ or b:/")
238 options, args = parser.parse_args(args)
239 if len(args) < 1:
240 parser.print_help()
241 sys.exit(1)
242 if args[0].endswith("/"): path = args[0][:-1]
243 else: path = args[0]
244 outfile = sys.stdout
245 dev.open()
246 try:
247 dev.get_file(path, outfile)
248 except ArgumentError, e:
249 print >>sys.stderr, e
250 finally:
251 dev.close()
252 else:
253 parser.print_help()
254 sys.exit(1)
255
256 if __name__ == "__main__":
257 main()
258