source: server/lib/ipp.py @ 2876403

no-cups
Last change on this file since 2876403 was 2876403, checked in by Jessica B. Hamrick <jhamrick@…>, 14 years ago

Add ipp server code from quickprint

  • Property mode set to 100755
File size: 6.0 KB
Line 
1#!/usr/bin/env python
2
3# Adapted from the Quickprint IPP server code
4
5import os, sys
6
7try:
8    if not os.path.isdir('/tmp/gutenbach'):
9        os.mkdir('/tmp/gutenbach')
10except e, Exception:
11    pass
12
13import cgi #, cgitb; cgitb.enable(logdir='/tmp/gutenbach')
14import MySQLdb
15from ipplib import IPPRequest
16import ipplib
17
18from tempfile import mkstemp
19from shutil import move
20
21authfail = False
22try:
23    printer_uri = 'http://%s%s' % (os.environ['SERVER_NAME'], os.environ['REQUEST_URI'])
24except:
25    pass
26try:
27    argv = cgi.parse(os.environ['QUERY_STRING'])
28    webauth = argv['BASIC']
29    if type(webauth) is list:
30        webauth = webauth[0]
31    webauth = webauth.split(' ')[1]
32    if not len(webauth):
33        authfail = True
34    else:
35        (authu, authp) = webauth.decode('base64').split(':')
36        db=MySQLdb.connect(read_default_file="/mit/gutenbach/.my.cnf")
37        c = db.cursor()
38        c.execute("SELECT 1 FROM auth WHERE auser=%s AND apass=%s LIMIT 1", (authu,authp,))
39        if c.fetchone() is None:
40            authfail = True
41except Exception, e:
42    authfail = True
43
44if authfail:
45    print "Status: 401 Authorization Required"
46    print "WWW-Authenticate: Basic realm=\"Gutenbach\""
47    print "Content-type: application/ipp\n"
48    sys.exit(0)
49else:
50    AUTH = authu.lower()
51
52print "Content-type: application/ipp\n"
53
54class IPPServer(object):
55    def __init__(self):
56        pass
57    def process(self, request_in, response_out):
58        data_in = request_in.read()
59        if not len(data_in):
60            return
61        request = IPPRequest(data=data_in)
62        request.parse()
63
64        response = IPPRequest(version=request.version,
65                            operation_id=request.operation_id,
66                            request_id=request.request_id)
67        #file('/mit/gutenbach/tmp/requests/'+str(request.operation_id)).write()
68        handler = getattr(self, "_operation_%d" % request.operation_id, None)
69
70        response._operation_attributes = [[]]
71        response._operation_attributes[0] = filter( \
72            lambda x: x[0] in ('attributes-charset', 'attributes-natural-language', 'printer-uri'),
73            request._operation_attributes[0])
74
75        # f = file('/tmp/gutenbach/printer2.log','a')
76        # f.write("\n" + "*"*80 + "\n")
77        # f.write(str(request))
78        if handler is not None:
79            response.setOperationId(handler(request, response))
80            data_out = response.dump()
81            response_out.write(data_out)
82            response_test = IPPRequest(data=data_out)
83            response_test.parse()
84        #     f.write("\n" + "-"*80 + "\n")
85        #     f.write(str(response_test))
86        # f.write("\n" + "*"*80 + "\n")
87        # f.close()
88
89    def _operation_2(self, request, response):
90        """print-job response"""
91        (fno, fname) = mkstemp(dir='/tmp/gutenbach')
92        os.write(fno, request.data)
93        os.close(fno)
94        opattr = filter(lambda x: x[0] in ('job-name'),
95            request._operation_attributes[0])
96        jname = 'unknown'
97        if len(opattr) and opattr[0][0] == 'job-name':
98            jname = opattr[0][1][0][1]
99        jstat = os.stat(fname)
100        jsize = jstat.st_size
101        c = db.cursor()
102        c.execute("INSERT INTO job (juser, jname, jfile, jsize, jtype) VALUES (%s, %s, %s, %s, %s)", \
103                (AUTH, jname, fname, jsize, 'PostScript',))
104        jid = db.insert_id()
105        jfile = '/mit/gutenbach/jobs/' + AUTH + '_' + str(jid)
106        move(fname, jfile)
107        c.execute("UPDATE job SET jfile=%s, dupdated=NOW() WHERE jid=%s", \
108                (jfile, str(jid),))
109        response._job_attributes = [[ \
110            ('job-id', [('integer', jid)]), \
111            ('printer-uri', [('uri', printer_uri)]), \
112            ('job-state', [('enum', ipplib.IPP_JOB_HELD)])]]
113        return ipplib.IPP_OK
114
115    def _operation_8(self, request, response):
116        """delete-job response"""
117        opattr = filter(lambda x: x[0] in ('job-id'),
118            request._operation_attributes[0])
119        if len(opattr) and opattr[0][0] == 'job-id':
120            jid = opattr[0][1][0][1]
121            c = db.cursor()
122            c.execute("UPDATE job SET jstate = 'DEL' WHERE juser = %s AND jid = %s", \
123                (AUTH, int(jid)))
124        return ipplib.IPP_OK
125
126    def _operation_9(self, request, response):
127        """get-job-properties response"""
128        opattr = filter(lambda x: x[0] in ('job-id'),
129            request._operation_attributes[0])
130        if len(opattr) and opattr[0][0] == 'job-id':
131            jid = opattr[0][1][0][1]
132        response._job_attributes.append([ \
133            ('job-id', [('integer', jid)]), \
134        #    ('job-name', [('nameWithoutLanguage', x[1])]), \
135            ('job-originating-user-name', [('nameWithoutLanguage', AUTH)]), \
136        #    ('job-k-octets', [('integer', x[2]/1024)]), \
137            ('job-state', [('enum', ipplib.IPP_JOB_COMPLETE)])
138        ])
139        return ipplib.IPP_OK
140
141    def _operation_10(self, request, response):
142        """get-jobs response"""
143        c = db.cursor()
144        c.execute("SELECT jid, jname, jsize, jstate FROM job WHERE juser = %s AND jstate != %s ORDER BY dadded", \
145            (AUTH, 'DEL',))
146        response._job_attributes = []
147        for x in c.fetchall():
148            if x[3] == 'NEW':
149                state = ipplib.IPP_JOB_HELD
150            elif x[3] == 'DONE':
151                state = ipplib.IPP_JOB_COMPLETE
152            else:
153                state = 0
154            response._job_attributes.append([ \
155                ('job-id', [('integer', x[0])]), \
156                ('job-name', [('nameWithoutLanguage', x[1])]), \
157                ('job-originating-user-name', [('nameWithoutLanguage', AUTH)]), \
158                ('job-k-octets', [('integer', x[2]/1024)]), \
159                ('job-state', [('enum', state)])
160            ])
161        return ipplib.IPP_OK
162
163    def _operation_11(self, request, response):
164        """get-printer-attributes response"""
165        response._printer_attributes = \
166            [[('printer-name', [('nameWithoutLanguage', 'Gutenbach')])]]
167        return ipplib.IPP_OK
168
169IPPServer().process(sys.stdin,sys.stdout)
Note: See TracBrowser for help on using the repository browser.