Tizen 2.1 base
[platform/upstream/hplip.git] / config_usb_printer.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 #
4 # (c) Copyright 2011-2014 Hewlett-Packard Development Company, L.P.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 # Author: Amarnath Chitumalla
21 #
22
23 __version__ = '1.0'
24 __title__ = 'HP device setup using USB'
25 __mod__ = 'hp-config_usb_printer'
26 __doc__ = "Detects HP printers connected using USB and installs HPLIP printers and faxes in the CUPS spooler. Tries to automatically determine the correct PPD file to use."
27
28 # Std Lib
29 import sys
30 import os
31 import getopt
32 import commands
33 import re
34 import time
35
36 # Local
37 from base.g import *
38 from base import device,utils, tui, models,module
39 from prnt import cups
40
41
42 LPSTAT_PAT = re.compile(r"""(\S*): (.*)""", re.IGNORECASE)
43 USB_PATTERN = re.compile(r'''serial=(.*)''',re.IGNORECASE)
44 BACK_END_PATTERN = re.compile(r'''(.*):(.*)''',re.IGNORECASE)
45 DBUS_SERVICE='com.hplip.StatusService'
46
47 ##### METHODS #####
48
49 # Returns already existing print queues for this printer.
50 def get_already_added_queues(udev_MDL, udev_serial_no, udev_back_end,remove_non_hp_config):
51     status, output = utils.run('lpstat -v')
52
53     same_printer_queues = []
54     for p in output.splitlines():
55         try:
56             match = LPSTAT_PAT.search(p)
57             printer_name = match.group(1)
58             device_uri = match.group(2)
59             if device_uri.startswith("cups-pdf:/"):
60                   continue
61             if not USB_PATTERN.search(device_uri):
62                   continue
63
64             back_end = BACK_END_PATTERN.search(device_uri).group(1)
65             serial = USB_PATTERN.search(device_uri).group(1)
66             log.debug("udev_serial_no[%s] serial[%s] udev_back_end[%s] back_end[%s]"%(udev_serial_no, serial, udev_back_end, back_end))
67             if udev_serial_no == serial and (udev_back_end == back_end or back_end == 'usb'):
68                 if remove_non_hp_config and printer_name.find('_') == -1 and printer_name.find('-') != -1:
69                     log.debug("Removed %s Queue"%printer_name)
70                     # remove queues using cups API
71                     cups.delPrinter(printer_name)
72                 else:
73                     same_printer_queues.append(printer_name)
74
75         except AttributeError:
76             pass
77
78     log.debug(same_printer_queues)
79     return same_printer_queues
80
81 def check_cups_process():
82     cups_running_sts = False
83     sts, output = utils.run('lpstat -r')
84     if sts == 0 and ('is running' in output):
85         cups_running_sts = True
86     
87     return cups_running_sts
88
89
90 def showPasswordUI(prompt):
91     import getpass
92     print ""
93     print log.bold(prompt)
94     username = raw_input("Username: ")
95     password = getpass.getpass("Password: ")
96
97     return (username, password)
98
99
100 # Restart cups
101 def restart_cups():
102     if os.path.exists('/etc/init.d/cups'):
103         return '/etc/init.d/cups restart'
104
105     elif os.path.exists('/etc/init.d/cupsys'):
106         return '/etc/init.d/cupsys restart'
107
108     else:
109         return 'killall -HUP cupsd'
110
111
112 # Send dbus event to hpssd on dbus system bus
113 def send_message(device_uri, printer_name, event_code, username, job_id, title, pipe_name=''):
114     log.debug("send_message() entered")
115     args = [device_uri, printer_name, event_code, username, job_id, title, pipe_name]
116     msg = lowlevel.SignalMessage('/', DBUS_SERVICE, 'Event')
117     msg.append(signature='ssisiss', *args)
118     SystemBus().send_message(msg)
119     log.debug("send_message() returning")
120
121
122 # Usage function
123 def usage(typ='text'):
124     utils.format_text(USAGE, typ, __title__, __mod__, __version__)
125     sys.exit(0)
126
127 # Systray service. If hp-systray is not running, starts.
128 def start_systray():
129     Systray_Is_Running=False
130     status,output = utils.Is_Process_Running('hp-systray')
131     if status is False:
132         log.debug("hp-systray is not running.")
133         if os.getuid() == 0:
134             log.error("Run \'hp-systray &\' in a terminal. ")
135         else:
136             log.debug("Starting hp-systray service")
137             child_pid = os.fork()
138             if child_pid == 0:
139                 status,output =utils.run('hp-systray &', True, None, 1, False)
140                 if status is not 0:
141                     log.error("Failed to start \'hp-systray\' service. Manually run \'hp-sysray &\' from terminal as non-root user.")
142                 sys.exit()
143             else:
144                 time.sleep(1)
145                 status,output = utils.Is_Process_Running('hp-systray')
146                 if  status is True:
147                     Systray_Is_Running=True
148     else:
149         Systray_Is_Running=True
150         log.debug("hp-systray service is running\n")
151     return Systray_Is_Running
152
153
154 USAGE = [ (__doc__, "", "name", True),
155           ("Usage: %s [OPTIONS] [SERIAL NO.|USB bus:device]" % __mod__, "", "summary", True),
156           utils.USAGE_OPTIONS,
157           utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
158           utils.USAGE_HELP,
159           ("[SERIAL NO.|USB bus:device]", "", "heading", False),
160           ("USB bus:device :", """"xxx:yyy" where 'xxx' is the USB bus and 'yyy' is the USB device. (Note: The ':' and all leading zeros must be present.)""", 'option', False),
161           ("", "Use the 'lsusb' command to obtain this information.", "option", False),
162           ("SERIAL NO.:", '"serial no." (future use)', "option", True),
163           utils.USAGE_EXAMPLES,
164           ("USB, IDs specified:", "$%s 001:002"%(__mod__), "example", False),
165           ("USB, using serial number:", "$%s US12345678A"%(__mod__), "example", False),
166           utils.USAGE_SPACE,
167           utils.USAGE_NOTES,
168           ("1. Using 'lsusb' to obtain USB IDs: (example)", "", 'note', False),
169           ("   $ lsusb", "", 'note', False),
170           ("         Bus 003 Device 011: ID 03f0:c202 Hewlett-Packard", "", 'note', False),
171           ("   $ %s 003:011"%(__mod__), "", 'note', False),
172           ("   (Note: You may have to run 'lsusb' from /sbin or another location. Use '$ locate lsusb' to determine this.)", "", 'note', True),
173         ]
174
175
176
177 mod = module.Module(__mod__, __title__, __version__, __doc__, USAGE, (INTERACTIVE_MODE, GUI_MODE), (UI_TOOLKIT_QT3, UI_TOOLKIT_QT4), run_as_root_ok=True, quiet=True)
178
179 opts, device_uri, printer_name, mode, ui_toolkit, loc = \
180     mod.parseStdOpts('gh',['time-out=', 'timeout='],handle_device_printer=False)
181
182
183 LOG_FILE = "/var/log/hp/hplip_config_usb_printer.log" 
184 if os.path.exists(LOG_FILE):
185     os.remove(LOG_FILE)
186
187 log.set_logfile(LOG_FILE)
188 log.set_where(log.LOG_TO_CONSOLE_AND_FILE)
189 cmd="chmod 777 "+LOG_FILE
190 sts,output = utils.run(cmd)
191 if sts != 0:
192     log.warn("Failed to change log file permissions: %s" %output)
193
194 cmd="chgrp lp "+LOG_FILE
195 sts,output = utils.run(cmd)
196 if sts != 0:
197     log.warn("Failed to change log file group permissions: %s" %output)
198
199 try:
200     import dbus
201     from dbus import SystemBus, lowlevel
202 except ImportError:
203         log.error("hp-check-plugin Tool requires dBus and python-dbus")
204         sys.exit(1)
205
206 try:
207     param = mod.args[0]
208 except IndexError:
209     param = ''
210
211 log.debug("param=%s" % param)
212 if len(param) < 1:
213     usage()
214     sys.exit()
215
216 try:
217     # ******************************* MAKEURI
218     if param:
219         device_uri, sane_uri, fax_uri = device.makeURI(param)
220     if not device_uri:
221         log.error("This is not a valid device")
222         sys.exit(0)
223
224     # ******************************* QUERY MODEL AND COLLECT PPDS
225     log.debug("\nSetting up device: %s\n" % device_uri)
226     back_end, is_hp, bus, model, serial, dev_file, host, zc, port = device.parseDeviceURI(device_uri)
227
228     mq = device.queryModelByURI(device_uri)
229     if not mq or mq.get('support-type', SUPPORT_TYPE_NONE) == SUPPORT_TYPE_NONE:
230         log.error("Unsupported printer model.")
231         sys.exit(1)
232     while check_cups_process() is False:
233         log.debug("CUPS is not running.. waiting for 30 sec")
234         time.sleep(30)
235
236     time.sleep(1)
237     norm_model = models.normalizeModelName(model).lower()
238     remove_non_hp_config =True
239     if not mq.get('fax-type', FAX_TYPE_NONE) in (FAX_TYPE_NONE, FAX_TYPE_NOT_SUPPORTED):
240         fax_config_list = get_already_added_queues(norm_model, serial, 'hpfax',remove_non_hp_config)
241
242
243     printer_config_list = get_already_added_queues(norm_model, serial, back_end, remove_non_hp_config)
244     if len(printer_config_list) ==0  or len(printer_config_list) == 0:
245         cmd ="hp-setup -i -x -a -q %s"%param
246         log.debug("%s"%cmd)
247         os.system(cmd)
248
249         if start_systray():
250             printer_name = ""
251             username = ""
252             send_message( device_uri, printer_name, EVENT_ADD_PRINTQUEUE, username, 0,'')
253             send_message( device_uri, printer_name, EVENT_DIAGNOSE_PRINTQUEUE, username, 0,'')
254     else:
255         if start_systray():
256             printer_name = ""
257             username = ""
258             send_message( device_uri, printer_name, EVENT_DIAGNOSE_PRINTQUEUE, username, 0,'')
259
260     # Cleaning CUPS created Queues. If any,
261     i =0
262     while i <24:
263         time.sleep(5)
264         get_already_added_queues(norm_model, serial, 'hpfax',remove_non_hp_config)
265         get_already_added_queues(norm_model, serial, 'hp',remove_non_hp_config)
266         i += 1
267
268
269 except KeyboardInterrupt:
270     log.error("User exit")
271
272 log.debug("Done.")