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
RevLine 
[2876403]1#!/usr/bin/env python
2
[c216863]3# Adapted from the Quickprint IPP server code (http://quikprint.mit.edu)
[efee0f1]4# Modifications and additions written by Jessica Hamrick (jhamrick@mit.edu)
[2876403]5
[efee0f1]6# Notes and Todo:
7#   - make sure package creates gutenbach folder in /var/log
[2876403]8
[efee0f1]9import os, sys
10import cgi, cgitb
11import logging
[2876403]12import MySQLdb
13import ipplib
14
[4ec7caa]15from ipprequest import IPPRequest
[2876403]16from tempfile import mkstemp
17from shutil import move
[efee0f1]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
[c216863]34# print the content type for our request
[2876403]35print "Content-type: application/ipp\n"
36
37class IPPServer(object):
[c216863]38   
39    # nothing to do in the init
[2876403]40    def __init__(self):
[4ec7caa]41        """
42        This function doesn't actually do anything.
43        """
[2876403]44        pass
[c216863]45
46    # this function processes an IPP request and sends a response
[2876403]47    def process(self, request_in, response_out):
[4ec7caa]48        """
49        Processes an IPP request and sends a response.
[c216863]50
[4ec7caa]51        Arguments:
[2876403]52
[4ec7caa]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
[2876403]63        response = IPPRequest(version=request.version,
[c216863]64                              operation_id=request.operation_id,
65                              request_id=request.request_id)
[4ec7caa]66       
[2876403]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
[efee0f1]74        # f = file('/tmp/gutenbach/ipp/printer2.log','a')
[2876403]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"""
[efee0f1]90        (fno, fname) = mkstemp(dir='/tmp/gutenbach/ipp')
[2876403]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.