")
- html.append(" ")
- return "\n".join(html)
-
-def get_time_page():
- """
- returns and html page with the current time in it
- """
- time = httpdate.httpdate_now()
- html = "
%s
"%time
- return html
-
-def get_file(URI):
-
- URI = URI.strip('/') #weird-- os.path.join does not like a leading slash
- # check if this is the time server option
- if URI.lower() == "get_time":
- return get_time_page(), 'html'
- else:
- filename = os.path.join( root_dir, URI)
- if os.path.isfile(filename):
- contents = open(filename, 'rb').read()
- ext = os.path.splitext(filename)[1].strip('.')
- return contents, ext
- elif os.path.isdir(filename):
- return format_dir_list(URI), 'htm'
- else:
- raise ValueError("there is nothing by that name")
-
-
-while True: # keep looking for new connections forever
- client, address = s.accept() # look for a connection
- request = client.recv(size)
- if request: # if the connection was closed there would be no data
- print "received:", request
- URI = parse_request(request)
- try:
- file_data, ext = get_file(URI)
- response = OK_response(file_data, ext)
- except ValueError:
- response = Error_response(URI)
- client.send(response)
- client.close()
-
+#!/usr/bin/env python
+
+import socket
+import os
+import email.utils
+import time
+#import httpdate
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+root_dir = 'web' # must be run from code dir...
+
+print "point your browser to http://localhost:%i"%port
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+#html = open("tiny_html.html").read()
+
+mime_types={}
+mime_types['html'] = "text/html"
+mime_types['htm'] = "text/html"
+mime_types['txt'] = "text/plain"
+mime_types['png'] = "image/png"
+mime_types['jpeg'] = "image/jpg"
+mime_types['jpg'] = "image/jpg"
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def OK_response(entity, extension='html'):
+ """
+ returns an HTTP response: header and entity in a string
+ """
+ resp = []
+ resp.append('HTTP/1.1 200 OK')
+ resp.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ resp.append( 'Content-Type: %s'%type )
+ resp.append('Content-Length: %i'%len(entity))
+ resp.append('')
+ resp.append(entity)
+
+ return "\r\n".join(resp)
+
+def Error_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+
+def parse_request(request):
+ """
+ parse an HTTP request
+
+ returns the URI asked for
+
+ note: minimal parsing -- only supprt GET
+
+ example:
+ GET / HTTP/1.1
+ Host: localhost:50000
+ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+ Accept-Language: en-us,en;q=0.5
+ Accept-Encoding: gzip, deflate
+ Connection: keep-alive
+ Cache-Control: max-age=0
+ """
+ # first line should be the method line:
+ lines = request.split("\r\n")
+
+ method, URI, protocol = lines[0].split()
+
+ # a bit of checking:
+ if method.strip() != "GET":
+ raise ValueError("I can only process a GET request")
+ if protocol.split('/')[0] != "HTTP":
+ raise ValueError("I can only process an HTTP request")
+
+ return URI
+
+def format_dir_list(URI):
+ """
+ format the contests of dir as HTML with links
+ """
+ dir = os.path.join(root_dir, URI)
+ names = os.listdir(dir)
+
+ dirs = [d for d in names if os.path.isdir(os.path.join(dir,d))]
+ files = [d for d in names if os.path.isfile(os.path.join(dir,d))]
+
+ html =[]
+ html.append(" ")
+ html.append("
%s
"%URI)
+ print "URI:", URI
+ if URI: # don't need the parent dir at the root
+ html.append('Parent' )
+ html.append("
")
+ html.append(" ")
+ return "\n".join(html)
+
+def get_time_page():
+ """
+ returns and html page with the current time in it
+ """
+ time = httpdate()
+ html = "
%s
"%time
+ return html
+
+def get_file(URI):
+
+ print 'URI = ', URI
+ URI = URI.strip('/') #weird-- os.path.join does not like a leading slash
+ # check if this is the time server option
+ if URI.lower() == "get_time":
+ return get_time_page(), 'html'
+ else:
+ filename = os.path.join( root_dir, URI)
+ if os.path.isfile(filename):
+ contents = open(filename, 'rb').read()
+ ext = os.path.splitext(filename)[1].strip('.')
+ return contents, ext
+ elif os.path.isdir(filename):
+ return format_dir_list(URI), 'htm'
+ else:
+ raise ValueError("there is nothing by that name")
+
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received:", request
+ URI = parse_request(request)
+ try:
+ file_data, ext = get_file(URI)
+ response = OK_response(file_data, ext)
+ except ValueError:
+ response = Error_response(URI)
+ print response
+ client.send(response)
+ client.close()
+
diff --git a/assignments/teachers/week02/answers/web/a_web_page.html b/assignments/teachers/week02/answers/web/a_web_page.html
new file mode 100644
index 00000000..e7c3c777
--- /dev/null
+++ b/assignments/teachers/week02/answers/web/a_web_page.html
@@ -0,0 +1,11 @@
+
+
+
+
+
My First Heading
+
+
My first paragraph.
+
+
+
+
diff --git a/assignments/teachers/week02/answers/web/images/JPEG_example.jpg b/assignments/teachers/week02/answers/web/images/JPEG_example.jpg
new file mode 100644
index 00000000..13506f01
Binary files /dev/null and b/assignments/teachers/week02/answers/web/images/JPEG_example.jpg differ
diff --git a/assignments/teachers/week02/answers/web/images/Sample_Scene_Balls.jpg b/assignments/teachers/week02/answers/web/images/Sample_Scene_Balls.jpg
new file mode 100644
index 00000000..1c0ccade
Binary files /dev/null and b/assignments/teachers/week02/answers/web/images/Sample_Scene_Balls.jpg differ
diff --git a/assignments/teachers/week02/answers/web/images/sample_1.png b/assignments/teachers/week02/answers/web/images/sample_1.png
new file mode 100644
index 00000000..5b2f52df
Binary files /dev/null and b/assignments/teachers/week02/answers/web/images/sample_1.png differ
diff --git a/assignments/teachers/week02/answers/web/make_time.py b/assignments/teachers/week02/answers/web/make_time.py
new file mode 100644
index 00000000..80166cee
--- /dev/null
+++ b/assignments/teachers/week02/answers/web/make_time.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+"""
+make_time.py
+
+simple script that returns and HTML page with the current time
+"""
+
+import datetime
+
+time_str = datetime.datetime.now().isoformat()
+
+html = """
+
+
+
The time is:
+
%s
+
+
+"""% time_str
+
+print html
+
+
+
diff --git a/assignments/teachers/week02/answers/web/sample.txt b/assignments/teachers/week02/answers/web/sample.txt
new file mode 100644
index 00000000..1e318a76
--- /dev/null
+++ b/assignments/teachers/week02/answers/web/sample.txt
@@ -0,0 +1,3 @@
+This is a very simple text file.
+Just to show that we can server it up.
+It is three lines long.
diff --git a/assignments/week01/athome/add_client.py b/assignments/week01/athome/add_client.py
new file mode 100644
index 00000000..ea3bf247
--- /dev/null
+++ b/assignments/week01/athome/add_client.py
@@ -0,0 +1,33 @@
+#-------------------------------------------------------------------------------
+# Name: add_client.py
+# Purpose:
+#
+# Author: Allen Su
+#
+# Created: 10/01/2013
+# Copyright: (c) allsu 2013
+# Licence:
+#-------------------------------------------------------------------------------
+
+import socket
+import sys
+
+client = socket.socket() # Create a TCP/IP socket
+
+# Connect the socket to the port where the server is listening
+server_address = ('localhost', 50000)
+client.connect(server_address)
+
+try:
+ # Send data
+ num1 = raw_input('Please input the 1st integer number: ')
+ num2 = raw_input('Please input the 2nd integer number: ')
+ message = '%s,%s' % (num1, num2)
+ client.sendall(message)
+
+ # print the response
+ print('%s + %s = %s') % (num1, num2, client.recv(4096))
+
+finally:
+ # close the socket to clean up
+ client.close()
diff --git a/assignments/week01/athome/add_server.py b/assignments/week01/athome/add_server.py
new file mode 100644
index 00000000..d14117c8
--- /dev/null
+++ b/assignments/week01/athome/add_server.py
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Name: add_server.py
+# Purpose:
+#
+# Author: Allen Su
+#
+# Created: 10/01/2013
+# Copyright: (c) allsu 2013
+# Licence:
+#-------------------------------------------------------------------------------
+
+import socket
+import sys
+
+# Create a TCP/IP socket
+server = socket.socket()
+
+# Bind the socket to the port
+server_address = ('localhost', 50000)
+server.bind(server_address)
+
+# Listen for incoming connections
+server.listen(100)
+
+try:
+
+ while True:
+ # Wait for a connection
+ con, addr = server.accept()
+ try:
+ # Receive the data and send it back
+ message = con.recv(4096)
+ delimiter = ','
+ num = message.split(delimiter)
+ total = int(num[0]) + int(num[1])
+ con.sendall(str(total))
+
+ finally:
+ # Clean up the connection
+ con.close()
+
+except KeyboardInterrupt:
+ server.close()
+ sys.exit()
diff --git a/assignments/week01/lab/echo_client.py b/assignments/week01/lab/echo_client.py
index b8898436..70707625 100644
--- a/assignments/week01/lab/echo_client.py
+++ b/assignments/week01/lab/echo_client.py
@@ -1,16 +1,20 @@
-import socket
-import sys
-
-# Create a TCP/IP socket
-
-# Connect the socket to the port where the server is listening
-server_address = ('localhost', 50000)
-
-try:
- # Send data
- message = 'This is the message. It will be repeated.'
-
- # print the response
-
-finally:
- # close the socket to clean up
+import socket
+import sys
+
+client = socket.socket() # Create a TCP/IP socket
+
+# Connect the socket to the port where the server is listening
+server_address = ('localhost', 50000)
+client.connect(server_address)
+
+try:
+ # Send data
+ message = 'This is the message. It will be repeated.'
+ client.sendall(message)
+
+ # print the response
+ print(client.recv(4096))
+
+finally:
+ # close the socket to clean up
+ client.close()
diff --git a/assignments/week01/lab/echo_server.py b/assignments/week01/lab/echo_server.py
index e2c52fc6..198da36b 100644
--- a/assignments/week01/lab/echo_server.py
+++ b/assignments/week01/lab/echo_server.py
@@ -1,19 +1,24 @@
-import socket
-import sys
-
-# Create a TCP/IP socket
-
-# Bind the socket to the port
-server_address = ('localhost', 50000)
-
-# Listen for incoming connections
-
-while True:
- # Wait for a connection
-
- try:
- # Receive the data and send it back
-
-
- finally:
- # Clean up the connection
+import socket
+import sys
+
+# Create a TCP/IP socket
+server = socket.socket()
+
+# Bind the socket to the port
+server_address = ('localhost', 50000)
+server.bind(server_address)
+
+# Listen for incoming connections
+server.listen(100)
+
+while True:
+ # Wait for a connection
+ con, addr = server.accept()
+ try:
+ # Receive the data and send it back
+ message = con.recv(4096)
+ con.sendall(message)
+
+ finally:
+ # Clean up the connection
+ con.close()
diff --git a/assignments/week02/athome/Assignment - Allen Su.txt b/assignments/week02/athome/Assignment - Allen Su.txt
new file mode 100644
index 00000000..3e4fc3a2
--- /dev/null
+++ b/assignments/week02/athome/Assignment - Allen Su.txt
@@ -0,0 +1,12 @@
+hi Chris, sorry for the late submission. I stunbled across several challenges that took me a long time to resolve.
+
+I was able to finish the labs and the assignment up to the "dynamic time-page" point, without the bonus (running it on the VM).
+
+However, in I ran into an issue that I can't figure out. I added another directory (web/images/test), and a file inside that directory (web/images/test/test.txt).
+
+the URI works fine until the test.txt file. For some reason, when I click the link on that file, the URI being passed with the request becomes /images/images/test/test.txt,
+which then resulted a 404 error.
+
+Thanks,
+
+Allen Su
\ No newline at end of file
diff --git a/assignments/week02/athome/http_server.py b/assignments/week02/athome/http_server.py
new file mode 100644
index 00000000..db7a498b
--- /dev/null
+++ b/assignments/week02/athome/http_server.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+import socket
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+html = open('tiny_html.html', 'r').read()
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ client.send(html)
+ client.close()
diff --git a/assignments/week02/athome/http_server2.py b/assignments/week02/athome/http_server2.py
new file mode 100644
index 00000000..3f23d695
--- /dev/null
+++ b/assignments/week02/athome/http_server2.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ r.append('Content Type: text/html')
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+html = open('tiny_html.html', 'r').read()
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ response = ok_response(html)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
diff --git a/assignments/week02/athome/http_server3.py b/assignments/week02/athome/http_server3.py
new file mode 100644
index 00000000..9fe6e52e
--- /dev/null
+++ b/assignments/week02/athome/http_server3.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ r.append('Content Type: text/html')
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response(method, protocol):
+ msg = '400 Error: Bad Request. Either %s or %s is not a supported request' % (method, protocol.split('/')[0])
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/html')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def parse_request(r, h):
+ """Parse a request and returns a URL"""
+ lines = r.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ print('URI requested is: %s') % URI
+
+ if method != 'GET':
+ response = client_error_response(method, protocol)
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response(method, protocol)
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ return ok_response(h)
+
+html = open('tiny_html.html', 'r').read()
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ response = parse_request(request, html)
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
diff --git a/assignments/week02/athome/http_server4.py b/assignments/week02/athome/http_server4.py
new file mode 100644
index 00000000..6c9ee91c
--- /dev/null
+++ b/assignments/week02/athome/http_server4.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(dir_list):
+ msg = ["Directory Listing:"]
+ for d in dir_list:
+ msg.append(d)
+ return "\n".join(msg)
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ root_dir = 'web'
+ URI = u.lstrip('/')
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ response = client_error_response() + '\r\nFile Access is not supported yet!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise NotImplementedError('File Access is not supported yet!')
+ elif os.path.isdir(filename):
+ data, ext = format_dir_list(os.listdir(filename)), 'txt'
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/athome/http_server5.py b/assignments/week02/athome/http_server5.py
new file mode 100644
index 00000000..1140bfa8
--- /dev/null
+++ b/assignments/week02/athome/http_server5.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(dir_list):
+ msg = ["Directory Listing:"]
+ for d in dir_list:
+ msg.append(d)
+ return "\n".join(msg)
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ root_dir = 'web'
+ URI = u.lstrip('/')
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ data = open(filename, 'rb').read()
+ ext = os.path.splitext(filename)[1].strip('.')
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ elif os.path.isdir(filename):
+ data, ext = format_dir_list(os.listdir(filename)), 'txt'
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/athome/http_server6.py b/assignments/week02/athome/http_server6.py
new file mode 100644
index 00000000..e7e09eec
--- /dev/null
+++ b/assignments/week02/athome/http_server6.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(dir_list):
+ """Format the Directory Listing as HTML"""
+ html = [' ']
+ html.append('
Directory Listing
')
+
+ for d in dir_list:
+ html.append('
%s
' % d)
+ html.append(' ')
+ return "\n".join(html)
+
+def get_time_page(u):
+ """Return a HTML page with current time listed in GMT format"""
+ time = httpdate()
+ html = "
%s
" % time
+ return html
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ root_dir = 'web'
+ URI = u.lstrip('/')
+ if URI.lower() == 'time-page':
+ response = ok_response(get_time_page(URI), 'html')
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ data = open(filename, 'rb').read()
+ ext = os.path.splitext(filename)[1].strip('.')
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ elif os.path.isdir(filename):
+ data, ext = format_dir_list(os.listdir(filename)), 'htm'
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/athome/http_server7.py b/assignments/week02/athome/http_server7.py
new file mode 100644
index 00000000..9a8febff
--- /dev/null
+++ b/assignments/week02/athome/http_server7.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+root_dir = 'web'
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(u):
+ """Format the Directory Listing as HTML with links"""
+
+ dir = os.path.join(root_dir, u)
+ names = os.listdir(dir)
+
+ dirs = []
+ files = []
+
+ for d in names:
+ if os.path.isdir(os.path.join(dir, d)):
+ dirs.append(d)
+ elif os.path.isfile(os.path.join(dir, d)):
+ files.append(d)
+
+ html =[]
+ html.append(" ")
+ html.append("
%s
" % u)
+ print "URI:", u
+ if u: # don't need the parent dir at the root
+ html.append('Parent' )
+ html.append("
Directories:
")
+ html.append("
")
+ for d in dirs:
+ path = u + '/' + d
+ html.append('
")
+ html.append(" ")
+ return "\n".join(html)
+
+def get_time_page(u):
+ """Return a HTML page with current time listed in GMT format"""
+ time = httpdate()
+ html = "
%s
" % time
+ return html
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ URI = u.lstrip('/')
+ if URI.lower() == 'time-page':
+ response = ok_response(get_time_page(URI), 'html')
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ data = open(filename, 'rb').read()
+ ext = os.path.splitext(filename)[1].strip('.')
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ elif os.path.isdir(filename):
+ data = format_dir_list(URI)
+ response = ok_response(data, 'html')
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/athome/test_client.py b/assignments/week02/athome/test_client.py
new file mode 100644
index 00000000..210ec545
--- /dev/null
+++ b/assignments/week02/athome/test_client.py
@@ -0,0 +1,20 @@
+import socket
+import sys
+
+client = socket.socket() # Create a TCP/IP socket
+
+# Connect the socket to the port where the server is listening
+server_address = ('localhost', 50000)
+client.connect(server_address)
+
+try:
+ # Send data
+ message = 'GET / FTP/1.1\r\n\r\n'
+ client.sendall(message)
+
+ # print the response
+ print(client.recv(4096))
+
+finally:
+ # close the socket to clean up
+ client.close()
diff --git a/assignments/week02/athome/tiny_html.html b/assignments/week02/athome/tiny_html.html
new file mode 100644
index 00000000..c5dd01dc
--- /dev/null
+++ b/assignments/week02/athome/tiny_html.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/assignments/week02/athome/web/favicon.ico b/assignments/week02/athome/web/favicon.ico
new file mode 100644
index 00000000..4e8c2d61
Binary files /dev/null and b/assignments/week02/athome/web/favicon.ico differ
diff --git a/assignments/week02/athome/web/images/JPEG_example.jpg b/assignments/week02/athome/web/images/JPEG_example.jpg
new file mode 100644
index 00000000..13506f01
Binary files /dev/null and b/assignments/week02/athome/web/images/JPEG_example.jpg differ
diff --git a/assignments/week02/athome/web/images/Sample_Scene_Balls.jpg b/assignments/week02/athome/web/images/Sample_Scene_Balls.jpg
new file mode 100644
index 00000000..1c0ccade
Binary files /dev/null and b/assignments/week02/athome/web/images/Sample_Scene_Balls.jpg differ
diff --git a/assignments/week02/athome/web/images/sample_1.png b/assignments/week02/athome/web/images/sample_1.png
new file mode 100644
index 00000000..5b2f52df
Binary files /dev/null and b/assignments/week02/athome/web/images/sample_1.png differ
diff --git a/assignments/week02/athome/web/images/test/test.txt b/assignments/week02/athome/web/images/test/test.txt
new file mode 100644
index 00000000..46fd6b2d
--- /dev/null
+++ b/assignments/week02/athome/web/images/test/test.txt
@@ -0,0 +1 @@
+test test 123
\ No newline at end of file
diff --git a/assignments/week02/athome/web/make_time.py b/assignments/week02/athome/web/make_time.py
new file mode 100644
index 00000000..80166cee
--- /dev/null
+++ b/assignments/week02/athome/web/make_time.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+"""
+make_time.py
+
+simple script that returns and HTML page with the current time
+"""
+
+import datetime
+
+time_str = datetime.datetime.now().isoformat()
+
+html = """
+
+
+
The time is:
+
%s
+
+
+"""% time_str
+
+print html
+
+
+
diff --git a/assignments/week02/athome/web/sample.txt b/assignments/week02/athome/web/sample.txt
new file mode 100644
index 00000000..1e318a76
--- /dev/null
+++ b/assignments/week02/athome/web/sample.txt
@@ -0,0 +1,3 @@
+This is a very simple text file.
+Just to show that we can server it up.
+It is three lines long.
diff --git a/assignments/week02/lab/echo_server.py b/assignments/week02/lab/echo_server.py
deleted file mode 100644
index 3eb3400f..00000000
--- a/assignments/week02/lab/echo_server.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-
-import socket
-
-host = '' # listen on all connections (WiFi, etc)
-port = 50000
-backlog = 5 # how many connections can we stack up
-size = 1024 # number of bytes to receive at once
-
-## create the socket
-s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-# set an option to tell the OS to re-use the socket
-s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
-# the bind makes it a server
-s.bind( (host,port) )
-s.listen(backlog)
-
-while True: # keep looking for new connections forever
- client, address = s.accept() # look for a connection
- data = client.recv(size)
- if data: # if the connection was closed there would be no data
- print "received: %s, sending it back"%data
- client.send(data)
- client.close()
\ No newline at end of file
diff --git a/assignments/week02/lab/http_server.py b/assignments/week02/lab/http_server.py
new file mode 100644
index 00000000..db7a498b
--- /dev/null
+++ b/assignments/week02/lab/http_server.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+import socket
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+html = open('tiny_html.html', 'r').read()
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ client.send(html)
+ client.close()
diff --git a/assignments/week02/lab/http_server2.py b/assignments/week02/lab/http_server2.py
new file mode 100644
index 00000000..3f23d695
--- /dev/null
+++ b/assignments/week02/lab/http_server2.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ r.append('Content Type: text/html')
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+html = open('tiny_html.html', 'r').read()
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ response = ok_response(html)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
diff --git a/assignments/week02/lab/http_server3.py b/assignments/week02/lab/http_server3.py
new file mode 100644
index 00000000..9fe6e52e
--- /dev/null
+++ b/assignments/week02/lab/http_server3.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ r.append('Content Type: text/html')
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response(method, protocol):
+ msg = '400 Error: Bad Request. Either %s or %s is not a supported request' % (method, protocol.split('/')[0])
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/html')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def parse_request(r, h):
+ """Parse a request and returns a URL"""
+ lines = r.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ print('URI requested is: %s') % URI
+
+ if method != 'GET':
+ response = client_error_response(method, protocol)
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response(method, protocol)
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ return ok_response(h)
+
+html = open('tiny_html.html', 'r').read()
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ response = parse_request(request, html)
+ print 'sending: '
+ print response
+ client.send(response)
+ client.close()
diff --git a/assignments/week02/lab/http_server4.py b/assignments/week02/lab/http_server4.py
new file mode 100644
index 00000000..6c9ee91c
--- /dev/null
+++ b/assignments/week02/lab/http_server4.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(dir_list):
+ msg = ["Directory Listing:"]
+ for d in dir_list:
+ msg.append(d)
+ return "\n".join(msg)
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ root_dir = 'web'
+ URI = u.lstrip('/')
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ response = client_error_response() + '\r\nFile Access is not supported yet!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise NotImplementedError('File Access is not supported yet!')
+ elif os.path.isdir(filename):
+ data, ext = format_dir_list(os.listdir(filename)), 'txt'
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/lab/http_server5.py b/assignments/week02/lab/http_server5.py
new file mode 100644
index 00000000..1140bfa8
--- /dev/null
+++ b/assignments/week02/lab/http_server5.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(dir_list):
+ msg = ["Directory Listing:"]
+ for d in dir_list:
+ msg.append(d)
+ return "\n".join(msg)
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ root_dir = 'web'
+ URI = u.lstrip('/')
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ data = open(filename, 'rb').read()
+ ext = os.path.splitext(filename)[1].strip('.')
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ elif os.path.isdir(filename):
+ data, ext = format_dir_list(os.listdir(filename)), 'txt'
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/lab/http_server6.py b/assignments/week02/lab/http_server6.py
new file mode 100644
index 00000000..e7e09eec
--- /dev/null
+++ b/assignments/week02/lab/http_server6.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(dir_list):
+ """Format the Directory Listing as HTML"""
+ html = [' ']
+ html.append('
Directory Listing
')
+
+ for d in dir_list:
+ html.append('
%s
' % d)
+ html.append(' ')
+ return "\n".join(html)
+
+def get_time_page(u):
+ """Return a HTML page with current time listed in GMT format"""
+ time = httpdate()
+ html = "
%s
" % time
+ return html
+
+def resolve_uri(u):
+ """Takes the URI and analyze it and return the proper HTTP code"""
+ root_dir = 'web'
+ URI = u.lstrip('/')
+ if URI.lower() == 'time-page':
+ response = ok_response(get_time_page(URI), 'html')
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ filename = os.path.join(root_dir, URI)
+ print 'The path requested is: %s' % filename
+ if os.path.isfile(filename):
+ data = open(filename, 'rb').read()
+ ext = os.path.splitext(filename)[1].strip('.')
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ elif os.path.isdir(filename):
+ data, ext = format_dir_list(os.listdir(filename)), 'htm'
+ response = ok_response(data, ext)
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ else:
+ response = notfound_response(u) + '\r\nNo such resource exist!'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('No such resource exist!')
+
+def parse_request(request):
+ """Parse a request and analyze the method, URI, and protocol, and return the proper response to the client"""
+ data = open('tiny_html.html', 'r').read()
+ lines = request.split('\r\n')
+
+ method, URI, protocol = lines[0].split()
+
+ if method != 'GET':
+ response = client_error_response() + '\r\nThis server currently can only process GET request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server currently can only process GET request')
+ elif protocol.split('/')[0] != 'HTTP':
+ response = client_error_response() + '\r\nThis server can only process HTTP request'
+ print 'sending: '
+ print response, '\r\n'
+ client.send(response)
+ client.close()
+ raise ValueError('This server can only process HTTP request')
+ else:
+ print('URI requested is: %s') % URI
+ resolve_uri(URI)
+
+while True: # keep looking for new connections forever
+ client, address = s.accept() # look for a connection
+ request = client.recv(size)
+ if request: # if the connection was closed there would be no data
+ print "received: "
+ print request
+ parse_request(request)
+
diff --git a/assignments/week02/lab/http_server7.py b/assignments/week02/lab/http_server7.py
new file mode 100644
index 00000000..7c816b6a
--- /dev/null
+++ b/assignments/week02/lab/http_server7.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+import socket
+import email.utils
+import time
+import os
+
+host = '' # listen on all connections (WiFi, etc)
+port = 50000
+backlog = 5 # how many connections can we stack up
+size = 1024 # number of bytes to receive at once
+
+root_dir = 'web'
+
+## create the socket
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# set an option to tell the OS to re-use the socket
+s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+# the bind makes it a server
+s.bind( (host,port) )
+s.listen(backlog)
+
+mime_types = {}
+mime_types['html'] = 'text/html'
+mime_types['htm'] = 'text/html'
+mime_types['txt'] = 'text/plain'
+mime_types['py'] = 'text/plain'
+mime_types['jpg'] = 'image/jpg'
+mime_types['jpeg'] = 'image/jpg'
+mime_types['png'] = 'image/png'
+
+def httpdate():
+ """Returns a date/time value in RFC1123 format"""
+ now = time.gmtime()
+ stamp = time.mktime(now)
+ return email.utils.formatdate(stamp, False, True)
+
+def ok_response(data, extension = 'html'):
+ r = []
+ r.append('HTTP/1.1 200 OK')
+ r.append(httpdate())
+ type = mime_types.get(extension, 'text/plain')
+ r.append('Content Type: %s' % type)
+ r.append('Content Length: %i' % len(data))
+ r.append('')
+ r.append(data)
+
+ return '\r\n'.join(r)
+
+def client_error_response():
+ msg = '400 Error: Bad Request. This is not a supported request!'
+ r = []
+ r.append('HTTP/1.1 400 Bad Request')
+ r.append(httpdate())
+ r.append('Content Type: text/plain')
+ r.append('Content Length: %i' % len(msg))
+ r.append('')
+ r.append(msg)
+
+ return '\r\n'.join(r)
+
+def notfound_response(URI):
+ """
+ returns an HTTP 404 Not Found Error response:
+
+ URI is the name of the entity not found
+ """
+ resp = []
+ resp.append('HTTP/1.1 404 Not Found')
+ resp.append(httpdate())
+ resp.append('Content-Type: text/plain')
+
+ msg = "404 Error:\n %s \n not found"%( URI )
+
+ resp.append('Content-Length: %i'%( len(msg) ) )
+ resp.append('')
+ resp.append(msg)
+
+ return "\r\n".join(resp)
+
+def format_dir_list(u):
+ """Format the Directory Listing as HTML with links"""
+
+ dir = os.path.join(root_dir, u)
+ names = os.listdir(dir)
+
+ dirs = []
+ files = []
+
+ for d in names:
+ if os.path.isdir(os.path.join(dir, d)):
+ dirs.append(d)
+ elif os.path.isfile(os.path.join(dir, d)):
+ files.append(d)
+
+ html =[]
+ html.append(" ")
+ html.append("
%s
" % u)
+ print "URI:", u
+ if u: # don't need the parent dir at the root
+ html.append('Parent' )
+ html.append("
Directories:
")
+ html.append("
")
+ for d in dirs:
+ path = (os.path.join(u, d)).replace('\\', '/')
+ html.append('
")
+ html.append(" ")
+ return "\n".join(html)
+
+def get_time_page(u):
+ """Return a HTML page with current time listed in GMT format"""
+ time = httpdate()
+ html = "
+
\ No newline at end of file
diff --git a/assignments/week05/lab/flask_intro.py b/assignments/week05/lab/flask_intro.py
new file mode 100644
index 00000000..25c2dd67
--- /dev/null
+++ b/assignments/week05/lab/flask_intro.py
@@ -0,0 +1,58 @@
+from flask import Flask, url_for, render_template, request
+app = Flask(__name__)
+
+@app.route('/')
+def index():
+ return 'Index Page'
+
+@app.route('/hello/')
+@app.route('/hello/')
+def hello(name=None):
+ return render_template('hello.html', name=name)
+
+@app.route('/user/')
+def show_user_profile(username):
+ # show the user profile for that user
+ return 'User %s' % username
+
+@app.route('/post/')
+def show_post(post_id):
+ # show the post with the given id, the id is an integer
+ return 'Post %d' % post_id
+
+@app.route('/div//')
+def divide(val):
+ return "%0.2f divided by 2 is %0.2f" % (val, val / 2)
+
+@app.route('/projects/')
+def projects():
+ return 'The project page'
+
+@app.route('/about')
+def about():
+ return 'The about page'
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+ if request.method == 'POST':
+ do_the_login()
+ else:
+ show_the_login_form()
+
+@app.route('/blog/entry//', methods=['GET',])
+def read_entry(id):
+ return "reading entry %d" % id
+
+@app.route('/blog/entry//', methods=['POST', ])
+def write_entry(id):
+ return 'writing entry %d' % id
+
+if __name__ == '__main__':
+ app.debug = True
+ app.run(host='0.0.0.0')
+
+ with app.test_request_context():
+ print url_for('index')
+ print url_for('login')
+ print url_for('login', next='/')
+ print url_for('profile', username='John Doe')
diff --git a/assignments/week05/lab/flaskr_1/flaskr.py b/assignments/week05/lab/flaskr_1/flaskr.py
index a959bdf9..1f8ba452 100644
--- a/assignments/week05/lab/flaskr_1/flaskr.py
+++ b/assignments/week05/lab/flaskr_1/flaskr.py
@@ -1,11 +1,22 @@
-from flask import Flask
-
-
-# configuration goes here
-
-
-app = Flask(__name__)
-
-
-if __name__ == '__main__':
- app.run(debug=True)
+from flask import Flask
+import sqlite3
+from contextlib import closing
+
+# configuration goes here
+DATABASE = '/tmp/flask.db'
+SECRET_KEY = 'development key'
+
+app = Flask(__name__)
+app.config.from_object(__name__)
+
+def connect_db():
+ return sqlite3.connect(app.config['DATABASE'])
+
+def init_db():
+ with closing(connect_db()) as db:
+ with app.open_resource('schema.sql') as f:
+ db.cursor().executescript(f.read())
+ db.commit()
+
+if __name__ == '__main__':
+ app.run(debug=True)
diff --git a/assignments/week05/lab/flaskr_1/flaskr_tests.py b/assignments/week05/lab/flaskr_1/flaskr_tests.py
index e69de29b..87d8696e 100644
--- a/assignments/week05/lab/flaskr_1/flaskr_tests.py
+++ b/assignments/week05/lab/flaskr_1/flaskr_tests.py
@@ -0,0 +1,27 @@
+import os
+import flaskr
+import unittest
+import tempfile
+
+class FlaskrTestCase(unittest.TestCase):
+
+ def setUp(self):
+ db_fd = tempfile.mkstemp()
+ self.db_fd, flaskr.app.config['DATABASE'] = db_fd
+ flaskr.app.config['TESTING'] = True
+ self.client = flaskr.app.test_client()
+ self.app = flaskr.app
+ flaskr.init_db()
+
+ def tearDown(self):
+ os.close(self.db_fd)
+ os.unlink(flaskr.app.config['DATABASE'])
+
+ def test_database_setup(self):
+ con = flaskr.connect_db()
+ cur = con.execute('PRAGMA table_info(entries);')
+ rows = cur.fetchall()
+ self.assertEquals(len(rows), 3)
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_1/schema.sql b/assignments/week05/lab/flaskr_1/schema.sql
index e69de29b..24b4ca8e 100644
--- a/assignments/week05/lab/flaskr_1/schema.sql
+++ b/assignments/week05/lab/flaskr_1/schema.sql
@@ -0,0 +1,6 @@
+drop table if exists entries;
+create table entries (
+ id integer primary key autoincrement,
+ title string not null,
+ text string not null
+);
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_2/flaskr.py b/assignments/week05/lab/flaskr_2/flaskr.py
index a97d679d..bca257c5 100644
--- a/assignments/week05/lab/flaskr_2/flaskr.py
+++ b/assignments/week05/lab/flaskr_2/flaskr.py
@@ -1,27 +1,51 @@
-import sqlite3
-from contextlib import closing
-
-from flask import Flask
-
-
-# configuration goes here
-DATABASE = '/tmp/flaskr.db'
-SECRET_KEY = 'development key'
-
-app = Flask(__name__)
-app.config.from_object(__name__)
-
-
-def connect_db():
- return sqlite3.connect(app.config['DATABASE'])
-
-
-def init_db():
- with closing(connect_db()) as db:
- with app.open_resource('schema.sql') as f:
- db.cursor().executescript(f.read())
- db.commit()
-
-
-if __name__ == '__main__':
- app.run(debug=True)
+import sqlite3
+from contextlib import closing
+
+from flask import Flask
+from flask import g
+from flask import render_template
+
+
+# configuration goes here
+DATABASE = '/tmp/flaskr.db'
+SECRET_KEY = 'development key'
+
+app = Flask(__name__)
+app.config.from_object(__name__)
+
+
+def connect_db():
+ return sqlite3.connect(app.config['DATABASE'])
+
+
+def init_db():
+ with closing(connect_db()) as db:
+ with app.open_resource('schema.sql') as f:
+ db.cursor().executescript(f.read())
+ db.commit()
+
+@app.before_request
+def before_request():
+ g.db = connect_db()
+
+def teardown_request(exception):
+ g.db.close()
+
+def write_entry(title, text):
+ g.db.execute('insert into entries (title, text) values (?, ?)',
+ [title, text])
+ g.db.commit()
+
+def get_all_entries():
+ cur = g.db.execute('select title, text from entries order by id desc')
+ entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
+ return entries
+
+@app.route('/')
+def show_entries():
+ entries = get_all_entries()
+ return render_template('show_entries.html', entries=entries)
+
+
+if __name__ == '__main__':
+ app.run(debug=True)
diff --git a/assignments/week05/lab/flaskr_2/flaskr_tests.py b/assignments/week05/lab/flaskr_2/flaskr_tests.py
index 50fef94d..71c3dcd2 100644
--- a/assignments/week05/lab/flaskr_2/flaskr_tests.py
+++ b/assignments/week05/lab/flaskr_2/flaskr_tests.py
@@ -1,28 +1,69 @@
-import os
-import flaskr
-import unittest
-import tempfile
-
-
-class FlaskrTestCase(unittest.TestCase):
-
- def setUp(self):
- self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
- flaskr.app.config['TESTING'] = True
- self.client = flaskr.app.test_client()
- self.app = flaskr.app
- flaskr.init_db()
-
- def tearDown(self):
- os.close(self.db_fd)
- os.unlink(flaskr.app.config['DATABASE'])
-
- def test_database_setup(self):
- con = flaskr.connect_db()
- cur = con.execute('PRAGMA table_info(entries);')
- rows = cur.fetchall()
- self.assertTrue(len(rows) == 3)
-
-
-if __name__ == '__main__':
+import os
+import flaskr
+import unittest
+import tempfile
+
+
+class FlaskrTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
+ flaskr.app.config['TESTING'] = True
+ self.client = flaskr.app.test_client()
+ self.app = flaskr.app
+ flaskr.init_db()
+
+ def tearDown(self):
+ os.close(self.db_fd)
+ os.unlink(flaskr.app.config['DATABASE'])
+
+ def test_database_setup(self):
+ con = flaskr.connect_db()
+ cur = con.execute('PRAGMA table_info(entries);')
+ rows = cur.fetchall()
+ self.assertTrue(len(rows) == 3)
+
+ def test_write_entry(self):
+ expected = ("My Title", "My Text")
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.write_entry(*expected)
+ con = flaskr.connect_db()
+ cur = con.execute("select * from entries;")
+ rows = cur.fetchall()
+ self.assertEquals(len(rows), 1)
+ for val in expected:
+ self.assertTrue(val in rows[0])
+
+ def test_get_all_entries_empty(self):
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ entries = flaskr.get_all_entries()
+ self.assertEquals(len(entries), 0)
+
+ def test_get_all_entries(self):
+ expected = ("My Title", "My Text")
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.write_entry(*expected)
+ entries = flaskr.get_all_entries()
+ self.assertEquals(len(entries), 1)
+ for entry in entries:
+ self.assertEquals(expected[0], entry['title'])
+ self.assertEquals(expected[1], entry['text'])
+
+ def test_empty_listing(self):
+ rv = self.client.get('/')
+ assert 'No entries here so far' in rv.data
+
+ def test_listing(self):
+ expected = ("My Title", "My Text")
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.write_entry(*expected)
+ rv = self.client.get('/')
+ for value in expected:
+ assert value in rv.data
+
+if __name__ == '__main__':
unittest.main()
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_2/templates/layout.html b/assignments/week05/lab/flaskr_2/templates/layout.html
new file mode 100644
index 00000000..50f79fe9
--- /dev/null
+++ b/assignments/week05/lab/flaskr_2/templates/layout.html
@@ -0,0 +1,12 @@
+
+
+
+ Flaskr
+
+
+
Flaskr
+
+ {% block body %}{% endblock %}
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_2/templates/show_entries.html b/assignments/week05/lab/flaskr_2/templates/show_entries.html
new file mode 100644
index 00000000..fe4bf872
--- /dev/null
+++ b/assignments/week05/lab/flaskr_2/templates/show_entries.html
@@ -0,0 +1,15 @@
+{% extends "layout.html" %}
+{% block body %}
+
Posts
+
+ {% for entry in entries %}
+
+
{{ entry.title }}
+
+ {{ entry.text|safe }}
+
+
+ {% else %}
+
No entries here so far
+ {% endfor %}
+
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_3/flaskr.py b/assignments/week05/lab/flaskr_3/flaskr.py
index 70fed771..fe7ee2d1 100644
--- a/assignments/week05/lab/flaskr_3/flaskr.py
+++ b/assignments/week05/lab/flaskr_3/flaskr.py
@@ -1,50 +1,95 @@
-import sqlite3
-from contextlib import closing
-
-from flask import Flask
-from flask import g
-
-
-# configuration goes here
-DATABASE = '/tmp/flaskr.db'
-SECRET_KEY = 'development key'
-
-app = Flask(__name__)
-app.config.from_object(__name__)
-
-
-def connect_db():
- return sqlite3.connect(app.config['DATABASE'])
-
-
-def init_db():
- with closing(connect_db()) as db:
- with app.open_resource('schema.sql') as f:
- db.cursor().executescript(f.read())
- db.commit()
-
-
-@app.before_request
-def before_request():
- g.db = connect_db()
-
-
-@app.teardown_request
-def teardown_request(exception):
- g.db.close()
-
-
-def write_entry(title, text):
- g.db.execute('insert into entries (title, text) values (?, ?)',
- [title, text])
- g.db.commit()
-
-
-def get_all_entries():
- cur = g.db.execute('select title, text from entries order by id desc')
- entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
- return entries
-
-
-if __name__ == '__main__':
- app.run(debug=True)
+import sqlite3
+from contextlib import closing
+
+from flask import Flask
+from flask import g
+from flask import render_template
+from flask import session
+from flask import request
+from flask import redirect
+from flask import flash
+from flask import url_for
+from flask import abort
+
+# configuration goes here
+DATABASE = '/tmp/flaskr.db'
+SECRET_KEY = 'development key'
+USERNAME = 'admin'
+PASSWORD = 'default'
+
+app = Flask(__name__)
+app.config.from_object(__name__)
+
+def connect_db():
+ return sqlite3.connect(app.config['DATABASE'])
+
+def init_db():
+ with closing(connect_db()) as db:
+ with app.open_resource('schema.sql') as f:
+ db.cursor().executescript(f.read())
+ db.commit()
+
+@app.before_request
+def before_request():
+ g.db = connect_db()
+
+@app.teardown_request
+def teardown_request(exception):
+ g.db.close()
+
+def write_entry(title, text):
+ g.db.execute('insert into entries (title, text) values (?, ?)',
+ [title, text])
+ g.db.commit()
+
+def get_all_entries():
+ cur = g.db.execute('select title, text from entries order by id desc')
+ entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
+ return entries
+
+@app.route('/')
+def show_entries():
+ entries = get_all_entries()
+ return render_template('show_entries.html', entries=entries)
+
+def do_login(usr, pwd):
+ if usr != app.config['USERNAME']:
+ raise ValueError
+ elif pwd != app.config['PASSWORD']:
+ raise ValueError
+ else:
+ session['logged_in'] = True
+
+@app.route('/login', methods=['GET', 'POST'])
+def login():
+ error = None
+ if request.method == 'POST':
+ try:
+ do_login(request.form['username'],
+ request.form['password'])
+ except ValueError:
+ error = "Invalid Login"
+ else:
+ flash('You were logged in')
+ return redirect(url_for('show_entries'))
+ return render_template('login.html', error=error)
+
+@app.route('/logout')
+def logout():
+ session.pop('logged_in', None)
+ flash('You were logged out')
+ return redirect(url_for('show_entries'))
+
+@app.route('/add', methods=['POST'])
+def add_entry():
+ if not session.get('logged_in'):
+ abort(401)
+ try:
+ write_entry(request.form['title'], request.form['text'])
+ flash('New entry was successfully posted')
+ except sqlite3.Error as e:
+ flash('There was an error: %s' % e.args[0])
+ return redirect(url_for('show_entries'))
+
+if __name__ == '__main__':
+ app.run(debug=True)
diff --git a/assignments/week05/lab/flaskr_3/flaskr_tests.py b/assignments/week05/lab/flaskr_3/flaskr_tests.py
index 4065dd31..a06b3514 100644
--- a/assignments/week05/lab/flaskr_3/flaskr_tests.py
+++ b/assignments/week05/lab/flaskr_3/flaskr_tests.py
@@ -1,59 +1,115 @@
-import os
-import flaskr
-import unittest
-import tempfile
-
-
-class FlaskrTestCase(unittest.TestCase):
-
- def setUp(self):
- self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
- flaskr.app.config['TESTING'] = True
- self.client = flaskr.app.test_client()
- self.app = flaskr.app
- flaskr.init_db()
-
- def tearDown(self):
- os.close(self.db_fd)
- os.unlink(flaskr.app.config['DATABASE'])
-
- def test_database_setup(self):
- con = flaskr.connect_db()
- cur = con.execute('PRAGMA table_info(entries);')
- rows = cur.fetchall()
- self.assertEqual(len(rows), 3)
-
- def test_write_entry(self):
- expected = ("My Title", "My Text")
- with self.app.test_request_context('/'):
- self.app.preprocess_request()
- flaskr.write_entry(*expected)
- con = flaskr.connect_db()
- cur = con.execute("select * from entries;")
- rows = cur.fetchall()
- self.assertEquals(len(rows), 1)
- for val in expected:
- self.assertTrue(val in rows[0])
-
-
- def test_get_all_entries_empty(self):
- with self.app.test_request_context('/'):
- self.app.preprocess_request()
- entries = flaskr.get_all_entries()
- self.assertEquals(len(entries), 0)
-
-
- def test_get_all_entries(self):
- expected = ("My Title", "My Text")
- with self.app.test_request_context('/'):
- self.app.preprocess_request()
- flaskr.write_entry(*expected)
- entries = flaskr.get_all_entries()
- self.assertEquals(len(entries), 1)
- for entry in entries:
- self.assertEquals(expected[0], entry['title'])
- self.assertEquals(expected[1], entry['text'])
-
-
-if __name__ == '__main__':
+import os
+import flaskr
+import unittest
+import tempfile
+
+
+class FlaskrTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
+ flaskr.app.config['TESTING'] = True
+ self.client = flaskr.app.test_client()
+ self.app = flaskr.app
+ flaskr.init_db()
+
+ def tearDown(self):
+ os.close(self.db_fd)
+ os.unlink(flaskr.app.config['DATABASE'])
+
+ def test_database_setup(self):
+ con = flaskr.connect_db()
+ cur = con.execute('PRAGMA table_info(entries);')
+ rows = cur.fetchall()
+ self.assertEqual(len(rows), 3)
+
+ def test_write_entry(self):
+ expected = ("My Title", "My Text")
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.write_entry(*expected)
+ con = flaskr.connect_db()
+ cur = con.execute("select * from entries;")
+ rows = cur.fetchall()
+ self.assertEquals(len(rows), 1)
+ for val in expected:
+ self.assertTrue(val in rows[0])
+
+
+ def test_get_all_entries_empty(self):
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ entries = flaskr.get_all_entries()
+ self.assertEquals(len(entries), 0)
+
+
+ def test_get_all_entries(self):
+ expected = ("My Title", "My Text")
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.write_entry(*expected)
+ entries = flaskr.get_all_entries()
+ self.assertEquals(len(entries), 1)
+ for entry in entries:
+ self.assertEquals(expected[0], entry['title'])
+ self.assertEquals(expected[1], entry['text'])
+
+ def test_empty_listing(self):
+ rv = self.client.get('/')
+ assert 'No entries here so far' in rv.data
+
+ def test_listing(self):
+ expected = ("My Title", "My Text")
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.write_entry(*expected)
+ rv = self.client.get('/')
+ for value in expected:
+ assert value in rv.data
+
+ def test_login_passes(self):
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ flaskr.do_login(flaskr.app.config['USERNAME'],
+ flaskr.app.config['PASSWORD'])
+ self.assertTrue(session.get('logged_in', False))
+
+ def test_login_fails(self):
+ with self.app.test_request_context('/'):
+ self.app.preprocess_request()
+ self.assertRaises(ValueError, flaskr.do_login,
+ flaskr.app.config['USERNAME'],
+ 'incorrectpassword')
+
+ def login(self, username, password):
+ return self.client.post('/login', data=dict(
+ username=username,
+ password=password
+ ), follow_redirects=True)
+
+ def logout(self):
+ return self.client.get('/logout', follow_redirects=True)
+
+ def test_login_logout(self):
+ rv = self.login('admin', 'default')
+ assert 'You were logged in' in rv.data
+ rv = self.logout()
+ assert 'You were logged out' in rv.data
+ rv = self.login('adminx', 'default')
+ assert 'Invalid Login' in rv.data
+ rv = self.login('admin', 'defaultx')
+ assert 'Invalid Login' in rv.data
+
+ def test_add_entries(self):
+ self.login('admin', 'default')
+ rv = self.client.post('/add', data=dict(
+ title='Hello',
+ text='This is a post'
+ ), follow_redirects=True)
+ assert 'No entries here so far' not in rv.data
+ assert 'Hello' in rv.data
+ assert 'This is a post' in rv.data
+
+
+if __name__ == '__main__':
unittest.main()
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_3/templates/New Text Document.txt b/assignments/week05/lab/flaskr_3/templates/New Text Document.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/assignments/week05/lab/flaskr_3/templates/layout.html b/assignments/week05/lab/flaskr_3/templates/layout.html
new file mode 100644
index 00000000..50f79fe9
--- /dev/null
+++ b/assignments/week05/lab/flaskr_3/templates/layout.html
@@ -0,0 +1,12 @@
+
+
+
+ Flaskr
+
+
+
Flaskr
+
+ {% block body %}{% endblock %}
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_3/templates/login.html b/assignments/week05/lab/flaskr_3/templates/login.html
new file mode 100644
index 00000000..2bbd936a
--- /dev/null
+++ b/assignments/week05/lab/flaskr_3/templates/login.html
@@ -0,0 +1,32 @@
+{% extends "layout.html" %}
+{% block body %}
+
Login
+ {% if error -%}
+
Error {{ error }}
+ {%- endif %}
+
+
+
Flaskr
+
+{% if not session.logged_in %}
+ log in
+{% else %}
+ log_out
+{% endif %}
+
+{% for message in get_flashed_messages() %}
+
{{ message }}
+{% endfor %}
+
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_3/templates/show_entries.html b/assignments/week05/lab/flaskr_3/templates/show_entries.html
new file mode 100644
index 00000000..3f7ba5f5
--- /dev/null
+++ b/assignments/week05/lab/flaskr_3/templates/show_entries.html
@@ -0,0 +1,33 @@
+{% extends "layout.html" %}
+{% block body %}
+
Posts
+
+ {% for entry in entries %}
+
+
{{ entry.title }}
+
+ {{ entry.text|safe }}
+
+
+ {% else %}
+
No entries here so far
+ {% endfor %}
+
+
+{% block body %}
+{% if session.logged_in %}
+
+{% endif %}
+
Posts
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_4/flaskr.py b/assignments/week05/lab/flaskr_4/flaskr.py
index d2a859ab..ae3cc873 100644
--- a/assignments/week05/lab/flaskr_4/flaskr.py
+++ b/assignments/week05/lab/flaskr_4/flaskr.py
@@ -105,3 +105,4 @@ def add_entry():
if __name__ == '__main__':
app.run(debug=True)
+ app.run(host = '0.0.0.0')
diff --git a/assignments/week06/athome/README.txt b/assignments/week06/athome/README.txt
new file mode 100644
index 00000000..e1e1b7e5
--- /dev/null
+++ b/assignments/week06/athome/README.txt
@@ -0,0 +1,7 @@
+I was able to finish the tasks except the form (posting a new blog entry) and the dynamic filtering.
+
+I will try to work on it the next 2 days but not sure if I will be able to get it right.
+
+Thanks,
+
+Allen Su
\ No newline at end of file
diff --git a/assignments/week06/athome/djangor/__init__.py b/assignments/week06/athome/djangor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/assignments/week06/athome/djangor/admin.py b/assignments/week06/athome/djangor/admin.py
new file mode 100644
index 00000000..dc2d1bf6
--- /dev/null
+++ b/assignments/week06/athome/djangor/admin.py
@@ -0,0 +1,10 @@
+from django.contrib import admin
+from djangor.models import BlogPost
+
+class BlogAdmin(admin.ModelAdmin):
+ list_display = ('pub_date', 'title',
+ 'published_today', 'owner')
+ list_filter = ('pub_date', )
+ ordering = ('pub_date', )
+
+admin.site.register(BlogPost, BlogAdmin)
\ No newline at end of file
diff --git a/assignments/week06/athome/djangor/models.py b/assignments/week06/athome/djangor/models.py
new file mode 100644
index 00000000..6f45ee4e
--- /dev/null
+++ b/assignments/week06/athome/djangor/models.py
@@ -0,0 +1,20 @@
+from django.db import models
+from django.utils import timezone
+from django.contrib.auth.models import User
+
+class BlogPost(models.Model):
+ title = models.CharField(max_length=200)
+ body = models.CharField(max_length=2000)
+ pub_date = models.DateTimeField('date published')
+ owner = models.ForeignKey(User)
+
+ def __unicode__(self):
+ return self.title
+
+ def published_today(self):
+ now = timezone.now()
+ time_delta = now - self.pub_date
+ return time_delta.days == 0
+ published_today.boolean = True
+ published_today.short_description = "Published Today?"
+
diff --git a/assignments/week06/athome/djangor/templates/base.html b/assignments/week06/athome/djangor/templates/base.html
new file mode 100644
index 00000000..f89925eb
--- /dev/null
+++ b/assignments/week06/athome/djangor/templates/base.html
@@ -0,0 +1,20 @@
+
+
+
+ My Site
+
+
+
+
+ {% if messages %}
+ {% for message in messages %}
+
+
+
diff --git a/assignments/week06/athome/djangor/templates/blogs/New Text Document.txt b/assignments/week06/athome/djangor/templates/blogs/New Text Document.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/assignments/week06/athome/djangor/templates/blogs/detail.html b/assignments/week06/athome/djangor/templates/blogs/detail.html
new file mode 100644
index 00000000..dd75cde4
--- /dev/null
+++ b/assignments/week06/athome/djangor/templates/blogs/detail.html
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+
+{% block content %}
+
{{ title }}
+
{{ date }}
+
+{{ body }}
+
+Back to the Blog Entries, please
+{% endblock %}
\ No newline at end of file
diff --git a/assignments/week06/athome/djangor/templates/blogs/list.html b/assignments/week06/athome/djangor/templates/blogs/list.html
new file mode 100644
index 00000000..3ddce447
--- /dev/null
+++ b/assignments/week06/athome/djangor/templates/blogs/list.html
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block content %}
+