#!/usr/bin/python

import sys
if not "/usr/share/printconf/util" in sys.path:
    sys.path.append("/usr/share/printconf/util")

from printconf_conf import *

_printers_conf = "/etc/cups/printers.conf"
_ppd_dir = "/etc/cups/ppd/"
_ppd_ext = ".ppd"
marker_line = "Info Created by redhat-config-printer 0.6.x\n"

def _load_foomatic_db ():
    try:
        foomatic.id_dict
    except:
        foomatic_init_overview ()

def _discover_queue (name, deviceURI, is_default = 0):
    data_dict = { 'queue_name' : name };
    type_space = None
    if deviceURI.startswith ("parallel:") or \
           deviceURI.startswith ("serial:") or \
           deviceURI.startswith ("usb:") or \
           deviceURI.startswith ("file:"):
        type_space = queue_types.local
        data_dict["local_printer_device"] = deviceURI[deviceURI.index (":")+1:]
    elif deviceURI.startswith ("socket:"):
        type_space = queue_types.jetdirect
        try:
            start_index = deviceURI.index ("://") + 3
        except:
            start_index = deviceURI.index (":") + 1

        try:
            end_index = start_index + deviceURI[start_index:].index ("/")
        except:
            end_index = len (deviceURI)

        data_dict["jetdirect_ip"] = deviceURI[start_index:end_index]
        start_index = end_index + 1
        end_index = len (deviceURI)
        data_dict["jetdirect_port"] = deviceURI[start_index:end_index]
        if data_dict["jetdirect_port"] == "":
            data_dict["jetdirect_port"] = "9100"
    elif deviceURI.startswith ("lpd:"):
        type_space = queue_types.lpd
        try:
            start_index = deviceURI.index ("://") + 3
        except:
            start_index = deviceURI.index (":") + 1

        try:
            end_index = start_index + deviceURI[start_index:].index ("/")
        except:
            end_index = len (deviceURI)

        data_dict["lpd_server"] = deviceURI[start_index:end_index]
        start_index = end_index + 1
        end_index = len (deviceURI)
        try:
            end_index = deviceURI[start_index].index ("/")
        except:
            pass

        data_dict["lpd_queue"] = deviceURI[start_index:]
    elif deviceURI.startswith ("smb:"):
        type_space = queue_types.smb
        try:
            start_index = deviceURI.index ("://") + 3
        except:
            start_index = deviceURI.index (":") + 1

        try:
            end_index = start_index + deviceURI[start_index:].index ("/")
        except:
            end_index = len (deviceURI)

        data_dict["smb_share"] = deviceURI[start_index:]
        data_dict["smb_ip"] = deviceURI[start_index:end_index]
        data_dict["smb_workgroup"] = ""
        data_dict["smb_user"] = ""
        data_dict["smb_password"] = ""
    else:
        print "Can't understand DeviceURI: %s" % deviceURI
        return

    try:
        f = open (_ppd_dir + name + _ppd_ext, 'r', 1)

        printer_id = None
        driver = None
        ppd = f.readlines ()
        for line in ppd:
            # Yuck.
            if line.startswith ("*% COMDATA #  'id' => '"):
                start_index = line.index ("=> '") + 4;
                end_index = start_index + line[start_index:].index ("'")
                printer_id = line[start_index:end_index]
            elif line.startswith ("*% COMDATA #  'driver' => '"):
                start_index = line.index ("=> '") + 4;
                end_index = start_index + line[start_index:].index ("'")
                driver = line[start_index:end_index]

        _load_foomatic_db ()
        driver_tuple = (drivers.foomatic,
                        (foomatic.id_dict[printer_id],
                         driver))
    except:
        # This is a raw queue.
        driver_tuple = (drivers.raw,)

    debug_print ("Discovered %s queue: %s on %s" %(type_space.long_pretty_name,
                                                   name, deviceURI))
    if driver_tuple[0] == drivers.foomatic:
        debug_print ("  Printer ID %s" % driver_tuple[1][0].id)
        debug_print ("  Driver %s" % driver_tuple[1][1])

    (name_dict, alias_dict) = get_queues ()
    if not check_queue_name_uniqueness (name, name_dict, alias_dict):
        try:
            for each in alias_dict[name]['queue']['alias_list']:
                if each.value == name:
                    each.unlink ()

            debug_print ("  Existing alias removed")
        except:
            delete_queue_and_fix_default (name_dict[name]['queue'])
            debug_print ("  Existing queue removed")

    construct_queue (type_space, data_dict, driver_tuple)
    debug_print ("  New queue imported")

    if driver_tuple[0] == drivers.foomatic:
        (name_dict, alias_dict) = get_queues ()
        queue = name_dict[name]['queue']
        dflt = queue['filter_data']['foomatic_defaults']
        _load_foomatic_db ()
        pd = foomatic_printer_driver_lookup (str(driver_tuple[1][0].id),
                                             driver_tuple[1][1])
        for opt in pd.options_by_en_shortname.keys ():
            for line in ppd:
                if line.startswith ("*Default" + opt + ":"):
                    for each in dflt:
                        if each["name"].value == str (opt):
                            each.unlink ()

                    val = line[line.index (" ") + 1:].strip ()
                    op = dflt.addData (AdmListType, "option_default")
                    op["name"] = str (opt)
                    op["type"] = str (pd.options_by_en_shortname[opt].type)
                    op["default"] = val
                    debug_print ("  %s: %s" % (opt, val))

    if is_default:
        set_default_queue_name (name)
        debug_print ("  This is the default queue")

def import_cups_queues ():
    try:
        f = open (_printers_conf, 'r', 1)
    except:
        return

    line = f.readlines ()
    for i in range (len (line)):
        if (line[i].startswith ("<Printer ") or
            line[i].startswith ("<DefaultPrinter ")):
            start_index = line[i].index (" ") + 1
            try:
                end_index = line[i].index (">")
            except ValueError:
                continue

            for j in range (i + 1, len (line)):
                if line[j].startswith ("</"):
                    break
                if line[j].startswith ("DeviceURI "):
                    deviceURI = line[j][line[j].index (" ") + 1:].strip ()
                    _discover_queue (line[i][start_index:end_index],
				     deviceURI,
                                    line[i][1] == "D")

def which_spooler ():
    """Return the name of the active spooler."""
    signal.signal (signal.SIGCHLD, signal.SIG_DFL)
    f = os.popen ('/usr/sbin/alternatives --display print')
    for l in f.readlines ():
        if l.startswith (" link currently points to"):
            which = l.split ('.')[1].strip ()
            break

    f.close ()
    return which

def import_needed (which = None):
    """Returns non-zero if we need to import CUPS queues."""
    if not which:
        which = which_spooler ()

    if which != "cups":
        return 0

    need_import = 1
    f = file (_printers_conf)
    printers_conf_lines = f.readlines ()
    count = 0
    for l in printers_conf_lines:
        if (l.startswith ("<Printer ") or
            l.startswith ("<DefaultPrinter ")):
            count += 1

        if l == marker_line:
            need_import = 0

    if need_import and count == 0:
        init_queue_edit_or_die ()
        (name_dict, alias_dict) = get_queues ()
        if len (name_dict) == 0:
            need_import = 0

    return need_import

if __name__ == '__main__':
    if import_needed ():
        foomatic_init_overview ()
        init_queue_edit_or_die ()
        import_cups_queues ()
        save_queues ()
