From d0b483e5a1676baea55766609c22f0b542cdbad9 Mon Sep 17 00:00:00 2001 From: bparrish206 Date: Fri, 10 Jan 2014 16:41:02 -0800 Subject: [PATCH 1/5] Update echo_server.py --- assignments/session01/echo_server.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/assignments/session01/echo_server.py b/assignments/session01/echo_server.py index 217380fb..270f7c69 100644 --- a/assignments/session01/echo_server.py +++ b/assignments/session01/echo_server.py @@ -7,16 +7,18 @@ def server(log_buffer=sys.stderr): address = ('127.0.0.1', 10000) # TODO: Replace the following line with your code which will instantiate # a TCP socket with IPv4 Addressing, call the socket you make 'sock' - sock = None + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) # TODO: Set an option to allow the socket address to be reused immediately # see the end of http://docs.python.org/2/library/socket.html + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # log that we are building a server print >>log_buffer, "making a server on {0}:{1}".format(*address) # TODO: bind your new sock 'sock' to the address above and begin to listen # for incoming connections - + sock.bind(address) + sock.listen(1) try: # the outer loop controls the creation of new connection sockets. The # server will handle each incoming connection one at a time. @@ -28,7 +30,8 @@ def server(log_buffer=sys.stderr): # the client so we can report it below. Replace the # following line with your code. It is only here to prevent # syntax errors - addr = ('bar', 'baz') + conn, client_address = sock.accept() + try: print >>log_buffer, 'connection - {0}:{1}'.format(*addr) @@ -41,12 +44,15 @@ def server(log_buffer=sys.stderr): # following line with your code. It's only here as # a placeholder to prevent an error in string # formatting - data = '' + data = conn.recv(16) print >>log_buffer, 'received "{0}"'.format(data) # TODO: you will need to check here to see if any data was # received. If so, send the data you got back to # the client. If not, exit the inner loop and wait # for a new connection from a client + if not data: break + conn.sendall(data) + finally: # TODO: When the inner loop exits, this 'finally' clause will @@ -54,16 +60,17 @@ def server(log_buffer=sys.stderr): # created above when a client connected. Replace the # call to `pass` below, which is only there to prevent # syntax problems - pass + conn.close() except KeyboardInterrupt: # TODO: Use the python KeyboardIntterupt exception as a signal to # close the server socket and exit from the server function. # Replace the call to `pass` below, which is only there to # prevent syntax problems - pass + sock.close() if __name__ == '__main__': server() - sys.exit(0) \ No newline at end of file + sys.exit(0) + From 14fe855d20ea48fd7098a1525866f71cfc415818 Mon Sep 17 00:00:00 2001 From: bparrish206 Date: Fri, 10 Jan 2014 22:43:13 -0800 Subject: [PATCH 2/5] Update echo_client.py --- assignments/session01/echo_client.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/assignments/session01/echo_client.py b/assignments/session01/echo_client.py index 61616c36..dd6a9129 100644 --- a/assignments/session01/echo_client.py +++ b/assignments/session01/echo_client.py @@ -6,15 +6,17 @@ def client(msg, log_buffer=sys.stderr): server_address = ('localhost', 10000) # TODO: Replace the following line with your code which will instantiate # a TCP socket with IPv4 Addressing, call the socket you make 'sock' - sock = None + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print >>log_buffer, 'connecting to {0} port {1}'.format(*server_address) # TODO: connect your socket to the server here. + sock.connect(server_address) # this try/finally block exists purely to allow us to close the socket # when we are finished with it try: print >>log_buffer, 'sending "{0}"'.format(msg) # TODO: send your message to the server here. + sock.sendall(msg) # TODO: the server should be sending you back your message as a series # of 16-byte chunks. You will want to log them as you receive @@ -24,13 +26,18 @@ def client(msg, log_buffer=sys.stderr): # # Make sure that you log each chunk you receive. Use the print # statement below to do it. (The tests expect this log format) - chunk = '' - print >>log_buffer, 'received "{0}"'.format(chunk) + + done = True + while done: + chunk = sock.recv(16) + print >>log_buffer, 'received "{0}"'.format(chunk) + if len(chunk) < 16: + done = False finally: # TODO: after you break out of the loop receiving echoed chunks from # the server you will want to close your client socket. print >>log_buffer, 'closing socket' - + sock.close() if __name__ == '__main__': if len(sys.argv) != 2: @@ -39,4 +46,4 @@ def client(msg, log_buffer=sys.stderr): sys.exit(1) msg = sys.argv[1] - client(msg) \ No newline at end of file + client(msg) From 06404314c59320d7dc4a547c0b38b869c8d14e33 Mon Sep 17 00:00:00 2001 From: bparrish206 Date: Fri, 10 Jan 2014 22:44:10 -0800 Subject: [PATCH 3/5] Update echo_server.py --- assignments/session01/echo_server.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/assignments/session01/echo_server.py b/assignments/session01/echo_server.py index 270f7c69..c8706280 100644 --- a/assignments/session01/echo_server.py +++ b/assignments/session01/echo_server.py @@ -7,7 +7,7 @@ def server(log_buffer=sys.stderr): address = ('127.0.0.1', 10000) # TODO: Replace the following line with your code which will instantiate # a TCP socket with IPv4 Addressing, call the socket you make 'sock' - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TODO: Set an option to allow the socket address to be reused immediately # see the end of http://docs.python.org/2/library/socket.html sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -30,7 +30,7 @@ def server(log_buffer=sys.stderr): # the client so we can report it below. Replace the # following line with your code. It is only here to prevent # syntax errors - conn, client_address = sock.accept() + conn, addr = sock.accept() try: print >>log_buffer, 'connection - {0}:{1}'.format(*addr) @@ -50,9 +50,9 @@ def server(log_buffer=sys.stderr): # received. If so, send the data you got back to # the client. If not, exit the inner loop and wait # for a new connection from a client - if not data: break conn.sendall(data) - + if len(data)<16: + break finally: # TODO: When the inner loop exits, this 'finally' clause will @@ -73,4 +73,3 @@ def server(log_buffer=sys.stderr): if __name__ == '__main__': server() sys.exit(0) - From 7ae72c5655a03119677b13984535d57faf9fdff2 Mon Sep 17 00:00:00 2001 From: bparrish206 Date: Mon, 20 Jan 2014 21:08:44 -0800 Subject: [PATCH 4/5] Update http_server.py --- assignments/session02/http_server.py | 39 +++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/assignments/session02/http_server.py b/assignments/session02/http_server.py index 12cbfeba..be27bb37 100644 --- a/assignments/session02/http_server.py +++ b/assignments/session02/http_server.py @@ -1,16 +1,35 @@ import socket import sys +import os +import mimetypes - -def response_ok(): +def response_ok(body, mimetype): """returns a basic HTTP response""" resp = [] resp.append("HTTP/1.1 200 OK") - resp.append("Content-Type: text/plain") + resp.append("Content-Type: {0}".format(mimetype)) resp.append("") - resp.append("this is a pretty minimal response") + resp.append(body) return "\r\n".join(resp) +def resolve_uri(uri): + base = 'webroot' + fileName = os.path.join(base, uri.lstrip('/')) + if os.path.isfile(filename): + mimetype = mimetypes.guess_type(fileName)[0] + body = open(filename, 'rb').read() + return body, mimetype + elif os.path.isdir(fileName): + bk = "\n".join(os.listdir(fileName)) + return bk, 'text/ plain' + else: + return 'File Not Found' + +def response_not_found(): + resp = [] + resp.append("HTTP/1.1 404 Not Found") + resp.append("") + return "\r\n".join(resp) def response_method_not_allowed(): """returns a 405 Method Not Allowed response""" @@ -19,13 +38,13 @@ def response_method_not_allowed(): resp.append("") return "\r\n".join(resp) - def parse_request(request): first_line = request.split("\r\n", 1)[0] method, uri, protocol = first_line.split() if method != "GET": raise NotImplementedError("We only accept GET") print >>sys.stderr, 'request is okay' + return uri def server(): @@ -50,11 +69,17 @@ def server(): break try: - parse_request(request) + uri = parse_request(request) + body, mimetype = resolve_uri(uri) + except NotImplementedError: response = response_method_not_allowed() + + except ValueError: + response = response_not_found() + else: - response = response_ok() + response = response_ok(body, mime) print >>sys.stderr, 'sending response' conn.sendall(response) From 69913a4312550340a5e6a84960948c1a1450f83e Mon Sep 17 00:00:00 2001 From: bparrish206 Date: Sun, 26 Jan 2014 11:30:35 -0800 Subject: [PATCH 5/5] Update and rename tasks.txt to tasks.py --- assignments/session03/tasks.py | 92 +++++++++++++++++++++++++++++++++ assignments/session03/tasks.txt | 38 -------------- 2 files changed, 92 insertions(+), 38 deletions(-) create mode 100644 assignments/session03/tasks.py delete mode 100644 assignments/session03/tasks.txt diff --git a/assignments/session03/tasks.py b/assignments/session03/tasks.py new file mode 100644 index 00000000..05b3741c --- /dev/null +++ b/assignments/session03/tasks.py @@ -0,0 +1,92 @@ +Session 3 Homework +================== + +#Assignment #3 Mashup + +#This was a enjoyable assignment that I learned a lot from. I tried to do a few more complicated tasks, but ran out of time. + +#This program is custom NPR News feed. It returns all my local npr station info and the full text, images, and audio of the news stories I'm interested in. But since sometimes the news is hard I also mashed in some imageges of kittens. + +#You should just be able to run this code. + +from urllib2 import urlopen +from json import load, dumps + +#NPR Key +key = "MDEyNTA4NzYxMDEzODMzMjY0NDQ5YTg4MQ001" + +def build_api_call(key, zip_code): + url = 'http://api.npr.org/stations?apiKey=' + key + url+='&format=json' + url += "&zip=" + str(zip_code) + return url + +def call_station_api(url): + response = urlopen(url) + j = load(response) + return j + +def parse_station_json(json_obj): + for station in json_obj['station']: + print (station['callLetters']['$text']+ ": " + + station['marketCity']['$text'] + ", " + + station['state']['$text']) + print "Frequency:" , station['frequency']['$text'] , station['band']['$text'] + + if 'url' in station: + print "MP3 Streams: " + for link in station['url']: + if link["type"] == "Audio MP3 Stream": + print "\t" , link["title"], " - " , link["$text"] + +def NPR_Stories(key, subject): + url = 'http://api.npr.org/query?apiKey=' + url = url + key + url += '&numResults=10&format=json' + url += '&id=' + str(subject) +'&requiredAssets=image,text,audio' + response = urlopen(url) + json_obj = load(response) + + f = open('output.json', 'w') + f.write(dumps(json_obj, indent=4)) + f.close() + + for story in json_obj['list']['story']: + print "TITLE: " + story['title']['$text'] + "\n" + print "DATE: " + story['storyDate']['$text'] + "\n" + print "TEASER: " + story['teaser']['$text'] + "\n" + + if 'byline' in story: + print "BYLINE: " + story['byline'][0]['name']['$text'] + "\n" + if 'show' in story: + print "PROGRAM: " + story['show'][0]['program']['$text']+"\n" + print "NPR URL: " + story['link'][0]['$text'] +"\n" + print "IMAGE: " +story['image'][0]['src'] +"\n" + if 'caption' in story: + print "IMAGE CAPTION: " +story['image'][0]['caption']['$text'] +"\n" + if 'producer' in story: + print 'IMAGE CREDIT: ' + story['image'][0]['producer']['$text'] +"\n" + print "MP3 AUDIO: " + story['audio'][0]['format']['mp3'][0]['$text'] +"\n" + for paragraph in story['textWithHtml']['paragraph']: + print paragraph['$text'] + "\n" + +def kittens(): + url = 'http://placekitten.com/250/250' + kitten = urlopen(url).read() + f = open('kittens.jpeg', 'w') + f.write(kitten) + print f + f.close() + + +if __name__ =='__main__': + url = build_api_call(key, 98115) + kittens() + print "URL: ", url + json_obj = call_station_api(url) + kittens() + parse_station_json(json_obj) + kittens() + NPR_Stories(key, 1049) + + diff --git a/assignments/session03/tasks.txt b/assignments/session03/tasks.txt deleted file mode 100644 index 6cae2679..00000000 --- a/assignments/session03/tasks.txt +++ /dev/null @@ -1,38 +0,0 @@ -Session 3 Homework -================== - -Required Tasks: ---------------- - -Using what you've learned this week, create a more complex mashup of some data -that interests you. Map the locations of the breweries near your house. Chart -a multi-axial graph of the popularity of various cities across several -categories. Visualize the most effective legislators in Congress. You have -interests, the Web has tools. Put them together to make something. - -Use the API directory at http://www.programmableweb.com/apis/directory to get -some ideas of data sources and what you might do with them. - -Place the following in the ``assignments/week03/athome`` directory and make a -pull request: - -A textual description of your mashup. - What data sources did you scan, what tools did you use, what is the - outcome you wanted to create? - -Your source code. - Give me an executable python script that I can run to get output. - -Any instructions I need. - If I need instructions beyond 'python myscript.py' to get the right - output, let me know. - -The data you produce need not be pretty, or even particularly visible. In -class we only produced a simple dictionary of values for each listing. Focus -on getting data sources combined rather than on what the output looks like. - - -Optional Tasks: ---------------- - -Write unit tests supporting the functions of your mashup script.