Public page for StudentProjects now displays public info.
Patch by: Lennard de Rijk
Reviewed by: to-be-reviewed
#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Copyright 2008 Python Software Foundation, Ian Bicking, and Google."""
import mimetools
import StringIO
import sys
CONTINUE = 100
SWITCHING_PROTOCOLS = 101
PROCESSING = 102
OK = 200
CREATED = 201
ACCEPTED = 202
NON_AUTHORITATIVE_INFORMATION = 203
NO_CONTENT = 204
RESET_CONTENT = 205
PARTIAL_CONTENT = 206
MULTI_STATUS = 207
IM_USED = 226
MULTIPLE_CHOICES = 300
MOVED_PERMANENTLY = 301
FOUND = 302
SEE_OTHER = 303
NOT_MODIFIED = 304
USE_PROXY = 305
TEMPORARY_REDIRECT = 307
BAD_REQUEST = 400
UNAUTHORIZED = 401
PAYMENT_REQUIRED = 402
FORBIDDEN = 403
NOT_FOUND = 404
METHOD_NOT_ALLOWED = 405
NOT_ACCEPTABLE = 406
PROXY_AUTHENTICATION_REQUIRED = 407
REQUEST_TIMEOUT = 408
CONFLICT = 409
GONE = 410
LENGTH_REQUIRED = 411
PRECONDITION_FAILED = 412
REQUEST_ENTITY_TOO_LARGE = 413
REQUEST_URI_TOO_LONG = 414
UNSUPPORTED_MEDIA_TYPE = 415
REQUESTED_RANGE_NOT_SATISFIABLE = 416
EXPECTATION_FAILED = 417
UNPROCESSABLE_ENTITY = 422
LOCKED = 423
FAILED_DEPENDENCY = 424
UPGRADE_REQUIRED = 426
INTERNAL_SERVER_ERROR = 500
NOT_IMPLEMENTED = 501
BAD_GATEWAY = 502
SERVICE_UNAVAILABLE = 503
GATEWAY_TIMEOUT = 504
HTTP_VERSION_NOT_SUPPORTED = 505
INSUFFICIENT_STORAGE = 507
NOT_EXTENDED = 510
responses = {
100: 'Continue',
101: 'Switching Protocols',
200: 'OK',
201: 'Created',
202: 'Accepted',
203: 'Non-Authoritative Information',
204: 'No Content',
205: 'Reset Content',
206: 'Partial Content',
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Found',
303: 'See Other',
304: 'Not Modified',
305: 'Use Proxy',
306: '(Unused)',
307: 'Temporary Redirect',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
403: 'Forbidden',
404: 'Not Found',
405: 'Method Not Allowed',
406: 'Not Acceptable',
407: 'Proxy Authentication Required',
408: 'Request Timeout',
409: 'Conflict',
410: 'Gone',
411: 'Length Required',
412: 'Precondition Failed',
413: 'Request Entity Too Large',
414: 'Request-URI Too Long',
415: 'Unsupported Media Type',
416: 'Requested Range Not Satisfiable',
417: 'Expectation Failed',
500: 'Internal Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
}
HTTP_PORT = 80
HTTPS_PORT = 443
class HTTPConnection:
protocol = 'http'
default_port = HTTP_PORT
_allow_truncated = True
_follow_redirects = False
def __init__(self, host, port=None, strict=False, timeout=None):
from google.appengine.api import urlfetch
self._fetch = urlfetch.fetch
self._method_map = {
'GET': urlfetch.GET,
'POST': urlfetch.POST,
'HEAD': urlfetch.HEAD,
'PUT': urlfetch.PUT,
'DELETE': urlfetch.DELETE,
}
self.host = host
self.port = port
self._method = self._url = None
self._body = ''
self.headers = []
def connect(self):
pass
def request(self, method, url, body=None, headers=None):
self._method = method
self._url = url
try:
self._body = body.read()
except AttributeError:
self._body = body
if headers is None:
headers = []
elif hasattr(headers, 'items'):
headers = headers.items()
self.headers = headers
def putrequest(self, request, selector, skip_host=False, skip_accept_encoding=False):
self._method = request
self._url = selector
def putheader(self, header, *lines):
line = '\r\n\t'.join(lines)
self.headers.append((header, line))
def endheaders(self):
pass
def set_debuglevel(self, level=None):
pass
def send(self, data):
self._body += data
def getresponse(self):
if self.port and self.port != self.default_port:
host = '%s:%s' % (self.host, self.port)
else:
host = self.host
url = '%s://%s%s' % (self.protocol, host, self._url)
headers = dict(self.headers)
try:
method = self._method_map[self._method.upper()]
except KeyError:
raise ValueError("%r is an unrecognized HTTP method" % self._method)
response = self._fetch(url, self._body, method, headers,
self._allow_truncated, self._follow_redirects)
return HTTPResponse(response)
def close(self):
pass
class HTTPSConnection(HTTPConnection):
protocol = 'https'
default_port = HTTPS_PORT
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=False, timeout=None):
if key_file is not None or cert_file is not None:
raise NotImplementedError(
"key_file and cert_file arguments are not implemented")
HTTPConnection.__init__(self, host, port=port, strict=strict,
timeout=timeout)
class HTTPResponse(object):
def __init__(self, fetch_response):
self._fetch_response = fetch_response
self.fp = StringIO.StringIO(fetch_response.content)
def __getattr__(self, attr):
return getattr(self.fp, attr)
def getheader(self, name, default=None):
return self._fetch_response.headers.get(name, default)
def getheaders(self):
return self._fetch_response.headers.items()
@property
def msg(self):
msg = mimetools.Message(StringIO.StringIO(''))
for name, value in self._fetch_response.headers.items():
msg[name] = value
return msg
version = 11
@property
def status(self):
return self._fetch_response.status_code
@property
def reason(self):
return responses.get(self._fetch_response.status_code, 'Unknown')
class HTTP:
"Compatibility class with httplib.py from 1.5."
_http_vsn = 11
_http_vsn_str = 'HTTP/1.1'
debuglevel = 0
_connection_class = HTTPConnection
def __init__(self, host='', port=None, strict=None):
"Provide a default host, since the superclass requires one."
if port == 0:
port = None
self._setup(self._connection_class(host, port, strict))
def _setup(self, conn):
self._conn = conn
self.send = conn.send
self.putrequest = conn.putrequest
self.endheaders = conn.endheaders
self.set_debuglevel = conn.set_debuglevel
conn._http_vsn = self._http_vsn
conn._http_vsn_str = self._http_vsn_str
self.file = None
def connect(self, host=None, port=None):
"Accept arguments to set the host/port, since the superclass doesn't."
self.__init__(host, port)
def getfile(self):
"Provide a getfile, since the superclass' does not use this concept."
return self.file
def putheader(self, header, *values):
"The superclass allows only one value argument."
self._conn.putheader(header, '\r\n\t'.join(values))
def getreply(self):
"""Compat definition since superclass does not define it.
Returns a tuple consisting of:
- server status code (e.g. '200' if all goes well)
- server "reason" corresponding to status code
- any RFC822 headers in the response from the server
"""
response = self._conn.getresponse()
self.headers = response.msg
self.file = response.fp
return response.status, response.reason, response.msg
def close(self):
self._conn.close()
self.file = None
class HTTPS(HTTP):
"""Compatibility with 1.5 httplib interface
Python 1.5.2 did not have an HTTPS class, but it defined an
interface for sending http requests that is also useful for
https.
"""
_connection_class = HTTPSConnection
def __init__(self, host='', port=None, key_file=None, cert_file=None,
strict=None):
if key_file is not None or cert_file is not None:
raise NotImplementedError(
"key_file and cert_file arguments are not implemented")
if port == 0:
port = None
self._setup(self._connection_class(host, port, key_file,
cert_file, strict))
self.key_file = key_file
self.cert_file = cert_file
class HTTPException(Exception):
pass
class NotConnected(HTTPException):
pass
class InvalidURL(HTTPException):
pass
class UnknownProtocol(HTTPException):
def __init__(self, version):
self.version = version
HTTPException.__init__(self, version)
class UnknownTransferEncoding(HTTPException):
pass
class UnimplementedFileMode(HTTPException):
pass
class IncompleteRead(HTTPException):
def __init__(self, partial):
self.partial = partial
HTTPException.__init__(self, partial)
class ImproperConnectionState(HTTPException):
pass
class CannotSendRequest(ImproperConnectionState):
pass
class CannotSendHeader(ImproperConnectionState):
pass
class ResponseNotReady(ImproperConnectionState):
pass
class BadStatusLine(HTTPException):
def __init__(self, line):
self.line = line
HTTPException.__init__(self, line)
error = HTTPException