source: server/lib/ipp.py @ c216863

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

Add an IPPRequest class/module to deal with storing and parsing IPP
requests.

  • Property mode set to 100755
File size: 5.7 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 ipplib 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        pass
42
43    # this function processes an IPP request and sends a response
44    def process(self, request_in, response_out):
45
46
47        response = IPPRequest(version=request.version,
48                              operation_id=request.operation_id,
49                              request_id=request.request_id)
50        #file('/mit/gutenbach/tmp/requests/'+str(request.operation_id)).write()
51        handler = getattr(self, "_operation_%d" % request.operation_id, None)
52
53        response._operation_attributes = [[]]
54        response._operation_attributes[0] = filter( \
55            lambda x: x[0] in ('attributes-charset', 'attributes-natural-language', 'printer-uri'),
56            request._operation_attributes[0])
57
58        # f = file('/tmp/gutenbach/ipp/printer2.log','a')
59        # f.write("\n" + "*"*80 + "\n")
60        # f.write(str(request))
61        if handler is not None:
62            response.setOperationId(handler(request, response))
63            data_out = response.dump()
64            response_out.write(data_out)
65            response_test = IPPRequest(data=data_out)
66            response_test.parse()
67        #     f.write("\n" + "-"*80 + "\n")
68        #     f.write(str(response_test))
69        # f.write("\n" + "*"*80 + "\n")
70        # f.close()
71
72    def _operation_2(self, request, response):
73        """print-job response"""
74        (fno, fname) = mkstemp(dir='/tmp/gutenbach/ipp')
75        os.write(fno, request.data)
76        os.close(fno)
77        opattr = filter(lambda x: x[0] in ('job-name'),
78            request._operation_attributes[0])
79        jname = 'unknown'
80        if len(opattr) and opattr[0][0] == 'job-name':
81            jname = opattr[0][1][0][1]
82        jstat = os.stat(fname)
83        jsize = jstat.st_size
84        c = db.cursor()
85        c.execute("INSERT INTO job (juser, jname, jfile, jsize, jtype) VALUES (%s, %s, %s, %s, %s)", \
86                (AUTH, jname, fname, jsize, 'PostScript',))
87        jid = db.insert_id()
88        jfile = '/mit/gutenbach/jobs/' + AUTH + '_' + str(jid)
89        move(fname, jfile)
90        c.execute("UPDATE job SET jfile=%s, dupdated=NOW() WHERE jid=%s", \
91                (jfile, str(jid),))
92        response._job_attributes = [[ \
93            ('job-id', [('integer', jid)]), \
94            ('printer-uri', [('uri', printer_uri)]), \
95            ('job-state', [('enum', ipplib.IPP_JOB_HELD)])]]
96        return ipplib.IPP_OK
97
98    def _operation_8(self, request, response):
99        """delete-job response"""
100        opattr = filter(lambda x: x[0] in ('job-id'),
101            request._operation_attributes[0])
102        if len(opattr) and opattr[0][0] == 'job-id':
103            jid = opattr[0][1][0][1]
104            c = db.cursor()
105            c.execute("UPDATE job SET jstate = 'DEL' WHERE juser = %s AND jid = %s", \
106                (AUTH, int(jid)))
107        return ipplib.IPP_OK
108
109    def _operation_9(self, request, response):
110        """get-job-properties response"""
111        opattr = filter(lambda x: x[0] in ('job-id'),
112            request._operation_attributes[0])
113        if len(opattr) and opattr[0][0] == 'job-id':
114            jid = opattr[0][1][0][1]
115        response._job_attributes.append([ \
116            ('job-id', [('integer', jid)]), \
117        #    ('job-name', [('nameWithoutLanguage', x[1])]), \
118            ('job-originating-user-name', [('nameWithoutLanguage', AUTH)]), \
119        #    ('job-k-octets', [('integer', x[2]/1024)]), \
120            ('job-state', [('enum', ipplib.IPP_JOB_COMPLETE)])
121        ])
122        return ipplib.IPP_OK
123
124    def _operation_10(self, request, response):
125        """get-jobs response"""
126        c = db.cursor()
127        c.execute("SELECT jid, jname, jsize, jstate FROM job WHERE juser = %s AND jstate != %s ORDER BY dadded", \
128            (AUTH, 'DEL',))
129        response._job_attributes = []
130        for x in c.fetchall():
131            if x[3] == 'NEW':
132                state = ipplib.IPP_JOB_HELD
133            elif x[3] == 'DONE':
134                state = ipplib.IPP_JOB_COMPLETE
135            else:
136                state = 0
137            response._job_attributes.append([ \
138                ('job-id', [('integer', x[0])]), \
139                ('job-name', [('nameWithoutLanguage', x[1])]), \
140                ('job-originating-user-name', [('nameWithoutLanguage', AUTH)]), \
141                ('job-k-octets', [('integer', x[2]/1024)]), \
142                ('job-state', [('enum', state)])
143            ])
144        return ipplib.IPP_OK
145
146    def _operation_11(self, request, response):
147        """get-printer-attributes response"""
148        response._printer_attributes = \
149            [[('printer-name', [('nameWithoutLanguage', 'Gutenbach')])]]
150        return ipplib.IPP_OK
151
152IPPServer().process(sys.stdin,sys.stdout)
Note: See TracBrowser for help on using the repository browser.