Ejemplo n.º 1
0
def load_pixmap(name, subdir=None, resize_to=None):
    name = ''.join([os.path.splitext(name)[0], '.png'])

    if subdir is None:
        dir = prop.image_dir
        ldir = os.path.join(os.getcwd(), 'data', 'images')
    else:
        dir = os.path.join(prop.image_dir, subdir)
        ldir = os.path.join(os.getcwd(), 'data', 'images', subdir)

    for d in [dir, ldir]:
        f = os.path.join(d, name)
        if os.path.exists(f):
            if resize_to is not None:
                img = QImage(f)
                x, y = resize_to
                return QPixmap.fromImage(img.scaled(x, y, Qt.IgnoreAspectRatio, Qt.SmoothTransformation))
            else:
                return QPixmap(f)

        for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=name):
            if resize_to is not None:
                img = QImage(w)
                x, y = resize_to
                return QPixmap.fromImage(img.scaled(x, y, Qt.IgnoreAspectRatio, Qt.SmoothTransformation))
            else:
                return QPixmap(w)

    log.error("Pixmap '%s' not found!" % name)
    return QPixmap()
Ejemplo n.º 2
0
def load_pixmap(name, subdir=None, resize_to=None): # Qt3 only
    name = ''.join([os.path.splitext(name)[0], '.png'])
    
    if subdir is None:
        dir = prop.image_dir
        ldir = os.path.join(os.getcwd(), 'data', 'images')
    else:
        dir = os.path.join(prop.image_dir, subdir)
        ldir = os.path.join(os.getcwd(), 'data', 'images', subdir)
    
    for d in [dir, ldir]:
        f = os.path.join(d, name)
    
        if os.path.exists(f):
            if resize_to is not None:
                img = QImage(f)
                pm = QPixmap()
                pm.convertFromImage(img.smoothScale(*resize_to), 0)
                return pm
            else:
                return QPixmap(f)
        
        for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=name):
            if resize_to is not None:
                img = QImage(w)
                pm = QPixmap()
                pm.convertFromImage(img.smoothScale(*resize_to), 0)
                return pm
            else:
                return QPixmap(w)

    log.error("Pixmap '%s' not found!" % name)
    return QPixmap()
Ejemplo n.º 3
0
def load_pixmap(name, subdir=None, resize_to=None):
    name = ''.join([os.path.splitext(name)[0], '.png'])

    if subdir is None:
        dir = prop.image_dir
        ldir = os.path.join(os.getcwd(), 'data', 'images')
    else:
        dir = os.path.join(prop.image_dir, subdir)
        ldir = os.path.join(os.getcwd(), 'data', 'images', subdir)

    for d in [dir, ldir]:
        f = os.path.join(d, name)
        if os.path.exists(f):
            if resize_to is not None:
                img = QImage(f)
                x, y = resize_to
                return QPixmap.fromImage(img.scaled(x, y, Qt.IgnoreAspectRatio, Qt.SmoothTransformation))
            else:
                return QPixmap(f)

        for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=name):
            if resize_to is not None:
                img = QImage(w)
                x, y = resize_to
                return QPixmap.fromImage(img.scaled(x, y, Qt.IgnoreAspectRatio, Qt.SmoothTransformation))
            else:
                return QPixmap(w)

    log.error("Pixmap '%s' not found!" % name)
    return QPixmap()
Ejemplo n.º 4
0
def check_file(f, dir="/usr/include"):
    log.debug("Searching for file '%s' in '%s'..." % (f, dir))
    for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=f):
        log.debug("File found at '%s'" % w)
        return True

    log.debug("File not found.")
    return False
Ejemplo n.º 5
0
def check_file(f, dir="/usr/include"):
    log.debug("Searching for file '%s' in '%s'..." % (f, dir))
    for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=f):
        log.debug("File found at '%s'" % w)
        return True

    log.debug("File not found.")
    return False
Ejemplo n.º 6
0
def getFaxPPDFile(mq, model):
    try:
        fax_ppd = None
        nick = "HP Fax hpcups"
        expected_fax_ppd_name = "HP-Fax-hpcups"
        log.debug("Searching for fax PPD for model %s  hpcups_build =%d" %
                  (model, prop.hpcups_build))
        if prop.hpcups_build:
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
                expected_fax_ppd_name = "HP-Fax3-hpcups"  # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax3 hpcups"
            elif mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or mq.get(
                    'fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
                expected_fax_ppd_name = "HP-Fax2-hpcups"  # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax2 hpcups"
            elif mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
                expected_fax_ppd_name = "HP-Fax4-hpcups"  # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax4 hpcups"
            else:
                expected_fax_ppd_name = "HP-Fax-hpcups"  # Standard
                nick = "HP Fax hpcups"

        else:  # hpijs
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
                expected_fax_ppd_name = "HP-Fax3-hpijs"  # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax3 hpijs"
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or mq.get(
                    'fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
                expected_fax_ppd_name = "HP-Fax2-hpijs"  # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax2 hpijs"
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
                expected_fax_ppd_name = "HP-Fax4-hpijs"  # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax4 hpijs"
            else:
                expected_fax_ppd_name = "HP-Fax-hpijs"  # Standard
                nick = "HP Fax hpijs"

        ppds = []
        for f in utils.walkFiles(sys_conf.get('dirs', 'ppd'),
                                 pattern="HP-Fax*.ppd*",
                                 abs_paths=True):
            ppds.append(f)
        log.debug("ppds=%s" % ppds)
        for f in ppds:
            if f.find(expected_fax_ppd_name) >= 0 and getPPDDescription(
                    f) == nick:
                fax_ppd = f
                log.debug("Found fax PPD: %s" % f)
                break
        else:
            log.error(
                "Unable to locate the HPLIP Fax PPD file: %s.ppd.gz file." %
                expected_fax_ppd_name)

    finally:
        return fax_ppd, expected_fax_ppd_name, nick
Ejemplo n.º 7
0
    def findFaxPPD(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            log.debug("Searching for fax PPD for model %s" % self.model)

            if prop.hpcups_build:
                if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
                    fax_ppd_name = "HP-Fax3-hpcups" # Fixed width (2528 pixels) and 300dpi rendering
                    nick = "HP Fax3 hpcups"
                elif self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
                    fax_ppd_name = "HP-Fax2-hpcups" # Fixed width (2528 pixels) and 300dpi rendering
                    nick = "HP Fax2 hpcups"
                elif self.mq.get('fax-type', FAX_TYPE_LEDM) == FAX_TYPE_LEDM:
                    fax_ppd_name = "HP-Fax4-hpcups"# Fixed width (2528 pixels) and 300dpi rendering
                    nick = "HP Fax4 hpcups"
                else:
                    fax_ppd_name = "HP-Fax-hpcups" # Standard
                    nick = "HP Fax hpcups"

            else: # hpijs
                if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
                    fax_ppd_name = "HP-Fax3-hpijs" # Fixed width (2528 pixels) and 300dpi rendering
                    nick = "HP Fax3 hpijs"
                if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
                    fax_ppd_name = "HP-Fax2-hpijs" # Fixed width (2528 pixels) and 300dpi rendering
                    nick = "HP Fax2 hpijs"
                if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
                    fax_ppd_name = "HP-Fax4-hpijs" # Fixed width (2528 pixels) and 300dpi rendering
                    nick = "HP Fax4 hpijs"
                else:
                    fax_ppd_name = "HP-Fax-hpijs" # Standard
                    nick = "HP Fax hpijs"

            ppds = []

            for f in utils.walkFiles(sys_conf.get('dirs', 'ppd'), pattern="HP-Fax*.ppd*", abs_paths=True):
                ppds.append(f)

            for f in ppds:
                if f.find(fax_ppd_name) >= 0 and cups.getPPDDescription(f) == nick:
                    self.fax_ppd = f
                    self.fax_setup_ok = True
                    log.debug("Found fax PPD: %s" % f)
                    break
            else:
                self.fax_ppd = None
                self.fax_setup_ok = False
                FailureUI(self, self.__tr("<b>Unable to locate the HPLIP Fax PPD file:</b><p>%1.ppd.gz</p><p>Fax setup has been disabled.").arg(fax_ppd_name))
                self.fax_setup = False
                self.SetupFaxGroupBox.setChecked(False)
                self.SetupFaxGroupBox.setEnabled(False)

        finally:
            QApplication.restoreOverrideCursor()
Ejemplo n.º 8
0
def locate_files(f, dir):
    log.debug("Searching for file(s) '%s' in '%s'..." % (f, dir))
    found = []
    for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=f):
        log.debug(w)
        found.append(w)

    if found:
        log.debug("Found files: %s" % found)
    else:
        log.debug("No files not found.")

    return found
Ejemplo n.º 9
0
def locate_files(f, dir):
    log.debug("Searching for file(s) '%s' in '%s'..." % (f, dir))
    found = []
    for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=f):
        log.debug(w)
        found.append(w)

    if found:
        log.debug("Found files: %s" % found)
    else:
        log.debug("No files not found.")

    return found
Ejemplo n.º 10
0
def get_process_list():
    processes = [] # (pid, cmdline), ...
    for x in utils.walkFiles("/proc", False, True, True):
        s = proc_pat.search(x) 
        if s is not None:
            try:
                cmdline = file(os.path.join(x, 'cmdline'), 'r').read().replace('\x00', '').replace('\n', '').strip()
            except IOError:
                cmdline = None
                
            if cmdline:
                processes.append((int(s.group(1)), cmdline))

    return processes
Ejemplo n.º 11
0
def getFaxPPDFile(mq, model):
    try:
        fax_ppd = None
        nick = "HP Fax hpcups"
        expected_fax_ppd_name = "HP-Fax-hpcups"
        log.debug("Searching for fax PPD for model %s  hpcups_build =%d" % (model,prop.hpcups_build))
        if prop.hpcups_build:
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
                expected_fax_ppd_name = "HP-Fax3-hpcups" # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax3 hpcups"
            elif mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
                expected_fax_ppd_name = "HP-Fax2-hpcups" # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax2 hpcups"
            elif mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
                expected_fax_ppd_name = "HP-Fax4-hpcups"# Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax4 hpcups"
            else:
                expected_fax_ppd_name = "HP-Fax-hpcups" # Standard
                nick = "HP Fax hpcups"

        else: # hpijs
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
                expected_fax_ppd_name = "HP-Fax3-hpijs" # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax3 hpijs"
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
                expected_fax_ppd_name = "HP-Fax2-hpijs" # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax2 hpijs"
            if mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
                expected_fax_ppd_name = "HP-Fax4-hpijs" # Fixed width (2528 pixels) and 300dpi rendering
                nick = "HP Fax4 hpijs"
            else:
                expected_fax_ppd_name = "HP-Fax-hpijs" # Standard
                nick = "HP Fax hpijs"

        ppds = []
        for f in utils.walkFiles(sys_conf.get('dirs', 'ppd'), pattern="HP-Fax*.ppd*", abs_paths=True):
            ppds.append(f)
        log.debug("ppds=%s"%ppds)
        for f in ppds:
            if f.find(expected_fax_ppd_name) >= 0 and getPPDDescription(f) == nick:
                fax_ppd = f
                log.debug("Found fax PPD: %s" % f)
                break
        else:
            log.error("Unable to locate the HPLIP Fax PPD file: %s.ppd.gz file."%expected_fax_ppd_name)

    finally:
        return fax_ppd,expected_fax_ppd_name, nick
Ejemplo n.º 12
0
def get_process_list():
    processes = []  # (pid, cmdline), ...
    for x in utils.walkFiles("/proc", False, True, True):
        s = proc_pat.search(x)
        if s is not None:
            try:
                cmdline = file(os.path.join(x, 'cmdline'),
                               'r').read().replace('\x00',
                                                   '').replace('\n',
                                                               '').strip()
            except IOError:
                cmdline = None

            if cmdline:
                processes.append((int(s.group(1)), cmdline))

    return processes
Ejemplo n.º 13
0
def locate_file_contains(f, dir, s):
    """
        Find a list of files located in a directory
        that contain a specified sub-string.
    """
    log.debug("Searching for file(s) '%s' in '%s' that contain '%s'..." % (f, dir, s))
    found = []
    for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=f):

        if check_file_contains(w, s):
            log.debug(w)
            found.append(w)

    if found:
        log.debug("Found files: %s" % found)
    else:
        log.debug("No files not found.")

    return found
Ejemplo n.º 14
0
def locate_file_contains(f, dir, s):
    """
        Find a list of files located in a directory
        that contain a specified sub-string.
    """
    log.debug("Searching for file(s) '%s' in '%s' that contain '%s'..." % (f, dir, s))
    found = []
    for w in utils.walkFiles(dir, recurse=True, abs_paths=True, return_folders=False, pattern=f):

        if check_file_contains(w, s):
            log.debug(w)
            found.append(w)

    if found:
        log.debug("Found files: %s" % found)
    else:
        log.debug("No files not found.")

    return found
Ejemplo n.º 15
0
def load_pixmap(name, subdir=None, resize_to=None):  # Qt3 only
    name = ''.join([os.path.splitext(name)[0], '.png'])

    if subdir is None:
        dir = prop.image_dir
        ldir = os.path.join(os.getcwd(), 'data', 'images')
    else:
        dir = os.path.join(prop.image_dir, subdir)
        ldir = os.path.join(os.getcwd(), 'data', 'images', subdir)

    for d in [dir, ldir]:
        f = os.path.join(d, name)

        if os.path.exists(f):
            if resize_to is not None:
                img = QImage(f)
                pm = QPixmap()
                pm.convertFromImage(img.smoothScale(*resize_to), 0)
                return pm
            else:
                return QPixmap(f)

        for w in utils.walkFiles(dir,
                                 recurse=True,
                                 abs_paths=True,
                                 return_folders=False,
                                 pattern=name):
            if resize_to is not None:
                img = QImage(w)
                pm = QPixmap()
                pm.convertFromImage(img.smoothScale(*resize_to), 0)
                return pm
            else:
                return QPixmap(w)

    log.error("Pixmap '%s' not found!" % name)
    return QPixmap()
Ejemplo n.º 16
0
            quiet = True

        elif o in ('-l', '--logging'):
            log.set_level(a.lower().strip())


    if not quiet:
        utils.log_title(__title__, __version__)

    drv_dir = os.path.join(cur_path, 'prnt', 'drv')

    errors = []
    warns = []
    notes = []

    for template_file in utils.walkFiles(drv_dir, recurse=False, abs_paths=True,
        return_folders=False, pattern='*.in.template'):

        basename = os.path.basename(template_file).split('.')[0]

        # Output
        drv_in_file = os.path.join(cur_path, 'prnt', 'drv', '%s.drv.in' % basename)

        # XML output (per model)
        output_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml', basename)

        # XML Output (master driver list)
        driver_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml', basename, '%s.xml' % basename)

        log.info("Working on %s file..." % basename)
        log.info("Input file: %s" % template_file)
        log.info("Output file: %s" % drv_in_file)
Ejemplo n.º 17
0
def getSystemPPDs():
    major, minor, patch = getVersionTuple()
    ppds = {} # {'ppd name' : 'desc', ...}

    if major == 1 and minor < 2:
        ppd_dir = sys_conf.get('dirs', 'ppd')
        log.debug("(CUPS 1.1.x) Searching for PPDs in: %s" % ppd_dir)

        for f in utils.walkFiles(ppd_dir, pattern="HP*ppd*;hp*ppd*", abs_paths=True):
            desc = getPPDDescription(f)

            if not ('foo2' in desc or
                    'gutenprint' in desc.lower() or
                    'gutenprint' in f):

                ppds[f] = desc
                log.debug("%s: %s" % (f, desc))

    else: # 1.2.x
        log.debug("(CUPS 1.2.x) Getting list of PPDs using CUPS_GET_PPDS...")
        ppd_dict = cupsext.getPPDList()
        cups_ppd_path = getPPDPath() # usually /usr/share/cups/model
        foomatic_ppd_path = sys_conf.get('dirs', 'ppdbase', '/usr/share/ppd')

        if not foomatic_ppd_path or not os.path.exists(foomatic_ppd_path):
            foomatic_ppd_path = '/usr/share/ppd'

        log.debug("CUPS PPD base path = %s" % cups_ppd_path)
        log.debug("Foomatic PPD base path = %s" % foomatic_ppd_path)

        for ppd in ppd_dict:
            if not ppd:
                continue

            if 'hp-' in ppd.lower() or 'hp_' in ppd.lower() and \
                ppd_dict[ppd]['ppd-make'] == 'HP':

                desc = ppd_dict[ppd]['ppd-make-and-model']

                if not ('foo2' in desc.lower() or
                        'gutenprint' in desc.lower() or
                        'gutenprint' in ppd):

                    # PPD files returned by CUPS_GET_PPDS (and by lpinfo -m)
                    # can be relative to /usr/share/ppd/ or to
                    # /usr/share/cups/model/. Not sure why this is.
                    # Here we will try both and see which one it is...

                    if os.path.exists(ppd):
                        path = ppd
                    else:
                        try:
                            path = os.path.join(foomatic_ppd_path, ppd)
                        except AttributeError: # happens on some boxes with provider: style ppds (foomatic: etc)
                            path = ppd
                        else:
                            if not os.path.exists(path):
                                try:
                                    path = os.path.join(cups_ppd_path, ppd)
                                except AttributeError:
                                    path = ppd
                                else:
                                    if not os.path.exists(path):
                                        path = ppd # foomatic: or some other driver

                    ppds[path] = desc
                    #log.debug("%s: %s" % (path, desc))

    return ppds
Ejemplo n.º 18
0
    def setupFax(self):
        QApplication.setOverrideCursor(QApplication.waitCursor)

        if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
            fax_ppd_name = "HP-Fax3-hplip" # Fixed width (2528 pixels) and 300dpi rendering
            nick = "HP Fax 3"
        if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_SOAP or self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
            fax_ppd_name = "HP-Fax2-hplip" # Fixed width (2528 pixels) and 300dpi rendering
            nick = "HP Fax 2"
        if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
            fax_ppd_name = "HP-Fax4-hplip" # Fixed width (1728 pixels) and 200dpi rendering
            nick = "HP Fax 4"
        else:
            fax_ppd_name = "HP-Fax-hplip" # Standard
            nick = "HP Fax"

        ppds = []

        log.debug("Searching for fax file %s..." % fax_ppd_name)

        ppd_dir = sys_conf.get('dirs', 'ppd')
        for f in utils.walkFiles(ppd_dir, pattern="HP-Fax*.ppd*", abs_paths=True):
            ppds.append(f)

        for f in ppds:
            if f.find(fax_ppd_name) >= 0:
                fax_ppd = f
                log.debug("Found PDD file: %s" % fax_ppd)
                log.debug("Nickname: %s" % cups.getPPDDescription(fax_ppd))
                break
        else:
            QApplication.restoreOverrideCursor()
            log.error("Fax PPD file not found.")

            if QMessageBox.warning(self, self.__tr("Unable to find HP fax PPD file."),
                self.__tr("The PPD file (%1.ppd) needed to setup the fax queue was not found.").arg(fax_ppd_name),
                self.__tr("Browse to file..."), # button 0
                self.__tr("Quit") # button 1
                ) == 0: # Browse

                while True:
                    ppd_dir = sys_conf.get('dirs', 'ppd')
                    fax_ppd = unicode(QFileDialog.getOpenFileName(ppd_dir,
                        "HP Fax PPD Files (*.ppd *.ppd.gz);;All Files (*)", self,
                        "open file dialog", "Choose the fax PPD file"))

                    if not fax_ppd: # user hit cancel
                        return

                    if os.path.exists(fax_ppd):
                        n = cups.getPPDDescription(fax_ppd)
                        if n == nick:
                            break
                        else:
                            self.FailureUI(self.__tr("<b>Incorrect fax PPD file.</b><p>The fax PPD file must have a nickname of '%1', not '%1'.").arg(nick).arg(n))
                    else:
                        self.FailureUI(self.__tr("<b>File not found.</b><p>hp-setup cannot find the file %1").arg(fax_ppd))

            else: # Quit
                return

        cups.setPasswordPrompt("You do not have permission to add a fax device.")
        if not os.path.exists(fax_ppd):
            status, status_str = cups.addPrinter(self.fax_name.encode('utf8'),
                self.fax_uri, self.fax_location, '', fax_ppd,  self.fax_desc)
        else:
            status, status_str = cups.addPrinter(self.fax_name.encode('utf8'),
                self.fax_uri, self.fax_location, fax_ppd, '', self.fax_desc)

        log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
        self.installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])

        log.debug(self.installed_fax_devices)

        if self.fax_uri not in self.installed_fax_devices or \
            self.fax_name not in self.installed_fax_devices[self.fax_uri]:

            self.FailureUI(self.__tr("<b>Fax queue setup failed.</b><p>Please restart CUPS and try again."))
        else:
            pass
            # TODO:
            #service.sendEvent(self.hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=self.fax_uri)

        QApplication.restoreOverrideCursor()
Ejemplo n.º 19
0
        elif o in ('-l', '--logging'):
            log.set_level(a.lower().strip())

    if not quiet:
        utils.log_title(__title__, __version__)

    drv_dir = os.path.join(cur_path, 'prnt', 'drv')

    errors = []
    warns = []
    notes = []

    for template_file in utils.walkFiles(drv_dir,
                                         recurse=False,
                                         abs_paths=True,
                                         return_folders=False,
                                         pattern='*.in.template'):

        basename = os.path.basename(template_file).split('.')[0]

        # Output
        drv_in_file = os.path.join(cur_path, 'prnt', 'drv',
                                   '%s.drv.in' % basename)

        # XML output (per model)
        output_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml',
                                   basename)

        # XML Output (master driver list)
        driver_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml',
Ejemplo n.º 20
0
def main(args):
    global errors
    global model_dat
    line_num = 0
    log.set_module("dat2drv.py")
    cur_path = os.path.realpath(os.path.normpath(os.getcwd()))
    dat_path = os.path.join(cur_path, 'data', 'models')
    model_dat = models.ModelData(dat_path)
    load_models()



    verbose = False
    quiet = False

    try:
        opts, args = getopt.getopt(args, 'd:l:ho:vq',
                                   ['logging=', 'help',
                                    'help-rest', 'help-man',
                                    'drv=', 'output=',
                                    'verbose', 'quiet'])
    except getopt.GetoptError as e:
        log.error(e.msg)
        usage()
        sys.exit(0)

    log_level = 'info'
    if os.getenv("HPLIP_DEBUG"):
        log.set_level('debug')

    for o, a in opts:
        if o in ('-h', '--help'):
            usage()

        elif o == '--help-rest':
            usage('rest')

        elif o == '--help-man':
            usage('man')

        elif o in ('-v', '--verbose'):
            verbose = True

        elif o in ('-q', '--quiet'):
            quiet = True

        elif o in ('-l', '--logging'):
            log.set_level(a.lower().strip())


    if not quiet:
        utils.log_title(__title__, __version__)

    drv_dir = os.path.join(cur_path, 'prnt', 'drv')

    errors = []
    warns = []
    notes = []

    for template_file in utils.walkFiles(drv_dir, recurse=False, abs_paths=True,
        return_folders=False, pattern='*.in.template'):

        basename = os.path.basename(template_file).split('.')[0]

        # Output
        drv_in_file = os.path.join(cur_path, 'prnt', 'drv', '%s.drv.in' % basename)

        # XML output (per model)
        output_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml', basename)

        # XML Output (master driver list)
        driver_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml', basename, '%s.xml' % basename)

        log.info("Working on %s file..." % basename)
        log.info("Input file: %s" % template_file)
        log.info("Output file: %s" % drv_in_file)
        log.info("Output XML directory: %s" % output_path)
        log.info("Output driver XML file: %s" % driver_path)



        # CREATE DRV.IN FILE

        log.info("Processing %s.drv.in.template..." % basename)
        tui.update_spinner()

        template_classes = []

        template_file_f = open(template_file, 'r')
        drv_in_file_f = open(drv_in_file, 'w')

        models_placement = {}
        for m in models_dict:
            models_placement[m] = 0

        line = 0

        for x in template_file_f:
            if verbose:
                log.info(x.strip())

            line += 1
            tui.update_spinner()
            drv_in_file_f.write(x)
            match = pat_template.match(x)
            if match is not None:
                matches = []
                indent = match.group(1)
                indent2 = ' '*(len(indent)+2)

                classes = match.group(2).split(':')
                tech_class = classes[0]

                if tech_class not in models.TECH_CLASSES:
                    errors.append("(%s:line %d) Invalid tech-class (%s): %s" % (basename, line, tech_class, x.strip()))
                    continue

                template_classes.append(tech_class)

                tech_subclass = classes[1:]

                ok = True
                for sc in tech_subclass:
                    if sc not in models.TECH_SUBCLASSES:
                        errors.append("(%s:line %d) Invalid tech-subclass (%s): %s" % (basename, line, sc, x.strip()))
                        ok = False

                if not ok:
                    continue

                for m in models_dict:
                    include = False

                    if tech_class in models_dict[m]['tech-class'] and \
                        len(models_dict[m]['tech-subclass']) == len(tech_subclass):

                        for msc in models_dict[m]['tech-subclass']:
                            if msc not in tech_subclass:
                               break
                        else:
                            include = True

                    if include:
                        models_placement[m] += 1
                        matches.append(m)

                if matches:
                    try:
                        matches.sort(key=lambda y: pat_prod_num.search(y).group(1))
                    except:
                        matches.sort(key=str.lower)
                    for p in matches:

                        if verbose:
                            log.info("(%s) Adding section for model: %s" % (basename, p))

                        drv_in_file_f.write("%s{\n" % indent)

                        if basename == 'hpcups':
                            model_name = models_dict[p]['norm_model']
                        else:
                            model_name = models_dict[p]['norm_model'] + " %s" % basename

                        orig_model_name = model_name

                        while True:
                            if len(model_name) > 31:
                                for k in SHORTENING_REPLACEMENTS:
                                    if k in model_name.lower():
                                        model_name = utils.ireplace(model_name, k, SHORTENING_REPLACEMENTS[k])
                                        model_name = model_name.replace('  ', ' ')

                                        if len(model_name) < 32:
                                            warns.append('len("%s")>31, shortened to len("%s")=%d using sub-brand shortening replacements.' % (orig_model_name, model_name, len(model_name)))
                                            break

                                if len(model_name) < 32:
                                    break

                                if "series" in model_name.lower():
                                    model_name = utils.ireplace(model_name, "series", "Ser.")
                                    model_name = model_name.replace('  ', ' ')

                                    if len(model_name) < 32:
                                        warns.append('len("%s")>31, shortened to len("%s")=%d using "series" to "ser." replacement.' % (orig_model_name, model_name, len(model_name)))
                                        break

                                if "ser." in model_name.lower():
                                    model_name = utils.ireplace(model_name, "ser.", "")
                                    model_name = model_name.replace('  ', ' ')

                                    if len(model_name) < 32:
                                        warns.append('len("%s")>31, shortened to len("%s")=%d using "ser." removal.' % (orig_model_name, model_name, len(model_name)))
                                        break

                                if len(model_name) > 31:
                                    model_name = model_name[:31]
                                    errors.append('len("%s")>31 chars, could not shorten to <32. Truncating to 31 chars (%s).' % (orig_model_name, model_name))

                            break

                        drv_in_file_f.write('%sModelName "%s"\n' % (indent2, orig_model_name))

                        if len(models_dict[p]['tech-class']) > 1:
                            if basename == "hpcups":
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s %s, %s $Version' %
                                    (indent2, orig_model_name, models.TECH_CLASS_PDLS[tech_class],basename))
                            else:
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s %s, $Version' %
                                    (indent2, orig_model_name, models.TECH_CLASS_PDLS[tech_class]))
                        else:
                            if basename == "hpcups":
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s, %s $Version' %
                                    (indent2, orig_model_name, basename))
                            else:
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s, $Version' %
                                    (indent2, orig_model_name))
                        if models_dict[p]['plugin'] in (1, 2):
                            if (models_dict[p]['plugin-reason'] & 15 ) in (1, 2, 3, 4, 5, 6, 8, 9, 10, 12):
                                drv_in_file_f.write(', requires proprietary plugin')

                        drv_in_file_f.write('"\n')

                        drv_in_file_f.write('%sAttribute "ShortNickName" "" "%s"\n' % (indent2, model_name))

                        pp = p.replace('_', ' ')
                        if 'apollo' in p.lower():
                            devid = "MFG:Apollo;MDL:%s;DES:%s;" % (pp, pp)
                        elif 'laserjet' in p.lower() or 'designjet' in p.lower():
                            devid = "MFG:Hewlett-Packard;MDL:%s;DES:%s;" % (pp, pp)
                        else:
                            devid = "MFG:HP;MDL:%s;DES:%s;" % (pp, pp)

                        drv_in_file_f.write('%sAttribute "1284DeviceID" "" "%s"\n' % (indent2, devid))

                        if len(models_dict[p]['tech-class']) > 1:
                            if basename == 'hpcups':
                                drv_in_file_f.write('%sPCFileName "%s-%s.ppd"\n' %
                                    (indent2, fixFileName(p), models.TECH_CLASS_PDLS[tech_class]))
                            else:
                                drv_in_file_f.write('%sPCFileName "%s-%s-%s.ppd"\n' %
                                    (indent2, fixFileName(p), basename, models.TECH_CLASS_PDLS[tech_class]))

                        elif tech_class != 'Postscript':
                            if basename == 'hpcups':
                                drv_in_file_f.write('%sPCFileName "%s.ppd"\n' % (indent2, fixFileName(p)))
                            else:
                                drv_in_file_f.write('%sPCFileName "%s-%s.ppd"\n' % (indent2, fixFileName(p), basename))

                        else:
                            drv_in_file_f.write('%sPCFileName "%s-ps.ppd"\n' % (indent2, fixFileName(p)))

                        for c in models_dict[p]['case_models']:
                            drv_in_file_f.write('%sAttribute "Product" "" "(%s)"\n' % (indent2, c))

                        drv_in_file_f.write("%s}\n" % indent)

                else:
                    errors.append("(%s:line %d) No models matched the specified classes on line: %s" % (basename, line, x.strip()))

            else:
                match = pat_template2.match(x)
                if match is not None:
                    errors.append("(%s:line %d) Malformed line: %s (missing initial //)" % (basename, line, x.strip()))


        template_file_f.close()
        drv_in_file_f.close()
        tui.cleanup_spinner()

        for tc in models.TECH_CLASSES:
            if tc.lower() in ('undefined', 'postscript', 'unsupported'):
                continue

            if tc not in template_classes:
                warns.append("(%s) Section <%%%s:...%%> not found." % (basename, tc))


        # OUTPUT XML FILES

        if not os.path.exists(output_path):
            os.makedirs(output_path)

        if os.path.exists(driver_path):
            os.remove(driver_path)

        files_to_delete = []
        for f in utils.walkFiles(output_path, recurse=True, abs_paths=True, return_folders=False, pattern='*'):
            files_to_delete.append(f)

        for f in files_to_delete:
            os.remove(f)

        driver_f = open(driver_path, 'w')


        driver_doc = XMLDocument("driver", id="driver/hplip")
        name_node = driver_doc.add("name")
        name_node.addText("hplip")
        url_node = driver_doc.add("url")
        url_node.addText("http://hplipopensource.com")
        supplier_node = driver_doc.add("supplier")
        supplier_node.addText("Hewlett-Packard")
        mfg_node = driver_doc.add("manufacturersupplied")
        mfg_node.addText("HP|Apollo")
        lic_node = driver_doc.add("license")
        lic_node.addText("BSD/GPL/MIT")
        driver_doc.add("freesoftware")
        support_node = driver_doc.add("supportcontact", level="voluntary", url="https://launchpad.net/hplip")
        support_node.addText("HPLIP Support at Launchpad.net")
        shortdesc_node = driver_doc.add("shortdescription")
        shortdesc_en_node = shortdesc_node.add("en")
        shortdesc_en_node.addText("HP's driver suite for printers and multi-function devices")
        func_node = driver_doc.add("functionality")
        maxresx_node = func_node.add("maxresx")
        maxresx_node.addText("1200")
        maxresy_node = func_node.add("maxresy")
        maxresy_node.addText("1200")
        func_node.add("color")
        exec_node = driver_doc.add("execution")
        exec_node.add("nopjl")
        exec_node.add("ijs")
        proto_node = exec_node.add("prototype")
        #proto_node.addText("gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -sDEVICE=ijs -sIjsServer=hpijs%A%B%C -dIjsUseOutputFD%Z -sOutputFile=- -")
        comments_node = driver_doc.add("comments")
        comments_en_node = comments_node.add("en")
        comments_en_node.addText("")

        printers_node = driver_doc.add("printers")

        for m in models_dict:

            if models_dict[m]['support-type'] == SUPPORT_TYPE_NONE:
                continue

            if 'apollo' in m.lower():
                make = 'Apollo'
            else:
                make = 'HP'

            if 'apollo' in m.lower():
                ieee1284 = "MFG:Apollo;MDL:%s;DES:%s;" % (m, m)

            else:
                ieee1284 = "MFG:HP;MDL:%s;DES:%s;" % (m, m)

            postscriptppd = ''
            if 'Postscript' in models_dict[m]['tech-class']:
                postscriptppd = "%s-ps.ppd" % fixFileName(m)

            stripped_model = m

            if stripped_model.startswith('hp_'):
                stripped_model = stripped_model.replace('hp_', '').capitalize()

            elif stripped_model.startswith('apollo_'):
                stripped_model = stripped_model.replace('apollo_', '').capitalize()

            fixed_model = stripped_model.replace('_', ' ').capitalize()

            # Output to the per-model XML file
            outputModel(m, fixed_model, stripped_model, make, postscriptppd, ieee1284, output_path, verbose)

            # Output to driver master XML file
            outputDriver(m, fixed_model, stripped_model, make, printers_node, verbose)

        driver_f.write(str(driver_doc))
        driver_f.close()

        # Make sure all models ended up in drv.in file
        log.info("Checking for errors...")
        tui.update_spinner()

        for m in models_dict:
            tui.update_spinner()
            tc = models_dict[m]['tech-class']
            st = models_dict[m]['support-type']

            if not tc or 'Undefined' in tc:
                if st:
                    errors.append('(%s) Invalid tech-class for model %s ("Undefined" or missing)' % (basename, m))
                #else:
                #    warns.append('(%s) Invalid tech-class for unsupported model %s ("Undefined" or missing)' % (basename, m))

            else:
                if not models_placement[m] and st and \
                    len(tc) == 1 and 'Postscript' not in tc:

                    sects = []
                    for tc in models_dict[m]['tech-class']:
                        for sc in models_dict[m]['tech-subclass']:
                            sects.append(sc)

                    errors.append("(%s) Model '%s' did not have a matching section. Needed section: <%%%s:%s%%>" %
                        (basename, m, tc, ':'.join(sects)))

                if len(tc) == 1 and 'Postscript' in tc:
                    notes.append("(%s) Postscript-only model %s was not included in DRV file." % (basename, m))

        tui.cleanup_spinner()

        # end for

    if not quiet or verbose:
        if notes:
            tui.header("NOTES")
            for n in notes:
                log.note(n)

        if warns:
            tui.header("WARNINGS")
            for w in warns:
                log.warn(w)

        if errors:
            tui.header("ERRORS")
            for e in errors:
                log.error(e)

    else:
        if warns:
            log.warn("%d warnings" % len(warns))

        if errors:
            log.error("%d errors" % len(errors))
Ejemplo n.º 21
0
    def setupFax(self):
        QApplication.setOverrideCursor(QApplication.waitCursor)

        if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_MARVELL:
            fax_ppd_name = "HP-Fax3-hplip"  # Fixed width (2528 pixels) and 300dpi rendering
            nick = "HP Fax 3"
        if self.mq.get('fax-type',
                       FAX_TYPE_NONE) == FAX_TYPE_SOAP or self.mq.get(
                           'fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDMSOAP:
            fax_ppd_name = "HP-Fax2-hplip"  # Fixed width (2528 pixels) and 300dpi rendering
            nick = "HP Fax 2"
        if self.mq.get('fax-type', FAX_TYPE_NONE) == FAX_TYPE_LEDM:
            fax_ppd_name = "HP-Fax4-hplip"  # Fixed width (1728 pixels) and 200dpi rendering
            nick = "HP Fax 4"
        else:
            fax_ppd_name = "HP-Fax-hplip"  # Standard
            nick = "HP Fax"

        ppds = []

        log.debug("Searching for fax file %s..." % fax_ppd_name)

        ppd_dir = sys_conf.get('dirs', 'ppd')
        for f in utils.walkFiles(ppd_dir,
                                 pattern="HP-Fax*.ppd*",
                                 abs_paths=True):
            ppds.append(f)

        for f in ppds:
            if f.find(fax_ppd_name) >= 0:
                fax_ppd = f
                log.debug("Found PDD file: %s" % fax_ppd)
                log.debug("Nickname: %s" % cups.getPPDDescription(fax_ppd))
                break
        else:
            QApplication.restoreOverrideCursor()
            log.error("Fax PPD file not found.")

            if QMessageBox.warning(
                    self,
                    self.__tr("Unable to find HP fax PPD file."),
                    self.__tr(
                        "The PPD file (%1.ppd) needed to setup the fax queue was not found."
                    ).arg(fax_ppd_name),
                    self.__tr("Browse to file..."),  # button 0
                    self.__tr("Quit")  # button 1
            ) == 0:  # Browse

                while True:
                    ppd_dir = sys_conf.get('dirs', 'ppd')
                    fax_ppd = unicode(
                        QFileDialog.getOpenFileName(
                            ppd_dir,
                            "HP Fax PPD Files (*.ppd *.ppd.gz);;All Files (*)",
                            self, "open file dialog",
                            "Choose the fax PPD file"))

                    if not fax_ppd:  # user hit cancel
                        return

                    if os.path.exists(fax_ppd):
                        n = cups.getPPDDescription(fax_ppd)
                        if n == nick:
                            break
                        else:
                            self.FailureUI(
                                self.__tr(
                                    "<b>Incorrect fax PPD file.</b><p>The fax PPD file must have a nickname of '%1', not '%1'."
                                ).arg(nick).arg(n))
                    else:
                        self.FailureUI(
                            self.__tr(
                                "<b>File not found.</b><p>hp-setup cannot find the file %1"
                            ).arg(fax_ppd))

            else:  # Quit
                return

        cups.setPasswordPrompt(
            "You do not have permission to add a fax device.")
        if not os.path.exists(fax_ppd):
            status, status_str = cups.addPrinter(self.fax_name.encode('utf8'),
                                                 self.fax_uri,
                                                 self.fax_location, '',
                                                 fax_ppd, self.fax_desc)
        else:
            status, status_str = cups.addPrinter(self.fax_name.encode('utf8'),
                                                 self.fax_uri,
                                                 self.fax_location, fax_ppd,
                                                 '', self.fax_desc)

        log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
        self.installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])

        log.debug(self.installed_fax_devices)

        if self.fax_uri not in self.installed_fax_devices or \
            self.fax_name not in self.installed_fax_devices[self.fax_uri]:

            self.FailureUI(
                self.__tr(
                    "<b>Fax queue setup failed.</b><p>Please restart CUPS and try again."
                ))
        else:
            pass
            # TODO:
            #service.sendEvent(self.hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=self.fax_uri)

        QApplication.restoreOverrideCursor()
Ejemplo n.º 22
0
def getSystemPPDs():
    major, minor, patch = getVersionTuple()
    ppds = {}  # {'ppd name' : 'desc', ...}

    if major == 1 and minor < 2:
        ppd_dir = sys_conf.get('dirs', 'ppd')
        log.debug("(CUPS 1.1.x) Searching for PPDs in: %s" % ppd_dir)

        for f in utils.walkFiles(ppd_dir,
                                 pattern="HP*ppd*;hp*ppd*",
                                 abs_paths=True):
            desc = getPPDDescription(f)

            if not ('foo2' in desc or 'gutenprint' in desc.lower()
                    or 'gutenprint' in f):

                ppds[f] = desc
                log.debug("%s: %s" % (f, desc))

    else:  # 1.2.x
        log.debug("(CUPS 1.2.x) Getting list of PPDs using CUPS_GET_PPDS...")
        ppd_dict = cupsext.getPPDList()
        cups_ppd_path = getPPDPath()  # usually /usr/share/cups/model
        foomatic_ppd_path = sys_conf.get('dirs', 'ppdbase', '/usr/share/ppd')

        if not foomatic_ppd_path or not os.path.exists(foomatic_ppd_path):
            foomatic_ppd_path = '/usr/share/ppd'

        log.debug("CUPS PPD base path = %s" % cups_ppd_path)
        log.debug("Foomatic PPD base path = %s" % foomatic_ppd_path)

        for ppd in ppd_dict:
            if not ppd:
                continue

            if 'hp-' in ppd.lower() or 'hp_' in ppd.lower() and \
                ppd_dict[ppd]['ppd-make'] == 'HP':

                desc = ppd_dict[ppd]['ppd-make-and-model']

                if not ('foo2' in desc.lower() or 'gutenprint' in desc.lower()
                        or 'gutenprint' in ppd):

                    # PPD files returned by CUPS_GET_PPDS (and by lpinfo -m)
                    # can be relative to /usr/share/ppd/ or to
                    # /usr/share/cups/model/. Not sure why this is.
                    # Here we will try both and see which one it is...

                    if os.path.exists(ppd):
                        path = ppd
                    else:
                        try:
                            path = os.path.join(foomatic_ppd_path, ppd)
                        except AttributeError:  # happens on some boxes with provider: style ppds (foomatic: etc)
                            path = ppd
                        else:
                            if not os.path.exists(path):
                                try:
                                    path = os.path.join(cups_ppd_path, ppd)
                                except AttributeError:
                                    path = ppd
                                else:
                                    if not os.path.exists(path):
                                        path = ppd  # foomatic: or some other driver

                    ppds[path] = desc
                    #log.debug("%s: %s" % (path, desc))

    return ppds
Ejemplo n.º 23
0
def main(args):
    global errors
    global model_dat
    line_num = 0
    log.set_module("dat2drv.py")
    cur_path = os.path.realpath(os.path.normpath(os.getcwd()))
    dat_path = os.path.join(cur_path, 'data', 'models')
    model_dat = models.ModelData(dat_path)
    load_models()



    verbose = False
    quiet = False

    try:
        opts, args = getopt.getopt(args, 'd:l:ho:vq',
                                   ['logging=', 'help',
                                    'help-rest', 'help-man',
                                    'drv=', 'output=',
                                    'verbose', 'quiet'])
    except getopt.GetoptError as e:
        log.error(e.msg)
        usage()
        sys.exit(0)

    log_level = 'info'
    if os.getenv("HPLIP_DEBUG"):
        log.set_level('debug')

    for o, a in opts:
        if o in ('-h', '--help'):
            usage()

        elif o == '--help-rest':
            usage('rest')

        elif o == '--help-man':
            usage('man')

        elif o in ('-v', '--verbose'):
            verbose = True

        elif o in ('-q', '--quiet'):
            quiet = True

        elif o in ('-l', '--logging'):
            log.set_level(a.lower().strip())


    if not quiet:
        utils.log_title(__title__, __version__)

    drv_dir = os.path.join(cur_path, 'prnt', 'drv')

    errors = []
    warns = []
    notes = []

    for template_file in utils.walkFiles(drv_dir, recurse=False, abs_paths=True,
        return_folders=False, pattern='*.in.template'):

        basename = os.path.basename(template_file).split('.')[0]

        # Output
        drv_in_file = os.path.join(cur_path, 'prnt', 'drv', '%s.drv.in' % basename)

        # XML output (per model)
        output_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml', basename)

        # XML Output (master driver list)
        driver_path = os.path.join(cur_path, 'prnt', 'drv', 'foomatic_xml', basename, '%s.xml' % basename)

        log.info("Working on %s file..." % basename)
        log.info("Input file: %s" % template_file)
        log.info("Output file: %s" % drv_in_file)
        log.info("Output XML directory: %s" % output_path)
        log.info("Output driver XML file: %s" % driver_path)



        # CREATE DRV.IN FILE

        log.info("Processing %s.drv.in.template..." % basename)
        tui.update_spinner()

        template_classes = []

        template_file_f = open(template_file, 'r')
        drv_in_file_f = open(drv_in_file, 'w')

        models_placement = {}
        for m in models_dict:
            models_placement[m] = 0

        line = 0

        for x in template_file_f:
            if verbose:
                log.info(x.strip())

            line += 1
            tui.update_spinner()
            drv_in_file_f.write(x)
            match = pat_template.match(x)
            if match is not None:
                matches = []
                indent = match.group(1)
                indent2 = ' '*(len(indent)+2)

                classes = match.group(2).split(':')
                tech_class = classes[0]

                if tech_class not in models.TECH_CLASSES:
                    errors.append("(%s:line %d) Invalid tech-class (%s): %s" % (basename, line, tech_class, x.strip()))
                    continue

                template_classes.append(tech_class)

                tech_subclass = classes[1:]

                ok = True
                for sc in tech_subclass:
                    if sc not in models.TECH_SUBCLASSES:
                        errors.append("(%s:line %d) Invalid tech-subclass (%s): %s" % (basename, line, sc, x.strip()))
                        ok = False

                if not ok:
                    continue

                for m in models_dict:
                    include = False

                    if tech_class in models_dict[m]['tech-class'] and \
                        len(models_dict[m]['tech-subclass']) == len(tech_subclass):

                        for msc in models_dict[m]['tech-subclass']:
                            if msc not in tech_subclass:
                               break
                        else:
                            include = True

                    if include:
                        models_placement[m] += 1
                        matches.append(m)

                if matches:
                    try:
                        matches.sort(key=lambda y: pat_prod_num.search(y).group(1))
                    except:
                        matches.sort(key=str.lower)
                    for p in matches:

                        if verbose:
                            log.info("(%s) Adding section for model: %s" % (basename, p))

                        drv_in_file_f.write("%s{\n" % indent)

                        if basename == 'hpcups':
                            model_name = models_dict[p]['norm_model']
                        else:
                            model_name = models_dict[p]['norm_model'] + " %s" % basename

                        orig_model_name = model_name

                        while True:
                            if len(model_name) > 31:
                                for k in SHORTENING_REPLACEMENTS:
                                    if k in model_name.lower():
                                        model_name = utils.ireplace(model_name, k, SHORTENING_REPLACEMENTS[k])
                                        model_name = model_name.replace('  ', ' ')

                                        if len(model_name) < 32:
                                            warns.append('len("%s")>31, shortened to len("%s")=%d using sub-brand shortening replacements.' % (orig_model_name, model_name, len(model_name)))
                                            break

                                if len(model_name) < 32:
                                    break

                                if "series" in model_name.lower():
                                    model_name = utils.ireplace(model_name, "series", "Ser.")
                                    model_name = model_name.replace('  ', ' ')

                                    if len(model_name) < 32:
                                        warns.append('len("%s")>31, shortened to len("%s")=%d using "series" to "ser." replacement.' % (orig_model_name, model_name, len(model_name)))
                                        break

                                if "ser." in model_name.lower():
                                    model_name = utils.ireplace(model_name, "ser.", "")
                                    model_name = model_name.replace('  ', ' ')

                                    if len(model_name) < 32:
                                        warns.append('len("%s")>31, shortened to len("%s")=%d using "ser." removal.' % (orig_model_name, model_name, len(model_name)))
                                        break

                                if len(model_name) > 31:
                                    model_name = model_name[:31]
                                    errors.append('len("%s")>31 chars, could not shorten to <32. Truncating to 31 chars (%s).' % (orig_model_name, model_name))

                            break

                        drv_in_file_f.write('%sModelName "%s"\n' % (indent2, orig_model_name))

                        if len(models_dict[p]['tech-class']) > 1:
                            if basename == "hpcups":
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s %s, %s $Version' %
                                    (indent2, orig_model_name, models.TECH_CLASS_PDLS[tech_class],basename))
                            else:
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s %s, $Version' %
                                    (indent2, orig_model_name, models.TECH_CLASS_PDLS[tech_class]))
                        else:
                            if basename == "hpcups":
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s, %s $Version' %
                                    (indent2, orig_model_name, basename))
                            else:
                                drv_in_file_f.write('%sAttribute "NickName" "" "%s, $Version' %
                                    (indent2, orig_model_name))
                        if models_dict[p]['plugin'] in (1, 2):
                            if (models_dict[p]['plugin-reason'] & 15 ) in (1, 2, 3, 4, 5, 6, 8, 9, 10, 12):
                                drv_in_file_f.write(', requires proprietary plugin')

                        drv_in_file_f.write('"\n')

                        drv_in_file_f.write('%sAttribute "ShortNickName" "" "%s"\n' % (indent2, model_name))

                        pp = p.replace('_', ' ')
                        if 'apollo' in p.lower():
                            devid = "MFG:Apollo;MDL:%s;DES:%s;" % (pp, pp)
                        elif 'laserjet' in p.lower() or 'designjet' in p.lower():
                            devid = "MFG:Hewlett-Packard;MDL:%s;DES:%s;" % (pp, pp)
                        else:
                            devid = "MFG:HP;MDL:%s;DES:%s;" % (pp, pp)

                        drv_in_file_f.write('%sAttribute "1284DeviceID" "" "%s"\n' % (indent2, devid))

                        if len(models_dict[p]['tech-class']) > 1:
                            if basename == 'hpcups':
                                drv_in_file_f.write('%sPCFileName "%s-%s.ppd"\n' %
                                    (indent2, fixFileName(p), models.TECH_CLASS_PDLS[tech_class]))
                            else:
                                drv_in_file_f.write('%sPCFileName "%s-%s-%s.ppd"\n' %
                                    (indent2, fixFileName(p), basename, models.TECH_CLASS_PDLS[tech_class]))

                        elif tech_class != 'Postscript':
                            if basename == 'hpcups':
                                drv_in_file_f.write('%sPCFileName "%s.ppd"\n' % (indent2, fixFileName(p)))
                            else:
                                drv_in_file_f.write('%sPCFileName "%s-%s.ppd"\n' % (indent2, fixFileName(p), basename))

                        else:
                            drv_in_file_f.write('%sPCFileName "%s-ps.ppd"\n' % (indent2, fixFileName(p)))

                        for c in models_dict[p]['case_models']:
                            drv_in_file_f.write('%sAttribute "Product" "" "(%s)"\n' % (indent2, c))

                        drv_in_file_f.write("%s}\n" % indent)

                else:
                    errors.append("(%s:line %d) No models matched the specified classes on line: %s" % (basename, line, x.strip()))

            else:
                match = pat_template2.match(x)
                if match is not None:
                    errors.append("(%s:line %d) Malformed line: %s (missing initial //)" % (basename, line, x.strip()))


        template_file_f.close()
        drv_in_file_f.close()
        tui.cleanup_spinner()

        for tc in models.TECH_CLASSES:
            if tc.lower() in ('undefined', 'postscript', 'unsupported'):
                continue

            if tc not in template_classes:
                warns.append("(%s) Section <%%%s:...%%> not found." % (basename, tc))


        # OUTPUT XML FILES

        if not os.path.exists(output_path):
            os.makedirs(output_path)

        if os.path.exists(driver_path):
            os.remove(driver_path)

        files_to_delete = []
        for f in utils.walkFiles(output_path, recurse=True, abs_paths=True, return_folders=False, pattern='*'):
            files_to_delete.append(f)

        for f in files_to_delete:
            os.remove(f)

        driver_f = open(driver_path, 'w')


        driver_doc = XMLDocument("driver", id="driver/hplip")
        name_node = driver_doc.add("name")
        name_node.addText("hplip")
        url_node = driver_doc.add("url")
        url_node.addText("http://hplipopensource.com")
        supplier_node = driver_doc.add("supplier")
        supplier_node.addText("Hewlett-Packard")
        mfg_node = driver_doc.add("manufacturersupplied")
        mfg_node.addText("HP|Apollo")
        lic_node = driver_doc.add("license")
        lic_node.addText("BSD/GPL/MIT")
        driver_doc.add("freesoftware")
        support_node = driver_doc.add("supportcontact", level="voluntary", url="https://launchpad.net/hplip")
        support_node.addText("HPLIP Support at Launchpad.net")
        shortdesc_node = driver_doc.add("shortdescription")
        shortdesc_en_node = shortdesc_node.add("en")
        shortdesc_en_node.addText("HP's driver suite for printers and multi-function devices")
        func_node = driver_doc.add("functionality")
        maxresx_node = func_node.add("maxresx")
        maxresx_node.addText("1200")
        maxresy_node = func_node.add("maxresy")
        maxresy_node.addText("1200")
        func_node.add("color")
        exec_node = driver_doc.add("execution")
        exec_node.add("nopjl")
        exec_node.add("ijs")
        proto_node = exec_node.add("prototype")
        #proto_node.addText("gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPAUSE -sDEVICE=ijs -sIjsServer=hpijs%A%B%C -dIjsUseOutputFD%Z -sOutputFile=- -")
        comments_node = driver_doc.add("comments")
        comments_en_node = comments_node.add("en")
        comments_en_node.addText("")

        printers_node = driver_doc.add("printers")

        for m in models_dict:

            if models_dict[m]['support-type'] == SUPPORT_TYPE_NONE:
                continue

            if 'apollo' in m.lower():
                make = 'Apollo'
            else:
                make = 'HP'

            if 'apollo' in m.lower():
                ieee1284 = "MFG:Apollo;MDL:%s;DES:%s;" % (m, m)

            else:
                ieee1284 = "MFG:HP;MDL:%s;DES:%s;" % (m, m)

            postscriptppd = ''
            if 'Postscript' in models_dict[m]['tech-class']:
                postscriptppd = "%s-ps.ppd" % fixFileName(m)

            stripped_model = m

            if stripped_model.startswith('hp_'):
                stripped_model = stripped_model.replace('hp_', '').capitalize()

            elif stripped_model.startswith('apollo_'):
                stripped_model = stripped_model.replace('apollo_', '').capitalize()

            fixed_model = stripped_model.replace('_', ' ').capitalize()

            # Output to the per-model XML file
            outputModel(m, fixed_model, stripped_model, make, postscriptppd, ieee1284, output_path, verbose)

            # Output to driver master XML file
            outputDriver(m, fixed_model, stripped_model, make, printers_node, verbose)

        driver_f.write(str(driver_doc))
        driver_f.close()

        # Make sure all models ended up in drv.in file
        log.info("Checking for errors...")
        tui.update_spinner()

        for m in models_dict:
            tui.update_spinner()
            tc = models_dict[m]['tech-class']
            st = models_dict[m]['support-type']

            if not tc or 'Undefined' in tc:
                if st:
                    errors.append('(%s) Invalid tech-class for model %s ("Undefined" or missing)' % (basename, m))
                #else:
                #    warns.append('(%s) Invalid tech-class for unsupported model %s ("Undefined" or missing)' % (basename, m))

            else:
                if not models_placement[m] and st and \
                    len(tc) == 1 and 'Postscript' not in tc:

                    sects = []
                    for tc in models_dict[m]['tech-class']:
                        for sc in models_dict[m]['tech-subclass']:
                            sects.append(sc)

                    errors.append("(%s) Model '%s' did not have a matching section. Needed section: <%%%s:%s%%>" %
                        (basename, m, tc, ':'.join(sects)))

                if len(tc) == 1 and 'Postscript' in tc:
                    notes.append("(%s) Postscript-only model %s was not included in DRV file." % (basename, m))

        tui.cleanup_spinner()

        # end for

    if not quiet or verbose:
        if notes:
            tui.header("NOTES")
            for n in notes:
                log.note(n)

        if warns:
            tui.header("WARNINGS")
            for w in warns:
                log.warn(w)

        if errors:
            tui.header("ERRORS")
            for e in errors:
                log.error(e)

    else:
        if warns:
            log.warn("%d warnings" % len(warns))

        if errors:
            log.error("%d errors" % len(errors))