From 6808947714e520e7d3764a82b3b695567db08e6a Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Mon, 14 Jan 2013 00:01:55 +0000 Subject: [PATCH 01/19] adding client, server, and number checker files --- assignments/week01/athome/add_client.py | 32 ++++++++++++++++++++ assignments/week01/athome/add_server.py | 33 +++++++++++++++++++++ assignments/week01/athome/number_checker.py | 33 +++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 assignments/week01/athome/add_client.py create mode 100644 assignments/week01/athome/add_server.py create mode 100644 assignments/week01/athome/number_checker.py diff --git a/assignments/week01/athome/add_client.py b/assignments/week01/athome/add_client.py new file mode 100644 index 00000000..c0322211 --- /dev/null +++ b/assignments/week01/athome/add_client.py @@ -0,0 +1,32 @@ +import socket +import sys +from number_checker import * + +# Create a TCP/IP socket +ecs = socket.socket(2,1,0) +# Connect the socket to the port where the server is listening +# IP Address could change, set it below +uw_ip = '67.214.219.123' +remote_address = (uw_ip, 50000) +ecs.connect(remote_address) + +#Get the numbers to add from the user +number1 = get_number() +number2 = get_number() +#Put the numbers into a string to send via socket +#Add "|" as a marker for the server to split string +# TODO: Think about pickling data instead of going to strings. +data = str(number1) + "|" + str(number2) + +try: + #Send data + print "Sending the numbers to web server..." + ecs.sendall(data) + # Print the response + print "The web server returned:", ecs.recv(64) + + + +finally: + # close the socket to clean up + ecs.close() \ No newline at end of file diff --git a/assignments/week01/athome/add_server.py b/assignments/week01/athome/add_server.py new file mode 100644 index 00000000..1569d68d --- /dev/null +++ b/assignments/week01/athome/add_server.py @@ -0,0 +1,33 @@ +import socket +import sys +import exceptions + +# Function from StackOverflow to deal with floats +def num (s): + try: + return int(s) + except exceptions.ValueError: + return float(s) + + +# Create a TCP/IP socket +ess = socket.socket(2,1,0) +# Bind the socket to the port +#server_address = ('127.0.0.1', 50000) +ess.bind(('67.214.219.123', 50000)) +# Listen for incoming connections +ess.listen(1) +while True: + # Wait for a connection + con, cli = ess.accept() + try: + # Receive the data and send it back + echo = con.recv(64) + num1,num2 = echo.split("|",1) + sum_of_numbers = num(num1) + num(num2) + sum_of_numbers = str(sum_of_numbers) + con.sendall(sum_of_numbers) + + finally: + # Clean up the connection + con.close() diff --git a/assignments/week01/athome/number_checker.py b/assignments/week01/athome/number_checker.py new file mode 100644 index 00000000..14856314 --- /dev/null +++ b/assignments/week01/athome/number_checker.py @@ -0,0 +1,33 @@ +def get_number(): + '''Prompts the user to input a number. Will not be satisfied until a float or an int is passed''' + while True: + number = is_float_or_int(raw_input("Please enter a number: ")) + if not number: + continue + else: + return number + +def is_float_or_int(number): + '''Checks to see whether the input is a number (float or int), returns the number or False if it is neither.''' + try: + if "." in number: + number = float(number) + else: + number = int(number) + except ValueError: + return False + return number + +def unit_tests(): + input = ["asdf.asdf","1","-1","1.0","-1.0","asdf","0","1.000003", "1230498", "-230845", "...", "1..0", ".5", ".00002347921"] + + for i in input: + print "Input:", i + print "Output: ", is_float_or_int(i) + print "The resulting type was: ", type(is_float_or_int(i)) + print "\n" + +if __name__ == '__main__': + #unit_tests() + get_number() + \ No newline at end of file From 4474085bc4aac6672abfb2265ce5a350c43f0c30 Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Fri, 25 Jan 2013 07:16:18 +0000 Subject: [PATCH 02/19] j-archive scraper, work in progress --- assignments/week03/athome/get_j-archive.py | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 assignments/week03/athome/get_j-archive.py diff --git a/assignments/week03/athome/get_j-archive.py b/assignments/week03/athome/get_j-archive.py new file mode 100644 index 00000000..bd45d3a7 --- /dev/null +++ b/assignments/week03/athome/get_j-archive.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) From d1c76886fcc02af3e91b838c1e40bf590791158e Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Tue, 29 Jan 2013 20:59:00 -0800 Subject: [PATCH 03/19] attempting to commit to save work --- assignments/week01/athome/.metadata/.lock | 0 assignments/week01/athome/.metadata/.log | 21 + .../athome/.metadata/.mylyn/.tasks.xml.zip | Bin 0 -> 250 bytes .../.metadata/.mylyn/repositories.xml.zip | Bin 0 -> 364 bytes .../athome/.metadata/.mylyn/tasks.xml.zip | Bin 0 -> 250 bytes .../.root/.indexes/history.version | 1 + .../.root/.indexes/properties.index | Bin 0 -> 57 bytes .../.root/.indexes/properties.version | 1 + .../org.eclipse.core.resources/.root/1.tree | Bin 0 -> 136 bytes .../.safetable/org.eclipse.core.resources | Bin 0 -> 364 bytes .../com.android.ide.eclipse.adt.prefs | 4 + .../org.eclipse.core.resources.prefs | 3 + .../.settings/org.eclipse.jdt.ui.prefs | 14 + .../org.eclipse.mylyn.context.core.prefs | 3 + .../org.eclipse.mylyn.monitor.ui.prefs | 3 + .../.settings/org.eclipse.ui.ide.prefs | 6 + .../.settings/org.eclipse.ui.prefs | 3 + .../org.eclipse.jdt.core/invalidArchivesCache | Bin 0 -> 4 bytes .../org.eclipse.jdt.core/nonChainingJarsCache | Bin 0 -> 4 bytes .../variablesAndContainers.dat | Bin 0 -> 115 bytes .../org.eclipse.jdt.ui/OpenTypeHistory.xml | 2 + .../QualifiedTypeNameHistory.xml | 2 + .../org.eclipse.jdt.ui/dialog_settings.xml | 10 + .../dialog_settings.xml | 3 + .../org.eclipse.ui.workbench/workbench.xml | 250 +++ .../org.eclipse.ui.workbench/workingsets.xml | 4 + .../week01/athome/.metadata/version.ini | 1 + assignments/week01/athome/add_client.py | 9 +- assignments/week01/athome/add_server.py | 34 +- assignments/week01/athome/number_checker.py | 3 +- assignments/week01/athome/python/.project | 17 + .../week01/athome/python/.pydevproject | 7 + .../week01/athome/python/athome/asdf.py | 9 + .../athome/python/athome/assignment.txt | 15 + .../python/athome/get_hints_and_context.py | 29 + .../athome/python/athome/get_jarchive.py | 124 ++ .../week01/athome/python/athome/jparty.html | 1463 +++++++++++++++++ .../python/athome/play_jeopary_with_hints.py | 89 + .../week01/athome/python/lab/bs_jarchive.py | 83 + .../week01/athome/python/lab/echo_server.py | 25 + .../week01/athome/python/lab/http_serve1.py | 27 + .../week01/athome/python/lab/http_serve2.py | 39 + .../week01/athome/python/lab/http_serve3.py | 158 ++ .../week01/athome/python/lab/jarchive.py | 45 + .../week01/athome/python/lab/tiny_html.html | 11 + .../athome/python/lab/web/a_web_page.html | 11 + .../python/lab/web/images/JPEG_example.jpg | Bin 0 -> 15138 bytes .../lab/web/images/Sample_Scene_Balls.jpg | Bin 0 -> 146534 bytes .../athome/python/lab/web/images/sample_1.png | Bin 0 -> 8760 bytes .../week01/athome/python/lab/web/make_time.py | 25 + .../week01/athome/python/lab/web/sample.txt | 3 + assignments/week01/lab/echo_client.py | 13 +- assignments/week01/lab/echo_server.py | 21 +- assignments/week02/lab/class2.py | 37 + assignments/week02/lab/http_serve1.py | 27 + assignments/week02/lab/http_serve2.py | 39 + assignments/week02/lab/http_serve3.py | 64 + assignments/week02/lab/http_serve4.py | 71 + assignments/week03/athome/asdf.py | 9 + assignments/week03/athome/final.html | 65 + assignments/week03/athome/get_j-archive.py | 2 +- assignments/week03/athome/jparty.html | 1463 +++++++++++++++++ assignments/week03/athome/scraper.py | 89 + assignments/week04/lab/cgi-bin/lab1_cgi.py | 41 + 64 files changed, 4464 insertions(+), 34 deletions(-) create mode 100644 assignments/week01/athome/.metadata/.lock create mode 100644 assignments/week01/athome/.metadata/.log create mode 100644 assignments/week01/athome/.metadata/.mylyn/.tasks.xml.zip create mode 100644 assignments/week01/athome/.metadata/.mylyn/repositories.xml.zip create mode 100644 assignments/week01/athome/.metadata/.mylyn/tasks.xml.zip create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml create mode 100644 assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml create mode 100644 assignments/week01/athome/.metadata/version.ini create mode 100644 assignments/week01/athome/python/.project create mode 100644 assignments/week01/athome/python/.pydevproject create mode 100644 assignments/week01/athome/python/athome/asdf.py create mode 100644 assignments/week01/athome/python/athome/assignment.txt create mode 100644 assignments/week01/athome/python/athome/get_hints_and_context.py create mode 100644 assignments/week01/athome/python/athome/get_jarchive.py create mode 100644 assignments/week01/athome/python/athome/jparty.html create mode 100644 assignments/week01/athome/python/athome/play_jeopary_with_hints.py create mode 100644 assignments/week01/athome/python/lab/bs_jarchive.py create mode 100644 assignments/week01/athome/python/lab/echo_server.py create mode 100644 assignments/week01/athome/python/lab/http_serve1.py create mode 100644 assignments/week01/athome/python/lab/http_serve2.py create mode 100644 assignments/week01/athome/python/lab/http_serve3.py create mode 100644 assignments/week01/athome/python/lab/jarchive.py create mode 100644 assignments/week01/athome/python/lab/tiny_html.html create mode 100644 assignments/week01/athome/python/lab/web/a_web_page.html create mode 100644 assignments/week01/athome/python/lab/web/images/JPEG_example.jpg create mode 100644 assignments/week01/athome/python/lab/web/images/Sample_Scene_Balls.jpg create mode 100644 assignments/week01/athome/python/lab/web/images/sample_1.png create mode 100644 assignments/week01/athome/python/lab/web/make_time.py create mode 100644 assignments/week01/athome/python/lab/web/sample.txt create mode 100644 assignments/week02/lab/class2.py create mode 100644 assignments/week02/lab/http_serve1.py create mode 100644 assignments/week02/lab/http_serve2.py create mode 100644 assignments/week02/lab/http_serve3.py create mode 100644 assignments/week02/lab/http_serve4.py create mode 100644 assignments/week03/athome/asdf.py create mode 100644 assignments/week03/athome/final.html create mode 100644 assignments/week03/athome/jparty.html create mode 100644 assignments/week03/athome/scraper.py create mode 100644 assignments/week04/lab/cgi-bin/lab1_cgi.py diff --git a/assignments/week01/athome/.metadata/.lock b/assignments/week01/athome/.metadata/.lock new file mode 100644 index 00000000..e69de29b diff --git a/assignments/week01/athome/.metadata/.log b/assignments/week01/athome/.metadata/.log new file mode 100644 index 00000000..33550b63 --- /dev/null +++ b/assignments/week01/athome/.metadata/.log @@ -0,0 +1,21 @@ +!SESSION 2013-01-29 19:55:04.429 ----------------------------------------------- +eclipse.buildId=M20110909-1335 +java.version=1.7.0 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US +Command-line arguments: -os win32 -ws win32 -arch x86_64 + +!ENTRY org.eclipse.mylyn.tasks.ui 2 0 2013-01-29 19:55:09.014 +!MESSAGE No search provider was registed. Tasks search is not available. + +!ENTRY org.eclipse.ui 4 4 2013-01-29 20:50:13.444 +!MESSAGE Invalid preference page path: XML Syntax +!SESSION 2013-01-29 20:50:59.400 ----------------------------------------------- +eclipse.buildId=M20110909-1335 +java.version=1.7.0 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US +Command-line arguments: -os win32 -ws win32 -arch x86_64 + +!ENTRY org.eclipse.mylyn.tasks.ui 2 0 2013-01-29 20:51:03.532 +!MESSAGE No search provider was registed. Tasks search is not available. diff --git a/assignments/week01/athome/.metadata/.mylyn/.tasks.xml.zip b/assignments/week01/athome/.metadata/.mylyn/.tasks.xml.zip new file mode 100644 index 0000000000000000000000000000000000000000..33efac3d0d14000a96a89f7d2462e74a0d01f078 GIT binary patch literal 250 zcmWIWW@Zs#;Nak3a9d{U#DD~Nfb5dQ;_RHv;u5`z+?>rD*Pl2WsNt=vb?(gh&7nqD zj01u^&U&BoKY7M`dngxg;pMFXK^l6VXS_YnoILNnHT2Z!@J-t{b9(BW`*u=CFOZ}8 zr3urkmJVz6X-k$p7Z25{U?_dcu(joxs&k9c>Y(5$B7cO64Ozav&H0j;c8ifAz?+>z sI9JxV0O*b>Kpf!B$Rxsma4WJL$gQXV+2sM=tZX1zMj*5T(yPEq0hS&}^#A|> literal 0 HcmV?d00001 diff --git a/assignments/week01/athome/.metadata/.mylyn/repositories.xml.zip b/assignments/week01/athome/.metadata/.mylyn/repositories.xml.zip new file mode 100644 index 0000000000000000000000000000000000000000..82f39269f17afb916d93435b9875e13c4cedfe3b GIT binary patch literal 364 zcmWIWW@Zs#;Nak35T0-A#DD|@fb62wg8bsllKi5~)MCAg+?=Ho4gHx7d0PK_J((+$ z!!v#LE`v~}g@?MF&c!VL^+==4t3UpHXIE1co4{<<-+Ry3<%$2Ec!sar#gA{@8&wIP z#@{p8*!f@2?#_-Vd3)>hH#uYP5Iw=8cf!tw%J*AY%$#|~Y}q}=!VfIV#H_BxZz!H} z(c+P`ddUWvjYl5L7Cn90h}T0SVF!;G^HH6Q)e_1n?sGR z7zYG-ob^8EfAWm?_E0X~!pmC&f;99z&v<*DIeFfDYv`%d;hVN^=JeD#_wA&PULZ&F zOB1G7EgjbC)0QlIE*`2?!BF~?VQb4XRp%C?)j`2iME(dB8?tFG|--P0qzbKV~ vzql+HDXBRniLMm|nMH{unfZC~`97<6 e6azy6hqBztoXR}ClEmWdV!hH#Tc~2({sRCi@_b(a literal 0 HcmV?d00001 diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs new file mode 100644 index 00000000..fd30f8c5 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs @@ -0,0 +1,4 @@ +#Tue Jan 29 20:50:13 PST 2013 +com.android.ide.eclipse.adt.sdk=C\:\\android-sdk +eclipse.preferences.version=1 +com.android.ide.eclipse.adt.fixLegacyEditors=1 diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..fe1e80e7 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Tue Jan 29 20:50:13 PST 2013 +version=1 +eclipse.preferences.version=1 diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000..9fe4ed9a --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,14 @@ +#Tue Jan 29 20:50:13 PST 2013 +useQuickDiffPrefPage=true +proposalOrderMigrated=true +tabWidthPropagated=true +content_assist_proposals_background=255,255,255 +org.eclipse.jdt.ui.javadoclocations.migrated=true +useAnnotationsPrefPage=true +org.eclipse.jface.textfont=1|Consolas|10.0|0|WINDOWS|1|0|0|0|0|0|0|0|0|1|0|0|0|0|Consolas; +org.eclipse.jdt.ui.editor.tab.width= +org.eclipse.jdt.ui.formatterprofiles.version=12 +spelling_locale_initialized=true +eclipse.preferences.version=1 +content_assist_proposals_foreground=0,0,0 +fontPropagated=true diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs new file mode 100644 index 00000000..57356199 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs @@ -0,0 +1,3 @@ +#Tue Jan 29 19:55:08 PST 2013 +eclipse.preferences.version=1 +mylyn.attention.migrated=true diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs new file mode 100644 index 00000000..fb919936 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs @@ -0,0 +1,3 @@ +#Tue Jan 29 19:55:08 PST 2013 +org.eclipse.mylyn.monitor.activity.tracking.enabled.checked=true +eclipse.preferences.version=1 diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs new file mode 100644 index 00000000..ac02e1af --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -0,0 +1,6 @@ +#Tue Jan 29 20:50:13 PST 2013 +eclipse.preferences.version=1 +tipsAndTricks=true +platformState=1318351369963 +quickStart=false +PROBLEMS_FILTERS_MIGRATE=true diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs new file mode 100644 index 00000000..d85a9928 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs @@ -0,0 +1,3 @@ +#Tue Jan 29 19:55:10 PST 2013 +eclipse.preferences.version=1 +showIntro=false diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat new file mode 100644 index 0000000000000000000000000000000000000000..46ba64d9130e8140814ad681109ca5fe45fb96df GIT binary patch literal 115 zcmZQzU|?c^05&ki + diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml new file mode 100644 index 00000000..9e390f50 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -0,0 +1,2 @@ + + diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml new file mode 100644 index 00000000..919f1d26 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml @@ -0,0 +1,10 @@ + +
+
+ + + + + +
+
diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml new file mode 100644 index 00000000..5ca0b776 --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -0,0 +1,3 @@ + +
+
diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml new file mode 100644 index 00000000..3a88c7bf --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml new file mode 100644 index 00000000..3e73ac4d --- /dev/null +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/assignments/week01/athome/.metadata/version.ini b/assignments/week01/athome/.metadata/version.ini new file mode 100644 index 00000000..c51ff745 --- /dev/null +++ b/assignments/week01/athome/.metadata/version.ini @@ -0,0 +1 @@ +org.eclipse.core.runtime=1 \ No newline at end of file diff --git a/assignments/week01/athome/add_client.py b/assignments/week01/athome/add_client.py index c0322211..a1c8f499 100644 --- a/assignments/week01/athome/add_client.py +++ b/assignments/week01/athome/add_client.py @@ -3,7 +3,9 @@ from number_checker import * # Create a TCP/IP socket -ecs = socket.socket(2,1,0) +ecs = socket.socket(socket.AF_INET, + socket.SOCK_STREAM, + socket.IPPROTO_IP) # Connect the socket to the port where the server is listening # IP Address could change, set it below uw_ip = '67.214.219.123' @@ -14,7 +16,6 @@ number1 = get_number() number2 = get_number() #Put the numbers into a string to send via socket -#Add "|" as a marker for the server to split string # TODO: Think about pickling data instead of going to strings. data = str(number1) + "|" + str(number2) @@ -23,9 +24,7 @@ print "Sending the numbers to web server..." ecs.sendall(data) # Print the response - print "The web server returned:", ecs.recv(64) - - + print "The web server returned:", ecs.recv(64) finally: # close the socket to clean up diff --git a/assignments/week01/athome/add_server.py b/assignments/week01/athome/add_server.py index 1569d68d..77269c2f 100644 --- a/assignments/week01/athome/add_server.py +++ b/assignments/week01/athome/add_server.py @@ -11,23 +11,29 @@ def num (s): # Create a TCP/IP socket -ess = socket.socket(2,1,0) +ess = socket.socket(socket.AF_INET, + socket.SOCK_STREAM, + socket.IPPROTO_IP) # Bind the socket to the port #server_address = ('127.0.0.1', 50000) -ess.bind(('67.214.219.123', 50000)) +server_ip = '67.214.219.123' +ess.bind((server_ip, 50000)) # Listen for incoming connections ess.listen(1) -while True: +try: + while True: # Wait for a connection - con, cli = ess.accept() - try: + con, cli = ess.accept() + try: # Receive the data and send it back - echo = con.recv(64) - num1,num2 = echo.split("|",1) - sum_of_numbers = num(num1) + num(num2) - sum_of_numbers = str(sum_of_numbers) - con.sendall(sum_of_numbers) - - finally: - # Clean up the connection - con.close() + echo = con.recv(64) + num1,num2 = echo.split("|",1) + sum_of_numbers = num(num1) + num(num2) + sum_of_numbers = str(sum_of_numbers) + con.sendall(sum_of_numbers) + finally: + con.close() + print "Returning sum:", sum_of_numbers +except KeyboardInterrupt: + # Clean up the connection + ess.close() diff --git a/assignments/week01/athome/number_checker.py b/assignments/week01/athome/number_checker.py index 14856314..494569ce 100644 --- a/assignments/week01/athome/number_checker.py +++ b/assignments/week01/athome/number_checker.py @@ -1,8 +1,9 @@ def get_number(): - '''Prompts the user to input a number. Will not be satisfied until a float or an int is passed''' + '''Prompts the user to input a number. Will not be satisfied until a float or an int is passed.''' while True: number = is_float_or_int(raw_input("Please enter a number: ")) if not number: + print "You did not enter a number. Please try again." continue else: return number diff --git a/assignments/week01/athome/python/.project b/assignments/week01/athome/python/.project new file mode 100644 index 00000000..33ca22cb --- /dev/null +++ b/assignments/week01/athome/python/.project @@ -0,0 +1,17 @@ + + + python + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/assignments/week01/athome/python/.pydevproject b/assignments/week01/athome/python/.pydevproject new file mode 100644 index 00000000..a9cca037 --- /dev/null +++ b/assignments/week01/athome/python/.pydevproject @@ -0,0 +1,7 @@ + + + + +Default +python 2.7 + diff --git a/assignments/week01/athome/python/athome/asdf.py b/assignments/week01/athome/python/athome/asdf.py new file mode 100644 index 00000000..2d25e199 --- /dev/null +++ b/assignments/week01/athome/python/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/week01/athome/python/athome/assignment.txt b/assignments/week01/athome/python/athome/assignment.txt new file mode 100644 index 00000000..3b0f2ec3 --- /dev/null +++ b/assignments/week01/athome/python/athome/assignment.txt @@ -0,0 +1,15 @@ +Complete your HTTP Web Server. Accomplish as many of the following goals as +you are able: + +* If you were unable to complete the first five steps in class, circle back + and finish them + +* Complete the 'Bonus point' parts from the first five steps, if you haven't + already done so + +* Format your directory listing as HTML + +* In the HTML directory listing, make the files clickable links + +* Add a new, dynamic endpoint. If the URI /time-page is requested, return an + HTML page with the current time displayed. \ No newline at end of file diff --git a/assignments/week01/athome/python/athome/get_hints_and_context.py b/assignments/week01/athome/python/athome/get_hints_and_context.py new file mode 100644 index 00000000..27623425 --- /dev/null +++ b/assignments/week01/athome/python/athome/get_hints_and_context.py @@ -0,0 +1,29 @@ +from get_jarchive import * +import urllib +import urllib2 +from bs4 import BeautifulSoup + + +bs = get_jarchive_html(True) +categories = get_categories(bs) +clue_dictionary = get_clues(bs, categories) + + + +for x in range(1,7): + for y in range (1,6): + clue = "clue_J_" + str(x) + "_" + str(y) + + print clue_dictionary[clue]["correct_answer"] + +#article = urllib.quote(article) +# + +#opener = urllib2.build_opener() +#opener.addheaders = [('User-agent', 'Mozilla/5.0')] #wikipedia needs this + +#resource = opener.open("http://en.wikipedia.org/wiki/" + article) +#data = resource.read() +#resource.close() +#soup = BeautifulSoup(data) +#print soup.find('div',id="bodyContent").p \ No newline at end of file diff --git a/assignments/week01/athome/python/athome/get_jarchive.py b/assignments/week01/athome/python/athome/get_jarchive.py new file mode 100644 index 00000000..7fc223eb --- /dev/null +++ b/assignments/week01/athome/python/athome/get_jarchive.py @@ -0,0 +1,124 @@ +from bs4 import BeautifulSoup +import urllib2 + +def get_jarchive_html(debug): + if debug == False: + game_id = raw_input("Please type in the a game number you wish to get: ") + url = "http://www.j-archive.com/showgame.php?game_id=" + str(game_id) + response = urllib2.urlopen(url) + #Added this in class 1/28 + if response.code == 200: + html = response.read() + else: + raise Exception + + bs = BeautifulSoup(html) + return bs_html + elif debug == True: + path = raw_input("Please type in the relative path to the html that you have on your local disk for J-Archive HTML: ") + print "You entered, ", path + f = open (str(path), "r") + data = f.read() + bs = BeautifulSoup(data) + return bs + +def get_categories(bs): + ''' Scrape the BeautifulSoup object that's passed in for the categories + and return a list of categories: + - [0-5] - Jeopardy Round Categories + - [6-11] - Double Jeopardy Round Categories + - [12] - Final Jeopardy Category + ''' + 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: + categories.append(cat.text) + return categories + + +def get_clues(bs, categories): + """Scrape the Beautiful Soup for all of the Jeopardy, Double Jeopary, and Final Jeopary clues. + Returns a dictionary of clue dictionaries. Each clue is in the following format with the exception of + the fj_clue which does not have a row: + "round" : round, + "category" : category, + "row" : row, + "dollar_value": dollar_value, + "clue_text" : clue_text, + "correct_answer": answer, + "daily_double" : dd + """ + allClues = bs.findAll(attrs={"class" : "clue"}) + clue_dictionary = {} + for clue in allClues: + if not clue.find("div"): + #There isn't a div included, which means that this question was never answered. + #TODO: Fix logic to create a clue with the correct clue information, but a null clue + # text and answer because a user might ask for this clue and we don't have an actual clue. + continue + else: + if not clue.find(attrs={"class" : "clue_value"}): + dd = True + dollar_value = clue.find(atts={"class" : "clue_value_daily_double"}) + else: + dd = False + 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 + 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)] + round = clue_props[1] + category_number = clue_props[2] + category = categories[int(category_number)] + row = clue_props[3] + clue_name = "clue_" + str(round) + "_" + str(category_number) + "_" + str(row) + clue = { + "round" : round, + "category" : category, + "row" : row, + "dollar_value": dollar_value, + "clue_text" : clue_text, + "correct_answer": answer, + "daily_double" : dd + } + + clue_dictionary[clue_name] = clue + fj_clue = get_final_jeopardy(bs, categories) + clue_dictionary["clue_fj"] = fj_clue + return clue_dictionary + +def get_final_jeopardy(bs_html, categories): + """ Grab the Final Jeopardy clue and return a clue dicionary to be added to the + clue dictionary. + """ + category = categories[-1] + clue_text = bs_html.find("td",{"id": "clue_FJ"}).text + finalj = bs_html.find("div", {"id": "final_jeopardy_round"}) + div = finalj.find("div") + #TODO: Grab category_comments + #category_comments = finalj.find(atts={"class": "category_comments"}).text + mouseover_js = div['onmouseover'].split(",",2) + answer_soup = BeautifulSoup(mouseover_js[2]) + answer = answer_soup.find('em').text + dollar_value = 0 + dd = False + clue = { + "round" : "FJ", + "category" : category, + "dollar_value": dollar_value, + "clue_text" : clue_text, + "correct_answer": answer, + "daily_double" : dd + } + return clue + +#bs = get_jarchive_html(True) +#categories = get_categories(bs) +#clue_dictionary = get_clues(bs, categories) \ No newline at end of file diff --git a/assignments/week01/athome/python/athome/jparty.html b/assignments/week01/athome/python/athome/jparty.html new file mode 100644 index 00000000..cf95bfb5 --- /dev/null +++ b/assignments/week01/athome/python/athome/jparty.html @@ -0,0 +1,1463 @@ + + + +J! Archive - Show #619, aired 1987-04-23 + + + + + + +
+

Show #619 - Thursday, April 23, 1987

+
Richard Cordray game 3.
+
+

Contestants

+ + + + +
+ [<< previous game] + +

Bob Hansen, a proofreader from St. Paul, Minnesota

+

Maureen Girr, a homemaker from Newport, Rhode Island

+

Richard Cordray, a judicial clerk from Grove City, Ohio (whose 2-day cash winnings total $18,201)

+
+ [next game >>] +
+
+
+

Jeopardy! Round

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
EUROPE
+
+ + + + +
SPORTS
+
+ + + + +
FASHION
+
+ + + + +
HOLIDAYS
+
+ + + + +
LYRICS
+
+ + + + +
THE MAIN INGREDIENT
+
+ + + + + + + +
+
+ + + + + + +
   $10026
+
+
Louis the Stubborn, Louis the Do-Nothing, & Louis from Overseas were all kings of this country
+
+ + + + + + + +
+
+ + + + + + +
   $10014
+
+
This offshoot of soccer is named for a school in England
+
+ + + + + + + +
+
+ + + + + + +
   $1008
+
+
Last name of designers Calvin & Anne, II
+
+ + + + + + + +
+
+ + + + + + +
   $10024
+
+
It's the 1st U.S. federal holiday of the year
+
+ + + + + + + +
+
+ + + + + + +
   $10021
+
+
"Who can take a sunrise, sprinkle it with dew, cover it in choc'late & a miracle or two?"
+
+ + + + + + + +
+
+ + + + + + +
   $1003
+
+
It tops the other 7 juices in V-8
+
+ + + + + + + +
+
+ + + + + + +
   $20015
+
+
European capital that contains the Lenin Library, the Lenin Stadium & the Lenin Mausoleum
+
+ + + + + + + +
+
+ + + + + + +
   $20017
+
+
The overarm "crawl" swimming stroke was introduced to England in 1902 from this country
+
+ + + + + + + +
+
+ + + + + + +
   $2009
+
+
Playboy okays wearing both suspenders & this, but only if trying out for nerd of the year
+
+ + + + + + + +
+
+ + + + + + +
   $20027
+
+
Flower most associated with Memorial Day
+
+ + + + + + + +
+
+ + + + + + +
   $20022
+
+
"He rocks in the tree-top all day long"
+
+ + + + + + + +
+
+ + + + + + +
   $2004
+
+
This main ingredient in S.O.S. pads helps you scour out scum
+
+ + + + + + + +
+
+ + + + + + +
   $30012
+
+
Country whose capital was formerly called Koebnannehavn, meaning "Merchants' Harbor"
+
+ + + + + + + +
+
+ + + + + + +
   $3001
+
+
Springfield, Massachusetts is site of this sport's Hall of Fame
+
+ + + + + + + +
+
+ + + + + + +
   $30018
+
+
He helped dress fake troops to fool the Germans in WWII, but didn't put a "BB" on the uniforms
+
+ + + + + + + +
+
+ + + + + + +
   $30016
+
+
In 1987, this holiday will be observed for the 212th time
+
+ + + + + + + +
+
+ + + + + + +
   $30028
+
+
"Wider than a mile; I'm crossin' you in style some day"
+
+ + + + + + + +
+
+ + + + + + +
   $3005
+
+
It tops the list on the Fritos bag
+
+ + + + + + + +
+
+ + + + + + +
   $4002
+
+
This low country's oldest university is the State University of Leiden, founded in 1575
+
+ + + + + + + +
+
+ + + + + + +
   $40013
+
+
Marks which distinguish Wilson footballs used in college games from the ones they make for the pros
+
+ + + + + + + +
+
+ + + + + + +
   $40019
+
+
Newsweek joked a museum for this apparel invented in 1946 might consist of 2 domes & a pyramid
+
+ + + + + + + +
+
+ + + + + + +
   $40023
+
+
Wintertime Jewish holiday that's mentioned in the New Testament but not in the Jewish Bible
+
+ + + + + + + +
+
+ + + + + + +
   $40029
+
+
"Doesn't have a point of view, knows not where he's going to, isn't he a bit like you & me?"
+
+ + + + + + + +
+
+ + + + + + +
   $4006
+
+
In Jell-O, it's sugar, but in sugar-free Jell-O, the main ingredient is this
+
+ + + + + + + +
+
+ + + + + + +
   $50011
+
+
Affair with Magda Lupescu kept Carol II from assuming the throne of this country for 3 years
+
+ + + + + + + +
+
+ + + + + + +
   $50010
+
+
When he KO'd Ingemar Johansson, 6/20/60, he became 1st man to regain heavyweight championship
+
+ + + + + + + +
+
+ + + + + + +
   DD: $30020
+
+
They probably got their name from the fact they were 4" longer than ordinary knickerbockers
+
+ + + + + + + +
+
+ + + + + + +
   $50025
+
+
Flag Day is a legal holiday only in this state, where Betsy Ross worked as a seamstress
+
+ + + + + + + +
+
+ + + + + + +
   $50030
+
+
"'Cause I can't explain the tears that I shed over you, over you"
+
+ + + + + + + +
+
+ + + + + + +
   $5007
+
+
It's the #1 ingredient in A.1. steak sauce & Johnson's baby shampoo, too
+
+

Scores at the first commercial break (after clue 13):

+ + + + + + + + + + + + +
RichardMaureenBob
$1,500$500$400
+ +

Scores at the end of the Jeopardy! Round:

+ + + + + + + + + + + + +
RichardMaureenBob
$2,800$1,400$800
+
+
+

Double Jeopardy! Round

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
AMERICAN RIVERS
+
+ + + + +
CONSTELLATIONS
+
+ + + + +
THE BODY HUMAN
+
+ + + + +
NEIGHBORHOODS
+
+ + + + +
STARS WITH "C"
+
+ + + + +
ACTORS & ROLE
(Alex: These have to do with different stars who have performed the same person--ficticious or real--on film or on stage.)
+
+ + + + + + + +
+
+ + + + + + +
   $2001
+
+
Longest American river east of the Mississippi is this tributary of the Mississippi
+
+ + + + + + + +
+
+ + + + + + +
   $2008
+
+
The word constellation is from Latin meaning these "together"
+
+ + + + + + + +
+
+ + + + + + +
   $2003
+
+
An ECG is used to detect arrhythmias in this organ
+
+ + + + + + + +
+
+ + + + + + +
   $20022
+
+
The Back Bay has been described as this New England's city's "Yuppieville"
+
+ + + + + + + +
+
+ + + + + + +
   $20016
+
+
Italian for "small house", it usually contains one-armed bandits & blackjacks
+
+ + + + + + + +
+
+ + + + + + +
   $20015
+
+
Errol Flynn, Doug Fairbanks, & Sean Connery have all been this nemesis of the Sheriff of Nottingham
+
+ + + + + + + +
+
+ + + + + + +
   $4004
+
+
State in which you'll find the Chicasawhay, Pascahoula & Yazoo Rivers
+
+ + + + + + + +
+
+ + + + + + +
   $4007
+
+
Myth says Orion was put on opposite side of sky from this creature which had stung him to death
+
+ + + + + + + +
+
+ + + + + + +
   $4009
+
+
The floor of the nasal cavity is also the roof of this
+
+ + + + + + + +
+
+ + + + + + +
   $40026
+
+
You can visit the Martin Luther King, Jr. historic district in this city
+
+ + + + + + + +
+
+ + + + + + +
   $40017
+
+
Property accepted as security on a loan, it also can mean running side by side
+
+ + + + + + + +
+
+ + + + + + +
   $40023
+
+
Walter Huston, Henry Fonda, Raymond Massey & Hal Holbrook all played this Kentucky-born president
+
+ + + + + + + +
+
+ + + + + + +
   $60012
+
+
Much of this main tributary of the Hudson, named for an Indian tribe, is part of the Erie Canal
+
+ + + + + + + +
+
+ + + + + + +
   DD: $1,2006
+
+
1 of the 5 constellations which are portrayed as all or part horse
+
+ + + + + + + +
+
+ + + + + + +
   $60010
+
+
The most prominent muscle on the anterior aspect of the arm
+
+ + + + + + + +
+
+ + + + + + +
   $60027
+
+
City whose North Beach neighborhood no longer has a beach
+
+ + + + + + + +
+
+ + + + + + +
   $60018
+
+
The burnt, dark-brown liquid obtained by heating sugar
+
+ + + + + + + +
+
+ + + + + + +
   $60024
+
+
Doctor portrayed on film by Elliott Gould & on TV by Wayne Rogers & Pernell Roberts
+
+ + + + + + + +
+
+ + + + + + +
   $80013
+
+
North America's deepest chasm, Hells Canyon, is formed by this twisting river
+
+ + + + + + + +
+
+ + + + + + +
   $8002
+
+
In legend, it's the part of Berenice, an Egyptian princess, that became a constellation
+
+ + + + + + + +
+
+ + + + + + +
   $80011
+
+
Its cone-shaped bony socket is called the "orbit"
+
+ + + + + + + +
+
+ + + + + + +
   DD: $1,20028
+
+
Neighborhood mentioned in title of this tune, Mike Hammer's TV theme:
+
+ + + + + + + +
+
+ + + + + + +
   $80019
+
+
In the 1st line of her radio show theme, Little Orphan Annie was described as 1 of these
+
+ + + + + + + +
+
+ + + + + + +
   $80025
+
+
C. Laughton, T. Howard & A. Hopkins were all adrift playing this part
+
+ + + + + + + +
+
+ + + + + + +
   $100014
+
+
Ironically, this West Virginia river is believed to be the oldest in North America
+
+ + + + + + + +
+
+ + + + + + +
   $10005
+
+
When a constellation "culminates", it has reached this
+
+ + + + + + + +
+
+ + + + + + +
   $100021
+
+
They are contained in the right & left pleural sacs
+
+ + + + + + + + +
+
+ + + + + + +
   $100020
+
+
Branches of this evergreen tree are used as a symbol of mourning
+
+
+

Scores at the end of the Double Jeopardy! Round:

+ + + + + + + + + + + + + + + + + +
RichardMaureenBob
$6,400$2,800$2,000
(lock game)
+

[wagering suggestions for these scores]

+
+
+

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:

+ + + + + + + + + + + + + + + + +
RichardMaureenBob
$5,601$0$2,500
3-day champion: $23,8023rd place: ladies' & gentlemen's matched watch set from the Club Collection of Daniel Mink watches2nd place: a trip to Dallas, Texas aboard Delta Airlines, with standard and wide-body service, with stay at the Viscount Hotel
+ +

Game dynamics:

+ Game dynamics graph + +

Coryat scores:

+ + + + + + + + + + + + + + + + +
RichardMaureenBob
$5,800$3,000$3,200
19 R
(including 1 DD),
3 W
17 R
(including 1 DD),
5 W
9 R,
3 W
(including 1 DD)
+ +

Combined Coryat: $12,000

+

[game responses] [game scores] [suggest correction]

+
+ + + +
+ +
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 @@ + + +

This is a header

+

+ and this is some regular text +

+

+ and some more +

+ + diff --git a/assignments/week01/athome/python/lab/web/a_web_page.html b/assignments/week01/athome/python/lab/web/a_web_page.html new file mode 100644 index 00000000..82e96100 --- /dev/null +++ b/assignments/week01/athome/python/lab/web/a_web_page.html @@ -0,0 +1,11 @@ + + + + +

My First Heading

+ +

My first paragraph.

+ + + + 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 0000000000000000000000000000000000000000..13506f01e9a514c53dc52cc7cbf499f52a29b6f8 GIT binary patch literal 15138 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1c0ccade2de6ac61a164052ed4a7da9fe9ce2068 GIT binary patch literal 146534 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%0AG!bll7=qnQE!?zJg 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 z z1n`K}5F9YiPwP-htXt+8`FKCXDo9kzaAIIo2ITwt)YGDi!VsJ&!vbk;Quk3+L^5!Z zFpv+Ko4pZ+X-Fz^pDqV+N**hFy{mH5F(daxSe3b#c7<-#CRiXR z*R4TzLAXVd77j-adK$JsT~(Pu+*b?_pr+igGKk#BTPL^5DR(PyXuoiqo1F1c$%kMQ z8<&E8D#+Z$ayJ;r&UmWRz|9iL5e18U*yw$zK+wmx5TJ1p<+)+dQ^JOVJf2C-Nikou z?UH7Vk0AiaV@`6uM0i|*(*lMhicb+AKG4h#-*74`vyOPnU!){_h z1J~&Gh zj>y0snaQ9NvMsIOl;v5nqtlv3xQbH8a}4{{V)q$4qre`V(|*$YhJ=X6ZL|lep%_*i zNW;@2gpuMUl0rw)szWJ|3{?6mPRR-B&u%HEcsF$*{b~o1 z`T(T%#YQ)l`O^UO;7}ISzZKxg+aUv{L8i%m(J%vhfzqm=5#_SGaZt6 z6Sw9#B>MB(x~~stD`PwpLvtfCfEW+}Z~nDaOkFHG=9Z*FgzCE@e+BqN>a$6wUdJ_^ z?0|V{@sLntWtbdbZO%Um_6-N&!+2}NhT6{cuQa48;hA=sNa$E}<0k^0qTR`>Uj4S@ z@3~+zA?k22KSBCeeW5Uwju&<@&3tA*h%psq?Be-j%c}fOZx5E!rD?rg&CNSXid*UL zb^~=e%#z>�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 x7uH_R#?^%;kmAuC#$UjQOmE(xFnt1Dwe_Dy| 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 KBK{cNAOG3+Y*1+c literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5b2f52dff2428c82276821909e466d877ea7608b GIT binary patch literal 8760 zcmeAS@N?(olHy`uVBq!ia0y~yVA%k|9Be?5*NU6Z11XkbC(jTLAgJL;=>YOM3p^r= z85p>QK$!8;-MT+OLD3S|h!W?b)Wnj^{5*w_%-mE4V|^nFeFMvP`oBR6WIzgn^V3So z6N^$A98>a>QWe}Xi&D$;i?WLqoP&*LTytY)U{GN2ba4!+nDgeAVcuZ}0T#!32mjYs z%32kxRNW4`%B}XWG2_k5*R!}88m3$RTgSi<_bR&@XgUMKAGZTcKuW=Plo}0!(Nr*+ z5k|{`(c*9@)(CI!$uZcx&*5kIVImjTu;27HbHnnTqm|ldr3S0iKnWzk*!Z?ELj!;L zxtsGCCOl%|2Iln!6UISKZKj9gb3=AH^qts{+ zjHZIoj4)ajj24H3yhhl)ot=SU&s=aN_VY;fp4}h5#UwBS9X&w}LY2iEr&qIlcs$45 z&eQy=;qzU4_I|jxXEy_b{*xh6Sr7Ww#Ha%Ye~WK4jz;5X2y{$FlPT%R6x^9ppEdL5 zJz%x>A$|v?LljN#%ic<~CMs|=DX{7B1wh0THU0t`zyBS38eT2isM znHjRqSpqxO3=9>I8(D#r!>oo;YBUILZM9|i(Ye`{;lchhIr_lVA;hl(N{yFT1_QP3 zE#raZGl2s^2YjD{T_-k}TsJ6!Xw(sdBdLzY!)QDZQEKkJ#{jH^8CyYX0f-AXhEBaSd?N0SG)@{an^LB{Ts5b?$DF literal 0 HcmV?d00001 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:

+ + + + + + + + + + + + + + + + +
RichardMaureenBob
$5,601$0$2,500
3-day champion: $23,8023rd place: ladies' & gentlemen's matched watch set from the Club Collection of Daniel Mink watches2nd place: a trip to Dallas, Texas aboard Delta Airlines, with standard and wide-body service, with stay at the Viscount Hotel
+

Game dynamics:

+Game dynamics graph +

Coryat scores:

+ + + + + + + + + + + + + + + + +
RichardMaureenBob
$5,800$3,000$3,200
19 R
(including 1 DD),
3 W
17 R
(including 1 DD),
5 W
9 R,
3 W
(including 1 DD)
+

Combined Coryat: $12,000

+

[game responses] [game scores] [suggest correction]

+
\ No newline at end of file diff --git a/assignments/week03/athome/get_j-archive.py b/assignments/week03/athome/get_j-archive.py index bd45d3a7..46bb3103 100644 --- a/assignments/week03/athome/get_j-archive.py +++ b/assignments/week03/athome/get_j-archive.py @@ -42,4 +42,4 @@ def get_clues(bs): print clue_props #categories = get_categories(bs_html) -get_clues(bs_html) +#get_clues(bs_html) diff --git a/assignments/week03/athome/jparty.html b/assignments/week03/athome/jparty.html new file mode 100644 index 00000000..cf95bfb5 --- /dev/null +++ b/assignments/week03/athome/jparty.html @@ -0,0 +1,1463 @@ + + + +J! Archive - Show #619, aired 1987-04-23 + + + + + + +
+

Show #619 - Thursday, April 23, 1987

+
Richard Cordray game 3.
+
+

Contestants

+ + + + +
+ [<< previous game] + +

Bob Hansen, a proofreader from St. Paul, Minnesota

+

Maureen Girr, a homemaker from Newport, Rhode Island

+

Richard Cordray, a judicial clerk from Grove City, Ohio (whose 2-day cash winnings total $18,201)

+
+ [next game >>] +
+
+
+

Jeopardy! Round

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
EUROPE
+
+ + + + +
SPORTS
+
+ + + + +
FASHION
+
+ + + + +
HOLIDAYS
+
+ + + + +
LYRICS
+
+ + + + +
THE MAIN INGREDIENT
+
+ + + + + + + +
+
+ + + + + + +
   $10026
+
+
Louis the Stubborn, Louis the Do-Nothing, & Louis from Overseas were all kings of this country
+
+ + + + + + + +
+
+ + + + + + +
   $10014
+
+
This offshoot of soccer is named for a school in England
+
+ + + + + + + +
+
+ + + + + + +
   $1008
+
+
Last name of designers Calvin & Anne, II
+
+ + + + + + + +
+
+ + + + + + +
   $10024
+
+
It's the 1st U.S. federal holiday of the year
+
+ + + + + + + +
+
+ + + + + + +
   $10021
+
+
"Who can take a sunrise, sprinkle it with dew, cover it in choc'late & a miracle or two?"
+
+ + + + + + + +
+
+ + + + + + +
   $1003
+
+
It tops the other 7 juices in V-8
+
+ + + + + + + +
+
+ + + + + + +
   $20015
+
+
European capital that contains the Lenin Library, the Lenin Stadium & the Lenin Mausoleum
+
+ + + + + + + +
+
+ + + + + + +
   $20017
+
+
The overarm "crawl" swimming stroke was introduced to England in 1902 from this country
+
+ + + + + + + +
+
+ + + + + + +
   $2009
+
+
Playboy okays wearing both suspenders & this, but only if trying out for nerd of the year
+
+ + + + + + + +
+
+ + + + + + +
   $20027
+
+
Flower most associated with Memorial Day
+
+ + + + + + + +
+
+ + + + + + +
   $20022
+
+
"He rocks in the tree-top all day long"
+
+ + + + + + + +
+
+ + + + + + +
   $2004
+
+
This main ingredient in S.O.S. pads helps you scour out scum
+
+ + + + + + + +
+
+ + + + + + +
   $30012
+
+
Country whose capital was formerly called Koebnannehavn, meaning "Merchants' Harbor"
+
+ + + + + + + +
+
+ + + + + + +
   $3001
+
+
Springfield, Massachusetts is site of this sport's Hall of Fame
+
+ + + + + + + +
+
+ + + + + + +
   $30018
+
+
He helped dress fake troops to fool the Germans in WWII, but didn't put a "BB" on the uniforms
+
+ + + + + + + +
+
+ + + + + + +
   $30016
+
+
In 1987, this holiday will be observed for the 212th time
+
+ + + + + + + +
+
+ + + + + + +
   $30028
+
+
"Wider than a mile; I'm crossin' you in style some day"
+
+ + + + + + + +
+
+ + + + + + +
   $3005
+
+
It tops the list on the Fritos bag
+
+ + + + + + + +
+
+ + + + + + +
   $4002
+
+
This low country's oldest university is the State University of Leiden, founded in 1575
+
+ + + + + + + +
+
+ + + + + + +
   $40013
+
+
Marks which distinguish Wilson footballs used in college games from the ones they make for the pros
+
+ + + + + + + +
+
+ + + + + + +
   $40019
+
+
Newsweek joked a museum for this apparel invented in 1946 might consist of 2 domes & a pyramid
+
+ + + + + + + +
+
+ + + + + + +
   $40023
+
+
Wintertime Jewish holiday that's mentioned in the New Testament but not in the Jewish Bible
+
+ + + + + + + +
+
+ + + + + + +
   $40029
+
+
"Doesn't have a point of view, knows not where he's going to, isn't he a bit like you & me?"
+
+ + + + + + + +
+
+ + + + + + +
   $4006
+
+
In Jell-O, it's sugar, but in sugar-free Jell-O, the main ingredient is this
+
+ + + + + + + +
+
+ + + + + + +
   $50011
+
+
Affair with Magda Lupescu kept Carol II from assuming the throne of this country for 3 years
+
+ + + + + + + +
+
+ + + + + + +
   $50010
+
+
When he KO'd Ingemar Johansson, 6/20/60, he became 1st man to regain heavyweight championship
+
+ + + + + + + +
+
+ + + + + + +
   DD: $30020
+
+
They probably got their name from the fact they were 4" longer than ordinary knickerbockers
+
+ + + + + + + +
+
+ + + + + + +
   $50025
+
+
Flag Day is a legal holiday only in this state, where Betsy Ross worked as a seamstress
+
+ + + + + + + +
+
+ + + + + + +
   $50030
+
+
"'Cause I can't explain the tears that I shed over you, over you"
+
+ + + + + + + +
+
+ + + + + + +
   $5007
+
+
It's the #1 ingredient in A.1. steak sauce & Johnson's baby shampoo, too
+
+

Scores at the first commercial break (after clue 13):

+ + + + + + + + + + + + +
RichardMaureenBob
$1,500$500$400
+ +

Scores at the end of the Jeopardy! Round:

+ + + + + + + + + + + + +
RichardMaureenBob
$2,800$1,400$800
+
+
+

Double Jeopardy! Round

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
AMERICAN RIVERS
+
+ + + + +
CONSTELLATIONS
+
+ + + + +
THE BODY HUMAN
+
+ + + + +
NEIGHBORHOODS
+
+ + + + +
STARS WITH "C"
+
+ + + + +
ACTORS & ROLE
(Alex: These have to do with different stars who have performed the same person--ficticious or real--on film or on stage.)
+
+ + + + + + + +
+
+ + + + + + +
   $2001
+
+
Longest American river east of the Mississippi is this tributary of the Mississippi
+
+ + + + + + + +
+
+ + + + + + +
   $2008
+
+
The word constellation is from Latin meaning these "together"
+
+ + + + + + + +
+
+ + + + + + +
   $2003
+
+
An ECG is used to detect arrhythmias in this organ
+
+ + + + + + + +
+
+ + + + + + +
   $20022
+
+
The Back Bay has been described as this New England's city's "Yuppieville"
+
+ + + + + + + +
+
+ + + + + + +
   $20016
+
+
Italian for "small house", it usually contains one-armed bandits & blackjacks
+
+ + + + + + + +
+
+ + + + + + +
   $20015
+
+
Errol Flynn, Doug Fairbanks, & Sean Connery have all been this nemesis of the Sheriff of Nottingham
+
+ + + + + + + +
+
+ + + + + + +
   $4004
+
+
State in which you'll find the Chicasawhay, Pascahoula & Yazoo Rivers
+
+ + + + + + + +
+
+ + + + + + +
   $4007
+
+
Myth says Orion was put on opposite side of sky from this creature which had stung him to death
+
+ + + + + + + +
+
+ + + + + + +
   $4009
+
+
The floor of the nasal cavity is also the roof of this
+
+ + + + + + + +
+
+ + + + + + +
   $40026
+
+
You can visit the Martin Luther King, Jr. historic district in this city
+
+ + + + + + + +
+
+ + + + + + +
   $40017
+
+
Property accepted as security on a loan, it also can mean running side by side
+
+ + + + + + + +
+
+ + + + + + +
   $40023
+
+
Walter Huston, Henry Fonda, Raymond Massey & Hal Holbrook all played this Kentucky-born president
+
+ + + + + + + +
+
+ + + + + + +
   $60012
+
+
Much of this main tributary of the Hudson, named for an Indian tribe, is part of the Erie Canal
+
+ + + + + + + +
+
+ + + + + + +
   DD: $1,2006
+
+
1 of the 5 constellations which are portrayed as all or part horse
+
+ + + + + + + +
+
+ + + + + + +
   $60010
+
+
The most prominent muscle on the anterior aspect of the arm
+
+ + + + + + + +
+
+ + + + + + +
   $60027
+
+
City whose North Beach neighborhood no longer has a beach
+
+ + + + + + + +
+
+ + + + + + +
   $60018
+
+
The burnt, dark-brown liquid obtained by heating sugar
+
+ + + + + + + +
+
+ + + + + + +
   $60024
+
+
Doctor portrayed on film by Elliott Gould & on TV by Wayne Rogers & Pernell Roberts
+
+ + + + + + + +
+
+ + + + + + +
   $80013
+
+
North America's deepest chasm, Hells Canyon, is formed by this twisting river
+
+ + + + + + + +
+
+ + + + + + +
   $8002
+
+
In legend, it's the part of Berenice, an Egyptian princess, that became a constellation
+
+ + + + + + + +
+
+ + + + + + +
   $80011
+
+
Its cone-shaped bony socket is called the "orbit"
+
+ + + + + + + +
+
+ + + + + + +
   DD: $1,20028
+
+
Neighborhood mentioned in title of this tune, Mike Hammer's TV theme:
+
+ + + + + + + +
+
+ + + + + + +
   $80019
+
+
In the 1st line of her radio show theme, Little Orphan Annie was described as 1 of these
+
+ + + + + + + +
+
+ + + + + + +
   $80025
+
+
C. Laughton, T. Howard & A. Hopkins were all adrift playing this part
+
+ + + + + + + +
+
+ + + + + + +
   $100014
+
+
Ironically, this West Virginia river is believed to be the oldest in North America
+
+ + + + + + + +
+
+ + + + + + +
   $10005
+
+
When a constellation "culminates", it has reached this
+
+ + + + + + + +
+
+ + + + + + +
   $100021
+
+
They are contained in the right & left pleural sacs
+
+ + + + + + + + +
+
+ + + + + + +
   $100020
+
+
Branches of this evergreen tree are used as a symbol of mourning
+
+
+

Scores at the end of the Double Jeopardy! Round:

+ + + + + + + + + + + + + + + + + +
RichardMaureenBob
$6,400$2,800$2,000
(lock game)
+

[wagering suggestions for these scores]

+
+
+

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:

+ + + + + + + + + + + + + + + + +
RichardMaureenBob
$5,601$0$2,500
3-day champion: $23,8023rd place: ladies' & gentlemen's matched watch set from the Club Collection of Daniel Mink watches2nd place: a trip to Dallas, Texas aboard Delta Airlines, with standard and wide-body service, with stay at the Viscount Hotel
+ +

Game dynamics:

+ Game dynamics graph + +

Coryat scores:

+ + + + + + + + + + + + + + + + +
RichardMaureenBob
$5,800$3,000$3,200
19 R
(including 1 DD),
3 W
17 R
(including 1 DD),
5 W
9 R,
3 W
(including 1 DD)
+ +

Combined Coryat: $12,000

+

[game responses] [game scores] [suggest correction]

+
+ + + +
+ +
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/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, From 7b69eea445131cb3e00273da1907a9e3c5330ca6 Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Wed, 30 Jan 2013 22:52:42 -0800 Subject: [PATCH 04/19] adding work in process for server --- .../week04/athome/bookdb_wsgi_server.py | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 assignments/week04/athome/bookdb_wsgi_server.py diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py new file mode 100644 index 00000000..4381e388 --- /dev/null +++ b/assignments/week04/athome/bookdb_wsgi_server.py @@ -0,0 +1,137 @@ +#!/usr/bin/python +import datetime +import bookdb +import pprint +body = """ + +WSGI Server - BookDB + + +

The BookDB

+ +%s + + +""" + +''' +def application(environ, start_response): + bookdb = get_bookdb() + print bookdb + titles = get_title_list(bookdb) + ids = get_ids(bookdb) + if get_path_info(environ) == "/": + html = make_html_for_main_page(titles, ids) + response_body = body % (html) + status = '200 OK' + response_headers = [('Content-Type', 'text/html'), + ('Content-Length', str(len(response_body)))] + start_response(status, response_headers) + #pp = pprint.PrettyPrinter() + #pp.pprint(environ) + #print environ + return [response_body] + elif "id" in get_path_info(environ): + #this means the user is looking for a book... + path = get_path_info(environ) + print "THE PATH: ", path + return make_html_for_book_info_page(path, database) +''' + +def application(environ, start_response): + bookdb = get_bookdb() + titles = get_title_list(bookdb) + ids = get_ids(bookdb) + if get_path_info(environ) == "/": + html = make_html_for_main_page(titles, ids) + response_body = body % (html) + status = '200 OK' + response_headers = [('Content-Type', 'text/html'), + ('Content-Length', str(len(response_body)))] + start_response(status, response_headers) + #pp = pprint.PrettyPrinter() + #pp.pprint(environ) + #print environ + return [response_body] + +def get_bookdb(): + 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): + 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): + 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): + book_id = path[1:] + book_id = str(book_id) + print "book_id: ", book_id + print "DB:" , database[book_id]["title"] + #for entries in database[book_id]: + html = "
  • TITLE: {0}
  • ".format(database[book_id]["title"]) + print html + return html + #return "Here is the book information for {0} : {1}".format(id,) + +#bookdb = get_bookdb() +#print make_html_for_book_info_page(bookdb, "id3") + + +def get_path_info(environ): + return environ.get("PATH_INFO", "Sorry, couldn't find that.") + + + + +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', 8080, application) + srv.serve_forever() + From bcd31d2a4b400c26b01d8ac6bb728407f3b7a686 Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Wed, 30 Jan 2013 23:14:17 -0800 Subject: [PATCH 05/19] working product on localhost. there will be some trickiness when going to VM. also, need to add error checking --- .../week04/athome/bookdb_wsgi_server.py | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py index 4381e388..1c973f0f 100644 --- a/assignments/week04/athome/bookdb_wsgi_server.py +++ b/assignments/week04/athome/bookdb_wsgi_server.py @@ -39,22 +39,25 @@ def application(environ, start_response): ''' def application(environ, start_response): - bookdb = get_bookdb() + bookdb = get_titles() titles = get_title_list(bookdb) ids = get_ids(bookdb) - if get_path_info(environ) == "/": + path = get_path_info(environ) + if "id" in path: + html = make_html_for_book_info_page(path,database) + else: html = make_html_for_main_page(titles, ids) - response_body = body % (html) - status = '200 OK' - response_headers = [('Content-Type', 'text/html'), - ('Content-Length', str(len(response_body)))] - start_response(status, response_headers) - #pp = pprint.PrettyPrinter() - #pp.pprint(environ) - #print environ - return [response_body] - -def get_bookdb(): + response_body = body % (html) + status = '200 OK' + response_headers = [('Content-Type', 'text/html'), + ('Content-Length', str(len(response_body)))] + start_response(status, response_headers) + #pp = pprint.PrettyPrinter() + #pp.pprint(environ) + #print environ + return [response_body] + +def get_titles(): return bookdb.BookDB().titles() def get_title_list(bookdb): @@ -84,10 +87,8 @@ def make_html_for_main_page(titles, ids): def make_html_for_book_info_page(path, bookdb): book_id = path[1:] book_id = str(book_id) - print "book_id: ", book_id - print "DB:" , database[book_id]["title"] - #for entries in database[book_id]: - html = "
  • TITLE: {0}
  • ".format(database[book_id]["title"]) + 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 print html return html #return "Here is the book information for {0} : {1}".format(id,) From ec372649d4a1bb8c2788049b6fad7c3454d7214b Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Thu, 31 Jan 2013 13:51:35 -0800 Subject: [PATCH 06/19] added image and some error handling, added some TODOs --- .../week04/athome/bookdb_wsgi_server.py | 208 +++++++++--------- 1 file changed, 105 insertions(+), 103 deletions(-) diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py index 1c973f0f..1a48e9f7 100644 --- a/assignments/week04/athome/bookdb_wsgi_server.py +++ b/assignments/week04/athome/bookdb_wsgi_server.py @@ -2,137 +2,139 @@ import datetime import bookdb import pprint +import StringIO +import Image body = """ WSGI Server - BookDB -

    The BookDB

    - +Books +
    +

    The BookDB

    %s - """ -''' -def application(environ, start_response): - bookdb = get_bookdb() - print bookdb - titles = get_title_list(bookdb) - ids = get_ids(bookdb) - if get_path_info(environ) == "/": - html = make_html_for_main_page(titles, ids) - response_body = body % (html) - status = '200 OK' - response_headers = [('Content-Type', 'text/html'), - ('Content-Length', str(len(response_body)))] - start_response(status, response_headers) - #pp = pprint.PrettyPrinter() - #pp.pprint(environ) - #print environ - return [response_body] - elif "id" in get_path_info(environ): - #this means the user is looking for a book... - path = get_path_info(environ) - print "THE PATH: ", path - return make_html_for_book_info_page(path, database) -''' - def application(environ, start_response): - bookdb = get_titles() - titles = get_title_list(bookdb) - ids = get_ids(bookdb) - path = get_path_info(environ) - if "id" in path: - html = make_html_for_book_info_page(path,database) - else: - html = make_html_for_main_page(titles, ids) - response_body = body % (html) - status = '200 OK' - response_headers = [('Content-Type', 'text/html'), - ('Content-Length', str(len(response_body)))] - start_response(status, response_headers) - #pp = pprint.PrettyPrinter() - #pp.pprint(environ) - #print environ - return [response_body] + 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) + 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() + 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 + titles = [] + i = 0 + while i < len(bookdb): + titles.append(bookdb[i]['title']) + i = i + 1 + return titles def get_ids(bookdb): - ids = [] - i = 0 - while i < len(bookdb): - ids.append(bookdb[i]['id']) - i = i + 1 - return ids + """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): - html = '' - i = 0 - for title in titles: - html = "{1}
    ".format(str(ids[i]) ,title) + html - i = i + 1 - return html + """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): - 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 - print html - return html - #return "Here is the book information for {0} : {1}".format(id,) - -#bookdb = get_bookdb() -#print make_html_for_book_info_page(bookdb, "id3") + """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): - return environ.get("PATH_INFO", "Sorry, couldn't find that.") - + """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', - }, + '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', 8080, application) - srv.serve_forever() + from wsgiref.simple_server import make_server + srv = make_server('localhost', 8081, application) + srv.serve_forever() From 5f01b67226ff7524db8680dbf7c8fd344555a7dd Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Thu, 31 Jan 2013 15:33:05 -0800 Subject: [PATCH 07/19] ugly but working way to return images via WSGI, TODOs remain... --- .../week04/athome/bookdb_wsgi_server.py | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py index 1a48e9f7..11b6780f 100644 --- a/assignments/week04/athome/bookdb_wsgi_server.py +++ b/assignments/week04/athome/bookdb_wsgi_server.py @@ -2,14 +2,14 @@ import datetime import bookdb import pprint -import StringIO -import Image +import cStringIO +from PIL import Image body = """ WSGI Server - BookDB -Books +Books

    The BookDB

    %s @@ -29,7 +29,21 @@ def application(environ, start_response): if "id" in path: html = make_html_for_book_info_page(path,database) elif path == "/": - html = make_html_for_main_page(titles, ids) + html = make_html_for_main_page(titles, ids) + elif "books.png" in path: + #TODO: create method to return image--this is really quite ugly + 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) @@ -88,6 +102,7 @@ def make_html_for_book_info_page(path, bookdb): #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 From 177fee64f179f1ec8ba68a5b7fbcedaa8ed859ca Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Thu, 31 Jan 2013 16:50:30 -0800 Subject: [PATCH 08/19] added reference to website that helped explain serving image via WSGI --- assignments/week04/athome/bookdb_wsgi_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py index 11b6780f..ee0cb011 100644 --- a/assignments/week04/athome/bookdb_wsgi_server.py +++ b/assignments/week04/athome/bookdb_wsgi_server.py @@ -32,6 +32,7 @@ def application(environ, start_response): 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 From c0feee6c133d6cfabd7ffb43bf616bebfc352f2b Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Thu, 31 Jan 2013 17:30:00 -0800 Subject: [PATCH 09/19] tweaked html layout --- assignments/week04/athome/bookdb_wsgi_server.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/assignments/week04/athome/bookdb_wsgi_server.py b/assignments/week04/athome/bookdb_wsgi_server.py index ee0cb011..43042665 100644 --- a/assignments/week04/athome/bookdb_wsgi_server.py +++ b/assignments/week04/athome/bookdb_wsgi_server.py @@ -9,11 +9,10 @@ WSGI Server - BookDB -Books -
    -

    The BookDB

    +

    BooksThe BookDB

    %s +
    (c) WTB 2013
    """ def application(environ, start_response): From f8bd1d9c301359c783c9d8c58d12107039fea8af Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Sat, 2 Feb 2013 14:32:55 -0800 Subject: [PATCH 10/19] updated version of wsgi server --- assignments/week04/athome/book_html.py | 39 ++++++++++ assignments/week04/athome/wsgi_book_server.py | 72 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 assignments/week04/athome/book_html.py create mode 100644 assignments/week04/athome/wsgi_book_server.py diff --git a/assignments/week04/athome/book_html.py b/assignments/week04/athome/book_html.py new file mode 100644 index 00000000..d0af8d3e --- /dev/null +++ b/assignments/week04/athome/book_html.py @@ -0,0 +1,39 @@ +#!/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

    + + """ + + back_button_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/wsgi_book_server.py b/assignments/week04/athome/wsgi_book_server.py new file mode 100644 index 00000000..579b972c --- /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 UNCHAGED. # +######################################################################################## + +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() \ No newline at end of file From 033d427220d487567fce801cd7283a0d88feabfa Mon Sep 17 00:00:00 2001 From: pwnee Date: Sat, 2 Feb 2013 14:40:25 -0800 Subject: [PATCH 11/19] Update assignments/week04/athome/wsgi_book_server.py fixed typo --- assignments/week04/athome/wsgi_book_server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignments/week04/athome/wsgi_book_server.py b/assignments/week04/athome/wsgi_book_server.py index 579b972c..44e314a9 100644 --- a/assignments/week04/athome/wsgi_book_server.py +++ b/assignments/week04/athome/wsgi_book_server.py @@ -6,7 +6,7 @@ ######################################################################################## # 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 UNCHAGED. # +# THE FUNCTIONS not_found AND application REMAIN UNCHANGED. # ######################################################################################## def debug_mode(bool): @@ -69,4 +69,4 @@ def application(environ, start_response): from wsgiref.simple_server import make_server server_name = debug_mode(True) srv = make_server(server_name, 8080, application) - srv.serve_forever() \ No newline at end of file + srv.serve_forever() From cc39188ca471960e31dd4c2c142bc36d006c3a03 Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Sat, 2 Feb 2013 14:48:55 -0800 Subject: [PATCH 12/19] minor html tweaks --- assignments/week04/athome/book_html.py | 8 +++++++- assignments/week04/athome/wsgi_book_server.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/assignments/week04/athome/book_html.py b/assignments/week04/athome/book_html.py index d0af8d3e..fba20990 100644 --- a/assignments/week04/athome/book_html.py +++ b/assignments/week04/athome/book_html.py @@ -33,7 +33,13 @@ def make_html_for_book_info_page(path, database):

    PUBLISHER: publisher

    """ + html = """ + + Book Info - {0} + +

    WSGI - Book Database

    + """.format(database[path]["title"]) back_button_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 + 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/wsgi_book_server.py b/assignments/week04/athome/wsgi_book_server.py index 44e314a9..1c512b6e 100644 --- a/assignments/week04/athome/wsgi_book_server.py +++ b/assignments/week04/athome/wsgi_book_server.py @@ -6,7 +6,7 @@ ######################################################################################## # 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. # +# THE FUNCTIONS not_found AND application REMAIN UNCHANGED. # ######################################################################################## def debug_mode(bool): From 806fa7331210999a8e97533d190bf730334321d5 Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Sat, 2 Feb 2013 15:02:06 -0800 Subject: [PATCH 13/19] adding README --- assignments/week04/athome/README.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 assignments/week04/athome/README.txt 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 From fd8e94825ba5e004e5434d6df2245c7f30296933 Mon Sep 17 00:00:00 2001 From: Wilson Bull Date: Mon, 11 Feb 2013 19:04:27 -0800 Subject: [PATCH 14/19] pushing code so i can pull down remotely --- .../athome/.metadata/.mylyn/.tasks.xml.zip | Bin 250 -> 250 bytes .../athome/.metadata/.mylyn/tasks.xml.zip | Bin 250 -> 250 bytes .../org.eclipse.ui.workbench/workbench.xml | 10 +- assignments/week04/athome/assignment.txt | 1 + assignments/week04/athome/bookdb.py | 1 + .../athome/bookdb_wsgi_server_PIL_NEEDED.py | 155 ++++++++++++++++ assignments/week04/athome/example.py | 75 ++++++++ .../athome/wsgi_book_server_no_image.py | 172 ++++++++++++++++++ .../week04/lab/src/lab2_wsgi_template.py | 2 +- assignments/week05/athome/cherry_app.py | 48 +++++ .../week05/athome/cherry_app_tests.py.py | 26 +++ assignments/week05/athome/schema.sql | 6 + .../week05/athome/templates/index.html | 16 ++ .../week05/athome/venv/Scripts/activate | 80 ++++++++ .../week05/athome/venv/Scripts/activate.bat | 26 +++ .../week05/athome/venv/Scripts/activate.ps1 | 148 +++++++++++++++ .../athome/venv/Scripts/activate_this.py | 34 ++++ .../week05/athome/venv/Scripts/cherryd | 109 +++++++++++ .../week05/athome/venv/Scripts/deactivate.bat | 18 ++ .../venv/Scripts/easy_install-2.7-script.py | 9 + .../athome/venv/Scripts/easy_install-2.7.exe | Bin 0 -> 7168 bytes .../Scripts/easy_install-2.7.exe.manifest | 17 ++ .../venv/Scripts/easy_install-script.py | 9 + .../athome/venv/Scripts/easy_install.exe | Bin 0 -> 7168 bytes .../venv/Scripts/easy_install.exe.manifest | 17 ++ .../athome/venv/Scripts/pip-2.7-script.py | 9 + .../week05/athome/venv/Scripts/pip-2.7.exe | Bin 0 -> 7168 bytes .../athome/venv/Scripts/pip-2.7.exe.manifest | 17 ++ .../week05/athome/venv/Scripts/pip-script.py | 9 + .../week05/athome/venv/Scripts/pip.exe | Bin 0 -> 7168 bytes .../athome/venv/Scripts/pip.exe.manifest | 17 ++ .../week05/athome/venv/Scripts/python.exe | Bin 0 -> 26624 bytes .../week05/athome/venv/Scripts/pythonw.exe | Bin 0 -> 27136 bytes assignments/week05/lab/venv/Scripts/activate | 80 ++++++++ .../week05/lab/venv/Scripts/activate.bat | 26 +++ .../week05/lab/venv/Scripts/activate.ps1 | 148 +++++++++++++++ .../week05/lab/venv/Scripts/activate_this.py | 34 ++++ .../week05/lab/venv/Scripts/deactivate.bat | 18 ++ .../venv/Scripts/easy_install-2.7-script.py | 9 + .../lab/venv/Scripts/easy_install-2.7.exe | Bin 0 -> 7168 bytes .../Scripts/easy_install-2.7.exe.manifest | 17 ++ .../lab/venv/Scripts/easy_install-script.py | 9 + .../week05/lab/venv/Scripts/easy_install.exe | Bin 0 -> 7168 bytes .../venv/Scripts/easy_install.exe.manifest | 17 ++ .../week05/lab/venv/Scripts/pip-2.7-script.py | 9 + .../week05/lab/venv/Scripts/pip-2.7.exe | Bin 0 -> 7168 bytes .../lab/venv/Scripts/pip-2.7.exe.manifest | 17 ++ .../week05/lab/venv/Scripts/pip-script.py | 9 + assignments/week05/lab/venv/Scripts/pip.exe | Bin 0 -> 7168 bytes .../week05/lab/venv/Scripts/pip.exe.manifest | 17 ++ .../week05/lab/venv/Scripts/python.exe | Bin 0 -> 26624 bytes .../week05/lab/venv/Scripts/pythonw.exe | Bin 0 -> 27136 bytes 52 files changed, 1438 insertions(+), 3 deletions(-) create mode 100644 assignments/week04/athome/bookdb_wsgi_server_PIL_NEEDED.py create mode 100644 assignments/week04/athome/example.py create mode 100644 assignments/week04/athome/wsgi_book_server_no_image.py create mode 100644 assignments/week05/athome/cherry_app.py create mode 100644 assignments/week05/athome/cherry_app_tests.py.py create mode 100644 assignments/week05/athome/schema.sql create mode 100644 assignments/week05/athome/templates/index.html create mode 100644 assignments/week05/athome/venv/Scripts/activate create mode 100644 assignments/week05/athome/venv/Scripts/activate.bat create mode 100644 assignments/week05/athome/venv/Scripts/activate.ps1 create mode 100644 assignments/week05/athome/venv/Scripts/activate_this.py create mode 100644 assignments/week05/athome/venv/Scripts/cherryd create mode 100644 assignments/week05/athome/venv/Scripts/deactivate.bat create mode 100644 assignments/week05/athome/venv/Scripts/easy_install-2.7-script.py create mode 100644 assignments/week05/athome/venv/Scripts/easy_install-2.7.exe create mode 100644 assignments/week05/athome/venv/Scripts/easy_install-2.7.exe.manifest create mode 100644 assignments/week05/athome/venv/Scripts/easy_install-script.py create mode 100644 assignments/week05/athome/venv/Scripts/easy_install.exe create mode 100644 assignments/week05/athome/venv/Scripts/easy_install.exe.manifest create mode 100644 assignments/week05/athome/venv/Scripts/pip-2.7-script.py create mode 100644 assignments/week05/athome/venv/Scripts/pip-2.7.exe create mode 100644 assignments/week05/athome/venv/Scripts/pip-2.7.exe.manifest create mode 100644 assignments/week05/athome/venv/Scripts/pip-script.py create mode 100644 assignments/week05/athome/venv/Scripts/pip.exe create mode 100644 assignments/week05/athome/venv/Scripts/pip.exe.manifest create mode 100644 assignments/week05/athome/venv/Scripts/python.exe create mode 100644 assignments/week05/athome/venv/Scripts/pythonw.exe create mode 100644 assignments/week05/lab/venv/Scripts/activate create mode 100644 assignments/week05/lab/venv/Scripts/activate.bat create mode 100644 assignments/week05/lab/venv/Scripts/activate.ps1 create mode 100644 assignments/week05/lab/venv/Scripts/activate_this.py create mode 100644 assignments/week05/lab/venv/Scripts/deactivate.bat create mode 100644 assignments/week05/lab/venv/Scripts/easy_install-2.7-script.py create mode 100644 assignments/week05/lab/venv/Scripts/easy_install-2.7.exe create mode 100644 assignments/week05/lab/venv/Scripts/easy_install-2.7.exe.manifest create mode 100644 assignments/week05/lab/venv/Scripts/easy_install-script.py create mode 100644 assignments/week05/lab/venv/Scripts/easy_install.exe create mode 100644 assignments/week05/lab/venv/Scripts/easy_install.exe.manifest create mode 100644 assignments/week05/lab/venv/Scripts/pip-2.7-script.py create mode 100644 assignments/week05/lab/venv/Scripts/pip-2.7.exe create mode 100644 assignments/week05/lab/venv/Scripts/pip-2.7.exe.manifest create mode 100644 assignments/week05/lab/venv/Scripts/pip-script.py create mode 100644 assignments/week05/lab/venv/Scripts/pip.exe create mode 100644 assignments/week05/lab/venv/Scripts/pip.exe.manifest create mode 100644 assignments/week05/lab/venv/Scripts/python.exe create mode 100644 assignments/week05/lab/venv/Scripts/pythonw.exe diff --git a/assignments/week01/athome/.metadata/.mylyn/.tasks.xml.zip b/assignments/week01/athome/.metadata/.mylyn/.tasks.xml.zip index 33efac3d0d14000a96a89f7d2462e74a0d01f078..db3b1aa15a69aade8db59c852f609e238b3abb78 100644 GIT binary patch delta 24 gcmeyx_=}M{z?+#xgn@&DgJJeW?$wO5CvJBJ08k(X*#H0l delta 24 fcmeyx_=}M{z?+#xgn@&DgTZYg_i9GBiQAn4OV0)` diff --git a/assignments/week01/athome/.metadata/.mylyn/tasks.xml.zip b/assignments/week01/athome/.metadata/.mylyn/tasks.xml.zip index db3b1aa15a69aade8db59c852f609e238b3abb78..03be81466ef6fcc00e45917a645e3bc36b59c43e 100644 GIT binary patch delta 25 hcmeyx_=}Mzz?+#xgn@&DgJJf{i9D+rS5DmF1OQpl2a*5) delta 25 hcmeyx_=}Mzz?+#xgn@&DgJJfvi9D+rmrdN^1OQp82aEs! diff --git a/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml index 3a88c7bf..65f3c121 100644 --- a/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml +++ b/assignments/week01/athome/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml @@ -1,7 +1,7 @@ - + - + @@ -235,6 +235,12 @@ + + + + + + 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/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_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 + + +

    BooksThe BookDB

    +%s + +
    (c) WTB 2013
    +""" + +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_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 + + +

    BooksThe BookDB

    +%s + +
    (c) WTB 2013
    +""" + +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/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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..f68a605bc88fe0c80029cccb7c6c064aede1ae0a GIT binary patch literal 26624 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 literal 0 HcmV?d00001 diff --git a/assignments/week05/athome/venv/Scripts/pythonw.exe b/assignments/week05/athome/venv/Scripts/pythonw.exe new file mode 100644 index 0000000000000000000000000000000000000000..42f3217912407ea5afa005e04c94862eb0f24adf GIT binary patch literal 27136 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..8906ff77a26d30d63766158b2cebe1284188e637 GIT binary patch literal 7168 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 + + + + + + + + + + + + \ 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 0000000000000000000000000000000000000000..f68a605bc88fe0c80029cccb7c6c064aede1ae0a GIT binary patch literal 26624 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 literal 0 HcmV?d00001 diff --git a/assignments/week05/lab/venv/Scripts/pythonw.exe b/assignments/week05/lab/venv/Scripts/pythonw.exe new file mode 100644 index 0000000000000000000000000000000000000000..42f3217912407ea5afa005e04c94862eb0f24adf GIT binary patch literal 27136 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 literal 0 HcmV?d00001 From 498682ac736bf1b1fb1de5e919319d3966ad81ae Mon Sep 17 00:00:00 2001 From: uw Date: Tue, 12 Feb 2013 05:02:09 +0000 Subject: [PATCH 15/19] up and running version of flaskr blog. created by following steps from lab --- assignments/week05/lab/flaskr_1/flaskr.py | 95 ++++++++++++++- .../week05/lab/flaskr_1/flaskr_tests.py | 110 ++++++++++++++++++ assignments/week05/lab/flaskr_1/schema.sql | 6 + .../week05/lab/flaskr_1/static/style.css | 17 +++ .../week05/lab/flaskr_1/templates/layout.html | 22 ++++ .../week05/lab/flaskr_1/templates/login.html | 22 ++++ .../lab/flaskr_1/templates/show_entries.html | 30 +++++ 7 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 assignments/week05/lab/flaskr_1/static/style.css create mode 100644 assignments/week05/lab/flaskr_1/templates/layout.html create mode 100644 assignments/week05/lab/flaskr_1/templates/login.html create mode 100644 assignments/week05/lab/flaskr_1/templates/show_entries.html 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

    +