2017-01-06 19 views
3

В настоящее время я делаю некоторые тесты с принтерами в Python, я пытаюсь перечислить все доступные принтеры.Получить все доступные принтеры в OS X с помощью Python

Сейчас я использую библиотеку PyCups, которая предоставляет несколько полезных API-интерфейсов в классе Connection. Среди них есть также getPrinters():

Вот отрывок, который я использую и работает:

>>> import cups 
>>> conn = cups.Connection() 
>>> printers = conn.getPrinters() 
>>> for printer in printers: 
...  print printer, printers[printer]["device-uri"] 
Brother_MFC_1910W_series 
Photosmart_6520_series 

мне было интересно, если есть какой-нибудь способ, чтобы написать код выше, без использования каких-либо внешних библиотек. Я совершенно уверен, что это невозможно сделать без использования C.

Любое предложение или ссылка на документы были бы очень оценены. Благодаря

Я использую Python 3

+1

Мотивировать downvotes. – Sid

+1

OSX поставляется с CUPS, я предполагаю, что имеет смысл использовать 'pycups', чтобы тыкать на него. Существует также «основной слой печати», который вы можете использовать для использования 'cffi' https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Printing/osxp_aboutprinting/osxp_aboutprt.html –

+1

Какова ваша общая цель .. .? Вы пытаетесь свести к минимуму количество дополнительных пакетов, которые вам нужно будет распространять с вашим приложением (оставаясь, по возможности, «pythonic»)? Или вы просто ищете самый «питонический» способ итерации принтеров на OS X? – Richard

ответ

1

Возможно использование библиотек C из Python со стандартными модулями. Список литературы: CUPS API, ctypes. Воплощение CUPS структуры и вызовы в ctypes синтаксиса, мы получаем код, который работает под стандартизованных OS X Python и Python 3:

from __future__ import print_function 

from ctypes import * 


class cups_option_t(Structure): 
    _fields_ = [ 
     ('name', c_char_p), 
     ('value', c_char_p) 
    ] 


class cups_dest_t(Structure): 
    _fields_ = [ 
     ('name', c_char_p), 
     ('instance', c_char_p), 
     ('is_default', c_int), 
     ('num_options', c_int), 
     ('cups_option_t', POINTER(cups_option_t)) 
    ] 


cups_lib = cdll.LoadLibrary('/usr/lib/libcups.dylib') 


if __name__ == '__main__': 
    dests = cups_dest_t() 
    dests_p = pointer(dests)  
    num_dests = cups_lib.cupsGetDests(byref(dests_p))  
    for i in range(num_dests): 
     dest = dests_p[i] 
     print(dest.is_default, dest.name) 
     for j in range(dest.num_options): 
      option = dest.cups_option_t[j] 
      print('', option.name, option.value, sep='\t')  
    cups_lib.cupsFreeDests(num_dests, dests_p) 

Будьте особенно осторожны при использовании ctypes, большинство ошибок будет производить ошибку сегментации.

+0

Ну, если я использую CUPS, чем я могу использовать предоставленный сниппп – Sid

+2

Какова задача тогда, вы имели в виду вообще избегать каких-либо библиотек? CUPS разрабатывается Apple и [находится ниже] (https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Printing/osxp_flexible/osxp_flexible.html) всех других интерфейсов. – void

+0

Я имею в виду вообще избегать библиотек и может быть что-то, что работает как на OSX, так и на Win – Sid

1

Вы можете выполнить подобный запрос с использованием терминала команды lpstat (man for OSX). Встроенный модуль Python subprocess позволит вам запустить эту команду и сохранить результат. Некоторое синтаксическое разбор текста должно содержать имя принтера.

from subprocess import Popen, PIPE 

# "lpstat -a" prints info on printers that can accept print requests 
p = Popen(['lpstat', '-a'], stdin=PIPE, stdout=PIPE, stderr=PIPE) 
output, errors = p.communicate() 

lines = output.split('\n') 
# check before you implement this parsing 
printers = map(lambda x: x.split(' ')[0], lines) 
+0

Да, я тоже думал то же самое, но мне было интересно, какой метод «Pythonic» – Sid

+2

'lpstat -a' показывает только имя принтера и принимающее состояние, которое не эквивалентно приведенному выше коду. На выходе не гарантируется стандартный формат, поэтому код разбора может быть поврежден в разных версиях OS X. – void

+0

@void goot point – Sid