~mimose/+junk/hplip-3.16.11

« back to all changes in this revision

Viewing changes to base/smart_install.py

  • Committer: guoyalong
  • Date: 2017-09-20 10:13:05 UTC
  • Revision ID: guoyalong@kylinos.cn-20170920101305-82zaolzpv1qghz29
Modified debian/control & debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
#
 
4
# (c) Copyright @2015 HP 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
 
 
24
# Std Lib
 
25
import sys
 
26
import os.path
 
27
import re
 
28
import os
 
29
 
 
30
# Local
 
31
from .g import *
 
32
from . import utils, tui
 
33
from base import password, validation
 
34
from base.codes import *
 
35
from base.strings import *
 
36
 
 
37
 
 
38
##### Global variables ###
 
39
HPLIP_INFO_SITE ="http://hplip.sourceforge.net/hplip_web.conf"
 
40
 
 
41
 
 
42
 
 
43
########### methods ###########
 
44
 
 
45
 
 
46
def get_usb_details(vid_pid):
 
47
    result_cnt = 0
 
48
    param_result = {"idVendor":'', "iProduct":'',  "bNumInterfaces":'', "bInterfaceClass":''}
 
49
    param_search = {"idVendor": re.compile(r"""\s*idVendor\s*([0-9a-fx]{1,})\s*.*""", re.I),
 
50
                    "iProduct" : re.compile(r"""\s*iProduct\s*[0-9a-fx]{1,}\s*(.*)""", re.I),
 
51
                    "bNumInterfaces" : re.compile(r"""\s*bNumInterfaces\s*(\d{1,})\s*.*""", re.I),
 
52
                    "bInterfaceClass" : re.compile(r"""\s*bInterfaceClass\s*(\d{1,})\s*.*""", re.I)  }
 
53
 
 
54
    lsusb_cmd = utils.which('lsusb',True)
 
55
    if lsusb_cmd:
 
56
        sts,out = utils.run("%s -d %s -v"%(lsusb_cmd, vid_pid), passwordObj = None, pswd_msg='', log_output=False)
 
57
        if sts == 0:
 
58
            for l in out.splitlines():
 
59
                for s in param_search:
 
60
                    if s in l:
 
61
                        result_cnt += 1
 
62
                        if param_search[s].match(l):
 
63
                            param_result[s] = param_search[s].match(l).group(1)
 
64
                        else:
 
65
                            log.warn("TBD... Shouldn't have entered into this condition. key[%s]"%s)
 
66
 
 
67
                        if "idVendor" ==  s and param_result[s].lower() != "0x03f0":  # if non-HP vendor, ignoring usb parsing.
 
68
                            return False, {}
 
69
                        elif "iProduct" == s and param_result[s] == "":
 
70
                            return False, {}
 
71
 
 
72
                        break
 
73
 
 
74
                if result_cnt == len(param_result):  # To avoid extra parsing...
 
75
                     break
 
76
 
 
77
    return True, param_result
 
78
 
 
79
 
 
80
# get_smartinstall_enabled_devices function checks CD-ROM enabled devices.
 
81
#Input:
 
82
#       None
 
83
# Output:
 
84
#       smartinstall_dev_list (list) --> Returns CD-ROM enabled device list.
 
85
#
 
86
def get_smartinstall_enabled_devices():
 
87
    smartinstall_dev_list=[]
 
88
    lsusb_cmd = utils.which('lsusb',True)
 
89
 
 
90
    if not lsusb_cmd:
 
91
        log.error("Failed to find the lsusb command")
 
92
        return smartinstall_dev_list
 
93
 
 
94
    try:
 
95
        sts,out = utils.run(lsusb_cmd)
 
96
        if sts !=  0:
 
97
            log.error("Failed to run the %s command"%lsusb_cmd)
 
98
            return smartinstall_dev_list
 
99
 
 
100
        for d in out.splitlines():
 
101
            usb_dev_pat = re.compile(r""".*([0-9a-f]{4}:([0-9a-f]{4}))\s*""", re.I)
 
102
 
 
103
            if usb_dev_pat.match(d):
 
104
                vid_pid = usb_dev_pat.match(d).group(1)
 
105
 
 
106
                bsts, usb_params = get_usb_details(vid_pid)
 
107
                if not bsts:
 
108
                    continue    # These are not HP-devices
 
109
 
 
110
                log.debug("Product['%s'],Interfaces[%s],InterfaceClass[%s]"%(usb_params["iProduct"], usb_params["bNumInterfaces"],usb_params["bInterfaceClass"]))
 
111
                if usb_params["bNumInterfaces"] == '1' and usb_params["bInterfaceClass"] == '8' and "laserjet" in usb_params["iProduct"].lower():    #'8' is MASS STORAGE
 
112
                    smartinstall_dev_list.append(usb_params["iProduct"])
 
113
 
 
114
            else:
 
115
                log.warn("Failed to find vid and pid for USB device[%s]"%d)
 
116
 
 
117
    except KeyError:
 
118
        pass
 
119
 
 
120
    if smartinstall_dev_list:
 
121
        smartinstall_dev_list = utils.uniqueList(smartinstall_dev_list)
 
122
 
 
123
    return smartinstall_dev_list
 
124
 
 
125
 
 
126
def check_SmartInstall():
 
127
    devices = get_smartinstall_enabled_devices()
 
128
    if devices:
 
129
        return True
 
130
    else:
 
131
        return False
 
132
 
 
133
 
 
134
def get_SmartInstall_tool_info():
 
135
    url, file_name = "", ""
 
136
    if not utils.check_network_connection():
 
137
        log.error("Internet connection not found.")
 
138
    else:
 
139
        sts, HPLIP_file = utils.download_from_network(HPLIP_INFO_SITE)
 
140
        if sts == 0:
 
141
            hplip_si_conf = ConfigBase(HPLIP_file)
 
142
            url = hplip_si_conf.get("SMART_INSTALL","reference","")
 
143
            if url:
 
144
                file_name = 'SmartInstallDisable-Tool.run'
 
145
            else:
 
146
                log.error("Failed to download %s."%HPLIP_INFO_SITE)
 
147
        else:
 
148
            log.error("Failed to download %s."%HPLIP_INFO_SITE)
 
149
 
 
150
    return url, file_name
 
151
 
 
152
def validate(mode, smart_install_run, smart_install_asc, req_checksum=''):
 
153
 
 
154
    #Validate Checksum
 
155
    calc_checksum = utils.get_checksum(open(smart_install_run, 'r').read())
 
156
    log.debug("File checksum=%s" % calc_checksum)
 
157
 
 
158
    if req_checksum and req_checksum != calc_checksum:
 
159
        return ERROR_FILE_CHECKSUM, queryString(ERROR_CHECKSUM_ERROR, 0, plugin_file)
 
160
 
 
161
    #Validate Digital Signature
 
162
    gpg_obj = validation.GPG_Verification()
 
163
    digsig_sts, error_str = gpg_obj.validate(smart_install_run, smart_install_asc)
 
164
 
 
165
    return digsig_sts, smart_install_run, smart_install_asc, error_str
 
166
 
 
167
 
 
168
 
 
169
def download(mode, passwordObj):
 
170
    if not utils.check_network_connection():
 
171
        log.error("Internet connection not found.")
 
172
        return ERROR_NO_NETWORK, "" , "" ,queryString(ERROR_NO_NETWORK)
 
173
 
 
174
    else:
 
175
        sts, HPLIP_file = utils.download_from_network(HPLIP_INFO_SITE)
 
176
        if sts == 0:
 
177
            hplip_si_conf = ConfigBase(HPLIP_file)
 
178
            source = hplip_si_conf.get("SMART_INSTALL","url","")
 
179
            if not source:
 
180
                log.error("Failed to download %s."%HPLIP_INFO_SITE)
 
181
                return ERROR_FAILED_TO_DOWNLOAD_FILE, "" , "", queryString(ERROR_FAILED_TO_DOWNLOAD_FILE, 0, HPLIP_INFO_SITE)
 
182
 
 
183
        sts, smart_install_run = utils.download_from_network(source)
 
184
        if sts:
 
185
            log.error("Failed to download %s."%source)
 
186
            return ERROR_FAILED_TO_DOWNLOAD_FILE, "" , "", queryString(ERROR_FAILED_TO_DOWNLOAD_FILE, 0, source)
 
187
 
 
188
        sts, smart_install_asc = utils.download_from_network(source+'.asc')
 
189
        if sts:
 
190
            log.error("Failed to download %s."%(source+'.asc'))
 
191
            return ERROR_FAILED_TO_DOWNLOAD_FILE, "" , "", queryString(ERROR_FAILED_TO_DOWNLOAD_FILE, 0, source + ".asc")
 
192
 
 
193
        digsig_sts, smart_install_run, smart_install_asc, error_str = validate(mode, smart_install_run, smart_install_asc)
 
194
 
 
195
        return digsig_sts, smart_install_run, smart_install_asc, error_str
 
196
 
 
197
 
 
198
def disable(mode, ui_toolkit='qt4', dialog=None, app=None, passwordObj = None):
 
199
 
 
200
    dev_list = get_smartinstall_enabled_devices()
 
201
    if not dev_list:
 
202
        log.debug("No Smart Install Device found")
 
203
        return ERROR_NO_SI_DEVICE, queryString(ERROR_NO_SI_DEVICE)
 
204
 
 
205
    return_val = ERROR_FAILED_TO_DISABLE_SI
 
206
    return_error_str = queryString(ERROR_FAILED_TO_DISABLE_SI)
 
207
    url, file_name = get_SmartInstall_tool_info()
 
208
    printer_names  = utils.list_to_string(dev_list)
 
209
 
 
210
    try:
 
211
        if mode == GUI_MODE:
 
212
            if ui_toolkit == 'qt3':
 
213
                try:
 
214
                    from ui.setupform import FailureMessageUI
 
215
                except ImportError:
 
216
                    log.error("Smart Install is enabled in %s device(s).\nAuto Smart Install disable is not supported in QT3.\nPlease refer link \'%s\' to disable manually"%(printer_names,url))
 
217
                else:
 
218
                    FailureMessageUI("Smart Install is enabled in %s device(s).\n\nAuto Smart Install disable is not supported in QT3.\nPlease refer link \'%s\' to disable manually"%(printer_names,url))
 
219
 
 
220
            else: #qt4
 
221
                if not utils.canEnterGUIMode4():
 
222
                    log.error("%s requires GUI support . Is Qt4 installed?" % __mod__)
 
223
                    return ERROR_FAILED_TO_DISABLE_SI, queryString(ERROR_FAILED_TO_DISABLE_SI)
 
224
 
 
225
                if dialog and app:  # If QT app already opened, re-using same object
 
226
                    dialog.init(printer_names, "", QUEUES_SMART_INSTALL_ENABLED)
 
227
                else:   # If QT object is not created, creating QT app
 
228
                    try:
 
229
                        from ui4.queuesconf import QueuesDiagnose
 
230
                    except ImportError:
 
231
                        log.error("Unable to load Qt4 support. Is it installed?")
 
232
                    else:       #  app = QApplication(sys.argv)   # caller needs to inoke this, if already QApplication object is not created.
 
233
                        dialog = QueuesDiagnose(None, printer_names ,"",QUEUES_SMART_INSTALL_ENABLED)
 
234
 
 
235
                log.debug("Starting GUI loop...")
 
236
                dialog.exec_()
 
237
 
 
238
                if check_SmartInstall():
 
239
                    dialog.showMessage("Failed to disable smart install.\nPlease refer link \'%s\' for more information" %url)
 
240
                else:
 
241
                    dialog.showSuccessMessage("Smart install disabled successfully.")
 
242
 
 
243
 
 
244
        #Interaction mode
 
245
        else: 
 
246
            log.error("Smart Install is enabled in %s device(s). "%printer_names)
 
247
            response, value = tui.enter_choice("Do you want to download and disable smart install?(y=yes*, n=no):",['y', 'n'], 'y')
 
248
 
 
249
            if not response or value != 'y':   #User exit
 
250
                return_val = ERROR_FAILED_TO_DISABLE_SI
 
251
                return_error_str = queryString(ERROR_FAILED_TO_DISABLE_SI)
 
252
 
 
253
            else:
 
254
                sts, smart_install_run, smart_install_asc, error_str = download(mode, passwordObj)
 
255
 
 
256
                disable_si = False
 
257
                return_val = sts
 
258
 
 
259
                if sts == ERROR_SUCCESS:
 
260
                    disable_si = True
 
261
 
 
262
                elif sts in (ERROR_UNABLE_TO_RECV_KEYS, ERROR_DIGITAL_SIGN_NOT_FOUND):
 
263
                    response, value = tui.enter_yes_no("Digital Sign verification failed, Do you want to continue?")
 
264
                    if not response or not value:
 
265
                        sys.exit(0)
 
266
                    else:   # Continue without validation succes.
 
267
                        disable_si = True
 
268
                else:
 
269
                    return_error_str = queryString(sts)
 
270
 
 
271
                if disable_si: 
 
272
                    sts, out = utils.run("sh %s"%smart_install_run)
 
273
 
 
274
                    # Once smart install disabler installation completed, cross verifying to ensure no smart install devices found
 
275
                    if sts or check_SmartInstall():
 
276
                        log.error("Failed to disable smart install .")
 
277
                        log.error("Please refer link \'%s\' to disable manually"%url)
 
278
                        return_val = ERROR_FAILED_TO_DISABLE_SI
 
279
                        return_error_str = queryString(ERROR_FAILED_TO_DISABLE_SI)
 
280
                    else:
 
281
                        log.info("Smart install disabled successfully.")
 
282
                        return_val = ERROR_SUCCESS
 
283
                        return_error_str = ""
 
284
 
 
285
    except KeyboardInterrupt:
 
286
        log.error("User exit")
 
287
        sys.exit(0)
 
288
 
 
289
    return return_val ,return_error_str
 
290