source: server/lib/ipp.py @ 4ec7caa

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

Add some comments to ipp.py; use struct module in ipprequest.py

  • Property mode set to 100755
File size: 6.1 KB
Line 
1#!/usr/bin/env python
2
3# Adapted from the Quickprint IPP server code (http://quikprint.mit.edu)
4# Modifications and additions written by Jessica Hamrick (jhamrick@mit.edu)
5
6# Notes and Todo:
7#   - make sure package creates gutenbach folder in /var/log
8
9import os, sys
10import cgi, cgitb
11import logging
12import MySQLdb
13import ipplib
14
15from ipprequest import IPPRequest
16from tempfile import mkstemp
17from shutil import move
18from logging import debug, info, warning, error, critical
19
20# set up logging
21LOGFILE = "/var/log/gutenbach/ipp.log"
22logging.basicConfig(filename=LOGFILE, level=logging.DEBUG)
23cgitb.enable(logdir='/var/log/gutenbach/cgi.log')
24
25# make sure a temporary folder exists
26TEMPDIR = '/tmp/gutenbach/ipp'
27try:
28    if not os.path.exists(TEMPDIR):
29        info("Creating temporay directory '%s'" % TEMPDIR)
30        os.makedirs(TEMPDIR)
31except e, Exception:
32    error("Could not create temporary directory '%s'" % TEMPDIR)
33
34# print the content type for our request
35print "Content-type: application/ipp\n"
36
37class IPPServer(object):
38   
39    # nothing to do in the init
40    def __init__(self):
41        """
42        This function doesn't actually do anything.
43        """
44        pass
45
46    # this function processes an IPP request and sends a response
47    def process(self, request_in, response_out):
48        """
49        Processes an IPP request and sends a response.
50
51        Arguments:
52
53            request_in -- a file handle to read in the request
54
55            request_out -- a file handle to print the response
56        """
57       
58        # parse the request from request_in
59        request = IPPRequest(request=request_in)
60
61        # create the response, copying the version, operation-id, and
62        # request-id from the request
63        response = IPPRequest(version=request.version,
64                              operation_id=request.operation_id,
65                              request_id=request.request_id)
66       
67        handler = getattr(self, "_operation_%d" % request.operation_id, None)
68
69        response._operation_attributes = [[]]
70        response._operation_attributes[0] = filter( \
71            lambda x: x[0] in ('attributes-charset', 'attributes-natural-language', 'printer-uri'),
72            request._operation_attributes[0])
73
74        # f = file('/tmp/gutenbach/ipp/printer2.log','a')
75        # f.write("\n" + "*"*80 + "\n")
76        # f.write(str(request))
77        if handler is not None:
78            response.setOperationId(handler(request, response))
79            data_out = response.dump()
80            response_out.write(data_out)
81            response_test = IPPRequest(data=data_out)
82            response_test.parse()
83        #     f.write("\n" + "-"*80 + "\n")
84        #     f.write(str(response_test))
85        # f.write("\n" + "*"*80 + "\n")
86        # f.close()
87
88    def _operation_2(self, request, response):
89        """print-job response"""
90        (fno, fname) = mkstemp(dir='/tmp/gutenbach/ipp')
91        os.write(fno, request.data)
92        os.close(fno)
93        opattr = filter(lambda x: x[0] in ('job-name'),
94            request._operation_attributes[0])
95        jname = 'unknown'
96        if len(opattr) and opattr[0][0] == 'job-name':
97            jname = opattr[0][1][0][1]
98        jstat = os.stat(fname)
99        jsize = jstat.st_size
100        c = db.cursor()
101        c.execute("INSERT INTO job (juser, jname, jfile, jsize, jtype) VALUES (%s, %s, %s, %s, %s)", \
102                (AUTH, jname, fname, jsize, 'PostScript',))
103        jid = db.insert_id()
104        jfile = '/mit/gutenbach/jobs/' + AUTH + '_' + str(jid)
105        move(fname, jfile)
106        c.execute("UPDATE job SET jfile=%s, dupdated=NOW() WHERE jid=%s", \
107                (jfile, str(jid),))
108        response._job_attributes = [[ \
109            ('job-id', [('integer', jid)]), \
110            ('printer-uri', [('uri', printer_uri)]), \
111            ('job-state', [('enum', ipplib.IPP_JOB_HELD)])]]
112        return ipplib.IPP_OK
113
114    def _operation_8(self, request, response):
115        """delete-job response"""
116        opattr = filter(lambda x: x[0] in ('job-id'),
117            request._operation_attributes[0])
118        if len(opattr) and opattr[0][0] == 'job-id':
119            jid = opattr[0][1][0][1]
120            c = db.cursor()
121            c.execute("UPDATE job SET jstate = 'DEL' WHERE juser = %s AND jid = %s", \
122                (AUTH, int(jid)))
123        return ipplib.IPP_OK
124
125    def _operation_9(self, request, response):
126        """get-job-properties response"""
127        opattr = filter(lambda x: x[0] in ('job-id'),
128            request._operation_attributes[0])
129        if len(opattr) and opattr[0][0] == 'job-id':
130            jid = opattr[0][1][0][1]
131        response._job_attributes.append([ \
132            ('job-id', [('integer', jid)]), \
133        #    ('job-name', [('nameWithoutLanguage', x[1])]), \
134            ('job-originating-user-name', [('nameWithoutLanguage', AUTH)]), \
135        #    ('job-k-octets', [('integer', x[2]/1024)]), \
136            ('job-state', [('enum', ipplib.IPP_JOB_COMPLETE)])
137        ])
138        return ipplib.IPP_OK
139
140    def _operation_10(self, request, response):
141        """get-jobs response"""
142        c = db.cursor()
143        c.execute("SELECT jid, jname, jsize, jstate FROM job WHERE juser = %s AND jstate != %s ORDER BY dadded", \
144            (AUTH, 'DEL',))
145        response._job_attributes = []
146        for x in c.fetchall():
147            if x[3] == 'NEW':
148                state = ipplib.IPP_JOB_HELD
149            elif x[3] == 'DONE':
150                state = ipplib.IPP_JOB_COMPLETE
151            else:
152                state = 0
153            response._job_attributes.append([ \
154                ('job-id', [('integer', x[0])]), \
155                ('job-name', [('nameWithoutLanguage', x[1])]), \
156                ('job-originating-user-name', [('nameWithoutLanguage', AUTH)]), \
157                ('job-k-octets', [('integer', x[2]/1024)]), \
158                ('job-state', [('enum', state)])
159            ])
160        return ipplib.IPP_OK
161
162    def _operation_11(self, request, response):
163        """get-printer-attributes response"""
164        response._printer_attributes = \
165            [[('printer-name', [('nameWithoutLanguage', 'Gutenbach')])]]
166        return ipplib.IPP_OK
167
168IPPServer().process(sys.stdin,sys.stdout)
Note: See TracBrowser for help on using the repository browser.