~ubuntu-branches/ubuntu/gutsy/hplip/gutsy-security

« back to all changes in this revision

Viewing changes to unload.py

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2006-09-15 18:00:07 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20060915180007-96mez3nck3oy5wij
Tags: 1.6.7-2ubuntu1
* Merge from debian unstable.
* Removed patches 50_ui-supportform-cleanups.dpatch and
  55_ui-supportform-debian.dpatch, there is no support window in the HP
  toolbox any more.
* HPLIP (file io/hpiod/usbext.h) includes linux/compiler.h which is not
  part of Ubuntu Linux and not needed. Removed the include with patch
  80_no-compiler.h.dpatch.
* debian/control: Let the "Conflicts:" of hpijs-ppds be only a "Breaks:"
  to facilitate an update from the previous version when both hpijs and
  hpijs-ppds are installed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#
22
22
 
23
23
 
24
 
__version__ = '1.9'
 
24
__version__ = '2.1'
25
25
__title__ = 'Photo Card Access Utility'
26
 
__doc__ = "Access inserted photo cards on supported HPLIP printers. This provides an alternative for older devices that do not support USB mass storage or for access to photo cards over a network. (GUI version)"
 
26
__doc__ = "Access inserted photo cards on supported HPLIP printers. This provides an alternative for older devices that do not support USB mass storage or for access to photo cards over a network."
27
27
 
28
28
# Std Lib
29
29
import sys
 
30
import os, os.path
30
31
import getopt
 
32
import re
 
33
import cmd
 
34
import readline
 
35
import time
 
36
import fnmatch
 
37
import string
31
38
 
32
39
# Local
33
40
from base.g import *
34
 
from base import utils, device
 
41
from base import device, service, utils #, exif
35
42
from prnt import cups
 
43
from pcard import photocard
36
44
 
37
 
use_qt_splashscreen = False
 
45
log.set_module('hp-unload')
38
46
 
39
47
 
40
48
USAGE = [(__doc__, "", "name", True),
41
 
         ("Usage: hp-unload [PRINTER|DEVICE-URI] [OPTIONS]", "", "summary", True),
 
49
         ("Usage: hp-unload [PRINTER|DEVICE-URI] [MODE] [OPTIONS]", "", "summary", True),
42
50
         utils.USAGE_ARGS,
43
51
         utils.USAGE_DEVICE,
44
52
         utils.USAGE_PRINTER,
45
53
         utils.USAGE_SPACE,
 
54
         ("[MODE]", "", "header", False),
 
55
         ("Enter interactive mode (ftp-like interface):", "-i or --interactive", "option", False),
 
56
         ("Enter graphical UI mode:", "-u or --gui (Default)", "option", False),
 
57
         ("Run in non-interactive mode (batch mode):", "-n or --non-interactive", "option", False),
 
58
         # TODO: File glob(s)
 
59
         utils.USAGE_SPACE,
46
60
         utils.USAGE_OPTIONS,
 
61
         ("Output directory:", "-o<dir> or --output=<dir> (Defaults to current directory)(Only used for non-GUI modes)", "option", False),
47
62
         utils.USAGE_BUS1, utils.USAGE_BUS2,
48
63
         utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
49
64
         utils.USAGE_HELP,
50
65
         utils.USAGE_SPACE,
51
66
         utils.USAGE_NOTES,
52
67
         utils.USAGE_STD_NOTES1, utils.USAGE_STD_NOTES2, 
53
 
         utils.USAGE_SEEALSO,
54
 
         ("hp-photo", "", "seealso", False),
 
68
         ("3. Use 'help' command at the pcard:> prompt for command help (Interactive mode (-i) only).", "", "note", True),
55
69
         ]
56
70
         
57
71
def usage(typ='text'):
61
75
    utils.format_text(USAGE, typ, __title__, 'hp-unload', __version__)
62
76
    sys.exit(0)
63
77
 
64
 
def __tr(s,c = None):
65
 
    return qApp.translate("Unload",s,c)
66
 
    
67
 
 
68
 
# PyQt
69
 
if not utils.checkPyQtImport():
70
 
    log.error("PyQt/Qt initialization error. Please check install of PyQt/Qt and try again.")
71
 
    sys.exit(1)
72
 
 
73
 
from qt import *
74
 
from ui import unloadform
75
 
 
 
78
 
 
79
## Console class (from ASPN Python Cookbook)
 
80
## Author:   James Thiele
 
81
## Date:     27 April 2004
 
82
## Version:  1.0
 
83
## Location: http://www.eskimo.com/~jet/python/examples/cmd/
 
84
## Copyright (c) 2004, James Thiele
 
85
 
 
86
class Console(cmd.Cmd):
 
87
 
 
88
    def __init__(self, pc):
 
89
        cmd.Cmd.__init__(self)
 
90
        self.intro  = "Type 'help' for a list of commands. Type 'exit' to quit."
 
91
        self.pc = pc
 
92
        disk_info = self.pc.info()
 
93
        pc.write_protect = disk_info[8]
 
94
        if pc.write_protect:
 
95
            log.warning("Photo card is write protected.")
 
96
        self.prompt = utils.bold("pcard: %s > " % self.pc.pwd())
 
97
 
 
98
    ## Command definitions ##
 
99
    def do_hist(self, args):
 
100
        """Print a list of commands that have been entered"""
 
101
        print self._hist
 
102
 
 
103
    def do_exit(self, args):
 
104
        """Exits from the console"""
 
105
        return -1
 
106
 
 
107
    def do_quit(self, args):
 
108
        """Exits from the console"""
 
109
        return -1
 
110
 
 
111
    ## Command definitions to support Cmd object functionality ##
 
112
    def do_EOF(self, args):
 
113
        """Exit on system end of file character"""
 
114
        return self.do_exit(args)
 
115
 
 
116
    def do_help(self, args):
 
117
        """Get help on commands
 
118
           'help' or '?' with no arguments prints a list of commands for which help is available
 
119
           'help <command>' or '? <command>' gives help on <command>
 
120
        """
 
121
        ## The only reason to define this method is for the help text in the doc string
 
122
        cmd.Cmd.do_help(self, args)
 
123
 
 
124
    ## Override methods in Cmd object ##
 
125
    def preloop(self):
 
126
        """Initialization before prompting user for commands.
 
127
           Despite the claims in the Cmd documentaion, Cmd.preloop() is not a stub.
 
128
        """
 
129
        cmd.Cmd.preloop(self)   ## sets up command completion
 
130
        self._hist    = []      ## No history yet
 
131
        self._locals  = {}      ## Initialize execution namespace for user
 
132
        self._globals = {}
 
133
 
 
134
    def postloop(self):
 
135
        """Take care of any unfinished business.
 
136
           Despite the claims in the Cmd documentaion, Cmd.postloop() is not a stub.
 
137
        """
 
138
        cmd.Cmd.postloop(self)   ## Clean up command completion
 
139
        print "Exiting..."
 
140
 
 
141
    def precmd(self, line):
 
142
        """ This method is called after the line has been input but before
 
143
            it has been interpreted. If you want to modifdy the input line
 
144
            before execution (for example, variable substitution) do it here.
 
145
        """
 
146
        self._hist += [line.strip()]
 
147
        return line
 
148
 
 
149
    def postcmd(self, stop, line):
 
150
        """If you want to stop the console, return something that evaluates to true.
 
151
           If you want to do some post command processing, do it here.
 
152
        """
 
153
        return stop
 
154
 
 
155
    def emptyline(self):
 
156
        """Do nothing on empty input line"""
 
157
        pass
 
158
 
 
159
    def default(self, line):
 
160
        print utils.bold("ERROR: Unrecognized command. Use 'help' to list commands.")
 
161
 
 
162
    def do_ldir(self, args):
 
163
        """ List local directory contents."""
 
164
        os.system('ls -l')
 
165
 
 
166
    def do_lls(self, args):
 
167
        """ List local directory contents."""
 
168
        os.system('ls -l')
 
169
 
 
170
    def do_dir(self, args):
 
171
        """Synonym for the ls command."""
 
172
        return self.do_ls(args)
 
173
 
 
174
    def do_ls(self, args):
 
175
        """List photo card directory contents."""
 
176
        args = args.strip().lower()
 
177
        files = self.pc.ls(True, args)
 
178
 
 
179
        total_size = 0
 
180
        formatter = utils.TextFormatter(
 
181
                (
 
182
                    {'width': 14, 'margin' : 2},
 
183
                    {'width': 12, 'margin' : 2, 'alignment' : utils.TextFormatter.RIGHT},
 
184
                    {'width': 30, 'margin' : 2},
 
185
                )
 
186
            )
 
187
 
 
188
        print
 
189
        print utils.bold(formatter.compose(("Name", "Size", "Type")))
 
190
 
 
191
        num_files = 0
 
192
        for d in self.pc.current_directories():
 
193
            if d[0] in ('.', '..'):
 
194
                print formatter.compose((d[0], "", "directory"))
 
195
            else:
 
196
                print formatter.compose((d[0] + "/", "", "directory"))
 
197
 
 
198
        for f in self.pc.current_files():
 
199
            print formatter.compose((f[0], utils.format_bytes(f[2]), self.pc.classify_file(f[0])))
 
200
            num_files += 1
 
201
            total_size += f[2]
 
202
 
 
203
        print utils.bold("% d files, %s" % (num_files, utils.format_bytes(total_size, True)))
 
204
 
 
205
 
 
206
    def do_df(self, args):
 
207
        """Display free space on photo card.
 
208
        Options:
 
209
        -h\tDisplay in human readable format
 
210
        """
 
211
        freespace = self.pc.df()
 
212
 
 
213
        if args.strip().lower() == '-h':
 
214
            fs = utils.format_bytes(freespace)
 
215
        else:
 
216
            fs = utils.commafy(freespace)
 
217
 
 
218
        print "Freespace = %s Bytes" % fs
 
219
 
 
220
 
 
221
    def do_cp(self, args, remove_after_copy=False):
 
222
        """Copy files from photo card to current local directory.
 
223
        Usage:
 
224
        \tcp FILENAME(S)|GLOB PATTERN(S)
 
225
        Example:
 
226
        \tCopy all JPEG and GIF files and a file named thumbs.db from photo card to local directory:
 
227
        \tcp *.jpg *.gif thumbs.db
 
228
        """
 
229
        args = args.strip().lower()
 
230
 
 
231
        matched_files = self.pc.match_files(args)
 
232
 
 
233
        if len(matched_files) == 0:
 
234
            print "ERROR: File(s) not found."
 
235
        else:
 
236
            total, delta = self.pc.cp_multiple(matched_files, remove_after_copy, self.cp_status_callback, self.rm_status_callback)
 
237
 
 
238
            print utils.bold("\n%s transfered in %d sec (%d KB/sec)" % (utils.format_bytes(total), delta, (total/1024)/(delta)))
 
239
 
 
240
    def do_unload(self, args):
 
241
        """Unload all image files from photocard to current local directory.
 
242
        Note:
 
243
        \tSubdirectories on photo card are not preserved
 
244
        Options:
 
245
        -x\tDon't remove files after copy
 
246
        -p\tPrint unload list but do not copy or remove files"""
 
247
        args = args.lower().strip().split()
 
248
        dont_remove = False
 
249
        if '-x' in args:
 
250
            if self.pc.write_protect:
 
251
                log.error("Photo card is write protected. -x not allowed.")
 
252
                return
 
253
            else:
 
254
                dont_remove = True
 
255
 
 
256
 
 
257
        unload_list = self.pc.get_unload_list()
 
258
        print
 
259
 
 
260
        if len(unload_list) > 0:
 
261
            if '-p' in args:
 
262
 
 
263
                max_len = 0
 
264
                for u in unload_list:
 
265
                    max_len = max(max_len, len(u[0]))
 
266
 
 
267
                formatter = utils.TextFormatter(
 
268
                        (
 
269
                            {'width': max_len+2, 'margin' : 2},
 
270
                            {'width': 12, 'margin' : 2, 'alignment' : utils.TextFormatter.RIGHT},
 
271
                            {'width': 12, 'margin' : 2},
 
272
                        )
 
273
                    )
 
274
 
 
275
                print
 
276
                print utils.bold(formatter.compose(("Name", "Size", "Type")))
 
277
 
 
278
                total = 0
 
279
                for u in unload_list:
 
280
                     print formatter.compose(('%s' % u[0], utils.format_bytes(u[1]), '%s/%s' % (u[2], u[3])))
 
281
                     total += u[1]
 
282
 
 
283
 
 
284
                print utils.bold("Found %d files to unload, %s" % (len(unload_list), utils.format_bytes(total, True)))
 
285
            else:
 
286
                print utils.bold("Unloading %d files..." % len(unload_list))
 
287
                total, delta, was_cancelled = self.pc.unload(unload_list, self.cp_status_callback, self.rm_status_callback, dont_remove)
 
288
                print utils.bold("\n%s unloaded in %d sec (%d KB/sec)" % (utils.format_bytes(total), delta, (total/1024)/delta))
 
289
 
 
290
        else:
 
291
            print "No image, audio, or video files found."
 
292
 
 
293
 
 
294
    def cp_status_callback(self, src, trg, size):
 
295
        if size == 1:
 
296
            print
 
297
            print utils.bold("Copying %s..." % src)
 
298
        else:
 
299
            print "\nCopied %s to %s (%s)..." % (src, trg, utils.format_bytes(size))
 
300
 
 
301
    def rm_status_callback(self, src):
 
302
        print "Removing %s..." % src
 
303
 
 
304
 
 
305
 
 
306
    def do_rm(self, args):
 
307
        """Remove files from photo card."""
 
308
        if self.pc.write_protect:
 
309
            log.error("Photo card is write protected. rm not allowed.")
 
310
            return
 
311
 
 
312
        args = args.strip().lower()
 
313
 
 
314
        matched_files = self.pc.match_files(args)
 
315
 
 
316
        if len(matched_files) == 0:
 
317
            print "ERROR: File(s) not found."
 
318
        else:
 
319
            for f in matched_files:
 
320
                self.pc.rm(f, False)
 
321
 
 
322
        self.pc.ls()
 
323
 
 
324
    def do_mv(self, args):
 
325
        """Move files off photocard"""
 
326
        if self.pc.write_protect:
 
327
            log.error("Photo card is write protected. mv not allowed.")
 
328
            return
 
329
        self.do_cp(args, True)
 
330
 
 
331
    def do_lpwd(self, args):
 
332
        """Print name of local current/working directory."""
 
333
        print os.getcwd()
 
334
 
 
335
    def do_lcd(self, args):
 
336
        """Change current local working directory."""
 
337
        try:
 
338
            os.chdir(args.strip())
 
339
        except OSError:
 
340
            print utils.bold("ERROR: Directory not found.")
 
341
        print os.getcwd()
 
342
 
 
343
    def do_pwd(self, args):
 
344
        """Print name of photo card current/working directory
 
345
        Usage:
 
346
        \t>pwd"""
 
347
        print self.pc.pwd()
 
348
 
 
349
    def do_cd(self, args):
 
350
        """Change current working directory on photo card.
 
351
        Note:
 
352
        \tYou may only specify one directory level at a time.
 
353
        Usage:
 
354
        \tcd <directory>
 
355
        """
 
356
        args = args.lower().strip()
 
357
 
 
358
        if args == '..':
 
359
            if self.pc.pwd() != '/':
 
360
                self.pc.cdup()
 
361
 
 
362
        elif args == '.':
 
363
            pass
 
364
 
 
365
        elif args == '/':
 
366
            self.pc.cd('/')
 
367
 
 
368
        else:
 
369
            matched_dirs = self.pc.match_dirs(args)
 
370
 
 
371
            if len(matched_dirs) == 0:
 
372
                print "Directory not found"
 
373
 
 
374
            elif len(matched_dirs) > 1:
 
375
                print "Pattern matches more than one directory"
 
376
 
 
377
            else:
 
378
                self.pc.cd(matched_dirs[0])
 
379
 
 
380
        self.prompt = utils.bold("pcard: %s > " % self.pc.pwd())
 
381
 
 
382
    def do_cdup(self, args):
 
383
        """Change to parent directory."""
 
384
        self.do_cd('..')
 
385
 
 
386
    #def complete_cd( self, text, line, begidx, endidx ):
 
387
    #    print text, line, begidx, endidx
 
388
    #    #return "XXX"
 
389
 
 
390
    def do_cache(self, args):
 
391
        """Display current cache entries, or turn cache on/off.
 
392
        Usage:
 
393
        \tDisplay: cache
 
394
        \tTurn on: cache on
 
395
        \tTurn off: cache off
 
396
        """
 
397
        args = args.strip().lower()
 
398
 
 
399
        if args == 'on':
 
400
            self.pc.cache_control(True)
 
401
 
 
402
        elif args == 'off':
 
403
            self.pc.cache_control(False)
 
404
 
 
405
        else:
 
406
            if self.pc.cache_state():
 
407
                cache_info = self.pc.cache_info()
 
408
 
 
409
                t = cache_info.keys()
 
410
                t.sort()
 
411
                print
 
412
                for s in t:
 
413
                    print "sector %d (%d hits)" % (s, cache_info[s])
 
414
 
 
415
                print utils.bold("Total cache usage: %s (%s maximum)" % (utils.format_bytes(len(t)*512), utils.format_bytes(photocard.MAX_CACHE * 512)))
 
416
                print utils.bold("Total cache sectors: %s of %s" % (utils.commafy(len(t)), utils.commafy(photocard.MAX_CACHE)))
 
417
            else:
 
418
                print "Cache is off."
 
419
 
 
420
    def do_sector(self, args):
 
421
        """Display sector data.
 
422
        Usage:
 
423
        \tsector <sector num>
 
424
        """
 
425
        args = args.strip().lower()
 
426
        cached = False
 
427
        try:
 
428
            sector = int(args)
 
429
        except ValueError:
 
430
            print "Sector must be specified as a number"
 
431
            return
 
432
 
 
433
        if self.pc.cache_check(sector) > 0:
 
434
            print "Cached sector"
 
435
 
 
436
        print repr(self.pc.sector(sector))
 
437
 
 
438
 
 
439
    def do_tree(self, args):
 
440
        """Display photo card directory tree."""
 
441
        tree = self.pc.tree()
 
442
        print
 
443
        self.print_tree(tree)
 
444
 
 
445
    def print_tree(self, tree, level=0):
 
446
        for d in tree:
 
447
            if type(tree[d]) == type({}):
 
448
                print ''.join([' '*level*4, d, '/'])
 
449
                self.print_tree(tree[d], level+1)
 
450
 
 
451
 
 
452
    def do_reset(self, args):
 
453
        """Reset the cache."""
 
454
        self.pc.cache_reset()
 
455
 
 
456
 
 
457
    def do_card(self, args):
 
458
        """Print info about photocard."""
 
459
        print
 
460
        print "Device URI = %s" % self.pc.device.device_uri
 
461
        print "Model = %s" % self.pc.device.model_ui
 
462
        print "Working dir = %s" % self.pc.pwd()
 
463
        disk_info = self.pc.info()
 
464
        print "OEM ID = %s" % disk_info[0]
 
465
        print "Bytes/sector = %d" % disk_info[1]
 
466
        print "Sectors/cluster = %d" % disk_info[2]
 
467
        print "Reserved sectors = %d" % disk_info[3]
 
468
        print "Root entries = %d" % disk_info[4]
 
469
        print "Sectors/FAT = %d" % disk_info[5]
 
470
        print "Volume label = %s" % disk_info[6]
 
471
        print "System ID = %s" % disk_info[7]
 
472
        print "Write protected = %d" % disk_info[8]
 
473
        print "Cached sectors = %s" % utils.commafy(len(self.pc.cache_info()))
 
474
 
 
475
 
 
476
    def do_display(self, args):
 
477
        """Display an image with ImageMagick.
 
478
        Usage:
 
479
        \tdisplay <filename>"""
 
480
        args = args.strip().lower()
 
481
        matched_files = self.pc.match_files(args)
 
482
 
 
483
        if len(matched_files) == 1:
 
484
 
 
485
            typ = self.pc.classify_file(args).split('/')[0]
 
486
 
 
487
            if typ == 'image':
 
488
                fd, temp_name = utils.make_temp_file()
 
489
                self.pc.cp(args, temp_name)
 
490
                os.system('display %s' % temp_name)
 
491
                os.remove(temp_name)
 
492
 
 
493
            else:
 
494
                print "File is not an image."
 
495
 
 
496
        elif len(matched_files) == 0:
 
497
            print "File not found."
 
498
 
 
499
        else:
 
500
            print "Only one file at a time may be specified for display."
 
501
 
 
502
    def do_show(self, args):
 
503
        """Synonym for the display command."""
 
504
        self.do_display(args)
 
505
 
 
506
    def do_thumbnail(self, args):
 
507
        """Display an embedded thumbnail image with ImageMagick.
 
508
        Note:
 
509
        \tOnly works with JPEG/JFIF images with embedded JPEG/TIFF thumbnails
 
510
        Usage:
 
511
        \tthumbnail <filename>"""
 
512
        args = args.strip().lower()
 
513
        matched_files = self.pc.match_files(args)
 
514
 
 
515
        if len(matched_files) == 1:
 
516
            typ, subtyp = self.pc.classify_file(args).split('/')
 
517
            #print "'%s' '%s'" % (typ, subtyp)
 
518
 
 
519
            if typ == 'image' and subtyp in ('jpeg', 'tiff'):
 
520
                exif_info = self.pc.get_exif(args)
 
521
 
 
522
                dir_name, file_name=os.path.split(args)
 
523
                photo_name, photo_ext=os.path.splitext(args)
 
524
 
 
525
                if 'JPEGThumbnail' in exif_info:
 
526
                    #print "JPEG thumbnail found."
 
527
                    temp_file_fd, temp_file_name = utils.make_temp_file()
 
528
                    #thumb_name = os.path.join( os.getcwd(), photo_name ) + '_thumb.jpg'
 
529
                    open(temp_file_name, 'wb').write(exif_info['JPEGThumbnail'])
 
530
                    os.system('display %s' % temp_file_name)
 
531
                    os.remove(temp_file_name)
 
532
 
 
533
                elif 'TIFFThumbnail' in exif_info:
 
534
                    #print "TIFF thumbnail found."
 
535
                    #thumb_name = os.path.join( os.getcwd(), photo_name ) + '_thumb.tif'
 
536
                    temp_file_fd, temp_file_name = utils.make_temp_file()
 
537
                    open(temp_file_name, 'wb').write(exif_info['TIFFThumbnail'])
 
538
                    os.system('display %s' % temp_file_name)
 
539
                    os.remove(temp_file_name)
 
540
 
 
541
                else:
 
542
                    print "No thumbnail found."
 
543
 
 
544
            else:
 
545
                print "Incorrect file type for thumbnail."
 
546
 
 
547
        elif len(matched_files) == 0:
 
548
            print "File not found."
 
549
        else:
 
550
            print "Only one file at a time may be specified for thumbnail display."
 
551
 
 
552
    def do_thumb(self, args):
 
553
        """Synonym for the thumbnail command."""
 
554
        self.do_thumbnail(args)
 
555
 
 
556
    def do_exif(self, args):
 
557
        """Display EXIF info for file.
 
558
        Usage:
 
559
        \texif <filename>"""
 
560
        args = args.strip().lower()
 
561
        matched_files = self.pc.match_files(args)
 
562
 
 
563
        if len(matched_files) == 1:
 
564
            typ, subtyp = self.pc.classify_file(args).split('/')
 
565
            #print "'%s' '%s'" % (typ, subtyp)
 
566
 
 
567
            if typ == 'image' and subtyp in ('jpeg', 'tiff'):
 
568
                exif_info = self.pc.get_exif(args)
 
569
 
 
570
                formatter = utils.TextFormatter(
 
571
                        (
 
572
                            {'width': 40, 'margin' : 2},
 
573
                            {'width': 40, 'margin' : 2},
 
574
                        )
 
575
                    )
 
576
 
 
577
                print
 
578
                print utils.bold(formatter.compose(("Tag", "Value")))
 
579
 
 
580
                ee = exif_info.keys()
 
581
                ee.sort()
 
582
                for e in ee:
 
583
                    if e not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename'):
 
584
                        #if e != 'EXIF MakerNote':
 
585
                        print formatter.compose((e, '%s' % exif_info[e]))
 
586
                        #else:
 
587
                        #    print formatter.compose( ( e, ''.join( [ chr(x) for x in exif_info[e].values if chr(x) in string.printable ] ) ) )
 
588
            else:
 
589
                print "Incorrect file type for thumbnail."
 
590
 
 
591
        elif len(matched_files) == 0:
 
592
            print "File not found."
 
593
        else:
 
594
            print "Only one file at a time may be specified for thumbnail display."
 
595
 
 
596
    def do_info(self, args):
 
597
        """Synonym for the exif command."""
 
598
        self.do_exif(args)
 
599
        
 
600
    def do_about(self, args):
 
601
        utils.log_title(__title__, __version__)
 
602
 
 
603
 
 
604
def status_callback(src, trg, size):
 
605
    if size == 1:
 
606
        print
 
607
        print utils.bold("Copying %s..." % src)
 
608
    else:
 
609
        print "\nCopied %s to %s (%s)..." % (src, trg, utils.format_bytes(size))
 
610
 
 
611
    
 
612
    
76
613
try:
77
 
    opts, args = getopt.getopt(sys.argv[1:],
78
 
                                'p:d:hl:b:g',
79
 
                                ['printer=',
80
 
                                  'device=',
81
 
                                  'help', 'help-rest', 'help-man',
82
 
                                  'logging=',
83
 
                                  'bus='
84
 
                                ]
85
 
                              )
 
614
    opts, args = getopt.getopt(sys.argv[1:], 'p:d:hb:l:giuno:',
 
615
                               ['printer=', 'device=', 'help', 'help-rest', 'help-man',
 
616
                                'bus=', 'logging=', 'interactive', 'gui', 'non-interactive',
 
617
                                'output='])
86
618
except getopt.GetoptError:
87
619
    usage()
88
620
 
89
 
if os.getenv("HPLIP_DEBUG"):
90
 
    log.set_level('debug')
91
 
 
92
621
printer_name = None
93
622
device_uri = None
94
623
bus = device.DEFAULT_PROBE_BUS
95
624
log_level = logger.DEFAULT_LOG_LEVEL
 
625
mode = GUI_MODE
 
626
mode_specified = False
 
627
output_dir = os.getcwd()
96
628
 
 
629
if os.getenv("HPLIP_DEBUG"):
 
630
    log.set_level('debug')
97
631
 
98
632
for o, a in opts:
99
 
 
100
633
    if o in ('-h', '--help'):
101
634
        usage()
102
635
        
103
636
    elif o == '--help-rest':
104
637
        usage('rest')
105
 
    
 
638
        
106
639
    elif o == '--help-man':
107
640
        usage('man')
108
641
 
109
642
    elif o in ('-p', '--printer'):
110
 
        if a.startswith('*'):
111
 
            printer_name = cups.getDefault()
112
 
        else:
113
 
            printer_name = a
 
643
        printer_name = a
114
644
 
115
645
    elif o in ('-d', '--device'):
116
646
        device_uri = a
127
657
            
128
658
    elif o == '-g':
129
659
        log.set_level('debug')
130
 
 
131
 
    
 
660
        
 
661
    elif o in ('-i', '--interactive'):
 
662
        if mode_specified:
 
663
            log.error("You may only specify a single mode as a parameter (-i, -n or -u).")
 
664
            sys.exit(1)
 
665
 
 
666
        mode = INTERACTIVE_MODE
 
667
        mode_specified = True
 
668
        
 
669
    elif o in ('-u', '--gui'):
 
670
        if mode_specified:
 
671
            log.error("You may only specify a single mode as a parameter (-i, -n or -u).")
 
672
            sys.exit(1)
 
673
        
 
674
        mode = GUI_MODE
 
675
        mode_specified = True
 
676
        
 
677
    elif o in ('-n', '--non-interactive'):
 
678
        if mode_specified:
 
679
            log.error("You may only specify a single mode as a parameter (-i, -n or -u).")
 
680
            sys.exit(1)
 
681
        
 
682
        mode = NON_INTERACTIVE_MODE
 
683
        mode_specified = True
 
684
        
 
685
    elif o in ('-o', '--output'):
 
686
        output_dir = a
 
687
 
 
688
 
132
689
utils.log_title(__title__, __version__)
133
 
            
134
 
 
135
 
#try:
136
 
if 1:
 
690
 
 
691
if mode == GUI_MODE:
 
692
    if not os.getenv('DISPLAY'):
 
693
        mode = INTERACTIVE_MODE
 
694
    elif not utils.checkPyQtImport():
 
695
        mode = INTERACTIVE_MODE
 
696
 
 
697
if mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE):
 
698
    if device_uri and printer_name:
 
699
        log.error("You may not specify both a printer (-p) and a device (-d).")
 
700
        usage()
 
701
    
 
702
        
 
703
    if printer_name:
 
704
        printer_list = cups.getPrinters()
 
705
        found = False
 
706
        for p in printer_list:
 
707
            if p.name == printer_name:
 
708
                found = True
 
709
    
 
710
        if not found:
 
711
            log.error("Unknown printer name: %s" % printer_name)
 
712
            sys.exit(1)
 
713
    
 
714
    
 
715
    if not device_uri and not printer_name:
 
716
        try:
 
717
            device_uri = device.getInteractiveDeviceURI(bus, 'pcard')
 
718
            if device_uri is None:
 
719
                sys.exit(1)
 
720
        except Error:
 
721
            log.error("Error occured during interactive mode. Exiting.")
 
722
            sys.exit(1)
 
723
 
 
724
    try:
 
725
        pc = photocard.PhotoCard( None, device_uri, printer_name )
 
726
    except Error, e:
 
727
        log.error("Unable to start photocard session: %s" % e.msg)
 
728
        sys.exit(1)
 
729
    
 
730
    pc.set_callback(update_spinner)
 
731
    
 
732
    if pc.device.device_uri is None and printer_name:
 
733
        log.error("Printer '%s' not found." % printer_name)
 
734
        sys.exit(1)
 
735
    
 
736
    if pc.device.device_uri is None and device_uri:
 
737
        log.error("Malformed/invalid device-uri: %s" % device_uri)
 
738
        sys.exit(1)
 
739
    
 
740
    pc.device.sendEvent(EVENT_START_PCARD_JOB)
 
741
    
 
742
    try:
 
743
        pc.mount()
 
744
    except Error:
 
745
        log.error("Unable to mount photo card on device. Check that device is powered on and photo card is correctly inserted.")
 
746
        pc.umount()
 
747
        pc.device.sendEvent(EVENT_PCARD_UNABLE_TO_MOUNT, typ='error')
 
748
        sys.exit(1)
 
749
    
 
750
    log.info(utils.bold("\nPhotocard on device %s mounted" % pc.device.device_uri))
 
751
    log.info(utils.bold("DO NOT REMOVE PHOTO CARD UNTIL YOU EXIT THIS PROGRAM"))
 
752
    
 
753
    output_dir = os.path.realpath(os.path.normpath(os.path.expanduser(output_dir)))
 
754
        
 
755
    try:
 
756
        os.chdir(output_dir)
 
757
    except OSError:
 
758
        print utils.bold("ERROR: Output directory %s not found." % output_dir)
 
759
        sys.exit(1)
 
760
    
 
761
    
 
762
            
 
763
    if mode == INTERACTIVE_MODE: # INTERACTIVE_MODE
 
764
        
 
765
        console = Console(pc)
 
766
        try:
 
767
            try:
 
768
                console . cmdloop()
 
769
            except KeyboardInterrupt:
 
770
                log.error("Aborted.")
 
771
            except Exception, e:
 
772
                log.error("An error occured: %s" % e)
 
773
        finally:
 
774
            pc.umount()
 
775
        
 
776
        pc.device.sendEvent(EVENT_END_PCARD_JOB)
 
777
        
 
778
 
 
779
    else: # NON_INTERACTIVE_MODE
 
780
        print "Output directory is %s" % os.getcwd()
 
781
        try:
 
782
            try:
 
783
                unload_list = pc.get_unload_list()
 
784
                print
 
785
        
 
786
                if len(unload_list) > 0:
 
787
        
 
788
                    max_len = 0
 
789
                    for u in unload_list:
 
790
                        max_len = max(max_len, len(u[0]))
 
791
        
 
792
                    formatter = utils.TextFormatter(
 
793
                            (
 
794
                                {'width': max_len+2, 'margin' : 2},
 
795
                                {'width': 12, 'margin' : 2, 'alignment' : utils.TextFormatter.RIGHT},
 
796
                                {'width': 12, 'margin' : 2},
 
797
                            )
 
798
                        )
 
799
        
 
800
                    print
 
801
                    print utils.bold(formatter.compose(("Name", "Size", "Type")))
 
802
        
 
803
                    total = 0
 
804
                    for u in unload_list:
 
805
                         print formatter.compose(('%s' % u[0], utils.format_bytes(u[1]), '%s/%s' % (u[2], u[3])))
 
806
                         total += u[1]
 
807
        
 
808
        
 
809
                    print utils.bold("Found %d files to unload, %s\n" % (len(unload_list), utils.format_bytes(total, True)))
 
810
                    print utils.bold("Unloading files...\n")
 
811
                    total, delta, was_cancelled = pc.unload(unload_list, status_callback, None, True)
 
812
                    print utils.bold("\n%s unloaded in %d sec (%d KB/sec)" % (utils.format_bytes(total), delta, (total/1024)/delta))
 
813
            
 
814
            except KeyboardInterrupt:
 
815
                log.error("Aborted.")
 
816
                pass
 
817
                
 
818
        finally:
 
819
            pc.umount()
 
820
 
 
821
 
 
822
else: # GUI_MODE
 
823
    
 
824
    from qt import *
 
825
    from ui import unloadform
 
826
 
137
827
    a = QApplication(sys.argv)
138
828
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
139
829
 
140
 
    if use_qt_splashscreen:
141
 
        pixmap = QPixmap(os.path.join(prop.image_dir, "hp-tux-printer.png"))
142
 
        splash = QSplashScreen(pixmap)
143
 
        splash.message(__tr("Loading..."), Qt.AlignBottom)
144
 
        splash.show()
145
 
 
146
830
    try:
147
831
        w = unloadform.UnloadForm(bus, device_uri, printer_name)
148
832
    except Error:
152
836
    a.setMainWidget(w)
153
837
    w.show()
154
838
 
155
 
    if use_qt_splashscreen:
156
 
        splash.finish(w)
157
 
 
158
839
    a.exec_loop()
159
 
#except Exception, e:
160
 
    #log.exception()
161
840
 
 
841
log.info("Done.")
 
842
sys.exit(0)
162
843