The J! Archive is created by fans, for fans. The Jeopardy! game show and all elements thereof, including but not limited to copyright and trademark thereto, are the property of Jeopardy Productions, Inc. and are protected under law. This website is not affiliated with, sponsored by, or operated by Jeopardy Productions, Inc. Join the discussion at JBoard.tv.
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week01/athome/python/athome/play_jeopary_with_hints.py b/assignments/week01/athome/python/athome/play_jeopary_with_hints.py
new file mode 100644
index 00000000..975226b8
--- /dev/null
+++ b/assignments/week01/athome/python/athome/play_jeopary_with_hints.py
@@ -0,0 +1,89 @@
+from bs4 import BeautifulSoup
+import urllib2
+from get_jarchive import *
+import urllib
+
+bs = get_jarchive_html(True)
+categories = get_categories(bs)
+clue_dictionary = get_clues(bs, categories)
+
+
+def start_game():
+ print "Welcome to Jeopardy with Hints. v0.1 \nIn this version of Jeopardy we supply you with hints pulled from various sources on the web.\nIf you need help just type "'"hintme"'" once you are at the answer prompt"
+ name = raw_input("Great, now that that's out of the way, please input your name: ")
+ print "Welcome to Jeopardy, ", name
+
+#TODO Implement question picking
+
+def ask_questions_for_category():
+
+ print "In this version of Jeopardy, you don't get to select the clues. You select the category and then answer all questions from lowest dollar amount to highest."
+ print "In order to get started, please take a look at the categories for the Jeopardy round!"
+
+ while len(categories) > 7:
+ print "Here are the categories:"
+ for x in range (0,((len(categories) - 7))):
+ print str(x) + ":" + categories[x]
+ category = raw_input("Please type in the category number to select your category: ")
+ category = int(category)
+ print "Great! You selected: ", categories[category]
+ #Remove category from list
+ del categories[category]
+ #Start with $100
+ print "Now we're going to get started with the $100 question for this category"
+ #clue_name = "clue_" + str(round) + "_"+ str(category_number) + "_" + str(row)
+ for x in range (1,6):
+ clue = "clue_J_" + str(category+1) + "_" + str(x)
+ #print clue
+ print "The clue for {0} is:\n\n{1}".format(clue_dictionary[clue]["dollar_value"],clue_dictionary[clue]["clue_text"])
+ answer = raw_input("\nPlease enter your answer or "'"hintme"'": ")
+ if answer == "hintme":
+ print "\nGetting hint information..."
+ hint_text = get_hint_text(clue,clue_dictionary)
+ display_hint_text(hint_text,clue_dictionary,clue)
+ elif answer == clue_dictionary[clue]["correct_answer"]:
+ print "\nYou are CORRECT! Adding {0} to the bank!".format(clue_dictionary[clue]["dollar_value"])
+ else:
+ print "\nSorry, that was not an exact match to the question.\nI'll need to match input better in the future.\nThe correct answer is: {0}.".format(clue_dictionary[clue]["correct_answer"])
+
+def get_hint_text(clue,clue_dictionary):
+ correct_answer = clue_dictionary[clue]["correct_answer"]
+ opener = urllib2.build_opener()
+ url = "https://www.googleapis.com/freebase/v1/text/en/" + correct_answer.lower()
+ print url
+ resource = opener.open(url)
+ data = resource.read()
+ resource.close()
+ return data
+
+ '''correct_answer = clue_dictionary[clue]["correct_answer"]
+ url_ending = urllib.quote(correct_answer)
+ opener = urllib2.build_opener()
+ opener.addheaders = [('User-agent', 'Mozilla/5.0')] #wikipedia needs this
+ resource = opener.open("http://en.wikipedia.org/wiki/" + url_ending)
+ data = resource.read()
+ resource.close()
+ soup = BeautifulSoup(data)
+ return soup.find('div',id="bodyContent").p'''
+
+def display_hint_text(hint_text, clue_dictionary, clue):
+ print "I'll show you word by word the first paragraph from Wikipedia.\nIf the correct answer is within the paragraph, you will see "'"CORRECTANSWER"'" output.\nHit "'"q"'" to stop and then enter your answer. Press any key to continue to the next word."
+ string = hint_text
+ words = string.split(" ")
+ x = len(words)
+ i = 0
+ while i < x:
+ input = raw_input()
+ if input == "q":
+ print "Hope the hints helped!"
+ break
+ else:
+ if clue_dictionary[clue]["correct_answer"] in words[i]:
+ print "CORRECTANSWER"
+ else:
+ print words[i]
+ i = i + 1
+
+start_game()
+ask_questions_for_category()
+
diff --git a/assignments/week01/athome/python/lab/bs_jarchive.py b/assignments/week01/athome/python/lab/bs_jarchive.py
new file mode 100644
index 00000000..3b604d51
--- /dev/null
+++ b/assignments/week01/athome/python/lab/bs_jarchive.py
@@ -0,0 +1,83 @@
+from bs4 import BeautifulSoup
+import urllib2
+
+
+response = urllib2.urlopen("http://www.j-archive.com/showgame.php?game_id=1337")
+html = response.read()
+bs_html = BeautifulSoup(html)
+
+#print bs_html
+
+def get_categories(bs):
+ #
EUROPE
+ allCategories = bs.findAll('td', {"class" : "category_name"})
+ #TODO: Get Category Comments as well--might be helpful for the
+ #
+ #allCategoryComments = bs.findAll('td', {"class" : "category_comments"})
+ categoriess = [] # List of All Categories
+ for cat in allCategories:
+ cats.append(cat.text)
+ return categories
+
+def get_clues(bs):
+ allClues = bs.findAll(attrs={"class" : "clue"})
+ for clue in allClues:
+ if clue.find("div"):
+ if clue.find(attrs={"class" : "clue_value"}) is not None:
+ dollar_value = clue.find(attrs={"class" : "clue_value"}).text
+ else:
+ dollar_value = clue.find(attrs={"class": "clue_value_daily_double"}).text
+ clue_text = clue.find(attrs={"class" : "clue_text"}).text
+ div = clue.find("div")
+ mouseover_js = div['onmouseover'].split(",",2)
+ answer_soup = BeautifulSoup(mouseover_js[2])
+ answer = answer_soup.find('em', {"class" : "correct_response"}).text
+ round_dict = {}
+
+
+ print dollar_value
+ print clue_text
+ print answer
+ else:
+ print "NO CLUE HERE!"
+ #clue_props = mouseover_js[1].split("_") #contains the unique ID of the clue for this specific game
+ #format: clue_["DJ"||"J"]_[Category(1-6]]_[Row(1-5)]
+
+
+#get_categories(bs_html)
+get_clues(bs_html)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+''' if div:
+ #Split the JS statement into it's arguments so we can extract the html from the final argument
+ mouseover_js = div['onmouseover'].split(",",2)
+ answer_soup = BeautifulSoup(mouseover_js[2]) #We need to go... deeper
+ answer = answer_soup.find('em', {"class" : "correct_response"}).text
+
+ clue_props = mouseover_js[1].split("_") #contains the unique ID of the clue for this specific game
+ #format: clue_["DJ"||"J"]_[Category(1-6]]_[Row(1-5)]
+
+ #Now to figure out the category
+ cat = cats[int(clue_props[2])-1]
+
+ #Are we in double jeopardy?
+ dj = clue_props[1] == "DJ"
+
+ #The class name for the dollar value varies if it's a daily double
+ dollar_value = clue.find(attrs={"class" : re.compile('clue_value*')}).text
+ clue_text = clue.find(attrs={"class" : "clue_text"}).text
+
+ return {"answer" : answer, "category" : cat, "text" : clue_text, "dollar_value": dollar_value}
+'''
\ No newline at end of file
diff --git a/assignments/week01/athome/python/lab/echo_server.py b/assignments/week01/athome/python/lab/echo_server.py
new file mode 100644
index 00000000..3eb3400f
--- /dev/null
+++ b/assignments/week01/athome/python/lab/echo_server.py
@@ -0,0 +1,25 @@
+#!/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/week01/athome/python/lab/http_serve1.py b/assignments/week01/athome/python/lab/http_serve1.py
new file mode 100644
index 00000000..5e8a8099
--- /dev/null
+++ b/assignments/week01/athome/python/lab/http_serve1.py
@@ -0,0 +1,27 @@
+#!/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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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(http_data)
+ client.close()
\ No newline at end of file
diff --git a/assignments/week01/athome/python/lab/http_serve2.py b/assignments/week01/athome/python/lab/http_serve2.py
new file mode 100644
index 00000000..e97624e5
--- /dev/null
+++ b/assignments/week01/athome/python/lab/http_serve2.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+import socket
+import email
+
+#"Wed, 09 Feb 1994 22:23:32 GMT"
+def get_date():
+ date = str(email.Utils.formatdate())
+ return date
+
+
+def ok_response(body):
+ date = get_date()
+ return_data = "HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nDate: {0}\r\n\r\n{1}".format(date,body)
+ return (return_data)
+
+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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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(ok_response(http_data))
+ client.close()
\ No newline at end of file
diff --git a/assignments/week01/athome/python/lab/http_serve3.py b/assignments/week01/athome/python/lab/http_serve3.py
new file mode 100644
index 00000000..a8e80688
--- /dev/null
+++ b/assignments/week01/athome/python/lab/http_serve3.py
@@ -0,0 +1,158 @@
+from bs4 import BeautifulSoup
+
+'''
+entries = parsed.find_all('div', class_='feedEntry')
+
+for e in entries:
+ anchor = e.find('a')
+ paragraph = e.find('p', 'discreet')
+ title = anchor.text.strip()
+ url = anchor.attrs['href']
+ print title
+ print url
+ try:
+ print paragraph.text.strip()
+ except AttributeError:
+ print 'Uncategorized'
+ print'''
+#def check_for_string(string, checker):
+
+
+
+def sort_entries(bs):
+ entries = bs.find_all('div', class_='feedEntry')
+ pgsql = []
+ django = []
+ other = []
+
+ for e in entries:
+ anchor = e.find('a')
+ paragraph = e.find('p', 'discreet')
+ text = paragraph.text
+ print text
+ lt = text.lower
+ print lt
+
+ title = anchor.text.strip()
+ url = anchor.attrs['href']
+ print title
+ print url
+ if "postgresql" in paragraph:
+ pgsql.append(e)
+ elif "django" in paragraph.lower:
+ django.append(e)
+ else:
+ other.append(e)
+ return pgsql, django, other
+fh = open('C:/Users/wtb/Desktop/bloglist.html', 'r')
+bs = BeautifulSoup(fh)
+pgsql, django, other = sort_entries(bs)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+'''#!/usr/bin/env python
+
+import socket
+import email
+
+#"Wed, 09 Feb 1994 22:23:32 GMT"
+def get_date():
+ date = str(email.Utils.formatdate())
+ return date
+
+def ok_response(body):
+ date = get_date()
+ return_data = "HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nDate: {0}\r\n\r\n{1}".format(date,body)
+ return (return_data)
+
+def parse_request(request):
+ if "GET" in request and "HTTP" in request:
+ req_list = request.split(" ")
+ uri = req_list[1]
+ print "the uri: ",uri
+ return uri
+ else:
+ raise ValueError('Request was not GET or HTTP')
+
+def client_error_response(request):
+ try:
+ parse_request(request)
+ except ValueError as e:
+ print "There was an error: ", e
+
+
+
+
+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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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_error_response(data)
+ #client.send(ok_response(http_data))
+ client.close()
+
+
+'''
\ No newline at end of file
diff --git a/assignments/week01/athome/python/lab/jarchive.py b/assignments/week01/athome/python/lab/jarchive.py
new file mode 100644
index 00000000..bd45d3a7
--- /dev/null
+++ b/assignments/week01/athome/python/lab/jarchive.py
@@ -0,0 +1,45 @@
+from bs4 import BeautifulSoup
+import urllib2
+
+
+#response = urllib2.urlopen("http://www.j-archive.com/showgame.php?game_id=1337")
+#html = response.read()
+f = open("jparty.html", "r")
+data = f.read()
+print data
+bs_html = BeautifulSoup(data)
+print bs_html
+
+
+#print bs_html
+
+def get_categories(bs):
+ #
EUROPE
+ allCategories = bs.findAll('td', {"class" : "category_name"})
+ #TODO: Get Category Comments as well--might be helpful for the
+ #
+ #allCategoryComments = bs.findAll('td', {"class" : "category_comments"})
+ categories = [] # List of All Categories
+ for cat in allCategories:
+ cats.append(cat.text)
+ return categories
+
+def get_clues(bs):
+ allClues = bs.findAll(attrs={"class" : "clue"})
+ for clue in allClues:
+ dollar_value = clue.find(attrs={"class" : "clue_value"}).text
+ clue_text = clue.find(attrs={"class" : "clue_text"}).text
+ div = clue.find("div")
+ mouseover_js = div['onmouseover'].split(",",2)
+ answer_soup = BeautifulSoup(mouseover_js[2])
+ answer = answer_soup.find('em', {"class" : "correct_response"}).text
+ round_dict = {}
+
+ print clue_text
+ print answer
+ clue_props = mouseover_js[1].split("_") #contains the unique ID of the clue for this specific game
+ #format: clue_["DJ"||"J"]_[Category(1-6]]_[Row(1-5)]
+ print clue_props
+
+#categories = get_categories(bs_html)
+get_clues(bs_html)
diff --git a/assignments/week01/athome/python/lab/tiny_html.html b/assignments/week01/athome/python/lab/tiny_html.html
new file mode 100644
index 00000000..8d4ec08c
--- /dev/null
+++ b/assignments/week01/athome/python/lab/tiny_html.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/assignments/week01/athome/python/lab/web/images/JPEG_example.jpg b/assignments/week01/athome/python/lab/web/images/JPEG_example.jpg
new file mode 100644
index 00000000..13506f01
Binary files /dev/null and b/assignments/week01/athome/python/lab/web/images/JPEG_example.jpg differ
diff --git a/assignments/week01/athome/python/lab/web/images/Sample_Scene_Balls.jpg b/assignments/week01/athome/python/lab/web/images/Sample_Scene_Balls.jpg
new file mode 100644
index 00000000..1c0ccade
Binary files /dev/null and b/assignments/week01/athome/python/lab/web/images/Sample_Scene_Balls.jpg differ
diff --git a/assignments/week01/athome/python/lab/web/images/sample_1.png b/assignments/week01/athome/python/lab/web/images/sample_1.png
new file mode 100644
index 00000000..5b2f52df
Binary files /dev/null and b/assignments/week01/athome/python/lab/web/images/sample_1.png differ
diff --git a/assignments/week01/athome/python/lab/web/make_time.py b/assignments/week01/athome/python/lab/web/make_time.py
new file mode 100644
index 00000000..d3064dd2
--- /dev/null
+++ b/assignments/week01/athome/python/lab/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/week01/athome/python/lab/web/sample.txt b/assignments/week01/athome/python/lab/web/sample.txt
new file mode 100644
index 00000000..1965c7d3
--- /dev/null
+++ b/assignments/week01/athome/python/lab/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/lab/echo_client.py b/assignments/week01/lab/echo_client.py
index b8898436..ac23f23f 100644
--- a/assignments/week01/lab/echo_client.py
+++ b/assignments/week01/lab/echo_client.py
@@ -2,15 +2,20 @@
import sys
# Create a TCP/IP socket
-
+ecs = socket.socket(2,1,0)
# Connect the socket to the port where the server is listening
-server_address = ('localhost', 50000)
+server_address = ('127.0.0.1', 50000)
+#server_address = ('67.214.219.123', 50000)
+ecs.connect(server_address)
+
try:
# Send data
- message = 'This is the message. It will be repeated.'
-
+ message = "5|6"
+ ecs.sendall(message)
# print the response
+ print ecs.recv(64)
finally:
# close the socket to clean up
+ ecs.close()
\ No newline at end of file
diff --git a/assignments/week01/lab/echo_server.py b/assignments/week01/lab/echo_server.py
index e2c52fc6..069c5f89 100644
--- a/assignments/week01/lab/echo_server.py
+++ b/assignments/week01/lab/echo_server.py
@@ -2,18 +2,21 @@
import sys
# Create a TCP/IP socket
-
+ess = socket.socket(2,1,0)
# Bind the socket to the port
-server_address = ('localhost', 50000)
-
+#server_address = ('127.0.0.1', 50000)
+ess.bind(('127.0.0.1', 50000))
# Listen for incoming connections
-
+ess.listen(1)
while True:
# Wait for a connection
-
- try:
+ con, cli = ess.accept()
+ try:
# Receive the data and send it back
-
+ echo = con.recv(64)
+
+ con.sendall(echo)
- finally:
- # Clean up the connection
+ finally:
+ # Clean up the connection
+ con.close()
diff --git a/assignments/week02/lab/class2.py b/assignments/week02/lab/class2.py
new file mode 100644
index 00000000..4ab252ab
--- /dev/null
+++ b/assignments/week02/lab/class2.py
@@ -0,0 +1,37 @@
+import urllib
+import urllib2
+import json
+from pprint import pprint
+
+'''base = 'http://maps.googleapis.com/maps/api/geocode/json'
+addr = '1325 4th Ave, Seattle, WA 98101'
+data = {'address': addr, 'sensor': 'false' }
+query = urllib.urlencode(data)
+res = urllib2.urlopen('?'.join([base, query]))
+response = json.load(res)
+pprint(response)
+
+
+base = 'http://api.techsavvy.io/jobs'
+search = 'python+web'
+res = urllib2.urlopen('/'.join([base, search]))
+response = json.load(res)
+for post in response['data']:
+ for key in sorted(post.keys()):
+ print "%s:\n %s" % (key, post[key])'''
+
+def reverse_lookup(lat,long):
+ base = 'http://maps.googleapis.com/maps/api/geocode/json'
+ latlong = str(lat) + "," + str(long)
+ print latlong
+ data = {'latlong':latlong, 'sensor': 'false'}
+ query = urllib.urlencode(data)
+ print query
+ res = urllib2.urlopen('?'.join([base, query]))
+ response = json.load(res)
+ pprint(response)
+
+reverse_lookup(40.714224,-73.961452)
+
+
+
diff --git a/assignments/week02/lab/http_serve1.py b/assignments/week02/lab/http_serve1.py
new file mode 100644
index 00000000..5e8a8099
--- /dev/null
+++ b/assignments/week02/lab/http_serve1.py
@@ -0,0 +1,27 @@
+#!/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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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(http_data)
+ client.close()
\ No newline at end of file
diff --git a/assignments/week02/lab/http_serve2.py b/assignments/week02/lab/http_serve2.py
new file mode 100644
index 00000000..e97624e5
--- /dev/null
+++ b/assignments/week02/lab/http_serve2.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+import socket
+import email
+
+#"Wed, 09 Feb 1994 22:23:32 GMT"
+def get_date():
+ date = str(email.Utils.formatdate())
+ return date
+
+
+def ok_response(body):
+ date = get_date()
+ return_data = "HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nDate: {0}\r\n\r\n{1}".format(date,body)
+ return (return_data)
+
+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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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(ok_response(http_data))
+ client.close()
\ No newline at end of file
diff --git a/assignments/week02/lab/http_serve3.py b/assignments/week02/lab/http_serve3.py
new file mode 100644
index 00000000..3b0da8a4
--- /dev/null
+++ b/assignments/week02/lab/http_serve3.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+import socket
+import email
+
+#"Wed, 09 Feb 1994 22:23:32 GMT"
+def get_date():
+ date = str(email.Utils.formatdate())
+ return date
+
+def ok_response(body):
+ date = get_date()
+ return_data = "HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nDate: {0}\r\n\r\n{1}".format(date,body)
+ return (return_data)
+
+def parse_request(request):
+ if "GET" in request and "HTTP" in request:
+ req_list = request.split(" ")
+ uri = req_list[1]
+ #print "the uri: ",uri
+ return uri
+ else:
+ raise ValueError('Request was not GET or HTTP')
+
+def client_error_response():
+ return "HTTP/1.0 501 Not Implemented\r\n\r\n"
+
+
+
+
+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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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)
+
+print "starting"
+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 "whupat"
+ try:
+ print "trying to parse"
+ parse_request(data)
+ except ValueError as e:
+ print "exception"
+ client.send(client_error_response())
+ #client.close()
+ #prnt "received: %s, sending it back"%data
+ else:
+ print "hit else"
+ client.send(ok_response(http_data))
+ client.close()
\ No newline at end of file
diff --git a/assignments/week02/lab/http_serve4.py b/assignments/week02/lab/http_serve4.py
new file mode 100644
index 00000000..e3583ca6
--- /dev/null
+++ b/assignments/week02/lab/http_serve4.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+
+import socket
+import email
+import os
+
+#"Wed, 09 Feb 1994 22:23:32 GMT"
+def get_date():
+ date = str(email.Utils.formatdate())
+ return date
+
+def ok_response(body):
+ date = get_date()
+ return_data = "HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nDate: {0}\r\n\r\n{1}".format(date,body)
+ return (return_data)
+
+def parse_request(request):
+ if "GET" in request and "HTTP" in request:
+ req_list = request.split(" ")
+ uri = req_list[1]
+ print "the uri: ",uri
+ return uri
+ else:
+ raise ValueError('Request was not GET or HTTP')
+
+def client_error_response():
+ return "HTTP/1.0 501 Not Implemented\r\n\r\n"
+
+def resolve_uri(uri,body):
+ if "web" in uri:
+ list_web = os.listdir("web")
+ date = get_date()
+ body = str(list_web)
+ return "HTTP/1.0 200 OK\r\n Content-Type: text/html\r\nDate: {0}\r\n\r\n{1}".format(date,body)
+ elif uri == "/":
+ return ok_response(body)
+
+
+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
+
+http_data = "\n\n
This is a header
\n
and this is some regular text
\n
\nand some more\n
\n\n"
+
+## 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
+ try:
+ print "trying to parse"
+ uri = parse_request(data)
+ client.send(resolve_uri(uri, data))
+ except ValueError as e:
+ print "exception"
+ client.send(client_error_response())
+ #client.close()
+ #prnt "received: %s, sending it back"%data
+ else:
+ print "hit else"
+ client.send(ok_response(http_data))
+ client.close()
\ No newline at end of file
diff --git a/assignments/week03/athome/asdf.py b/assignments/week03/athome/asdf.py
new file mode 100644
index 00000000..2d25e199
--- /dev/null
+++ b/assignments/week03/athome/asdf.py
@@ -0,0 +1,9 @@
+from bs4 import BeautifulSoup
+import urllib2
+
+
+response = urllib2.urlopen("http://www.j-archive.com/showgame.php?game_id=1337")
+html = response.read()
+f = open("jparty.html", "wb")
+f.write(html)
+f.close()
diff --git a/assignments/week03/athome/final.html b/assignments/week03/athome/final.html
new file mode 100644
index 00000000..43bf75cb
--- /dev/null
+++ b/assignments/week03/athome/final.html
@@ -0,0 +1,65 @@
+
+
Final Jeopardy! Round
+
+
+
+
+
+
GAY '90s
+
+
+
+
+
+
+
+
+
+
By 1897, as many as half of Seattle's police & firemen had left the city to go there
+
+
+
+
+
+
+
Final scores:
+
+
+
Richard
+
Maureen
+
Bob
+
+
+
$5,601
+
$0
+
$2,500
+
+
+
3-day champion: $23,802
+
3rd place: ladies' & gentlemen's matched watch set from the Club Collection of Daniel Mink watches
+
2nd place: a trip to Dallas, Texas aboard Delta Airlines, with standard and wide-body service, with stay at the Viscount Hotel
The J! Archive is created by fans, for fans. The Jeopardy! game show and all elements thereof, including but not limited to copyright and trademark thereto, are the property of Jeopardy Productions, Inc. and are protected under law. This website is not affiliated with, sponsored by, or operated by Jeopardy Productions, Inc. Join the discussion at JBoard.tv.
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week03/athome/scraper.py b/assignments/week03/athome/scraper.py
new file mode 100644
index 00000000..c7402323
--- /dev/null
+++ b/assignments/week03/athome/scraper.py
@@ -0,0 +1,89 @@
+from bs4 import BeautifulSoup
+import scraperwiki
+import datetime
+import time
+import re
+
+# define the order our columns are displayed in the datastore
+scraperwiki.metadata.save('data_columns', ['air_date','episode', 'category', 'dollar_value', 'text', 'answer','uid'])
+
+seasons_url = 'http://www.j-archive.com/listseasons.php'
+base_url = 'http://www.j-archive.com/'
+
+def scrape_all_seasons(url):
+
+ soup = BeautifulSoup(scraperwiki.scrape(url))
+
+ #Grab all of the seasons listed
+ seasons = soup.find('div', {"id":"content"}).findAll('a')
+ for season in seasons:
+ scrape_season(base_url+season['href'])
+
+def scrape_season(url):
+
+ soup = BeautifulSoup(scraperwiki.scrape(url))
+
+ #Grab the div that contains the content and search for any links
+ episodes = soup.find('div', {"id":"content"}).findAll('a',{"href":re.compile('showgame\.php')})
+ for episode in episodes:
+
+ ep_data = episode.text.split(',')
+ ep_num = ep_data[0][5:len(ep_data[0])]
+
+ #Fuck this is messy
+ air_data = ep_data[1].split('-')
+ air_date = datetime.date (int (air_data[0][12:len(air_data[0])]), int(air_data[1]), int(air_data[2]))
+ timestamp = time.mktime(air_date.timetuple())
+
+ scrape_episode(episode['href'], ep_num, timestamp)
+
+def scrape_episode(url, episode, air_date):
+
+ soup = BeautifulSoup(scraperwiki.scrape(url))
+
+ allCategories = soup.findAll('td', {"class" : "category_name"})
+ cats = [] # List of categories without any html
+ for cat in allCategories:
+ cats.append(cat.text)
+
+ allClues = soup.findAll(attrs={"class" : "clue"})
+ for clue in allClues:
+
+ clue_attribs = get_clue_attribs(clue, cats)
+ if clue_attribs:
+ clue_attribs['air_date'] = air_date
+ clue_attribs['episode'] = episode
+
+ #a shitty unique id but it should do
+ clue_attribs['uid'] = str(episode)+clue_attribs['category']+str(clue_attribs['dollar_value'])
+ scraperwiki.datastore.save(['uid'], clue_attribs)
+
+
+
+def get_clue_attribs(clue, cats):
+ #Because of the way jarchive hides the answers to clues
+ #this is here to keep things a bit more tidy
+ div = clue.find('div')
+
+ if div:
+ #Split the JS statement into it's arguments so we can extract the html from the final argument
+ mouseover_js = div['onmouseover'].split(",",2)
+ answer_soup = BeautifulSoup(mouseover_js[2]) #We need to go... deeper
+ answer = answer_soup.find('em', {"class" : "correct_response"}).text
+
+ clue_props = mouseover_js[1].split("_") #contains the unique ID of the clue for this specific game
+ #format: clue_["DJ"||"J"]_[Category(1-6]]_[Row(1-5)]
+
+ #Now to figure out the category
+ cat = cats[int(clue_props[2])-1]
+
+ #Are we in double jeopardy?
+ dj = clue_props[1] == "DJ"
+
+ #The class name for the dollar value varies if it's a daily double
+ dollar_value = clue.find(attrs={"class" : re.compile('clue_value*')}).text
+ clue_text = clue.find(attrs={"class" : "clue_text"}).text
+
+ return {"answer" : answer, "category" : cat, "text" : clue_text, "dollar_value": dollar_value}
+
+scrape_all_seasons(seasons_url)
diff --git a/assignments/week04/athome/README.txt b/assignments/week04/athome/README.txt
new file mode 100644
index 00000000..3d0c2293
--- /dev/null
+++ b/assignments/week04/athome/README.txt
@@ -0,0 +1,9 @@
+Here is the URL to hit the WSGI book information server:
+
+http://block647040-vrs.blueboxgrid.com:8080/
+
+There are also two servers in the week04/athome folder. The first one (book_wsgi_server.py) was a first cut at the assignment before I really took a look at it. It was a rough working copy, but it didn't have any error handling, and it isn't nearly as elegant as the example provided in the blogpost. The second one is that one that is running on my VM and it is probably superior considering the error handling and general readability. I do have a few comments that I'll list below.
+
+I ran into issues trying to server up images using PIL and the code I have in the original server I created (book_wsgi_server.py). I couldn't figure out a good way to get PIL on my VM via virtualenv. Googling around showed that there are issues with PIL and virtualenv. I'm bummed I couldn't get that up and running live, but I didn't want to contaminate the VM w/PIL...
+
+Also, one thought I had when setting up the image serving--do you have any suggestions on caching the image? If I were to serve it up via WSGI, it doesn't scale very well because with each request to either page, it had to return the image. Ideally it would cache after the first request to the index and then it wouldn't kill the server with each subsequent request. I understand that this isn't a hot webapp that's going to get slammed with traffic, just wondering what others might do if they wanted to cache and use WSGI to serve their content. Middleware?
\ No newline at end of file
diff --git a/assignments/week04/athome/assignment.txt b/assignments/week04/athome/assignment.txt
index 0e043082..f8e5c7d5 100644
--- a/assignments/week04/athome/assignment.txt
+++ b/assignments/week04/athome/assignment.txt
@@ -4,6 +4,7 @@ Using what you've learned this week, Attempt the following:
* Use ``assignments/week04/athome/bookdb.py`` as a data source
* Your app index page should list the books in the db
* Each listing should supply a link to a detail page
+
* Each detail page should list information about the book
HINT:
diff --git a/assignments/week04/athome/book_html.py b/assignments/week04/athome/book_html.py
new file mode 100644
index 00000000..fba20990
--- /dev/null
+++ b/assignments/week04/athome/book_html.py
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+import datetime
+import bookdb
+
+def make_html_for_main_page(titles):
+ """Takes in the titles of the books and the ids. Returns an HTML link for
+ each title in the list of titles. HTML is in this format:
+
+ Title of book id1 "
+
+ Also provides a title and h1 in the HTML.
+ """
+ html = """
+
+ WSGI Server - BookDB
+
+
WSGI - Book Database
+ """
+ i = 0
+ for title in titles:
+ html = html + "{1}
".format(str(titles[i]['id']) , titles[i]['title'])
+ i = i + 1
+ return html + ''
+
+def make_html_for_book_info_page(path, database):
+ """Takes the path from the environ (essentially, whatever the user is requesting via HTTP) and returns
+ HTML of the book details, along with a back button to go one step back in the user's history.
+ HTML is in this format:
+
+
TITLE: title
+
AUTHOR: author
+
ISBN: isbn
+
PUBLISHER: publisher
+
+ """
+ html = """
+
+ Book Info - {0}
+
+
WSGI - Book Database
+ """.format(database[path]["title"])
+
+ back_button_html = ""
+ html = html + "
TITLE: {0}
".format(database[path]["title"]) + "
AUTHOR: {0}
".format(database[path]["author"]) + "
ISBN: {0}
".format(database[path]["isbn"]) + "
PUBLISHER: {0}
".format(database[path]["publisher"]) + back_button_html
+ return html
\ No newline at end of file
diff --git a/assignments/week04/athome/bookdb.py b/assignments/week04/athome/bookdb.py
index 49769f37..4dbd5890 100644
--- a/assignments/week04/athome/bookdb.py
+++ b/assignments/week04/athome/bookdb.py
@@ -37,3 +37,4 @@ def title_info(self, id):
'author' : 'Andrew Hunt, David Thomas',
},
}
+
diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py
new file mode 100644
index 00000000..43042665
--- /dev/null
+++ b/assignments/week04/athome/bookdb_wsgi_server.py
@@ -0,0 +1,155 @@
+#!/usr/bin/python
+import datetime
+import bookdb
+import pprint
+import cStringIO
+from PIL import Image
+body = """
+
+WSGI Server - BookDB
+
+
+
The BookDB
+%s
+
+
+"""
+
+def application(environ, start_response):
+ bookdb = get_titles()
+ titles = get_title_list(bookdb)
+ ids = get_ids(bookdb)
+ path = get_path_info(environ)
+ #This is dangerous--users could just put in /id235rlkasjdf and it would try and make the HTML...
+ #What's the best way to check to see that there is content that can be served for a given URL?
+ #TODO: Figure the above out.
+ #TODO: Incorporate error handling. 404, 500, 501 etc.
+ #Make a method to create the status and headers for a given request?
+ if "id" in path:
+ html = make_html_for_book_info_page(path,database)
+ elif path == "/":
+ html = make_html_for_main_page(titles, ids)
+ elif "books.png" in path:
+ #TODO: create method to return image--this is really quite ugly
+ # Reference for displaying image via WSGI comes from this website. Accessed 1/31/13: http://lost-theory.org/python/dynamicimg.html
+ f = cStringIO.StringIO()
+ img = Image.open("/home/wilson/Projects/training.python_web/assignments/week04/athome/images/books.png", "r")
+ print img.size
+ img.save(f, "PNG")
+ f.seek(0)
+ response_body = f.read()
+ print "rb:", response_body
+ status = '200 OK'
+ response_headers = [('Content-Type', 'image/png'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+ return [response_body]
+ else:
+ html = "
We couldn't find what you were looking for. Sorry.
"
+ response_body = body % (html)
+ status = '200 OK'
+ response_headers = [('Content-Type', 'text/html'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+ return [response_body]
+
+def get_titles():
+ return bookdb.BookDB().titles()
+
+
+def get_title_list(bookdb):
+ titles = []
+ i = 0
+ while i < len(bookdb):
+ titles.append(bookdb[i]['title'])
+ i = i + 1
+ return titles
+
+def get_ids(bookdb):
+ """Returns the ids of all the books in an array."""
+ ids = []
+ i = 0
+ while i < len(bookdb):
+ ids.append(bookdb[i]['id'])
+ i = i + 1
+ return ids
+
+def make_html_for_main_page(titles, ids):
+ """Takes in the titles of the books and the ids. Returns an HTML link for
+ each title in the list of titles. HTML is in this format:
+
+ Title of book id1 "
+
+ """
+ html = ''
+ i = 0
+ for title in titles:
+ html = "{1}
".format(str(ids[i]) ,title) + html
+ i = i + 1
+ return html
+
+def make_html_for_book_info_page(path, bookdb):
+ """Takes the path from the environ (essentially, whatever the user is requesting via HTTP) and returns
+ HTML of the book details, along with a back button to go one step back in the user's history.
+ HTML is in this format:
+
+
TITLE: title
+
AUTHOR: author
+
ISBN: isbn
+
PUBLISHER: publisher
+
+ """
+ #TODO: there is probably a better way of doing this--similar to how the HTML is created for the main page. Maybe in a for loop
+ book_id = path[1:]
+ book_id = str(book_id)
+
+ back_button_html = ""
+ html = "
TITLE: {0}
".format(database[book_id]["title"]) + "
AUTHOR: {0}
".format(database[book_id]["author"]) + "
ISBN: {0}
".format(database[book_id]["isbn"]) + "
PUBLISHER: {0}
".format(database[book_id]["publisher"]) + back_button_html
+ return html
+
+
+def get_path_info(environ):
+ """Returns the PATH_INFO from the request. For a request to the website itself it returns "/". If it can't find the key
+ in the environ dictionary, it returns "Sorry, couldn't find that".
+ """
+ return environ.get("PATH_INFO", "Sorry, couldn't find that.")
+
+
+
+#What's the right way of pulling in bookdb.py? I feel kinda like this is cheating.
+# Is the below the right way?
+# from bookdb.py import *
+#
+database = {
+ 'id1' : {'title' : 'CherryPy Essentials: Rapid Python Web Application Development',
+ 'isbn' : '978-1904811848',
+ 'publisher' : 'Packt Publishing (March 31, 2007)',
+ 'author' : 'Sylvain Hellegouarch',
+ },
+ 'id2' : {'title' : 'Python for Software Design: How to Think Like a Computer Scientist',
+ 'isbn' : '978-0521725965',
+ 'publisher' : 'Cambridge University Press; 1 edition (March 16, 2009)',
+ 'author' : 'Allen B. Downey',
+ },
+ 'id3' : {'title' : 'Foundations of Python Network Programming',
+ 'isbn' : '978-1430230038',
+ 'publisher' : 'Apress; 2 edition (December 21, 2010)',
+ 'author' : 'John Goerzen',
+ },
+ 'id4' : {'title' : 'Python Cookbook, Second Edition',
+ 'isbn' : '978-0-596-00797-3',
+ 'publisher' : 'O''Reilly Media',
+ 'author' : 'Alex Martelli, Anna Ravenscroft, David Ascher',
+ },
+ 'id5' : {'title' : 'The Pragmatic Programmer: From Journeyman to Master',
+ 'isbn' : '978-0201616224',
+ 'publisher' : 'Addison-Wesley Professional (October 30, 1999)',
+ 'author' : 'Andrew Hunt, David Thomas',
+ },
+}
+
+if __name__ == '__main__':
+ from wsgiref.simple_server import make_server
+ srv = make_server('localhost', 8081, application)
+ srv.serve_forever()
+
diff --git a/assignments/week04/athome/bookdb_wsgi_server_PIL_NEEDED.py b/assignments/week04/athome/bookdb_wsgi_server_PIL_NEEDED.py
new file mode 100644
index 00000000..43042665
--- /dev/null
+++ b/assignments/week04/athome/bookdb_wsgi_server_PIL_NEEDED.py
@@ -0,0 +1,155 @@
+#!/usr/bin/python
+import datetime
+import bookdb
+import pprint
+import cStringIO
+from PIL import Image
+body = """
+
+WSGI Server - BookDB
+
+
+
The BookDB
+%s
+
+
+"""
+
+def application(environ, start_response):
+ bookdb = get_titles()
+ titles = get_title_list(bookdb)
+ ids = get_ids(bookdb)
+ path = get_path_info(environ)
+ #This is dangerous--users could just put in /id235rlkasjdf and it would try and make the HTML...
+ #What's the best way to check to see that there is content that can be served for a given URL?
+ #TODO: Figure the above out.
+ #TODO: Incorporate error handling. 404, 500, 501 etc.
+ #Make a method to create the status and headers for a given request?
+ if "id" in path:
+ html = make_html_for_book_info_page(path,database)
+ elif path == "/":
+ html = make_html_for_main_page(titles, ids)
+ elif "books.png" in path:
+ #TODO: create method to return image--this is really quite ugly
+ # Reference for displaying image via WSGI comes from this website. Accessed 1/31/13: http://lost-theory.org/python/dynamicimg.html
+ f = cStringIO.StringIO()
+ img = Image.open("/home/wilson/Projects/training.python_web/assignments/week04/athome/images/books.png", "r")
+ print img.size
+ img.save(f, "PNG")
+ f.seek(0)
+ response_body = f.read()
+ print "rb:", response_body
+ status = '200 OK'
+ response_headers = [('Content-Type', 'image/png'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+ return [response_body]
+ else:
+ html = "
We couldn't find what you were looking for. Sorry.
"
+ response_body = body % (html)
+ status = '200 OK'
+ response_headers = [('Content-Type', 'text/html'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+ return [response_body]
+
+def get_titles():
+ return bookdb.BookDB().titles()
+
+
+def get_title_list(bookdb):
+ titles = []
+ i = 0
+ while i < len(bookdb):
+ titles.append(bookdb[i]['title'])
+ i = i + 1
+ return titles
+
+def get_ids(bookdb):
+ """Returns the ids of all the books in an array."""
+ ids = []
+ i = 0
+ while i < len(bookdb):
+ ids.append(bookdb[i]['id'])
+ i = i + 1
+ return ids
+
+def make_html_for_main_page(titles, ids):
+ """Takes in the titles of the books and the ids. Returns an HTML link for
+ each title in the list of titles. HTML is in this format:
+
+ Title of book id1 "
+
+ """
+ html = ''
+ i = 0
+ for title in titles:
+ html = "{1}
".format(str(ids[i]) ,title) + html
+ i = i + 1
+ return html
+
+def make_html_for_book_info_page(path, bookdb):
+ """Takes the path from the environ (essentially, whatever the user is requesting via HTTP) and returns
+ HTML of the book details, along with a back button to go one step back in the user's history.
+ HTML is in this format:
+
+
TITLE: title
+
AUTHOR: author
+
ISBN: isbn
+
PUBLISHER: publisher
+
+ """
+ #TODO: there is probably a better way of doing this--similar to how the HTML is created for the main page. Maybe in a for loop
+ book_id = path[1:]
+ book_id = str(book_id)
+
+ back_button_html = ""
+ html = "
TITLE: {0}
".format(database[book_id]["title"]) + "
AUTHOR: {0}
".format(database[book_id]["author"]) + "
ISBN: {0}
".format(database[book_id]["isbn"]) + "
PUBLISHER: {0}
".format(database[book_id]["publisher"]) + back_button_html
+ return html
+
+
+def get_path_info(environ):
+ """Returns the PATH_INFO from the request. For a request to the website itself it returns "/". If it can't find the key
+ in the environ dictionary, it returns "Sorry, couldn't find that".
+ """
+ return environ.get("PATH_INFO", "Sorry, couldn't find that.")
+
+
+
+#What's the right way of pulling in bookdb.py? I feel kinda like this is cheating.
+# Is the below the right way?
+# from bookdb.py import *
+#
+database = {
+ 'id1' : {'title' : 'CherryPy Essentials: Rapid Python Web Application Development',
+ 'isbn' : '978-1904811848',
+ 'publisher' : 'Packt Publishing (March 31, 2007)',
+ 'author' : 'Sylvain Hellegouarch',
+ },
+ 'id2' : {'title' : 'Python for Software Design: How to Think Like a Computer Scientist',
+ 'isbn' : '978-0521725965',
+ 'publisher' : 'Cambridge University Press; 1 edition (March 16, 2009)',
+ 'author' : 'Allen B. Downey',
+ },
+ 'id3' : {'title' : 'Foundations of Python Network Programming',
+ 'isbn' : '978-1430230038',
+ 'publisher' : 'Apress; 2 edition (December 21, 2010)',
+ 'author' : 'John Goerzen',
+ },
+ 'id4' : {'title' : 'Python Cookbook, Second Edition',
+ 'isbn' : '978-0-596-00797-3',
+ 'publisher' : 'O''Reilly Media',
+ 'author' : 'Alex Martelli, Anna Ravenscroft, David Ascher',
+ },
+ 'id5' : {'title' : 'The Pragmatic Programmer: From Journeyman to Master',
+ 'isbn' : '978-0201616224',
+ 'publisher' : 'Addison-Wesley Professional (October 30, 1999)',
+ 'author' : 'Andrew Hunt, David Thomas',
+ },
+}
+
+if __name__ == '__main__':
+ from wsgiref.simple_server import make_server
+ srv = make_server('localhost', 8081, application)
+ srv.serve_forever()
+
diff --git a/assignments/week04/athome/example.py b/assignments/week04/athome/example.py
new file mode 100644
index 00000000..b15d28b2
--- /dev/null
+++ b/assignments/week04/athome/example.py
@@ -0,0 +1,75 @@
+from cgi import parse_qs, escape
+import re
+#from book_html import *
+import book_html
+import bookdb
+
+def index(environ, start_response):
+ """This function will be mounted on "/" and display the list of books availabed."""
+ start_response('200 OK', [('Content-Type', 'text/html')])
+ titles = bookdb.BookDB().titles()
+ html = book_html.make_html_for_main_page(titles)
+ return [html]
+
+
+def book_info(environ, start_response):
+ start_response('200 OK', [('Content-Type', 'text/html')])
+ path = environ.get("PATH_INFO", "No path info found.")
+ path = path[1:]
+ database = bookdb.database
+ html = book_html.make_html_for_book_info_page(path,database)
+ return [html]
+
+def image
+
+
+def hello(environ, start_response):
+ """Like the example above, but it uses the name specified in the
+URL."""
+ # get the name from the url if it was specified there.
+ args = environ['myapp.url_args']
+ if args:
+ subject = escape(args[0])
+ else:
+ subject = 'World'
+ start_response('200 OK', [('Content-Type', 'text/html')])
+ return ['''Hello %(subject)s
+ Hello %(subject)s!
+
+''' % {'subject': subject}]
+
+def not_found(environ, start_response):
+ """Called if no URL matches."""
+ start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
+ return ['Not Found']
+
+# map urls to functions
+urls = [
+ (r'^$', index),
+ (r'id[0-9]', book_info),
+]
+
+def application(environ, start_response):
+ """
+ The main WSGI application. Dispatch the current request to
+ the functions from above and store the regular expression
+ captures in the WSGI environment as `myapp.url_args` so that
+ the functions from above can access the url placeholders.
+
+ If nothing matches call the `not_found` function.
+ """
+ path = environ.get('PATH_INFO', '').lstrip('/')
+ print "PATH:", path
+ for regex, callback in urls:
+ match = re.search(regex, path)
+ if match is not None:
+ environ['myapp.url_args'] = match.groups()
+ return callback(environ, start_response)
+ return not_found(environ, start_response)
+
+
+
+if __name__ == '__main__':
+ from wsgiref.simple_server import make_server
+ srv = make_server('localhost', 8080, application)
+ srv.serve_forever()
\ No newline at end of file
diff --git a/assignments/week04/athome/wsgi_book_server.py b/assignments/week04/athome/wsgi_book_server.py
new file mode 100644
index 00000000..1c512b6e
--- /dev/null
+++ b/assignments/week04/athome/wsgi_book_server.py
@@ -0,0 +1,72 @@
+from cgi import parse_qs, escape
+import re
+import book_html
+import bookdb
+
+########################################################################################
+# NOTE: THE SET UP OF THIS SERVER IS BASED ON THE SIMPLE SERVER DESCRIBED ON THIS #
+# WEBSITE: http://lucumr.pocoo.org/2007/5/21/getting-started-with-wsgi/ IN PARTICULAR #
+# THE FUNCTIONS not_found AND application REMAIN UNCHANGED. #
+########################################################################################
+
+def debug_mode(bool):
+ if bool == True:
+ server = 'localhost'
+ else:
+ server = '67.214.219.123' #VM on blueboxgrid
+ return server
+
+def index(environ, start_response):
+ """This function will be mounted on "/" and display the list of books availabed."""
+ start_response('200 OK', [('Content-Type', 'text/html')])
+ titles = bookdb.BookDB().titles()
+ html = book_html.make_html_for_main_page(titles)
+ return [html]
+
+def book_info(environ, start_response):
+ start_response('200 OK', [('Content-Type', 'text/html')])
+ path = environ.get("PATH_INFO", "No path info found.")
+ path = path[1:]
+ database = bookdb.database
+ html = book_html.make_html_for_book_info_page(path,database)
+ return [html]
+
+def image (environ, start_response):
+ start_response('200 OK', [('Content-Type', 'text/html')])
+ path = environ.get("PATH_INFO", "No path info found.")
+ html = book_html.make_html_for_image(path)
+ return [html]
+
+def not_found(environ, start_response):
+ """Called if no URL matches."""
+ start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
+ return ['Not Found']
+
+# map urls to functions
+urls = [
+ (r'^$', index),
+ (r'id[0-9]', book_info),
+]
+
+def application(environ, start_response):
+ """
+ The main WSGI application. Dispatch the current request to
+ the functions from above and store the regular expression
+ captures in the WSGI environment as `myapp.url_args` so that
+ the functions from above can access the url placeholders.
+
+ If nothing matches call the `not_found` function.
+ """
+ path = environ.get('PATH_INFO', '').lstrip('/')
+ for regex, callback in urls:
+ match = re.search(regex, path)
+ if match is not None:
+ environ['myapp.url_args'] = match.groups()
+ return callback(environ, start_response)
+ return not_found(environ, start_response)
+
+if __name__ == '__main__':
+ from wsgiref.simple_server import make_server
+ server_name = debug_mode(True)
+ srv = make_server(server_name, 8080, application)
+ srv.serve_forever()
diff --git a/assignments/week04/athome/wsgi_book_server_no_image.py b/assignments/week04/athome/wsgi_book_server_no_image.py
new file mode 100644
index 00000000..1a377f55
--- /dev/null
+++ b/assignments/week04/athome/wsgi_book_server_no_image.py
@@ -0,0 +1,172 @@
+#!/usr/bin/python
+import datetime
+import bookdb
+import pprint
+
+
+def index(environ, start_response):
+ """This function will be mounted on "/" and display the list of books availabed."""
+ start_response('200 OK', [('Content-Type', 'text/html')])
+
+ return ['''Hello World Application
+ This is the Hello World application:
+
+`continue `_
+
+''']
+
+
+
+
+
+
+
+body = """
+
+WSGI Server - BookDB
+
+
+
The BookDB
+%s
+
+
+"""
+
+def application(environ, start_response):
+ bookdb = get_titles()
+ titles = get_title_list(bookdb)
+ ids = get_ids(bookdb)
+ path = get_path_info(environ)
+ #This is dangerous--users could just put in /id235rlkasjdf and it would try and make the HTML...
+ #What's the best way to check to see that there is content that can be served for a given URL?
+ #TODO: Figure the above out.
+ #TODO: Incorporate error handling. 404, 500, 501 etc.
+ #Make a method to create the status and headers for a given request?
+ if "id" in path:
+ html = make_html_for_book_info_page(path,database)
+ elif path == "/":
+ html = make_html_for_main_page(titles, ids)
+ elif "books.png" in path:
+ #TODO: create method to return image--this is really quite ugly
+ # Reference for displaying image via WSGI comes from this website. Accessed 1/31/13: http://lost-theory.org/python/dynamicimg.html
+ f = cStringIO.StringIO()
+ img = Image.open("/home/wilson/Projects/training.python_web/assignments/week04/athome/images/books.png", "r")
+ print img.size
+ img.save(f, "PNG")
+ f.seek(0)
+ response_body = f.read()
+ print "rb:", response_body
+ status = '200 OK'
+ response_headers = [('Content-Type', 'image/png'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+ return [response_body]
+ else:
+ html = "
We couldn't find what you were looking for. Sorry.
"
+ response_body = body % (html)
+ status = '200 OK'
+ response_headers = [('Content-Type', 'text/html'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+ return [response_body]
+
+def get_titles():
+ return bookdb.BookDB().titles()
+
+
+def get_title_list(bookdb):
+ titles = []
+ i = 0
+ while i < len(bookdb):
+ titles.append(bookdb[i]['title'])
+ i = i + 1
+ return titles
+
+def get_ids(bookdb):
+ """Returns the ids of all the books in an array."""
+ ids = []
+ i = 0
+ while i < len(bookdb):
+ ids.append(bookdb[i]['id'])
+ i = i + 1
+ return ids
+
+def make_html_for_main_page(titles, ids):
+ """Takes in the titles of the books and the ids. Returns an HTML link for
+ each title in the list of titles. HTML is in this format:
+
+ Title of book id1 "
+
+ """
+ html = ''
+ i = 0
+ for title in titles:
+ html = "{1}
".format(str(ids[i]) ,title) + html
+ i = i + 1
+ return html
+
+def make_html_for_book_info_page(path, bookdb):
+ """Takes the path from the environ (essentially, whatever the user is requesting via HTTP) and returns
+ HTML of the book details, along with a back button to go one step back in the user's history.
+ HTML is in this format:
+
+
TITLE: title
+
AUTHOR: author
+
ISBN: isbn
+
PUBLISHER: publisher
+
+ """
+ #TODO: there is probably a better way of doing this--similar to how the HTML is created for the main page. Maybe in a for loop
+ book_id = path[1:]
+ book_id = str(book_id)
+
+ back_button_html = ""
+ html = "
TITLE: {0}
".format(database[book_id]["title"]) + "
AUTHOR: {0}
".format(database[book_id]["author"]) + "
ISBN: {0}
".format(database[book_id]["isbn"]) + "
PUBLISHER: {0}
".format(database[book_id]["publisher"]) + back_button_html
+ return html
+
+
+def get_path_info(environ):
+ """Returns the PATH_INFO from the request. For a request to the website itself it returns "/". If it can't find the key
+ in the environ dictionary, it returns "Sorry, couldn't find that".
+ """
+ return environ.get("PATH_INFO", "Sorry, couldn't find that.")
+
+
+
+#What's the right way of pulling in bookdb.py? I feel kinda like this is cheating.
+# Is the below the right way?
+# from bookdb.py import *
+#
+database = {
+ 'id1' : {'title' : 'CherryPy Essentials: Rapid Python Web Application Development',
+ 'isbn' : '978-1904811848',
+ 'publisher' : 'Packt Publishing (March 31, 2007)',
+ 'author' : 'Sylvain Hellegouarch',
+ },
+ 'id2' : {'title' : 'Python for Software Design: How to Think Like a Computer Scientist',
+ 'isbn' : '978-0521725965',
+ 'publisher' : 'Cambridge University Press; 1 edition (March 16, 2009)',
+ 'author' : 'Allen B. Downey',
+ },
+ 'id3' : {'title' : 'Foundations of Python Network Programming',
+ 'isbn' : '978-1430230038',
+ 'publisher' : 'Apress; 2 edition (December 21, 2010)',
+ 'author' : 'John Goerzen',
+ },
+ 'id4' : {'title' : 'Python Cookbook, Second Edition',
+ 'isbn' : '978-0-596-00797-3',
+ 'publisher' : 'O''Reilly Media',
+ 'author' : 'Alex Martelli, Anna Ravenscroft, David Ascher',
+ },
+ 'id5' : {'title' : 'The Pragmatic Programmer: From Journeyman to Master',
+ 'isbn' : '978-0201616224',
+ 'publisher' : 'Addison-Wesley Professional (October 30, 1999)',
+ 'author' : 'Andrew Hunt, David Thomas',
+ },
+}
+
+if __name__ == '__main__':
+ from wsgiref.simple_server import make_server
+ srv = make_server('localhost', 8081, application)
+ srv.serve_forever()
+
diff --git a/assignments/week04/lab/cgi-bin/lab1_cgi.py b/assignments/week04/lab/cgi-bin/lab1_cgi.py
new file mode 100644
index 00000000..ae6dfe31
--- /dev/null
+++ b/assignments/week04/lab/cgi-bin/lab1_cgi.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+import cgi
+import cgitb
+cgitb.enable()
+import os
+import datetime
+
+
+print "Content-Type: text/html"
+print
+
+body = """
+
+Lab 1 - CGI experiments
+
+
+The server name is %s. (if an IP address, then a DNS problem)
+
+The server address is %s:%s.
+
+Your hostname is %s.
+
+You are coming from %s:%s.
+
+The currenly executing script is %s
+
+The request arrived at %s
+
+
+""" % (
+ os.environ['SERVER_NAME'], # Server Hostname
+ 'aaaa', # server IP
+ 'bbbb', # server port
+ 'cccc', # client hostname
+ 'dddd', # client IP
+ 'eeee', # client port
+ 'ffff', # this script name
+ 'gggg', # time
+ )
+
+print body,
diff --git a/assignments/week04/lab/src/lab2_wsgi_template.py b/assignments/week04/lab/src/lab2_wsgi_template.py
index 476097e7..2d2d559b 100755
--- a/assignments/week04/lab/src/lab2_wsgi_template.py
+++ b/assignments/week04/lab/src/lab2_wsgi_template.py
@@ -3,7 +3,7 @@
body = """
-Lab 2 - WSGI experiments
+WSGI Server - BookDB
diff --git a/assignments/week05/athome/cherry_app.py b/assignments/week05/athome/cherry_app.py
new file mode 100644
index 00000000..d645ac6c
--- /dev/null
+++ b/assignments/week05/athome/cherry_app.py
@@ -0,0 +1,48 @@
+import cherrypy
+from jinja2 import Environment, FileSystemLoader
+import sqlite3
+from contextlib import closing
+
+
+#config for db stuff
+DATABASE = 'C:/tmp/cherrypy.db'
+SECRET_KEY = 'development key'
+
+
+def connect_db():
+ return sqlite3.connect(app.config['DATABASE'])
+
+def init_db():
+ with closing(connect_db()) as db:
+ with
+
+env = Environment(loader=FileSystemLoader('templates'))
+
+class Blog:
+ '''def index(self):
+ tmpl = env.get_template('index.html')
+ return tmpl.render(salutation='Hello', target='World')
+ index.exposed = True'''
+ def connect(thread_index):
+ # Create a connection and store it in the current thread
+ cherrypy.thread_data.db = MySQLdb.connect('host', 'user', 'password', 'dbname')
+
+ def index(self):
+ c = cherrypy.thread_data.db.cursor()
+ c.execute('select count(*) from table')
+ res = c.fetchone()
+ c.close()
+ return "Hello, you have %d records in your table" % res[0]
+
+
+if __name__ == '__main__':
+ # CherryPy always starts with app.root when trying to map request URIs
+ # to objects, so we need to mount a request handler root. A request
+ # to '/' will be mapped to HelloWorld().index().
+ print "main"
+ cherrypy.quickstart(Blog())
+else:
+ print "test"
+ # This branch is for the test suite; you can ignore it.
+ cherrypy.tree.mount(HitCounter())
+
diff --git a/assignments/week05/athome/cherry_app_tests.py.py b/assignments/week05/athome/cherry_app_tests.py.py
new file mode 100644
index 00000000..cb381499
--- /dev/null
+++ b/assignments/week05/athome/cherry_app_tests.py.py
@@ -0,0 +1,26 @@
+import cherrypy
+import os
+import unittest
+import tempfile
+
+class CherryTestCase(unittest.TestCase):
+ def setUp(self):
+ db_fd = tempfile.mkstemp()
+ self.db_fd, cherrypy.config['DATABASE'] = db_fd
+ cherrypy.config['TESTING'] = True
+ self.client = cherrypy.test_client()
+ self.app = cherrypy
+
+ def tearDown(self):
+ os.close(self.db_fd)
+ os.unlink(cherrypy.app.config['DATABASE'])
+
+ def test_databse_setup(self):
+ con = cherrypy.connect_db()
+ cur = con.execute('PRAGMA tablet_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/athome/schema.sql b/assignments/week05/athome/schema.sql
new file mode 100644
index 00000000..a1ab60c1
--- /dev/null
+++ b/assignments/week05/athome/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/athome/templates/index.html b/assignments/week05/athome/templates/index.html
new file mode 100644
index 00000000..5dfb3b2e
--- /dev/null
+++ b/assignments/week05/athome/templates/index.html
@@ -0,0 +1,16 @@
+
+
+
+ My Webpage
+
+
+
+
+
+
+
+
+
My Webpage
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/athome/venv/Scripts/activate b/assignments/week05/athome/venv/Scripts/activate
new file mode 100644
index 00000000..38b6fb98
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/activate
@@ -0,0 +1,80 @@
+# This file must be used with "source bin/activate" *from bash*
+# you cannot run it directly
+
+deactivate () {
+ unset pydoc
+
+ # reset old environment variables
+ if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
+ PATH="$_OLD_VIRTUAL_PATH"
+ export PATH
+ unset _OLD_VIRTUAL_PATH
+ fi
+ if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
+ PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
+ export PYTHONHOME
+ unset _OLD_VIRTUAL_PYTHONHOME
+ fi
+
+ # This should detect bash and zsh, which have a hash command that must
+ # be called to get it to forget past commands. Without forgetting
+ # past commands the $PATH changes we made may not be respected
+ if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+ hash -r 2>/dev/null
+ fi
+
+ if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
+ PS1="$_OLD_VIRTUAL_PS1"
+ export PS1
+ unset _OLD_VIRTUAL_PS1
+ fi
+
+ unset VIRTUAL_ENV
+ if [ ! "$1" = "nondestructive" ] ; then
+ # Self destruct!
+ unset -f deactivate
+ fi
+}
+
+# unset irrelevant variables
+deactivate nondestructive
+
+VIRTUAL_ENV="$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u 'C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv'; else echo '/C/cygwin/home/wtb/training.python_web/assignments/week05/athome/venv'; fi;)"
+export VIRTUAL_ENV
+
+_OLD_VIRTUAL_PATH="$PATH"
+PATH="$VIRTUAL_ENV/Scripts:$PATH"
+export PATH
+
+# unset PYTHONHOME if set
+# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
+# could use `if (set -u; : $PYTHONHOME) ;` in bash
+if [ -n "$PYTHONHOME" ] ; then
+ _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
+ unset PYTHONHOME
+fi
+
+if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
+ _OLD_VIRTUAL_PS1="$PS1"
+ if [ "x" != x ] ; then
+ PS1="$PS1"
+ else
+ if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
+ # special case for Aspen magic directories
+ # see http://www.zetadev.com/software/aspen/
+ PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
+ else
+ PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
+ fi
+ fi
+ export PS1
+fi
+
+alias pydoc="python -m pydoc"
+
+# This should detect bash and zsh, which have a hash command that must
+# be called to get it to forget past commands. Without forgetting
+# past commands the $PATH changes we made may not be respected
+if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+ hash -r 2>/dev/null
+fi
diff --git a/assignments/week05/athome/venv/Scripts/activate.bat b/assignments/week05/athome/venv/Scripts/activate.bat
new file mode 100644
index 00000000..16662039
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/activate.bat
@@ -0,0 +1,26 @@
+@echo off
+set "VIRTUAL_ENV=C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv"
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+) else (
+ if not defined PROMPT (
+ set "PROMPT=$P$G"
+ )
+ set "_OLD_VIRTUAL_PROMPT=%PROMPT%"
+)
+set "PROMPT=(venv) %PROMPT%"
+
+if not defined _OLD_VIRTUAL_PYTHONHOME (
+ set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%"
+)
+set PYTHONHOME=
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+) else (
+ set "_OLD_VIRTUAL_PATH=%PATH%"
+)
+set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%"
+
+:END
diff --git a/assignments/week05/athome/venv/Scripts/activate.ps1 b/assignments/week05/athome/venv/Scripts/activate.ps1
new file mode 100644
index 00000000..e40ca1bf
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/activate.ps1
@@ -0,0 +1,148 @@
+# This file must be dot sourced from PoSh; you cannot run it
+# directly. Do this: . ./activate.ps1
+
+# FIXME: clean up unused vars.
+$script:THIS_PATH = $myinvocation.mycommand.path
+$script:BASE_DIR = split-path (resolve-path "$THIS_PATH/..") -Parent
+$script:DIR_NAME = split-path $BASE_DIR -Leaf
+
+function global:deactivate ( [switch] $NonDestructive ){
+
+ if ( test-path variable:_OLD_VIRTUAL_PATH ) {
+ $env:PATH = $variable:_OLD_VIRTUAL_PATH
+ remove-variable "_OLD_VIRTUAL_PATH" -scope global
+ }
+
+ if ( test-path function:_old_virtual_prompt ) {
+ $function:prompt = $function:_old_virtual_prompt
+ remove-item function:\_old_virtual_prompt
+ }
+
+ if ($env:VIRTUAL_ENV) {
+ $old_env = split-path $env:VIRTUAL_ENV -leaf
+ remove-item env:VIRTUAL_ENV -erroraction silentlycontinue
+ }
+
+ if ( !$NonDestructive ) {
+ # Self destruct!
+ remove-item function:deactivate
+ }
+}
+
+# unset irrelevant variables
+deactivate -nondestructive
+
+$VIRTUAL_ENV = $BASE_DIR
+$env:VIRTUAL_ENV = $VIRTUAL_ENV
+
+$global:_OLD_VIRTUAL_PATH = $env:PATH
+$env:PATH = "$env:VIRTUAL_ENV/Scripts;" + $env:PATH
+function global:_old_virtual_prompt { "" }
+$function:_old_virtual_prompt = $function:prompt
+function global:prompt {
+ # Add a prefix to the current prompt, but don't discard it.
+ write-host "($(split-path $env:VIRTUAL_ENV -leaf)) " -nonewline
+ & $function:_old_virtual_prompt
+}
+
+# SIG # Begin signature block
+# MIISeAYJKoZIhvcNAQcCoIISaTCCEmUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
+# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
+# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUS5reBwSg3zOUwhXf2jPChZzf
+# yPmggg6tMIIGcDCCBFigAwIBAgIBJDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQG
+# EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
+# Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
+# dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjIwMTQ2WhcNMTcxMDI0MjIw
+# MTQ2WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzAp
+# BgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNV
+# BAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgT2JqZWN0
+# IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyiOLIjUemqAbPJ1J
+# 0D8MlzgWKbr4fYlbRVjvhHDtfhFN6RQxq0PjTQxRgWzwFQNKJCdU5ftKoM5N4YSj
+# Id6ZNavcSa6/McVnhDAQm+8H3HWoD030NVOxbjgD/Ih3HaV3/z9159nnvyxQEckR
+# ZfpJB2Kfk6aHqW3JnSvRe+XVZSufDVCe/vtxGSEwKCaNrsLc9pboUoYIC3oyzWoU
+# TZ65+c0H4paR8c8eK/mC914mBo6N0dQ512/bkSdaeY9YaQpGtW/h/W/FkbQRT3sC
+# pttLVlIjnkuY4r9+zvqhToPjxcfDYEf+XD8VGkAqle8Aa8hQ+M1qGdQjAye8OzbV
+# uUOw7wIDAQABo4IB6TCCAeUwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+# AQYwHQYDVR0OBBYEFNBOD0CZbLhLGW87KLjg44gHNKq3MB8GA1UdIwQYMBaAFE4L
+# 7xqkQFulF2mHMMo0aEPQQa7yMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAoYh
+# aHR0cDovL3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3J0MFsGA1UdHwRUMFIwJ6Al
+# oCOGIWh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDAnoCWgI4YhaHR0
+# cDovL2NybC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMIGABgNVHSAEeTB3MHUGCysG
+# AQQBgbU3AQIBMGYwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+# L3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+# L2ludGVybWVkaWF0ZS5wZGYwEQYJYIZIAYb4QgEBBAQDAgABMFAGCWCGSAGG+EIB
+# DQRDFkFTdGFydENvbSBDbGFzcyAyIFByaW1hcnkgSW50ZXJtZWRpYXRlIE9iamVj
+# dCBTaWduaW5nIENlcnRpZmljYXRlczANBgkqhkiG9w0BAQUFAAOCAgEAcnMLA3Va
+# N4OIE9l4QT5OEtZy5PByBit3oHiqQpgVEQo7DHRsjXD5H/IyTivpMikaaeRxIv95
+# baRd4hoUcMwDj4JIjC3WA9FoNFV31SMljEZa66G8RQECdMSSufgfDYu1XQ+cUKxh
+# D3EtLGGcFGjjML7EQv2Iol741rEsycXwIXcryxeiMbU2TPi7X3elbwQMc4JFlJ4B
+# y9FhBzuZB1DV2sN2irGVbC3G/1+S2doPDjL1CaElwRa/T0qkq2vvPxUgryAoCppU
+# FKViw5yoGYC+z1GaesWWiP1eFKAL0wI7IgSvLzU3y1Vp7vsYaxOVBqZtebFTWRHt
+# XjCsFrrQBngt0d33QbQRI5mwgzEp7XJ9xu5d6RVWM4TPRUsd+DDZpBHm9mszvi9g
+# VFb2ZG7qRRXCSqys4+u/NLBPbXi/m/lU00cODQTlC/euwjk9HQtRrXQ/zqsBJS6U
+# J+eLGw1qOfj+HVBl/ZQpfoLk7IoWlRQvRL1s7oirEaqPZUIWY/grXq9r6jDKAp3L
+# ZdKQpPOnnogtqlU4f7/kLjEJhrrc98mrOWmVMK/BuFRAfQ5oDUMnVmCzAzLMjKfG
+# cVW/iMew41yfhgKbwpfzm3LBr1Zv+pEBgcgW6onRLSAn3XHM0eNtz+AkxH6rRf6B
+# 2mYhLEEGLapH8R1AMAo4BbVFOZR5kXcMCwowggg1MIIHHaADAgECAgIEuDANBgkq
+# hkiG9w0BAQUFADCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0
+# ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcx
+# ODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUg
+# T2JqZWN0IENBMB4XDTExMTIwMzE1MzQxOVoXDTEzMTIwMzE0NTgwN1owgYwxIDAe
+# BgNVBA0TFzU4MTc5Ni1HaDd4Zkp4a3hRU0lPNEUwMQswCQYDVQQGEwJERTEPMA0G
+# A1UECBMGQmVybGluMQ8wDQYDVQQHEwZCZXJsaW4xFjAUBgNVBAMTDUphbm5pcyBM
+# ZWlkZWwxITAfBgkqhkiG9w0BCQEWEmphbm5pc0BsZWlkZWwuaW5mbzCCAiIwDQYJ
+# KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMcPeABYdN7nPq/AkZ/EkyUBGx/l2Yui
+# Lfm8ZdLG0ulMb/kQL3fRY7sUjYPyn9S6PhqqlFnNoGHJvbbReCdUC9SIQYmOEjEA
+# raHfb7MZU10NjO4U2DdGucj2zuO5tYxKizizOJF0e4yRQZVxpUGdvkW/+GLjCNK5
+# L7mIv3Z1dagxDKHYZT74HXiS4VFUwHF1k36CwfM2vsetdm46bdgSwV+BCMmZICYT
+# IJAS9UQHD7kP4rik3bFWjUx08NtYYFAVOd/HwBnemUmJe4j3IhZHr0k1+eDG8hDH
+# KVvPgLJIoEjC4iMFk5GWsg5z2ngk0LLu3JZMtckHsnnmBPHQK8a3opUNd8hdMNJx
+# gOwKjQt2JZSGUdIEFCKVDqj0FmdnDMPfwy+FNRtpBMl1sz78dUFhSrnM0D8NXrqa
+# 4rG+2FoOXlmm1rb6AFtpjAKksHRpYcPk2DPGWp/1sWB+dUQkS3gOmwFzyqeTuXpT
+# 0juqd3iAxOGx1VRFQ1VHLLf3AzV4wljBau26I+tu7iXxesVucSdsdQu293jwc2kN
+# xK2JyHCoZH+RyytrwS0qw8t7rMOukU9gwP8mn3X6mgWlVUODMcHTULjSiCEtvyZ/
+# aafcwjUbt4ReEcnmuZtWIha86MTCX7U7e+cnpWG4sIHPnvVTaz9rm8RyBkIxtFCB
+# nQ3FnoQgyxeJAgMBAAGjggOdMIIDmTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIH
+# gDAuBgNVHSUBAf8EJDAiBggrBgEFBQcDAwYKKwYBBAGCNwIBFQYKKwYBBAGCNwoD
+# DTAdBgNVHQ4EFgQUWyCgrIWo8Ifvvm1/YTQIeMU9nc8wHwYDVR0jBBgwFoAU0E4P
+# QJlsuEsZbzsouODjiAc0qrcwggIhBgNVHSAEggIYMIICFDCCAhAGCysGAQQBgbU3
+# AQICMIIB/zAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9s
+# aWN5LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50
+# ZXJtZWRpYXRlLnBkZjCB9wYIKwYBBQUHAgIwgeowJxYgU3RhcnRDb20gQ2VydGlm
+# aWNhdGlvbiBBdXRob3JpdHkwAwIBARqBvlRoaXMgY2VydGlmaWNhdGUgd2FzIGlz
+# c3VlZCBhY2NvcmRpbmcgdG8gdGhlIENsYXNzIDIgVmFsaWRhdGlvbiByZXF1aXJl
+# bWVudHMgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeSwgcmVsaWFuY2Ugb25seSBm
+# b3IgdGhlIGludGVuZGVkIHB1cnBvc2UgaW4gY29tcGxpYW5jZSBvZiB0aGUgcmVs
+# eWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4wgZwGCCsGAQUFBwICMIGPMCcWIFN0YXJ0
+# Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MAMCAQIaZExpYWJpbGl0eSBhbmQg
+# d2FycmFudGllcyBhcmUgbGltaXRlZCEgU2VlIHNlY3Rpb24gIkxlZ2FsIGFuZCBM
+# aW1pdGF0aW9ucyIgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeS4wNgYDVR0fBC8w
+# LTAroCmgJ4YlaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0YzItY3JsLmNybDCB
+# iQYIKwYBBQUHAQEEfTB7MDcGCCsGAQUFBzABhitodHRwOi8vb2NzcC5zdGFydHNz
+# bC5jb20vc3ViL2NsYXNzMi9jb2RlL2NhMEAGCCsGAQUFBzAChjRodHRwOi8vYWlh
+# LnN0YXJ0c3NsLmNvbS9jZXJ0cy9zdWIuY2xhc3MyLmNvZGUuY2EuY3J0MCMGA1Ud
+# EgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tLzANBgkqhkiG9w0BAQUFAAOC
+# AQEAhrzEV6zwoEtKjnFRhCsjwiPykVpo5Eiye77Ve801rQDiRKgSCCiW6g3HqedL
+# OtaSs65Sj2pm3Viea4KR0TECLcbCTgsdaHqw2x1yXwWBQWZEaV6EB05lIwfr94P1
+# SFpV43zkuc+bbmA3+CRK45LOcCNH5Tqq7VGTCAK5iM7tvHwFlbQRl+I6VEL2mjpF
+# NsuRjDOVrv/9qw/a22YJ9R7Y1D0vUSs3IqZx2KMUaYDP7H2mSRxJO2nADQZBtriF
+# gTyfD3lYV12MlIi5CQwe3QC6DrrfSMP33i5Wa/OFJiQ27WPxmScYVhiqozpImFT4
+# PU9goiBv9RKXdgTmZE1PN0NQ5jGCAzUwggMxAgEBMIGTMIGMMQswCQYDVQQGEwJJ
+# TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
+# YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
+# MiBQcmltYXJ5IEludGVybWVkaWF0ZSBPYmplY3QgQ0ECAgS4MAkGBSsOAwIaBQCg
+# eDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEE
+# AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJ
+# BDEWBBRVGw0FDSiaIi38dWteRUAg/9Pr6DANBgkqhkiG9w0BAQEFAASCAgCInvOZ
+# FdaNFzbf6trmFDZKMojyx3UjKMCqNjHVBbuKY0qXwFC/ElYDV1ShJ2CBZbdurydO
+# OQ6cIQ0KREOCwmX/xB49IlLHHUxNhEkVv7HGU3EKAFf9IBt9Yr7jikiR9cjIsfHK
+# 4cjkoKJL7g28yEpLLkHt1eo37f1Ga9lDWEa5Zq3U5yX+IwXhrUBm1h8Xr033FhTR
+# VEpuSz6LHtbrL/zgJnCzJ2ahjtJoYevdcWiNXffosJHFaSfYDDbiNsPRDH/1avmb
+# 5j/7BhP8BcBaR6Fp8tFbNGIcWHHGcjqLMnTc4w13b7b4pDhypqElBa4+lCmwdvv9
+# GydYtRgPz8GHeoBoKj30YBlMzRIfFYaIFGIC4Ai3UEXkuH9TxYohVbGm/W0Kl4Lb
+# RJ1FwiVcLcTOJdgNId2vQvKc+jtNrjcg5SP9h2v/C4aTx8tyc6tE3TOPh2f9b8DL
+# S+SbVArJpuJqrPTxDDoO1QNjTgLcdVYeZDE+r/NjaGZ6cMSd8db3EaG3ijD/0bud
+# SItbm/OlNVbQOFRR76D+ZNgPcU5iNZ3bmvQQIg6aSB9MHUpIE/SeCkNl9YeVk1/1
+# GFULgNMRmIYP4KLvu9ylh5Gu3hvD5VNhH6+FlXANwFy07uXks5uF8mfZVxVCnodG
+# xkNCx+6PsrA5Z7WP4pXcmYnMn97npP/Q9EHJWw==
+# SIG # End signature block
diff --git a/assignments/week05/athome/venv/Scripts/activate_this.py b/assignments/week05/athome/venv/Scripts/activate_this.py
new file mode 100644
index 00000000..ea12c28a
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/activate_this.py
@@ -0,0 +1,34 @@
+"""By using execfile(this_file, dict(__file__=this_file)) you will
+activate this virtualenv environment.
+
+This can be used when you must use an existing Python interpreter, not
+the virtualenv bin/python
+"""
+
+try:
+ __file__
+except NameError:
+ raise AssertionError(
+ "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
+import sys
+import os
+
+old_os_path = os.environ['PATH']
+os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
+base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+if sys.platform == 'win32':
+ site_packages = os.path.join(base, 'Lib', 'site-packages')
+else:
+ site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
+prev_sys_path = list(sys.path)
+import site
+site.addsitedir(site_packages)
+sys.real_prefix = sys.prefix
+sys.prefix = base
+# Move the added items to the front of the path:
+new_sys_path = []
+for item in list(sys.path):
+ if item not in prev_sys_path:
+ new_sys_path.append(item)
+ sys.path.remove(item)
+sys.path[:0] = new_sys_path
diff --git a/assignments/week05/athome/venv/Scripts/cherryd b/assignments/week05/athome/venv/Scripts/cherryd
new file mode 100644
index 00000000..3bad9555
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/cherryd
@@ -0,0 +1,109 @@
+#!C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv\Scripts\python.exe
+"""The CherryPy daemon."""
+
+import sys
+
+import cherrypy
+from cherrypy.process import plugins, servers
+from cherrypy import Application
+
+def start(configfiles=None, daemonize=False, environment=None,
+ fastcgi=False, scgi=False, pidfile=None, imports=None,
+ cgi=False):
+ """Subscribe all engine plugins and start the engine."""
+ sys.path = [''] + sys.path
+ for i in imports or []:
+ exec("import %s" % i)
+
+ for c in configfiles or []:
+ cherrypy.config.update(c)
+ # If there's only one app mounted, merge config into it.
+ if len(cherrypy.tree.apps) == 1:
+ for app in cherrypy.tree.apps.values():
+ if isinstance(app, Application):
+ app.merge(c)
+
+ engine = cherrypy.engine
+
+ if environment is not None:
+ cherrypy.config.update({'environment': environment})
+
+ # Only daemonize if asked to.
+ if daemonize:
+ # Don't print anything to stdout/sterr.
+ cherrypy.config.update({'log.screen': False})
+ plugins.Daemonizer(engine).subscribe()
+
+ if pidfile:
+ plugins.PIDFile(engine, pidfile).subscribe()
+
+ if hasattr(engine, "signal_handler"):
+ engine.signal_handler.subscribe()
+ if hasattr(engine, "console_control_handler"):
+ engine.console_control_handler.subscribe()
+
+ if (fastcgi and (scgi or cgi)) or (scgi and cgi):
+ cherrypy.log.error("You may only specify one of the cgi, fastcgi, and "
+ "scgi options.", 'ENGINE')
+ sys.exit(1)
+ elif fastcgi or scgi or cgi:
+ # Turn off autoreload when using *cgi.
+ cherrypy.config.update({'engine.autoreload_on': False})
+ # Turn off the default HTTP server (which is subscribed by default).
+ cherrypy.server.unsubscribe()
+
+ addr = cherrypy.server.bind_addr
+ if fastcgi:
+ f = servers.FlupFCGIServer(application=cherrypy.tree,
+ bindAddress=addr)
+ elif scgi:
+ f = servers.FlupSCGIServer(application=cherrypy.tree,
+ bindAddress=addr)
+ else:
+ f = servers.FlupCGIServer(application=cherrypy.tree,
+ bindAddress=addr)
+ s = servers.ServerAdapter(engine, httpserver=f, bind_addr=addr)
+ s.subscribe()
+
+ # Always start the engine; this will start all other services
+ try:
+ engine.start()
+ except:
+ # Assume the error has been logged already via bus.log.
+ sys.exit(1)
+ else:
+ engine.block()
+
+
+if __name__ == '__main__':
+ from optparse import OptionParser
+
+ p = OptionParser()
+ p.add_option('-c', '--config', action="http://github.com/append", dest='config',
+ help="specify config file(s)")
+ p.add_option('-d', action="http://github.com/store_true", dest='daemonize',
+ help="run the server as a daemon")
+ p.add_option('-e', '--environment', dest='environment', default=None,
+ help="apply the given config environment")
+ p.add_option('-f', action="http://github.com/store_true", dest='fastcgi',
+ help="start a fastcgi server instead of the default HTTP server")
+ p.add_option('-s', action="http://github.com/store_true", dest='scgi',
+ help="start a scgi server instead of the default HTTP server")
+ p.add_option('-x', action="http://github.com/store_true", dest='cgi',
+ help="start a cgi server instead of the default HTTP server")
+ p.add_option('-i', '--import', action="http://github.com/append", dest='imports',
+ help="specify modules to import")
+ p.add_option('-p', '--pidfile', dest='pidfile', default=None,
+ help="store the process id in the given file")
+ p.add_option('-P', '--Path', action="http://github.com/append", dest='Path',
+ help="add the given paths to sys.path")
+ options, args = p.parse_args()
+
+ if options.Path:
+ for p in options.Path:
+ sys.path.insert(0, p)
+
+ start(options.config, options.daemonize,
+ options.environment, options.fastcgi, options.scgi,
+ options.pidfile, options.imports, options.cgi)
+
diff --git a/assignments/week05/athome/venv/Scripts/deactivate.bat b/assignments/week05/athome/venv/Scripts/deactivate.bat
new file mode 100644
index 00000000..52aabe5e
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/deactivate.bat
@@ -0,0 +1,18 @@
+@echo off
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+ set _OLD_VIRTUAL_PROMPT=
+)
+
+if defined _OLD_VIRTUAL_PYTHONHOME (
+ set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
+ set _OLD_VIRTUAL_PYTHONHOME=
+)
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+ set _OLD_VIRTUAL_PATH=
+)
+
+:END
diff --git a/assignments/week05/athome/venv/Scripts/easy_install-2.7-script.py b/assignments/week05/athome/venv/Scripts/easy_install-2.7-script.py
new file mode 100644
index 00000000..fd4b6723
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/easy_install-2.7-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install-2.7'
+__requires__ = 'setuptools==0.6c11'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install-2.7')()
+)
diff --git a/assignments/week05/athome/venv/Scripts/easy_install-2.7.exe b/assignments/week05/athome/venv/Scripts/easy_install-2.7.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/athome/venv/Scripts/easy_install-2.7.exe differ
diff --git a/assignments/week05/athome/venv/Scripts/easy_install-2.7.exe.manifest b/assignments/week05/athome/venv/Scripts/easy_install-2.7.exe.manifest
new file mode 100644
index 00000000..32d05995
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/easy_install-2.7.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/athome/venv/Scripts/easy_install-script.py b/assignments/week05/athome/venv/Scripts/easy_install-script.py
new file mode 100644
index 00000000..b7af7c5a
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/easy_install-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
+__requires__ = 'setuptools==0.6c11'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install')()
+)
diff --git a/assignments/week05/athome/venv/Scripts/easy_install.exe b/assignments/week05/athome/venv/Scripts/easy_install.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/athome/venv/Scripts/easy_install.exe differ
diff --git a/assignments/week05/athome/venv/Scripts/easy_install.exe.manifest b/assignments/week05/athome/venv/Scripts/easy_install.exe.manifest
new file mode 100644
index 00000000..ea8659ad
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/easy_install.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/athome/venv/Scripts/pip-2.7-script.py b/assignments/week05/athome/venv/Scripts/pip-2.7-script.py
new file mode 100644
index 00000000..1f816cac
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/pip-2.7-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.2.1','console_scripts','pip-2.7'
+__requires__ = 'pip==1.2.1'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('pip==1.2.1', 'console_scripts', 'pip-2.7')()
+)
diff --git a/assignments/week05/athome/venv/Scripts/pip-2.7.exe b/assignments/week05/athome/venv/Scripts/pip-2.7.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/athome/venv/Scripts/pip-2.7.exe differ
diff --git a/assignments/week05/athome/venv/Scripts/pip-2.7.exe.manifest b/assignments/week05/athome/venv/Scripts/pip-2.7.exe.manifest
new file mode 100644
index 00000000..1e531b68
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/pip-2.7.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/athome/venv/Scripts/pip-script.py b/assignments/week05/athome/venv/Scripts/pip-script.py
new file mode 100644
index 00000000..2f1ac689
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/pip-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\training.python_web\assignments\week05\athome\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.2.1','console_scripts','pip'
+__requires__ = 'pip==1.2.1'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('pip==1.2.1', 'console_scripts', 'pip')()
+)
diff --git a/assignments/week05/athome/venv/Scripts/pip.exe b/assignments/week05/athome/venv/Scripts/pip.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/athome/venv/Scripts/pip.exe differ
diff --git a/assignments/week05/athome/venv/Scripts/pip.exe.manifest b/assignments/week05/athome/venv/Scripts/pip.exe.manifest
new file mode 100644
index 00000000..98b524f4
--- /dev/null
+++ b/assignments/week05/athome/venv/Scripts/pip.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/athome/venv/Scripts/python.exe b/assignments/week05/athome/venv/Scripts/python.exe
new file mode 100644
index 00000000..f68a605b
Binary files /dev/null and b/assignments/week05/athome/venv/Scripts/python.exe differ
diff --git a/assignments/week05/athome/venv/Scripts/pythonw.exe b/assignments/week05/athome/venv/Scripts/pythonw.exe
new file mode 100644
index 00000000..42f32179
Binary files /dev/null and b/assignments/week05/athome/venv/Scripts/pythonw.exe differ
diff --git a/assignments/week05/lab/flaskr_1/README.txt b/assignments/week05/lab/flaskr_1/README.txt
new file mode 100644
index 00000000..0ba20220
--- /dev/null
+++ b/assignments/week05/lab/flaskr_1/README.txt
@@ -0,0 +1,5 @@
+Chris,
+
+Sorry for the delay getting this in. I had spent a few hours Sunday trying to get CherryPy playing nice with some sort of database on my Windows machine, but I couldn't get it going. I was also concerned with getting that transered from the Windows machine to the VM. That and it seems like a pain to get databases set up in general on Windows. I was able to get the hello world for CherryPy up and running, but then when I tried to get my TDD going, I couldn't figure out how to get a db to play nice, nor the syntax for CherryPy when I tried to follow the steps for Flask I got kinda lost. Not everything translated very well. I did end up following the lab to get the flaskr example up and running on my VM, you can get to it here: http://block647040-vrs.blueboxgrid.com/
+
+I don't think there are many differences between whats up and running and the lab itself. If I had gone a different direction I think it may have tried to implement some new features and enhancements. See you in class.
diff --git a/assignments/week05/lab/flaskr_1/flaskr.py b/assignments/week05/lab/flaskr_1/flaskr.py
index a959bdf9..1a512d36 100644
--- a/assignments/week05/lab/flaskr_1/flaskr.py
+++ b/assignments/week05/lab/flaskr_1/flaskr.py
@@ -1,11 +1,102 @@
from flask import Flask
-
+from contextlib import closing
+import sqlite3
+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 = 'notdefault'
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
+
+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('/')
+def show_entries():
+ entries = get_all_entries()
+ return render_template('show_entries.html', entries = entries)
+
+
+@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)
+ app.run(debug=True, host = '0.0.0.0')
diff --git a/assignments/week05/lab/flaskr_1/flaskr_tests.py b/assignments/week05/lab/flaskr_1/flaskr_tests.py
index e69de29b..8b4293b8 100644
--- a/assignments/week05/lab/flaskr_1/flaskr_tests.py
+++ b/assignments/week05/lab/flaskr_1/flaskr_tests.py
@@ -0,0 +1,110 @@
+import os
+import flaskr
+import unittest
+import tempfile
+from flask import session
+
+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_db_setup(self):
+ con = flaskr.connect_db()
+ cur = con.execute('PRAGMA table_info(entries)')
+ rows = cur.fetchall()
+ self.assertEquals(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'], 'incorrectpw')
+
+ 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', 'notdefault')
+ assert 'You were logged in' in rv.data
+ rv = self.logout()
+ assert 'You were logged out' in rv.data
+ rv = self.login('adminx','notdefault')
+ assert 'Invalid Login' in rv.data
+ rv = self.login('admin', 'notdeafaulot')
+ assert 'Invalid Login' in rv.data
+
+
+ def test_add_entries(self):
+ self.login('admin','notdefault')
+ rv = self.client.post('/add', data= dict(title='Hello', text='This is a post'), follow_redirects = True)
+ assert 'No entries here so far...stay tuned' not in rv.data
+ assert 'Hello' in rv.data
+ assert 'This is a post' in rv.data
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/assignments/week05/lab/flaskr_1/schema.sql b/assignments/week05/lab/flaskr_1/schema.sql
index e69de29b..71fe0588 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
+);
diff --git a/assignments/week05/lab/flaskr_1/static/style.css b/assignments/week05/lab/flaskr_1/static/style.css
new file mode 100644
index 00000000..f53d77f7
--- /dev/null
+++ b/assignments/week05/lab/flaskr_1/static/style.css
@@ -0,0 +1,17 @@
+body { font-family: sans-serif; background: #eee; }
+a, h1, h2 { color: #377BA8; }
+h1, h2 { font-family: 'Georgia', serif; margin: 0; }
+h1 { border-bottom: 2px solid #eee; }
+h2 { font-size: 1.2em; }
+.page { margin: 2em auto; width: 35em; border: 5px solid #ccc;
+ padding: 0.8em; background: white; }
+.entries { list-style: none; margin: 0; padding: 0; }
+.entries li { margin: 0.8em 1.2em; }
+.entries li h2 { margin-left: -1em; }
+.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }
+.add-entry dl { font-weight: bold; }
+.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
+ margin-bottom: 1em; background: #fafafa; }
+.flash { background: #CEE5F5; padding: 0.5em;
+ border: 1px solid #AACBE2; }
+.error { background: #F0D6D6; padding: 0.5em; }
\ No newline at end of file
diff --git a/assignments/week05/lab/flaskr_1/templates/layout.html b/assignments/week05/lab/flaskr_1/templates/layout.html
new file mode 100644
index 00000000..df0d3640
--- /dev/null
+++ b/assignments/week05/lab/flaskr_1/templates/layout.html
@@ -0,0 +1,22 @@
+
+
+
+ Flaskr
+
+
+
+
flaskr
+ {% if not session.logged_in %}
+ log in
+ {% else %}
+ log_out
+ {% endif %}
+
+ {% for message in get_flashed_messages() %}
+
{{ message }}
+ {% endfor %}
+
+ {% block body %} {% endblock %}
+
+
+
diff --git a/assignments/week05/lab/flaskr_1/templates/login.html b/assignments/week05/lab/flaskr_1/templates/login.html
new file mode 100644
index 00000000..67e18b82
--- /dev/null
+++ b/assignments/week05/lab/flaskr_1/templates/login.html
@@ -0,0 +1,22 @@
+
+{% extends "layout.html" %}
+{% block body %}
+
Login
+ {% if error -%}
+
Error {{ error }}
+ {%- endif %}
+
+{% endblock %}
+
diff --git a/assignments/week05/lab/flaskr_1/templates/show_entries.html b/assignments/week05/lab/flaskr_1/templates/show_entries.html
new file mode 100644
index 00000000..fde823af
--- /dev/null
+++ b/assignments/week05/lab/flaskr_1/templates/show_entries.html
@@ -0,0 +1,30 @@
+{% extends "layout.html"%}
+{% block body %}
+ {% if session.logged_in %}
+
+ {% endif %}
+
POSTS
+
+ {%for entry in entries %}
+
+
{{ entry.title }}
+
+ {{entry.text|safe}}
+
+
+ {% else %}
+
No entries here so far...stay tuned.
+ {% endfor %}
+ {%endblock%}
diff --git a/assignments/week05/lab/venv/Scripts/activate b/assignments/week05/lab/venv/Scripts/activate
new file mode 100644
index 00000000..557c9289
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/activate
@@ -0,0 +1,80 @@
+# This file must be used with "source bin/activate" *from bash*
+# you cannot run it directly
+
+deactivate () {
+ unset pydoc
+
+ # reset old environment variables
+ if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
+ PATH="$_OLD_VIRTUAL_PATH"
+ export PATH
+ unset _OLD_VIRTUAL_PATH
+ fi
+ if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
+ PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
+ export PYTHONHOME
+ unset _OLD_VIRTUAL_PYTHONHOME
+ fi
+
+ # This should detect bash and zsh, which have a hash command that must
+ # be called to get it to forget past commands. Without forgetting
+ # past commands the $PATH changes we made may not be respected
+ if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+ hash -r 2>/dev/null
+ fi
+
+ if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
+ PS1="$_OLD_VIRTUAL_PS1"
+ export PS1
+ unset _OLD_VIRTUAL_PS1
+ fi
+
+ unset VIRTUAL_ENV
+ if [ ! "$1" = "nondestructive" ] ; then
+ # Self destruct!
+ unset -f deactivate
+ fi
+}
+
+# unset irrelevant variables
+deactivate nondestructive
+
+VIRTUAL_ENV="$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u 'c:\cygwin\home\wtb\training.python_web\assignments\week05\lab\venv'; else echo '/c/cygwin/home/wtb/training.python_web/assignments/week05/lab/venv'; fi;)"
+export VIRTUAL_ENV
+
+_OLD_VIRTUAL_PATH="$PATH"
+PATH="$VIRTUAL_ENV/Scripts:$PATH"
+export PATH
+
+# unset PYTHONHOME if set
+# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
+# could use `if (set -u; : $PYTHONHOME) ;` in bash
+if [ -n "$PYTHONHOME" ] ; then
+ _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
+ unset PYTHONHOME
+fi
+
+if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
+ _OLD_VIRTUAL_PS1="$PS1"
+ if [ "x" != x ] ; then
+ PS1="$PS1"
+ else
+ if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
+ # special case for Aspen magic directories
+ # see http://www.zetadev.com/software/aspen/
+ PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
+ else
+ PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
+ fi
+ fi
+ export PS1
+fi
+
+alias pydoc="python -m pydoc"
+
+# This should detect bash and zsh, which have a hash command that must
+# be called to get it to forget past commands. Without forgetting
+# past commands the $PATH changes we made may not be respected
+if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+ hash -r 2>/dev/null
+fi
diff --git a/assignments/week05/lab/venv/Scripts/activate.bat b/assignments/week05/lab/venv/Scripts/activate.bat
new file mode 100644
index 00000000..03f2cfc3
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/activate.bat
@@ -0,0 +1,26 @@
+@echo off
+set "VIRTUAL_ENV=c:\cygwin\home\wtb\training.python_web\assignments\week05\lab\venv"
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+) else (
+ if not defined PROMPT (
+ set "PROMPT=$P$G"
+ )
+ set "_OLD_VIRTUAL_PROMPT=%PROMPT%"
+)
+set "PROMPT=(venv) %PROMPT%"
+
+if not defined _OLD_VIRTUAL_PYTHONHOME (
+ set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%"
+)
+set PYTHONHOME=
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+) else (
+ set "_OLD_VIRTUAL_PATH=%PATH%"
+)
+set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%"
+
+:END
diff --git a/assignments/week05/lab/venv/Scripts/activate.ps1 b/assignments/week05/lab/venv/Scripts/activate.ps1
new file mode 100644
index 00000000..e40ca1bf
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/activate.ps1
@@ -0,0 +1,148 @@
+# This file must be dot sourced from PoSh; you cannot run it
+# directly. Do this: . ./activate.ps1
+
+# FIXME: clean up unused vars.
+$script:THIS_PATH = $myinvocation.mycommand.path
+$script:BASE_DIR = split-path (resolve-path "$THIS_PATH/..") -Parent
+$script:DIR_NAME = split-path $BASE_DIR -Leaf
+
+function global:deactivate ( [switch] $NonDestructive ){
+
+ if ( test-path variable:_OLD_VIRTUAL_PATH ) {
+ $env:PATH = $variable:_OLD_VIRTUAL_PATH
+ remove-variable "_OLD_VIRTUAL_PATH" -scope global
+ }
+
+ if ( test-path function:_old_virtual_prompt ) {
+ $function:prompt = $function:_old_virtual_prompt
+ remove-item function:\_old_virtual_prompt
+ }
+
+ if ($env:VIRTUAL_ENV) {
+ $old_env = split-path $env:VIRTUAL_ENV -leaf
+ remove-item env:VIRTUAL_ENV -erroraction silentlycontinue
+ }
+
+ if ( !$NonDestructive ) {
+ # Self destruct!
+ remove-item function:deactivate
+ }
+}
+
+# unset irrelevant variables
+deactivate -nondestructive
+
+$VIRTUAL_ENV = $BASE_DIR
+$env:VIRTUAL_ENV = $VIRTUAL_ENV
+
+$global:_OLD_VIRTUAL_PATH = $env:PATH
+$env:PATH = "$env:VIRTUAL_ENV/Scripts;" + $env:PATH
+function global:_old_virtual_prompt { "" }
+$function:_old_virtual_prompt = $function:prompt
+function global:prompt {
+ # Add a prefix to the current prompt, but don't discard it.
+ write-host "($(split-path $env:VIRTUAL_ENV -leaf)) " -nonewline
+ & $function:_old_virtual_prompt
+}
+
+# SIG # Begin signature block
+# MIISeAYJKoZIhvcNAQcCoIISaTCCEmUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
+# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
+# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUS5reBwSg3zOUwhXf2jPChZzf
+# yPmggg6tMIIGcDCCBFigAwIBAgIBJDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQG
+# EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
+# Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
+# dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjIwMTQ2WhcNMTcxMDI0MjIw
+# MTQ2WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzAp
+# BgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNV
+# BAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgT2JqZWN0
+# IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyiOLIjUemqAbPJ1J
+# 0D8MlzgWKbr4fYlbRVjvhHDtfhFN6RQxq0PjTQxRgWzwFQNKJCdU5ftKoM5N4YSj
+# Id6ZNavcSa6/McVnhDAQm+8H3HWoD030NVOxbjgD/Ih3HaV3/z9159nnvyxQEckR
+# ZfpJB2Kfk6aHqW3JnSvRe+XVZSufDVCe/vtxGSEwKCaNrsLc9pboUoYIC3oyzWoU
+# TZ65+c0H4paR8c8eK/mC914mBo6N0dQ512/bkSdaeY9YaQpGtW/h/W/FkbQRT3sC
+# pttLVlIjnkuY4r9+zvqhToPjxcfDYEf+XD8VGkAqle8Aa8hQ+M1qGdQjAye8OzbV
+# uUOw7wIDAQABo4IB6TCCAeUwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+# AQYwHQYDVR0OBBYEFNBOD0CZbLhLGW87KLjg44gHNKq3MB8GA1UdIwQYMBaAFE4L
+# 7xqkQFulF2mHMMo0aEPQQa7yMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAoYh
+# aHR0cDovL3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3J0MFsGA1UdHwRUMFIwJ6Al
+# oCOGIWh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDAnoCWgI4YhaHR0
+# cDovL2NybC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMIGABgNVHSAEeTB3MHUGCysG
+# AQQBgbU3AQIBMGYwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+# L3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+# L2ludGVybWVkaWF0ZS5wZGYwEQYJYIZIAYb4QgEBBAQDAgABMFAGCWCGSAGG+EIB
+# DQRDFkFTdGFydENvbSBDbGFzcyAyIFByaW1hcnkgSW50ZXJtZWRpYXRlIE9iamVj
+# dCBTaWduaW5nIENlcnRpZmljYXRlczANBgkqhkiG9w0BAQUFAAOCAgEAcnMLA3Va
+# N4OIE9l4QT5OEtZy5PByBit3oHiqQpgVEQo7DHRsjXD5H/IyTivpMikaaeRxIv95
+# baRd4hoUcMwDj4JIjC3WA9FoNFV31SMljEZa66G8RQECdMSSufgfDYu1XQ+cUKxh
+# D3EtLGGcFGjjML7EQv2Iol741rEsycXwIXcryxeiMbU2TPi7X3elbwQMc4JFlJ4B
+# y9FhBzuZB1DV2sN2irGVbC3G/1+S2doPDjL1CaElwRa/T0qkq2vvPxUgryAoCppU
+# FKViw5yoGYC+z1GaesWWiP1eFKAL0wI7IgSvLzU3y1Vp7vsYaxOVBqZtebFTWRHt
+# XjCsFrrQBngt0d33QbQRI5mwgzEp7XJ9xu5d6RVWM4TPRUsd+DDZpBHm9mszvi9g
+# VFb2ZG7qRRXCSqys4+u/NLBPbXi/m/lU00cODQTlC/euwjk9HQtRrXQ/zqsBJS6U
+# J+eLGw1qOfj+HVBl/ZQpfoLk7IoWlRQvRL1s7oirEaqPZUIWY/grXq9r6jDKAp3L
+# ZdKQpPOnnogtqlU4f7/kLjEJhrrc98mrOWmVMK/BuFRAfQ5oDUMnVmCzAzLMjKfG
+# cVW/iMew41yfhgKbwpfzm3LBr1Zv+pEBgcgW6onRLSAn3XHM0eNtz+AkxH6rRf6B
+# 2mYhLEEGLapH8R1AMAo4BbVFOZR5kXcMCwowggg1MIIHHaADAgECAgIEuDANBgkq
+# hkiG9w0BAQUFADCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0
+# ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcx
+# ODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUg
+# T2JqZWN0IENBMB4XDTExMTIwMzE1MzQxOVoXDTEzMTIwMzE0NTgwN1owgYwxIDAe
+# BgNVBA0TFzU4MTc5Ni1HaDd4Zkp4a3hRU0lPNEUwMQswCQYDVQQGEwJERTEPMA0G
+# A1UECBMGQmVybGluMQ8wDQYDVQQHEwZCZXJsaW4xFjAUBgNVBAMTDUphbm5pcyBM
+# ZWlkZWwxITAfBgkqhkiG9w0BCQEWEmphbm5pc0BsZWlkZWwuaW5mbzCCAiIwDQYJ
+# KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMcPeABYdN7nPq/AkZ/EkyUBGx/l2Yui
+# Lfm8ZdLG0ulMb/kQL3fRY7sUjYPyn9S6PhqqlFnNoGHJvbbReCdUC9SIQYmOEjEA
+# raHfb7MZU10NjO4U2DdGucj2zuO5tYxKizizOJF0e4yRQZVxpUGdvkW/+GLjCNK5
+# L7mIv3Z1dagxDKHYZT74HXiS4VFUwHF1k36CwfM2vsetdm46bdgSwV+BCMmZICYT
+# IJAS9UQHD7kP4rik3bFWjUx08NtYYFAVOd/HwBnemUmJe4j3IhZHr0k1+eDG8hDH
+# KVvPgLJIoEjC4iMFk5GWsg5z2ngk0LLu3JZMtckHsnnmBPHQK8a3opUNd8hdMNJx
+# gOwKjQt2JZSGUdIEFCKVDqj0FmdnDMPfwy+FNRtpBMl1sz78dUFhSrnM0D8NXrqa
+# 4rG+2FoOXlmm1rb6AFtpjAKksHRpYcPk2DPGWp/1sWB+dUQkS3gOmwFzyqeTuXpT
+# 0juqd3iAxOGx1VRFQ1VHLLf3AzV4wljBau26I+tu7iXxesVucSdsdQu293jwc2kN
+# xK2JyHCoZH+RyytrwS0qw8t7rMOukU9gwP8mn3X6mgWlVUODMcHTULjSiCEtvyZ/
+# aafcwjUbt4ReEcnmuZtWIha86MTCX7U7e+cnpWG4sIHPnvVTaz9rm8RyBkIxtFCB
+# nQ3FnoQgyxeJAgMBAAGjggOdMIIDmTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIH
+# gDAuBgNVHSUBAf8EJDAiBggrBgEFBQcDAwYKKwYBBAGCNwIBFQYKKwYBBAGCNwoD
+# DTAdBgNVHQ4EFgQUWyCgrIWo8Ifvvm1/YTQIeMU9nc8wHwYDVR0jBBgwFoAU0E4P
+# QJlsuEsZbzsouODjiAc0qrcwggIhBgNVHSAEggIYMIICFDCCAhAGCysGAQQBgbU3
+# AQICMIIB/zAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9s
+# aWN5LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50
+# ZXJtZWRpYXRlLnBkZjCB9wYIKwYBBQUHAgIwgeowJxYgU3RhcnRDb20gQ2VydGlm
+# aWNhdGlvbiBBdXRob3JpdHkwAwIBARqBvlRoaXMgY2VydGlmaWNhdGUgd2FzIGlz
+# c3VlZCBhY2NvcmRpbmcgdG8gdGhlIENsYXNzIDIgVmFsaWRhdGlvbiByZXF1aXJl
+# bWVudHMgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeSwgcmVsaWFuY2Ugb25seSBm
+# b3IgdGhlIGludGVuZGVkIHB1cnBvc2UgaW4gY29tcGxpYW5jZSBvZiB0aGUgcmVs
+# eWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4wgZwGCCsGAQUFBwICMIGPMCcWIFN0YXJ0
+# Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MAMCAQIaZExpYWJpbGl0eSBhbmQg
+# d2FycmFudGllcyBhcmUgbGltaXRlZCEgU2VlIHNlY3Rpb24gIkxlZ2FsIGFuZCBM
+# aW1pdGF0aW9ucyIgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeS4wNgYDVR0fBC8w
+# LTAroCmgJ4YlaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0YzItY3JsLmNybDCB
+# iQYIKwYBBQUHAQEEfTB7MDcGCCsGAQUFBzABhitodHRwOi8vb2NzcC5zdGFydHNz
+# bC5jb20vc3ViL2NsYXNzMi9jb2RlL2NhMEAGCCsGAQUFBzAChjRodHRwOi8vYWlh
+# LnN0YXJ0c3NsLmNvbS9jZXJ0cy9zdWIuY2xhc3MyLmNvZGUuY2EuY3J0MCMGA1Ud
+# EgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tLzANBgkqhkiG9w0BAQUFAAOC
+# AQEAhrzEV6zwoEtKjnFRhCsjwiPykVpo5Eiye77Ve801rQDiRKgSCCiW6g3HqedL
+# OtaSs65Sj2pm3Viea4KR0TECLcbCTgsdaHqw2x1yXwWBQWZEaV6EB05lIwfr94P1
+# SFpV43zkuc+bbmA3+CRK45LOcCNH5Tqq7VGTCAK5iM7tvHwFlbQRl+I6VEL2mjpF
+# NsuRjDOVrv/9qw/a22YJ9R7Y1D0vUSs3IqZx2KMUaYDP7H2mSRxJO2nADQZBtriF
+# gTyfD3lYV12MlIi5CQwe3QC6DrrfSMP33i5Wa/OFJiQ27WPxmScYVhiqozpImFT4
+# PU9goiBv9RKXdgTmZE1PN0NQ5jGCAzUwggMxAgEBMIGTMIGMMQswCQYDVQQGEwJJ
+# TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
+# YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
+# MiBQcmltYXJ5IEludGVybWVkaWF0ZSBPYmplY3QgQ0ECAgS4MAkGBSsOAwIaBQCg
+# eDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEE
+# AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJ
+# BDEWBBRVGw0FDSiaIi38dWteRUAg/9Pr6DANBgkqhkiG9w0BAQEFAASCAgCInvOZ
+# FdaNFzbf6trmFDZKMojyx3UjKMCqNjHVBbuKY0qXwFC/ElYDV1ShJ2CBZbdurydO
+# OQ6cIQ0KREOCwmX/xB49IlLHHUxNhEkVv7HGU3EKAFf9IBt9Yr7jikiR9cjIsfHK
+# 4cjkoKJL7g28yEpLLkHt1eo37f1Ga9lDWEa5Zq3U5yX+IwXhrUBm1h8Xr033FhTR
+# VEpuSz6LHtbrL/zgJnCzJ2ahjtJoYevdcWiNXffosJHFaSfYDDbiNsPRDH/1avmb
+# 5j/7BhP8BcBaR6Fp8tFbNGIcWHHGcjqLMnTc4w13b7b4pDhypqElBa4+lCmwdvv9
+# GydYtRgPz8GHeoBoKj30YBlMzRIfFYaIFGIC4Ai3UEXkuH9TxYohVbGm/W0Kl4Lb
+# RJ1FwiVcLcTOJdgNId2vQvKc+jtNrjcg5SP9h2v/C4aTx8tyc6tE3TOPh2f9b8DL
+# S+SbVArJpuJqrPTxDDoO1QNjTgLcdVYeZDE+r/NjaGZ6cMSd8db3EaG3ijD/0bud
+# SItbm/OlNVbQOFRR76D+ZNgPcU5iNZ3bmvQQIg6aSB9MHUpIE/SeCkNl9YeVk1/1
+# GFULgNMRmIYP4KLvu9ylh5Gu3hvD5VNhH6+FlXANwFy07uXks5uF8mfZVxVCnodG
+# xkNCx+6PsrA5Z7WP4pXcmYnMn97npP/Q9EHJWw==
+# SIG # End signature block
diff --git a/assignments/week05/lab/venv/Scripts/activate_this.py b/assignments/week05/lab/venv/Scripts/activate_this.py
new file mode 100644
index 00000000..ea12c28a
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/activate_this.py
@@ -0,0 +1,34 @@
+"""By using execfile(this_file, dict(__file__=this_file)) you will
+activate this virtualenv environment.
+
+This can be used when you must use an existing Python interpreter, not
+the virtualenv bin/python
+"""
+
+try:
+ __file__
+except NameError:
+ raise AssertionError(
+ "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
+import sys
+import os
+
+old_os_path = os.environ['PATH']
+os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
+base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+if sys.platform == 'win32':
+ site_packages = os.path.join(base, 'Lib', 'site-packages')
+else:
+ site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
+prev_sys_path = list(sys.path)
+import site
+site.addsitedir(site_packages)
+sys.real_prefix = sys.prefix
+sys.prefix = base
+# Move the added items to the front of the path:
+new_sys_path = []
+for item in list(sys.path):
+ if item not in prev_sys_path:
+ new_sys_path.append(item)
+ sys.path.remove(item)
+sys.path[:0] = new_sys_path
diff --git a/assignments/week05/lab/venv/Scripts/deactivate.bat b/assignments/week05/lab/venv/Scripts/deactivate.bat
new file mode 100644
index 00000000..52aabe5e
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/deactivate.bat
@@ -0,0 +1,18 @@
+@echo off
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+ set _OLD_VIRTUAL_PROMPT=
+)
+
+if defined _OLD_VIRTUAL_PYTHONHOME (
+ set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
+ set _OLD_VIRTUAL_PYTHONHOME=
+)
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+ set _OLD_VIRTUAL_PATH=
+)
+
+:END
diff --git a/assignments/week05/lab/venv/Scripts/easy_install-2.7-script.py b/assignments/week05/lab/venv/Scripts/easy_install-2.7-script.py
new file mode 100644
index 00000000..30bc6764
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/easy_install-2.7-script.py
@@ -0,0 +1,9 @@
+#!c:\cygwin\home\wtb\training.python_web\assignments\week05\lab\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install-2.7'
+__requires__ = 'setuptools==0.6c11'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install-2.7')()
+)
diff --git a/assignments/week05/lab/venv/Scripts/easy_install-2.7.exe b/assignments/week05/lab/venv/Scripts/easy_install-2.7.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/lab/venv/Scripts/easy_install-2.7.exe differ
diff --git a/assignments/week05/lab/venv/Scripts/easy_install-2.7.exe.manifest b/assignments/week05/lab/venv/Scripts/easy_install-2.7.exe.manifest
new file mode 100644
index 00000000..32d05995
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/easy_install-2.7.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/lab/venv/Scripts/easy_install-script.py b/assignments/week05/lab/venv/Scripts/easy_install-script.py
new file mode 100644
index 00000000..84d4816f
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/easy_install-script.py
@@ -0,0 +1,9 @@
+#!c:\cygwin\home\wtb\training.python_web\assignments\week05\lab\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
+__requires__ = 'setuptools==0.6c11'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install')()
+)
diff --git a/assignments/week05/lab/venv/Scripts/easy_install.exe b/assignments/week05/lab/venv/Scripts/easy_install.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/lab/venv/Scripts/easy_install.exe differ
diff --git a/assignments/week05/lab/venv/Scripts/easy_install.exe.manifest b/assignments/week05/lab/venv/Scripts/easy_install.exe.manifest
new file mode 100644
index 00000000..ea8659ad
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/easy_install.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/lab/venv/Scripts/pip-2.7-script.py b/assignments/week05/lab/venv/Scripts/pip-2.7-script.py
new file mode 100644
index 00000000..617ab9e7
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/pip-2.7-script.py
@@ -0,0 +1,9 @@
+#!c:\cygwin\home\wtb\training.python_web\assignments\week05\lab\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.2.1','console_scripts','pip-2.7'
+__requires__ = 'pip==1.2.1'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('pip==1.2.1', 'console_scripts', 'pip-2.7')()
+)
diff --git a/assignments/week05/lab/venv/Scripts/pip-2.7.exe b/assignments/week05/lab/venv/Scripts/pip-2.7.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/lab/venv/Scripts/pip-2.7.exe differ
diff --git a/assignments/week05/lab/venv/Scripts/pip-2.7.exe.manifest b/assignments/week05/lab/venv/Scripts/pip-2.7.exe.manifest
new file mode 100644
index 00000000..1e531b68
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/pip-2.7.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/lab/venv/Scripts/pip-script.py b/assignments/week05/lab/venv/Scripts/pip-script.py
new file mode 100644
index 00000000..2bff88eb
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/pip-script.py
@@ -0,0 +1,9 @@
+#!c:\cygwin\home\wtb\training.python_web\assignments\week05\lab\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.2.1','console_scripts','pip'
+__requires__ = 'pip==1.2.1'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('pip==1.2.1', 'console_scripts', 'pip')()
+)
diff --git a/assignments/week05/lab/venv/Scripts/pip.exe b/assignments/week05/lab/venv/Scripts/pip.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week05/lab/venv/Scripts/pip.exe differ
diff --git a/assignments/week05/lab/venv/Scripts/pip.exe.manifest b/assignments/week05/lab/venv/Scripts/pip.exe.manifest
new file mode 100644
index 00000000..98b524f4
--- /dev/null
+++ b/assignments/week05/lab/venv/Scripts/pip.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week05/lab/venv/Scripts/python.exe b/assignments/week05/lab/venv/Scripts/python.exe
new file mode 100644
index 00000000..f68a605b
Binary files /dev/null and b/assignments/week05/lab/venv/Scripts/python.exe differ
diff --git a/assignments/week05/lab/venv/Scripts/pythonw.exe b/assignments/week05/lab/venv/Scripts/pythonw.exe
new file mode 100644
index 00000000..42f32179
Binary files /dev/null and b/assignments/week05/lab/venv/Scripts/pythonw.exe differ
diff --git a/assignments/week06/athome/blog_djang/README.txt b/assignments/week06/athome/blog_djang/README.txt
new file mode 100644
index 00000000..fcbee921
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/README.txt
@@ -0,0 +1,19 @@
+Hi Cris,
+
+I made the mistake of not looking at the repo before I started down the path I took. I also didn't that there were instructions and I started work against what I thought we had to do for homework. I spent the majority of today trying to get the blog part up and running and now I'm hitting a point where I'm going to submit what I have and hopefully learn about better ways to get data into your database. I've been struggling with trying to create the proper way to get the POST set up so a user can submit a blog post. It's been frustrating because I feel like I know exactly what needs to be done (get POST parameters from HTML, send the POST, set the post entries in the BlogPost class I have and then save the blogpost). I have not been able to get that working because, from what I can tell, I haven't got the CSRF verification configured properly when I post. I get this error:
+
+CSRF verification failed. Request aborted.
+Help
+Reason given for failure:
+ CSRF token missing or incorrect.
+
+In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
+Your browser is accepting cookies.
+The view function uses RequestContext for the template, instead of Context.
+In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
+If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
+You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
+You can customize this page using the CSRF_FAILURE_VIEW setting.
+
+Do you have any tips on getting past this?
+I've verified that browser is accepting cookies, so I'm guessing it has to do with making sure the view function uses RequestContext for the template?
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/__init__.py b/assignments/week06/athome/blog_djang/microblog/blog/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/admin.py b/assignments/week06/athome/blog_djang/microblog/blog/admin.py
new file mode 100644
index 00000000..cab01933
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from blog.models import BlogPost
+
+admin.site.register(BlogPost)
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/models.py b/assignments/week06/athome/blog_djang/microblog/blog/models.py
new file mode 100644
index 00000000..af21862e
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/models.py
@@ -0,0 +1,20 @@
+from django.db import models
+import datetime
+from django.utils import timezone
+from django.contrib.auth.models import User
+# Create your models here.
+
+class BlogPost(models.Model):
+ """
+ Blog post model includes: title, post, author, and publish date
+ """
+ title = models.CharField('title', max_length=200)
+ post = models.CharField('post', max_length=2000)
+ author = models.ForeignKey(User)
+ pub_date = models.DateTimeField('date published')
+
+ def __unicode__(self):
+ return self.title
+
+from django import forms
+
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/templates/about.html b/assignments/week06/athome/blog_djang/microblog/blog/templates/about.html
new file mode 100644
index 00000000..d0909e26
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/templates/about.html
@@ -0,0 +1,11 @@
+
+
+
+ Flaskr on Django
+
+
+
+
asdf
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/templates/add_entry.html b/assignments/week06/athome/blog_djang/microblog/blog/templates/add_entry.html
new file mode 100644
index 00000000..a951cd49
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/templates/add_entry.html
@@ -0,0 +1,16 @@
+
+
+
+ Flaskr on Django
+
+
+
Add Entry
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/templates/blog.html b/assignments/week06/athome/blog_djang/microblog/blog/templates/blog.html
new file mode 100644
index 00000000..f7b7cc40
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/templates/blog.html
@@ -0,0 +1,39 @@
+
+
+
+ Flaskr on Django
+
+
+{% if latest_blog_posts %}
+
Posts
+
+ {% for entry in latest_blog_posts %}
+
+
{{ entry.title }}
+
+ {{ entry.post|safe }}
+
+
+ {{ entry.pub_date }}
+
+
+ {{ entry.author }}
+
+ {% endfor %}
+{% else %}
+
No blog posts are available.
+{% endif %}
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/templates/entry.html b/assignments/week06/athome/blog_djang/microblog/blog/templates/entry.html
new file mode 100644
index 00000000..e1a54644
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/templates/entry.html
@@ -0,0 +1,17 @@
+
+
+
+ Flaskr on Django
+
+
+{% if latest_blog_posts %}
+
+{% endif %}
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/tests.py b/assignments/week06/athome/blog_djang/microblog/blog/tests.py
new file mode 100644
index 00000000..501deb77
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/tests.py
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+ def test_basic_addition(self):
+ """
+ Tests that 1 + 1 always equals 2.
+ """
+ self.assertEqual(1 + 1, 2)
diff --git a/assignments/week06/athome/blog_djang/microblog/blog/views.py b/assignments/week06/athome/blog_djang/microblog/blog/views.py
new file mode 100644
index 00000000..11061168
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/blog/views.py
@@ -0,0 +1,48 @@
+# Create your views here.
+from django.http import HttpResponse
+from django.views.generic import TemplateView
+from django.template import Context, loader
+from blog.models import BlogPost
+#from django.template import RequestContext
+#from blog.models import ContactForm
+#from django.core.context_processor import csrf
+from django.views.decorators.csrf import csrf_protect
+from django.shortcuts import render
+
+def blog_index(request):
+ latest_blog_posts = BlogPost.objects.order_by('pub_date')
+ template = loader.get_template('C:\cygwin\home\wtb\\blog_djang\microblog\\blog\\templates\\blog.html')
+ output = ', ' .join(b.title for b in latest_blog_posts)
+ context = Context({
+ 'latest_blog_posts': latest_blog_posts,
+ })
+ return HttpResponse(template.render(context))
+
+'''def add_entry(request):
+ if request.method = 'POST':
+ data = BlogPost(request.POST)
+ entry = BlogPost(title = "asdf", post = "f2fw", pub_date = timezone.now, user = user)
+ entry.save()
+
+def detail(request, entry_id):
+ requested_entry = BlogPost.objects.filter(id=entry_id)
+ template = loader.get_template('C:\cygwin\home\wtb\\blog_djang\microblog\\blog\\templates\\entry.html')
+ utput = ', ' .join(b.title for b in )
+ return HttpResponse("Blog Post Title %s." % requested_entry.[0]title)'''
+@csrf_protect
+def add_entry(request):
+ print "wtf:", request
+
+ if request.method == 'POST': # If the form has been submitted...
+ form = ContactForm(request.POST) # A form bound to the POST data
+ if form.is_valid(): # All validation rules pass
+ # Process the data in form.cleaned_data
+ # ...
+ return HttpResponseRedirect('/thanks/') # Redirect after POST
+ else:
+ form = ContactForm() # An unbound form
+
+ return render_to_response('contact.html', {
+ 'form': form,},context_instance = RequestContext(request) )
+
+ #
diff --git a/assignments/week06/athome/blog_djang/microblog/manage.py b/assignments/week06/athome/blog_djang/microblog/manage.py
new file mode 100644
index 00000000..3a30d8fd
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/manage.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "microblog.settings")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)
diff --git a/assignments/week06/athome/blog_djang/microblog/microblog.db b/assignments/week06/athome/blog_djang/microblog/microblog.db
new file mode 100644
index 00000000..964af3c1
Binary files /dev/null and b/assignments/week06/athome/blog_djang/microblog/microblog.db differ
diff --git a/assignments/week06/athome/blog_djang/microblog/microblog/__init__.py b/assignments/week06/athome/blog_djang/microblog/microblog/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/assignments/week06/athome/blog_djang/microblog/microblog/settings.py b/assignments/week06/athome/blog_djang/microblog/microblog/settings.py
new file mode 100644
index 00000000..ae83f373
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/microblog/settings.py
@@ -0,0 +1,152 @@
+# Django settings for microblog project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+ # ('Your Name', 'your_email@example.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ 'NAME': 'C:\cygwin\home\wtb\\blog_djang\microblog\microblog.db', # Or path to database file if using sqlite3.
+ 'USER': '', # Not used with sqlite3.
+ 'PASSWORD': '', # Not used with sqlite3.
+ 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
+ 'PORT': '', # Set to empty string for default. Not used with sqlite3.
+ }
+}
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# In a Windows environment this must be set to your system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# If you set this to False, Django will not format dates, numbers and
+# calendars according to the current locale.
+USE_L10N = True
+
+# If you set this to False, Django will not use timezone-aware datetimes.
+USE_TZ = True
+
+# Absolute filesystem path to the directory that will hold user-uploaded files.
+# Example: "/home/media/media.lawrence.com/media/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash.
+# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
+MEDIA_URL = ''
+
+# Absolute path to the directory static files should be collected to.
+# Don't put anything in this directory yourself; store your static files
+# in apps' "static/" subdirectories and in STATICFILES_DIRS.
+# Example: "/home/media/media.lawrence.com/static/"
+STATIC_ROOT = ''
+
+# URL prefix for static files.
+# Example: "http://media.lawrence.com/static/"
+STATIC_URL = '/static/'
+
+# Additional locations of static files
+STATICFILES_DIRS = (
+ # Put strings here, like "/home/html/static" or "C:/www/django/static".
+ # Always use forward slashes, even on Windows.
+ # Don't forget to use absolute paths, not relative paths.
+)
+
+# List of finder classes that know how to find static files in
+# various locations.
+STATICFILES_FINDERS = (
+ 'django.contrib.staticfiles.finders.FileSystemFinder',
+ 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
+)
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = 'm%mpe=m#i7p+wopl5^(hn5vfhhbzwy)@5%^q2+_c8j5tb+j1f@'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+# 'django.template.loaders.eggs.Loader',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ # Uncomment the next line for simple clickjacking protection:
+ # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+)
+
+ROOT_URLCONF = 'microblog.urls'
+
+# Python dotted path to the WSGI application used by Django's runserver.
+WSGI_APPLICATION = 'microblog.wsgi.application'
+
+TEMPLATE_DIRS = (
+ # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+ # Always use forward slashes, even on Windows.
+ # Don't forget to use absolute paths, not relative paths.
+)
+
+INSTALLED_APPS = (
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.sites',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ # Uncomment the next line to enable the admin:
+ 'django.contrib.admin',
+ # Uncomment the next line to enable admin documentation:
+ # 'django.contrib.admindocs',
+ 'blog',
+)
+
+# A sample logging configuration. The only tangible logging
+# performed by this configuration is to send an email to
+# the site admins on every HTTP 500 error when DEBUG=False.
+# See http://docs.djangoproject.com/en/dev/topics/logging for
+# more details on how to customize your logging configuration.
+LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'filters': {
+ 'require_debug_false': {
+ '()': 'django.utils.log.RequireDebugFalse'
+ }
+ },
+ 'handlers': {
+ 'mail_admins': {
+ 'level': 'ERROR',
+ 'filters': ['require_debug_false'],
+ 'class': 'django.utils.log.AdminEmailHandler'
+ }
+ },
+ 'loggers': {
+ 'django.request': {
+ 'handlers': ['mail_admins'],
+ 'level': 'ERROR',
+ 'propagate': True,
+ },
+ }
+}
diff --git a/assignments/week06/athome/blog_djang/microblog/microblog/urls.py b/assignments/week06/athome/blog_djang/microblog/microblog/urls.py
new file mode 100644
index 00000000..35b661df
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/microblog/urls.py
@@ -0,0 +1,22 @@
+from django.conf.urls import patterns, include, url
+
+# Uncomment the next two lines to enable the admin:
+from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+ # Examples:
+ #url(http://github.com/r'%5E'),%20'microblog.views.home',%20name='home'),
+ # url(http://github.com/r'%5Emicroblog/',%20include('microblog.foo.urls')),
+
+ # Uncomment the admin/doc line below to enable admin documentation:
+ url(http://github.com/r'%5Eadmin/doc/',%20include('django.contrib.admindocs.urls')),
+
+ # Uncomment the next line to enable the admin:
+ url(http://github.com/r'%5Eadmin/',%20include(admin.site.urls)),
+ url(http://github.com/r'%5E'),%20'blog.views.blog_index'),
+ url(http://github.com/r'%5Eadd_entry/',%20'blog.views.add_entry'),
+ #url(http://github.com/r'%5E(?P%3Centry_id%3E\d+)/$', 'blog.views.detail', name='detail'),
+
+
+)
diff --git a/assignments/week06/athome/blog_djang/microblog/microblog/wsgi.py b/assignments/week06/athome/blog_djang/microblog/microblog/wsgi.py
new file mode 100644
index 00000000..ab348528
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/microblog/microblog/wsgi.py
@@ -0,0 +1,28 @@
+"""
+WSGI config for microblog project.
+
+This module contains the WSGI application used by Django's development server
+and any production WSGI deployments. It should expose a module-level variable
+named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
+this application via the ``WSGI_APPLICATION`` setting.
+
+Usually you will have the standard Django WSGI application here, but it also
+might make sense to replace the whole Django WSGI application with a custom one
+that later delegates to the Django one. For example, you could introduce WSGI
+middleware here, or combine a Django application with an application of another
+framework.
+
+"""
+import os
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "microblog.settings")
+
+# This application object is used by any WSGI server configured to use this
+# file. This includes Django's development server, if the WSGI_APPLICATION
+# setting points here.
+from django.core.wsgi import get_wsgi_application
+application = get_wsgi_application()
+
+# Apply WSGI middleware here.
+# from helloworld.wsgi import HelloWorldApplication
+# application = HelloWorldApplication(application)
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/activate b/assignments/week06/athome/blog_djang/venv/Scripts/activate
new file mode 100644
index 00000000..860c0c29
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/activate
@@ -0,0 +1,80 @@
+# This file must be used with "source bin/activate" *from bash*
+# you cannot run it directly
+
+deactivate () {
+ unset pydoc
+
+ # reset old environment variables
+ if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
+ PATH="$_OLD_VIRTUAL_PATH"
+ export PATH
+ unset _OLD_VIRTUAL_PATH
+ fi
+ if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
+ PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
+ export PYTHONHOME
+ unset _OLD_VIRTUAL_PYTHONHOME
+ fi
+
+ # This should detect bash and zsh, which have a hash command that must
+ # be called to get it to forget past commands. Without forgetting
+ # past commands the $PATH changes we made may not be respected
+ if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+ hash -r 2>/dev/null
+ fi
+
+ if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
+ PS1="$_OLD_VIRTUAL_PS1"
+ export PS1
+ unset _OLD_VIRTUAL_PS1
+ fi
+
+ unset VIRTUAL_ENV
+ if [ ! "$1" = "nondestructive" ] ; then
+ # Self destruct!
+ unset -f deactivate
+ fi
+}
+
+# unset irrelevant variables
+deactivate nondestructive
+
+VIRTUAL_ENV="$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u 'C:\cygwin\home\wtb\blog_djang\venv'; else echo '/C/cygwin/home/wtb/blog_djang/venv'; fi;)"
+export VIRTUAL_ENV
+
+_OLD_VIRTUAL_PATH="$PATH"
+PATH="$VIRTUAL_ENV/Scripts:$PATH"
+export PATH
+
+# unset PYTHONHOME if set
+# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
+# could use `if (set -u; : $PYTHONHOME) ;` in bash
+if [ -n "$PYTHONHOME" ] ; then
+ _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
+ unset PYTHONHOME
+fi
+
+if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
+ _OLD_VIRTUAL_PS1="$PS1"
+ if [ "x" != x ] ; then
+ PS1="$PS1"
+ else
+ if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
+ # special case for Aspen magic directories
+ # see http://www.zetadev.com/software/aspen/
+ PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
+ else
+ PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
+ fi
+ fi
+ export PS1
+fi
+
+alias pydoc="python -m pydoc"
+
+# This should detect bash and zsh, which have a hash command that must
+# be called to get it to forget past commands. Without forgetting
+# past commands the $PATH changes we made may not be respected
+if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+ hash -r 2>/dev/null
+fi
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/activate.bat b/assignments/week06/athome/blog_djang/venv/Scripts/activate.bat
new file mode 100644
index 00000000..3ab9e950
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/activate.bat
@@ -0,0 +1,26 @@
+@echo off
+set "VIRTUAL_ENV=C:\cygwin\home\wtb\blog_djang\venv"
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+) else (
+ if not defined PROMPT (
+ set "PROMPT=$P$G"
+ )
+ set "_OLD_VIRTUAL_PROMPT=%PROMPT%"
+)
+set "PROMPT=(venv) %PROMPT%"
+
+if not defined _OLD_VIRTUAL_PYTHONHOME (
+ set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%"
+)
+set PYTHONHOME=
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+) else (
+ set "_OLD_VIRTUAL_PATH=%PATH%"
+)
+set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%"
+
+:END
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/activate.ps1 b/assignments/week06/athome/blog_djang/venv/Scripts/activate.ps1
new file mode 100644
index 00000000..e40ca1bf
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/activate.ps1
@@ -0,0 +1,148 @@
+# This file must be dot sourced from PoSh; you cannot run it
+# directly. Do this: . ./activate.ps1
+
+# FIXME: clean up unused vars.
+$script:THIS_PATH = $myinvocation.mycommand.path
+$script:BASE_DIR = split-path (resolve-path "$THIS_PATH/..") -Parent
+$script:DIR_NAME = split-path $BASE_DIR -Leaf
+
+function global:deactivate ( [switch] $NonDestructive ){
+
+ if ( test-path variable:_OLD_VIRTUAL_PATH ) {
+ $env:PATH = $variable:_OLD_VIRTUAL_PATH
+ remove-variable "_OLD_VIRTUAL_PATH" -scope global
+ }
+
+ if ( test-path function:_old_virtual_prompt ) {
+ $function:prompt = $function:_old_virtual_prompt
+ remove-item function:\_old_virtual_prompt
+ }
+
+ if ($env:VIRTUAL_ENV) {
+ $old_env = split-path $env:VIRTUAL_ENV -leaf
+ remove-item env:VIRTUAL_ENV -erroraction silentlycontinue
+ }
+
+ if ( !$NonDestructive ) {
+ # Self destruct!
+ remove-item function:deactivate
+ }
+}
+
+# unset irrelevant variables
+deactivate -nondestructive
+
+$VIRTUAL_ENV = $BASE_DIR
+$env:VIRTUAL_ENV = $VIRTUAL_ENV
+
+$global:_OLD_VIRTUAL_PATH = $env:PATH
+$env:PATH = "$env:VIRTUAL_ENV/Scripts;" + $env:PATH
+function global:_old_virtual_prompt { "" }
+$function:_old_virtual_prompt = $function:prompt
+function global:prompt {
+ # Add a prefix to the current prompt, but don't discard it.
+ write-host "($(split-path $env:VIRTUAL_ENV -leaf)) " -nonewline
+ & $function:_old_virtual_prompt
+}
+
+# SIG # Begin signature block
+# MIISeAYJKoZIhvcNAQcCoIISaTCCEmUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
+# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
+# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUS5reBwSg3zOUwhXf2jPChZzf
+# yPmggg6tMIIGcDCCBFigAwIBAgIBJDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQG
+# EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
+# Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
+# dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjIwMTQ2WhcNMTcxMDI0MjIw
+# MTQ2WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzAp
+# BgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNV
+# BAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgT2JqZWN0
+# IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyiOLIjUemqAbPJ1J
+# 0D8MlzgWKbr4fYlbRVjvhHDtfhFN6RQxq0PjTQxRgWzwFQNKJCdU5ftKoM5N4YSj
+# Id6ZNavcSa6/McVnhDAQm+8H3HWoD030NVOxbjgD/Ih3HaV3/z9159nnvyxQEckR
+# ZfpJB2Kfk6aHqW3JnSvRe+XVZSufDVCe/vtxGSEwKCaNrsLc9pboUoYIC3oyzWoU
+# TZ65+c0H4paR8c8eK/mC914mBo6N0dQ512/bkSdaeY9YaQpGtW/h/W/FkbQRT3sC
+# pttLVlIjnkuY4r9+zvqhToPjxcfDYEf+XD8VGkAqle8Aa8hQ+M1qGdQjAye8OzbV
+# uUOw7wIDAQABo4IB6TCCAeUwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+# AQYwHQYDVR0OBBYEFNBOD0CZbLhLGW87KLjg44gHNKq3MB8GA1UdIwQYMBaAFE4L
+# 7xqkQFulF2mHMMo0aEPQQa7yMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAoYh
+# aHR0cDovL3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3J0MFsGA1UdHwRUMFIwJ6Al
+# oCOGIWh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDAnoCWgI4YhaHR0
+# cDovL2NybC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMIGABgNVHSAEeTB3MHUGCysG
+# AQQBgbU3AQIBMGYwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+# L3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+# L2ludGVybWVkaWF0ZS5wZGYwEQYJYIZIAYb4QgEBBAQDAgABMFAGCWCGSAGG+EIB
+# DQRDFkFTdGFydENvbSBDbGFzcyAyIFByaW1hcnkgSW50ZXJtZWRpYXRlIE9iamVj
+# dCBTaWduaW5nIENlcnRpZmljYXRlczANBgkqhkiG9w0BAQUFAAOCAgEAcnMLA3Va
+# N4OIE9l4QT5OEtZy5PByBit3oHiqQpgVEQo7DHRsjXD5H/IyTivpMikaaeRxIv95
+# baRd4hoUcMwDj4JIjC3WA9FoNFV31SMljEZa66G8RQECdMSSufgfDYu1XQ+cUKxh
+# D3EtLGGcFGjjML7EQv2Iol741rEsycXwIXcryxeiMbU2TPi7X3elbwQMc4JFlJ4B
+# y9FhBzuZB1DV2sN2irGVbC3G/1+S2doPDjL1CaElwRa/T0qkq2vvPxUgryAoCppU
+# FKViw5yoGYC+z1GaesWWiP1eFKAL0wI7IgSvLzU3y1Vp7vsYaxOVBqZtebFTWRHt
+# XjCsFrrQBngt0d33QbQRI5mwgzEp7XJ9xu5d6RVWM4TPRUsd+DDZpBHm9mszvi9g
+# VFb2ZG7qRRXCSqys4+u/NLBPbXi/m/lU00cODQTlC/euwjk9HQtRrXQ/zqsBJS6U
+# J+eLGw1qOfj+HVBl/ZQpfoLk7IoWlRQvRL1s7oirEaqPZUIWY/grXq9r6jDKAp3L
+# ZdKQpPOnnogtqlU4f7/kLjEJhrrc98mrOWmVMK/BuFRAfQ5oDUMnVmCzAzLMjKfG
+# cVW/iMew41yfhgKbwpfzm3LBr1Zv+pEBgcgW6onRLSAn3XHM0eNtz+AkxH6rRf6B
+# 2mYhLEEGLapH8R1AMAo4BbVFOZR5kXcMCwowggg1MIIHHaADAgECAgIEuDANBgkq
+# hkiG9w0BAQUFADCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0
+# ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcx
+# ODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUg
+# T2JqZWN0IENBMB4XDTExMTIwMzE1MzQxOVoXDTEzMTIwMzE0NTgwN1owgYwxIDAe
+# BgNVBA0TFzU4MTc5Ni1HaDd4Zkp4a3hRU0lPNEUwMQswCQYDVQQGEwJERTEPMA0G
+# A1UECBMGQmVybGluMQ8wDQYDVQQHEwZCZXJsaW4xFjAUBgNVBAMTDUphbm5pcyBM
+# ZWlkZWwxITAfBgkqhkiG9w0BCQEWEmphbm5pc0BsZWlkZWwuaW5mbzCCAiIwDQYJ
+# KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMcPeABYdN7nPq/AkZ/EkyUBGx/l2Yui
+# Lfm8ZdLG0ulMb/kQL3fRY7sUjYPyn9S6PhqqlFnNoGHJvbbReCdUC9SIQYmOEjEA
+# raHfb7MZU10NjO4U2DdGucj2zuO5tYxKizizOJF0e4yRQZVxpUGdvkW/+GLjCNK5
+# L7mIv3Z1dagxDKHYZT74HXiS4VFUwHF1k36CwfM2vsetdm46bdgSwV+BCMmZICYT
+# IJAS9UQHD7kP4rik3bFWjUx08NtYYFAVOd/HwBnemUmJe4j3IhZHr0k1+eDG8hDH
+# KVvPgLJIoEjC4iMFk5GWsg5z2ngk0LLu3JZMtckHsnnmBPHQK8a3opUNd8hdMNJx
+# gOwKjQt2JZSGUdIEFCKVDqj0FmdnDMPfwy+FNRtpBMl1sz78dUFhSrnM0D8NXrqa
+# 4rG+2FoOXlmm1rb6AFtpjAKksHRpYcPk2DPGWp/1sWB+dUQkS3gOmwFzyqeTuXpT
+# 0juqd3iAxOGx1VRFQ1VHLLf3AzV4wljBau26I+tu7iXxesVucSdsdQu293jwc2kN
+# xK2JyHCoZH+RyytrwS0qw8t7rMOukU9gwP8mn3X6mgWlVUODMcHTULjSiCEtvyZ/
+# aafcwjUbt4ReEcnmuZtWIha86MTCX7U7e+cnpWG4sIHPnvVTaz9rm8RyBkIxtFCB
+# nQ3FnoQgyxeJAgMBAAGjggOdMIIDmTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIH
+# gDAuBgNVHSUBAf8EJDAiBggrBgEFBQcDAwYKKwYBBAGCNwIBFQYKKwYBBAGCNwoD
+# DTAdBgNVHQ4EFgQUWyCgrIWo8Ifvvm1/YTQIeMU9nc8wHwYDVR0jBBgwFoAU0E4P
+# QJlsuEsZbzsouODjiAc0qrcwggIhBgNVHSAEggIYMIICFDCCAhAGCysGAQQBgbU3
+# AQICMIIB/zAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9s
+# aWN5LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50
+# ZXJtZWRpYXRlLnBkZjCB9wYIKwYBBQUHAgIwgeowJxYgU3RhcnRDb20gQ2VydGlm
+# aWNhdGlvbiBBdXRob3JpdHkwAwIBARqBvlRoaXMgY2VydGlmaWNhdGUgd2FzIGlz
+# c3VlZCBhY2NvcmRpbmcgdG8gdGhlIENsYXNzIDIgVmFsaWRhdGlvbiByZXF1aXJl
+# bWVudHMgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeSwgcmVsaWFuY2Ugb25seSBm
+# b3IgdGhlIGludGVuZGVkIHB1cnBvc2UgaW4gY29tcGxpYW5jZSBvZiB0aGUgcmVs
+# eWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4wgZwGCCsGAQUFBwICMIGPMCcWIFN0YXJ0
+# Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MAMCAQIaZExpYWJpbGl0eSBhbmQg
+# d2FycmFudGllcyBhcmUgbGltaXRlZCEgU2VlIHNlY3Rpb24gIkxlZ2FsIGFuZCBM
+# aW1pdGF0aW9ucyIgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeS4wNgYDVR0fBC8w
+# LTAroCmgJ4YlaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0YzItY3JsLmNybDCB
+# iQYIKwYBBQUHAQEEfTB7MDcGCCsGAQUFBzABhitodHRwOi8vb2NzcC5zdGFydHNz
+# bC5jb20vc3ViL2NsYXNzMi9jb2RlL2NhMEAGCCsGAQUFBzAChjRodHRwOi8vYWlh
+# LnN0YXJ0c3NsLmNvbS9jZXJ0cy9zdWIuY2xhc3MyLmNvZGUuY2EuY3J0MCMGA1Ud
+# EgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tLzANBgkqhkiG9w0BAQUFAAOC
+# AQEAhrzEV6zwoEtKjnFRhCsjwiPykVpo5Eiye77Ve801rQDiRKgSCCiW6g3HqedL
+# OtaSs65Sj2pm3Viea4KR0TECLcbCTgsdaHqw2x1yXwWBQWZEaV6EB05lIwfr94P1
+# SFpV43zkuc+bbmA3+CRK45LOcCNH5Tqq7VGTCAK5iM7tvHwFlbQRl+I6VEL2mjpF
+# NsuRjDOVrv/9qw/a22YJ9R7Y1D0vUSs3IqZx2KMUaYDP7H2mSRxJO2nADQZBtriF
+# gTyfD3lYV12MlIi5CQwe3QC6DrrfSMP33i5Wa/OFJiQ27WPxmScYVhiqozpImFT4
+# PU9goiBv9RKXdgTmZE1PN0NQ5jGCAzUwggMxAgEBMIGTMIGMMQswCQYDVQQGEwJJ
+# TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
+# YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
+# MiBQcmltYXJ5IEludGVybWVkaWF0ZSBPYmplY3QgQ0ECAgS4MAkGBSsOAwIaBQCg
+# eDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEE
+# AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJ
+# BDEWBBRVGw0FDSiaIi38dWteRUAg/9Pr6DANBgkqhkiG9w0BAQEFAASCAgCInvOZ
+# FdaNFzbf6trmFDZKMojyx3UjKMCqNjHVBbuKY0qXwFC/ElYDV1ShJ2CBZbdurydO
+# OQ6cIQ0KREOCwmX/xB49IlLHHUxNhEkVv7HGU3EKAFf9IBt9Yr7jikiR9cjIsfHK
+# 4cjkoKJL7g28yEpLLkHt1eo37f1Ga9lDWEa5Zq3U5yX+IwXhrUBm1h8Xr033FhTR
+# VEpuSz6LHtbrL/zgJnCzJ2ahjtJoYevdcWiNXffosJHFaSfYDDbiNsPRDH/1avmb
+# 5j/7BhP8BcBaR6Fp8tFbNGIcWHHGcjqLMnTc4w13b7b4pDhypqElBa4+lCmwdvv9
+# GydYtRgPz8GHeoBoKj30YBlMzRIfFYaIFGIC4Ai3UEXkuH9TxYohVbGm/W0Kl4Lb
+# RJ1FwiVcLcTOJdgNId2vQvKc+jtNrjcg5SP9h2v/C4aTx8tyc6tE3TOPh2f9b8DL
+# S+SbVArJpuJqrPTxDDoO1QNjTgLcdVYeZDE+r/NjaGZ6cMSd8db3EaG3ijD/0bud
+# SItbm/OlNVbQOFRR76D+ZNgPcU5iNZ3bmvQQIg6aSB9MHUpIE/SeCkNl9YeVk1/1
+# GFULgNMRmIYP4KLvu9ylh5Gu3hvD5VNhH6+FlXANwFy07uXks5uF8mfZVxVCnodG
+# xkNCx+6PsrA5Z7WP4pXcmYnMn97npP/Q9EHJWw==
+# SIG # End signature block
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/activate_this.py b/assignments/week06/athome/blog_djang/venv/Scripts/activate_this.py
new file mode 100644
index 00000000..ea12c28a
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/activate_this.py
@@ -0,0 +1,34 @@
+"""By using execfile(this_file, dict(__file__=this_file)) you will
+activate this virtualenv environment.
+
+This can be used when you must use an existing Python interpreter, not
+the virtualenv bin/python
+"""
+
+try:
+ __file__
+except NameError:
+ raise AssertionError(
+ "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
+import sys
+import os
+
+old_os_path = os.environ['PATH']
+os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
+base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+if sys.platform == 'win32':
+ site_packages = os.path.join(base, 'Lib', 'site-packages')
+else:
+ site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
+prev_sys_path = list(sys.path)
+import site
+site.addsitedir(site_packages)
+sys.real_prefix = sys.prefix
+sys.prefix = base
+# Move the added items to the front of the path:
+new_sys_path = []
+for item in list(sys.path):
+ if item not in prev_sys_path:
+ new_sys_path.append(item)
+ sys.path.remove(item)
+sys.path[:0] = new_sys_path
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/deactivate.bat b/assignments/week06/athome/blog_djang/venv/Scripts/deactivate.bat
new file mode 100644
index 00000000..52aabe5e
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/deactivate.bat
@@ -0,0 +1,18 @@
+@echo off
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+ set _OLD_VIRTUAL_PROMPT=
+)
+
+if defined _OLD_VIRTUAL_PYTHONHOME (
+ set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
+ set _OLD_VIRTUAL_PYTHONHOME=
+)
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+ set _OLD_VIRTUAL_PATH=
+)
+
+:END
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/django-admin.py b/assignments/week06/athome/blog_djang/venv/Scripts/django-admin.py
new file mode 100644
index 00000000..43027302
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/django-admin.py
@@ -0,0 +1,5 @@
+#!C:\cygwin\home\wtb\blog_djang\venv\Scripts\python.exe
+from django.core import management
+
+if __name__ == "__main__":
+ management.execute_from_command_line()
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7-script.py b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7-script.py
new file mode 100644
index 00000000..5b9327b2
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\blog_djang\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install-2.7'
+__requires__ = 'setuptools==0.6c11'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install-2.7')()
+)
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7.exe b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7.exe differ
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7.exe.manifest b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7.exe.manifest
new file mode 100644
index 00000000..32d05995
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-2.7.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-script.py b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-script.py
new file mode 100644
index 00000000..a0046207
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\blog_djang\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c11','console_scripts','easy_install'
+__requires__ = 'setuptools==0.6c11'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('setuptools==0.6c11', 'console_scripts', 'easy_install')()
+)
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/easy_install.exe b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install.exe differ
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/easy_install.exe.manifest b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install.exe.manifest
new file mode 100644
index 00000000..ea8659ad
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/easy_install.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7-script.py b/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7-script.py
new file mode 100644
index 00000000..a42bdcf5
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\blog_djang\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.2.1','console_scripts','pip-2.7'
+__requires__ = 'pip==1.2.1'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('pip==1.2.1', 'console_scripts', 'pip-2.7')()
+)
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7.exe b/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7.exe differ
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7.exe.manifest b/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7.exe.manifest
new file mode 100644
index 00000000..1e531b68
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/pip-2.7.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pip-script.py b/assignments/week06/athome/blog_djang/venv/Scripts/pip-script.py
new file mode 100644
index 00000000..e70da877
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/pip-script.py
@@ -0,0 +1,9 @@
+#!C:\cygwin\home\wtb\blog_djang\venv\Scripts\python.exe
+# EASY-INSTALL-ENTRY-SCRIPT: 'pip==1.2.1','console_scripts','pip'
+__requires__ = 'pip==1.2.1'
+import sys
+from pkg_resources import load_entry_point
+
+sys.exit(
+ load_entry_point('pip==1.2.1', 'console_scripts', 'pip')()
+)
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pip.exe b/assignments/week06/athome/blog_djang/venv/Scripts/pip.exe
new file mode 100644
index 00000000..8906ff77
Binary files /dev/null and b/assignments/week06/athome/blog_djang/venv/Scripts/pip.exe differ
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pip.exe.manifest b/assignments/week06/athome/blog_djang/venv/Scripts/pip.exe.manifest
new file mode 100644
index 00000000..98b524f4
--- /dev/null
+++ b/assignments/week06/athome/blog_djang/venv/Scripts/pip.exe.manifest
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/python.exe b/assignments/week06/athome/blog_djang/venv/Scripts/python.exe
new file mode 100644
index 00000000..f68a605b
Binary files /dev/null and b/assignments/week06/athome/blog_djang/venv/Scripts/python.exe differ
diff --git a/assignments/week06/athome/blog_djang/venv/Scripts/pythonw.exe b/assignments/week06/athome/blog_djang/venv/Scripts/pythonw.exe
new file mode 100644
index 00000000..42f32179
Binary files /dev/null and b/assignments/week06/athome/blog_djang/venv/Scripts/pythonw.exe differ