source: server/lib/ipp.py @ 84e8137

no-cups
Last change on this file since 84e8137 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
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
[efee0f1]15from ipplib 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):
41        pass
[c216863]42
43    # this function processes an IPP request and sends a response
[2876403]44    def process(self, request_in, response_out):
[c216863]45
[2876403]46
47        response = IPPRequest(version=request.version,
[c216863]48                              operation_id=request.operation_id,
49                              request_id=request.request_id)
[2876403]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
[efee0f1]58        # f = file('/tmp/gutenbach/ipp/printer2.log','a')
[2876403]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"""
[efee0f1]74        (fno, fname) = mkstemp(dir='/tmp/gutenbach/ipp')
[2876403]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.