From c631bff033b872be185c3c5d4523c1c1f511d3e6 Mon Sep 17 00:00:00 2001 From: neelp22 Date: Tue, 28 Oct 2014 12:39:19 -0400 Subject: [PATCH 001/103] added functionality to all 3 servers to write to '_comments.json' within the post request --- _comments.json | 7 +------ server.js | 1 + server.py | 10 +++++++++- server.rb | 1 + 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/_comments.json b/_comments.json index ea8ae2ce..2c527fda 100644 --- a/_comments.json +++ b/_comments.json @@ -1,6 +1 @@ -[ - { - "author": "Pete Hunt", - "text": "Hey there!" - } -] +[{"author":"Pete Hunt","text":"Hey there!"}] \ No newline at end of file diff --git a/server.js b/server.js index 5dafe0ee..85a4dbdb 100644 --- a/server.js +++ b/server.js @@ -29,6 +29,7 @@ app.get('/comments.json', function(req, res) { app.post('/comments.json', function(req, res) { comments.push(req.body); + fs.writeFile('_comments.json', JSON.stringify(comments)) res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(comments)); }); diff --git a/server.py b/server.py index 7edb6f65..657ce81d 100644 --- a/server.py +++ b/server.py @@ -16,7 +16,9 @@ PUBLIC_PATH = "public" -comments = json.loads(open('_comments.json').read()) +file = open('_comments.json', 'r+') +comments = json.loads(file.read()) +file.close() def sendJSON(res): res.send_response(200) @@ -47,6 +49,12 @@ def do_POST(self): # Save the data comments.append({u"author": form.getfirst("author"), u"text": form.getfirst("text")}) + print comments + # Write to file + file = open('_comments.json', 'w+') + file.write(json.dumps(comments)) + file.close() + sendJSON(self) else: SimpleHTTPRequestHandler.do_POST(self) diff --git a/server.rb b/server.rb index 1838a289..1d9349c0 100644 --- a/server.rb +++ b/server.rb @@ -22,6 +22,7 @@ if req.request_method == 'POST' # Assume it's well formed comments << req.query + File.write('./_comments.json', comments.to_json) end # always return json From 21a4cf443fac030a963d4318de6949c1a60c015f Mon Sep 17 00:00:00 2001 From: neelp22 Date: Tue, 28 Oct 2014 12:41:35 -0400 Subject: [PATCH 002/103] checked '_comments.json' to previous commit for the purpose of restoring json formatting --- _comments.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/_comments.json b/_comments.json index 2c527fda..ea8ae2ce 100644 --- a/_comments.json +++ b/_comments.json @@ -1 +1,6 @@ -[{"author":"Pete Hunt","text":"Hey there!"}] \ No newline at end of file +[ + { + "author": "Pete Hunt", + "text": "Hey there!" + } +] From 7105db66423893cfb7023d389af37663975ec4d8 Mon Sep 17 00:00:00 2001 From: neelp22 Date: Tue, 28 Oct 2014 12:49:55 -0400 Subject: [PATCH 003/103] removed a print line from server.py --- server.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server.py b/server.py index 657ce81d..6618ec83 100644 --- a/server.py +++ b/server.py @@ -49,7 +49,6 @@ def do_POST(self): # Save the data comments.append({u"author": form.getfirst("author"), u"text": form.getfirst("text")}) - print comments # Write to file file = open('_comments.json', 'w+') file.write(json.dumps(comments)) From 896efce6174b7775a436b25360654932f95619ee Mon Sep 17 00:00:00 2001 From: Victor Leung Date: Sat, 29 Nov 2014 21:36:09 +0800 Subject: [PATCH 004/103] add missing semicolon --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 5dafe0ee..8f52309e 100644 --- a/server.js +++ b/server.js @@ -16,7 +16,7 @@ var express = require('express'); var bodyParser = require('body-parser'); var app = express(); -var comments = JSON.parse(fs.readFileSync('_comments.json')) +var comments = JSON.parse(fs.readFileSync('_comments.json')); app.use('/', express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); From be9179b69c5447b2d5c78f4681260d426787b30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Wed, 10 Dec 2014 13:12:00 -0800 Subject: [PATCH 005/103] Update for 0.12 Fixes #6 Closes #8 --- public/index.html | 6 +++--- public/scripts/example.js | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/public/index.html b/public/index.html index 937b5212..dbf4df43 100644 --- a/public/index.html +++ b/public/index.html @@ -4,13 +4,13 @@ Codestin Search App - - + +
- + diff --git a/public/scripts/example.js b/public/scripts/example.js index dd29cbfd..c9474266 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -8,8 +8,6 @@ * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * @jsx React.DOM */ var converter = new Showdown.converter(); @@ -124,7 +122,7 @@ var CommentForm = React.createClass({ } }); -React.renderComponent( +React.render( , document.getElementById('content') ); From 85a92a09a9dbfbde6c74bf6fbc9cfa2919775d61 Mon Sep 17 00:00:00 2001 From: high5 Date: Wed, 21 Jan 2015 13:27:34 +0900 Subject: [PATCH 006/103] Update for 0.12.2 --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index dbf4df43..0c6cdf06 100644 --- a/public/index.html +++ b/public/index.html @@ -4,8 +4,8 @@ Codestin Search App - - + + From c6c8f1f74b1b260dc6f88d334027ff3b39756a49 Mon Sep 17 00:00:00 2001 From: Andrew Switlyk Date: Thu, 22 Jan 2015 11:02:27 -0800 Subject: [PATCH 007/103] update comments variable after get request to "comments.json" --- server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server.js b/server.js index f03c34c2..724c4ba9 100644 --- a/server.js +++ b/server.js @@ -25,6 +25,7 @@ app.use(bodyParser.urlencoded({extended: true})); app.get('/comments.json', function(req, res) { res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(comments)); + comments = JSON.parse(fs.readFileSync('_comments.json')); }); app.post('/comments.json', function(req, res) { From 6e6d46c56374e76a1bc60fdc59931d630cba30d3 Mon Sep 17 00:00:00 2001 From: Andrew Switlyk Date: Thu, 22 Jan 2015 12:15:12 -0800 Subject: [PATCH 008/103] on get request to comments.json, update variable comments (from filesystem read) before sending stringified comments in response. --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 724c4ba9..161c488a 100644 --- a/server.js +++ b/server.js @@ -23,14 +23,14 @@ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.get('/comments.json', function(req, res) { + comments = JSON.parse(fs.readFileSync('_comments.json')); res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(comments)); - comments = JSON.parse(fs.readFileSync('_comments.json')); }); app.post('/comments.json', function(req, res) { comments.push(req.body); - fs.writeFile('_comments.json', JSON.stringify(comments)) + fs.writeFile('_comments.json', JSON.stringify(comments)); res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(comments)); }); From 3d2d07806268a26060d13a96d71556e03930fd2d Mon Sep 17 00:00:00 2001 From: Andrew Switlyk Date: Thu, 22 Jan 2015 16:18:04 -0800 Subject: [PATCH 009/103] removed comments var from global and all I/O of comments to/from disk --- server.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/server.js b/server.js index 161c488a..843c34c2 100644 --- a/server.js +++ b/server.js @@ -16,23 +16,26 @@ var express = require('express'); var bodyParser = require('body-parser'); var app = express(); -var comments = JSON.parse(fs.readFileSync('_comments.json')); - app.use('/', express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.get('/comments.json', function(req, res) { - comments = JSON.parse(fs.readFileSync('_comments.json')); - res.setHeader('Content-Type', 'application/json'); - res.send(JSON.stringify(comments)); + fs.readFile('_comments.json', function(err, data) { + res.setHeader('Content-Type', 'application/json'); + res.send(data); + }); }); app.post('/comments.json', function(req, res) { - comments.push(req.body); - fs.writeFile('_comments.json', JSON.stringify(comments)); - res.setHeader('Content-Type', 'application/json'); - res.send(JSON.stringify(comments)); + fs.readFile('_comments.json', function(err, data) { + var tempComments = JSON.parse(data); + tempComments.push(req.body); + fs.writeFile('_comments.json', JSON.stringify(tempComments), function(err) { + res.setHeader('Content-Type', 'application/json'); + res.send(JSON.stringify(tempComments)); + }); + }); }); app.listen(3000); From 8e78f6ca2774cdd9dc63f1159e05a25a777ff6d5 Mon Sep 17 00:00:00 2001 From: David Bunker Date: Thu, 22 Jan 2015 20:17:58 -0500 Subject: [PATCH 010/103] Switch python server to use Flask --- README.md | 1 + requirements.txt | 1 + server.py | 58 +++++++++++------------------------------------- 3 files changed, 15 insertions(+), 45 deletions(-) create mode 100644 requirements.txt diff --git a/README.md b/README.md index 81d62e73..13bf7668 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ node server.js ### Python ```sh +pip install -r requirements.txt python server.py ``` diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..632a1efa --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +Flask==0.10.1 diff --git a/server.py b/server.py index 6618ec83..4216b877 100644 --- a/server.py +++ b/server.py @@ -8,57 +8,25 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import os import json -import cgi -from BaseHTTPServer import HTTPServer -from SimpleHTTPServer import SimpleHTTPRequestHandler +from flask import Flask, Response, request -PUBLIC_PATH = "public" +app = Flask(__name__, static_url_path='', static_folder='public') +app.add_url_rule('/', 'root', lambda: app.send_static_file('index.html')) -file = open('_comments.json', 'r+') -comments = json.loads(file.read()) -file.close() +@app.route('/comments.json', methods=['GET', 'POST']) +def comments_handler(): -def sendJSON(res): - res.send_response(200) - res.send_header('Content-type', 'application/json') - res.end_headers() - res.wfile.write(json.dumps(comments)) + with open('_comments.json', 'r') as file: + comments = json.loads(file.read()) -class MyHandler(SimpleHTTPRequestHandler): - def translate_path(self, path): - root = os.getcwd() - path = PUBLIC_PATH + path - return os.path.join(root, path) + if request.method == 'POST': + comments.append(request.form.to_dict()) - def do_GET(self): - if (self.path == "/comments.json"): - sendJSON(self) - else: - SimpleHTTPRequestHandler.do_GET(self) + with open('_comments.json', 'w') as file: + file.write(json.dumps(comments, indent=4, separators=(',', ': '))) - def do_POST(self): - if (self.path == "/comments.json"): - form = cgi.FieldStorage( - fp=self.rfile, - headers=self.headers, - environ={'REQUEST_METHOD':'POST', - 'CONTENT_TYPE':self.headers['Content-Type']} - ) - - # Save the data - comments.append({u"author": form.getfirst("author"), u"text": form.getfirst("text")}) - # Write to file - file = open('_comments.json', 'w+') - file.write(json.dumps(comments)) - file.close() - - sendJSON(self) - else: - SimpleHTTPRequestHandler.do_POST(self) + return Response(json.dumps(comments), mimetype='application/json') if __name__ == '__main__': - print "Server started: http://localhost:3000/" - httpd = HTTPServer(('127.0.0.1', 3000), MyHandler) - httpd.serve_forever() + app.run(port=3000) From b093b3450da81b438a892991e0aa3e6ad554c75f Mon Sep 17 00:00:00 2001 From: Leonidez Acosta Date: Wed, 4 Feb 2015 20:32:22 -0600 Subject: [PATCH 011/103] read _comments.json after request received The _comments.json file was getting cached and would not update the view when the json was changed. --- server.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.rb b/server.rb index 1d9349c0..687162d2 100644 --- a/server.rb +++ b/server.rb @@ -11,14 +11,14 @@ require 'webrick' require 'json' -comments = react_version = JSON.parse(File.read('./_comments.json')) - puts 'Server started: http://localhost:3000/' root = File.expand_path './public' server = WEBrick::HTTPServer.new :Port => 3000, :DocumentRoot => root server.mount_proc '/comments.json' do |req, res| + comments = react_version = JSON.parse(File.read('./_comments.json')) + if req.request_method == 'POST' # Assume it's well formed comments << req.query From d62a9681ddd63744543c7dbd07d16a5a5f68a15a Mon Sep 17 00:00:00 2001 From: Andy Mathys Date: Thu, 5 Feb 2015 20:04:41 +0100 Subject: [PATCH 012/103] add initial version of the php server --- server.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 server.php diff --git a/server.php b/server.php new file mode 100644 index 00000000..44ee6263 --- /dev/null +++ b/server.php @@ -0,0 +1,21 @@ + $_POST['author'], + 'text' => $_POST['text']]; + + $comments = json_encode($commentsDecoded); + file_put_contents('_comments.json', $comments); + } + header('Content-Type: application/json'); + echo $comments; + break; + default: + return false; +} From 9bb89c59c2f596942a07733cc2b5e59733edb784 Mon Sep 17 00:00:00 2001 From: Andy Mathys Date: Thu, 5 Feb 2015 20:08:45 +0100 Subject: [PATCH 013/103] Update readme with info about starting the php server --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 81d62e73..8fefc462 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,9 @@ python server.py ruby server.rb ``` +### PHP +```sh +php -S localhost:3000 -t public/ server.php +``` + And visit . Try opening multiple tabs! From a23093686383eff7da9798c26372550086a06422 Mon Sep 17 00:00:00 2001 From: Andy Mathys Date: Thu, 5 Feb 2015 21:35:45 +0100 Subject: [PATCH 014/103] Start sever when invoked with `php server.php` --- server.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server.php b/server.php index 44ee6263..5609437d 100644 --- a/server.php +++ b/server.php @@ -1,4 +1,8 @@ Date: Thu, 5 Feb 2015 21:36:12 +0100 Subject: [PATCH 015/103] Updated readme file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fefc462..a294a99c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ruby server.rb ### PHP ```sh -php -S localhost:3000 -t public/ server.php +php server.php ``` And visit . Try opening multiple tabs! From 094d32cc39b1b857a03487058bfaf41bdafa7b9a Mon Sep 17 00:00:00 2001 From: Andy Mathys Date: Thu, 5 Feb 2015 21:45:48 +0100 Subject: [PATCH 016/103] small refactoring --- server.php | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/server.php b/server.php index 5609437d..d9d01f0c 100644 --- a/server.php +++ b/server.php @@ -1,25 +1,35 @@ $_POST['author'], - 'text' => $_POST['text']]; +function routeRequest() +{ + $comments = file_get_contents('_comments.json'); + switch($_SERVER["REQUEST_URI"]) { + case '/': + echo file_get_contents('./public/index.html'); + break; + case '/comments.json': + if($_SERVER['REQUEST_METHOD'] === 'POST') { + $commentsDecoded = json_decode($comments, true); + $commentsDecoded[] = ['author' => $_POST['author'], + 'text' => $_POST['text']]; - $comments = json_encode($commentsDecoded); - file_put_contents('_comments.json', $comments); - } - header('Content-Type: application/json'); - echo $comments; - break; - default: - return false; + $comments = json_encode($commentsDecoded); + file_put_contents('_comments.json', $comments); + } + header('Content-Type: application/json'); + echo $comments; + break; + default: + return false; + } } + From 2945ececce782bc3f54ed1f930ae02e447cdd908 Mon Sep 17 00:00:00 2001 From: Andy Mathys Date: Thu, 5 Feb 2015 21:47:15 +0100 Subject: [PATCH 017/103] Indentation + better startup message --- server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.php b/server.php index d9d01f0c..c7542a33 100644 --- a/server.php +++ b/server.php @@ -3,7 +3,7 @@ isset($_SERVER['argv'][0]) && $_SERVER['argv'][0] === 'server.php'; if($scriptInvokedFromCli) { - echo 'server listening on port 3000'; + echo 'starting server on port 3000' . PHP_EOL; exec('php -S localhost:3000 -t public server.php'); } else { return routeRequest(); @@ -20,7 +20,7 @@ function routeRequest() if($_SERVER['REQUEST_METHOD'] === 'POST') { $commentsDecoded = json_decode($comments, true); $commentsDecoded[] = ['author' => $_POST['author'], - 'text' => $_POST['text']]; + 'text' => $_POST['text']]; $comments = json_encode($commentsDecoded); file_put_contents('_comments.json', $comments); From 223ccb3fd20e360e9c8330f77fe7861f1a76fb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 5 Feb 2015 18:49:15 -0800 Subject: [PATCH 018/103] editorconfig --- .editorconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..bd901785 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{js,rb}] +indent_size=2 From 76552e3a19f0254bd4d52620cc49ff9246663dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 5 Feb 2015 18:50:28 -0800 Subject: [PATCH 019/103] strip trailing whitespace from server.php --- server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.php b/server.php index c7542a33..99f4de97 100644 --- a/server.php +++ b/server.php @@ -19,12 +19,12 @@ function routeRequest() case '/comments.json': if($_SERVER['REQUEST_METHOD'] === 'POST') { $commentsDecoded = json_decode($comments, true); - $commentsDecoded[] = ['author' => $_POST['author'], + $commentsDecoded[] = ['author' => $_POST['author'], 'text' => $_POST['text']]; $comments = json_encode($commentsDecoded); file_put_contents('_comments.json', $comments); - } + } header('Content-Type: application/json'); echo $comments; break; From 7d31d05ca4aa8952bf4338199c370e149e3a6d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 5 Feb 2015 21:22:39 -0800 Subject: [PATCH 020/103] remove unused var in ruby server --- server.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.rb b/server.rb index 687162d2..4247c3ed 100644 --- a/server.rb +++ b/server.rb @@ -17,8 +17,8 @@ server = WEBrick::HTTPServer.new :Port => 3000, :DocumentRoot => root server.mount_proc '/comments.json' do |req, res| - comments = react_version = JSON.parse(File.read('./_comments.json')) - + comments = JSON.parse(File.read('./_comments.json')) + if req.request_method == 'POST' # Assume it's well formed comments << req.query From ce163987a2fb4ed74ac01779826c672f48bb9487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 5 Feb 2015 21:30:16 -0800 Subject: [PATCH 021/103] Fixup some nits in node server. --- server.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 843c34c2..e5e3efc0 100644 --- a/server.js +++ b/server.js @@ -29,11 +29,11 @@ app.get('/comments.json', function(req, res) { app.post('/comments.json', function(req, res) { fs.readFile('_comments.json', function(err, data) { - var tempComments = JSON.parse(data); - tempComments.push(req.body); - fs.writeFile('_comments.json', JSON.stringify(tempComments), function(err) { + var comments = JSON.parse(data); + comments.push(req.body); + fs.writeFile('_comments.json', JSON.stringify(comments), function(err) { res.setHeader('Content-Type', 'application/json'); - res.send(JSON.stringify(tempComments)); + res.send(JSON.stringify(comments)); }); }); }); From be57a92cf3a074312537df746727f394e08922c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 5 Feb 2015 21:33:14 -0800 Subject: [PATCH 022/103] Format JSON consistently (pretty print) when writing to disk --- _comments.json | 8 ++++---- server.js | 2 +- server.php | 2 +- server.rb | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/_comments.json b/_comments.json index ea8ae2ce..32938452 100644 --- a/_comments.json +++ b/_comments.json @@ -1,6 +1,6 @@ [ - { - "author": "Pete Hunt", - "text": "Hey there!" - } + { + "author": "Pete Hunt", + "text": "Hey there!" + } ] diff --git a/server.js b/server.js index e5e3efc0..1f7a7f92 100644 --- a/server.js +++ b/server.js @@ -31,7 +31,7 @@ app.post('/comments.json', function(req, res) { fs.readFile('_comments.json', function(err, data) { var comments = JSON.parse(data); comments.push(req.body); - fs.writeFile('_comments.json', JSON.stringify(comments), function(err) { + fs.writeFile('_comments.json', JSON.stringify(comments, null, 4), function(err) { res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(comments)); }); diff --git a/server.php b/server.php index 99f4de97..91fb4d1d 100644 --- a/server.php +++ b/server.php @@ -22,7 +22,7 @@ function routeRequest() $commentsDecoded[] = ['author' => $_POST['author'], 'text' => $_POST['text']]; - $comments = json_encode($commentsDecoded); + $comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT); file_put_contents('_comments.json', $comments); } header('Content-Type: application/json'); diff --git a/server.rb b/server.rb index 4247c3ed..23b29f0b 100644 --- a/server.rb +++ b/server.rb @@ -22,7 +22,7 @@ if req.request_method == 'POST' # Assume it's well formed comments << req.query - File.write('./_comments.json', comments.to_json) + File.write('./_comments.json', JSON.pretty_generate(comments, :indent => ' ')) end # always return json From 5848e372ae0d3a7756bc6f58f7562410258adeb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 5 Feb 2015 22:26:08 -0800 Subject: [PATCH 023/103] use JSON.generate in ruby --- server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.rb b/server.rb index 23b29f0b..bc1157b0 100644 --- a/server.rb +++ b/server.rb @@ -27,7 +27,7 @@ # always return json res['Content-Type'] = 'application/json' - res.body = comments.to_json + res.body = JSON.generate(comments) end trap 'INT' do server.shutdown end From 6c40ea64c384ac18a9048f29424d79cb507f99fe Mon Sep 17 00:00:00 2001 From: David Bunker Date: Fri, 6 Feb 2015 18:08:28 -0500 Subject: [PATCH 024/103] Remove unnecessary return --- public/scripts/example.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/scripts/example.js b/public/scripts/example.js index c9474266..c912e497 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -109,7 +109,6 @@ var CommentForm = React.createClass({ this.props.onCommentSubmit({author: author, text: text}); this.refs.author.getDOMNode().value = ''; this.refs.text.getDOMNode().value = ''; - return; }, render: function() { return ( From c0d91faaca31003c2aaf79c593f1a2992a741c7f Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Mon, 9 Feb 2015 22:01:18 -0800 Subject: [PATCH 025/103] Add a go sample --- README.md | 5 ++++ server.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 server.go diff --git a/README.md b/README.md index a5ffe8a7..7a6e518a 100644 --- a/README.md +++ b/README.md @@ -30,4 +30,9 @@ ruby server.rb php server.php ``` +### Go +```sh +go run server.go +``` + And visit . Try opening multiple tabs! diff --git a/server.go b/server.go new file mode 100644 index 00000000..c8797f6b --- /dev/null +++ b/server.go @@ -0,0 +1,85 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "sync" +) + +type comment struct { + Author string `json:"author"` + Text string `json:"text"` +} + +const dataFile = "./_comments.json" + +var commentMutex = new(sync.Mutex) + +// Handle comments +func handleComments(w http.ResponseWriter, r *http.Request) { + // Since multiple requests could come in at once, ensure we have a lock + // around all file operations + commentMutex.Lock() + defer commentMutex.Unlock() + + // Stat the file, so we can find it's current permissions + fi, err := os.Stat(dataFile) + if err != nil { + http.Error(w, fmt.Sprintf("Unable to stat data file (%s): %s", dataFile, err), http.StatusInternalServerError) + return + } + + // Open the file Read/Write + cFile, err := os.OpenFile(dataFile, os.O_RDWR, fi.Mode()) + if err != nil { + http.Error(w, fmt.Sprintf("Unable to open data file (%s): %s", dataFile, err), http.StatusInternalServerError) + return + } + defer cFile.Close() //Ensure the file is closed when we are done. + + switch r.Method { + case "POST": + // Decode the JSON data + comments := make([]comment, 0) + commentsDecoder := json.NewDecoder(cFile) + if err := commentsDecoder.Decode(&comments); err != nil { + http.Error(w, fmt.Sprintf("Unable to read comments from data file (%s): %s", dataFile, err), http.StatusInternalServerError) + return + } + + // Add a new comment to the in memory slice of comments + comments = append(comments, comment{Author: r.FormValue("author"), Text: r.FormValue("text")}) + + // Truncate the file and Seek to the beginning of it + if err := cFile.Truncate(0); err != nil { + http.Error(w, fmt.Sprintf("Unable to truncate data file (%s): %s", dataFile, err), http.StatusInternalServerError) + return + } + if r, err := cFile.Seek(0, 0); r != 0 && err != nil { + http.Error(w, fmt.Sprintf("Unable to seek to beginning of data file (%s): %s", dataFile, err), http.StatusInternalServerError) + return + } + + // Write out the json response + commentsEncoder := json.NewEncoder(cFile) + commentsEncoder.Encode(comments) + + case "GET": + // stream the contents of the file to the response + io.Copy(w, cFile) + + default: + // Don't know the method, so error + http.Error(w, fmt.Sprintf("Unsupported method: %s", r.Method), http.StatusMethodNotAllowed) + } +} + +func main() { + http.HandleFunc("/comments.json", handleComments) + http.Handle("/", http.FileServer(http.Dir("./public"))) + log.Fatal(http.ListenAndServe(":3000", nil)) +} From 75e366cc08ef6dab3c7f756cbec7e6c0ec95fab6 Mon Sep 17 00:00:00 2001 From: AlexZou Date: Sun, 15 Feb 2015 14:35:10 +0800 Subject: [PATCH 026/103] Remove duplicated semicolon in base.css --- public/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/css/base.css b/public/css/base.css index 3ed9ea38..bf382be3 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -1,6 +1,6 @@ body { background: #fff; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 15px; line-height: 1.7; margin: 0; From 17366cd34e193d3bb3f762608129c1fca951a9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Wed, 18 Feb 2015 14:03:42 -0800 Subject: [PATCH 027/103] Use https script sources --- public/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 0c6cdf06..0edd2ac5 100644 --- a/public/index.html +++ b/public/index.html @@ -4,10 +4,10 @@ Codestin Search App - - - - + + + +
From 4cf10f5c4a7f83c8e2e3b02ddbc87da019390ed8 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Wed, 25 Feb 2015 17:10:27 -0800 Subject: [PATCH 028/103] Updates based on #30 Allocate []bytes for reading data in and write out indented JSON. --- server.go | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/server.go b/server.go index c8797f6b..86a53e5f 100644 --- a/server.go +++ b/server.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "encoding/json" "fmt" "io" + "io/ioutil" "log" "net/http" "os" @@ -29,48 +31,46 @@ func handleComments(w http.ResponseWriter, r *http.Request) { // Stat the file, so we can find it's current permissions fi, err := os.Stat(dataFile) if err != nil { - http.Error(w, fmt.Sprintf("Unable to stat data file (%s): %s", dataFile, err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("Unable to stat the data file (%s): %s", dataFile, err), http.StatusInternalServerError) return } - // Open the file Read/Write - cFile, err := os.OpenFile(dataFile, os.O_RDWR, fi.Mode()) + // Read the comments from the file. + commentData, err := ioutil.ReadFile(dataFile) if err != nil { - http.Error(w, fmt.Sprintf("Unable to open data file (%s): %s", dataFile, err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("Unable to read the data file (%s): %s", dataFile, err), http.StatusInternalServerError) return } - defer cFile.Close() //Ensure the file is closed when we are done. switch r.Method { case "POST": // Decode the JSON data comments := make([]comment, 0) - commentsDecoder := json.NewDecoder(cFile) - if err := commentsDecoder.Decode(&comments); err != nil { - http.Error(w, fmt.Sprintf("Unable to read comments from data file (%s): %s", dataFile, err), http.StatusInternalServerError) + if err := json.Unmarshal(commentData, &comments); err != nil { + http.Error(w, fmt.Sprintf("Unable to Unmarshal comments from data file (%s): %s", dataFile, err), http.StatusInternalServerError) return } // Add a new comment to the in memory slice of comments comments = append(comments, comment{Author: r.FormValue("author"), Text: r.FormValue("text")}) - // Truncate the file and Seek to the beginning of it - if err := cFile.Truncate(0); err != nil { - http.Error(w, fmt.Sprintf("Unable to truncate data file (%s): %s", dataFile, err), http.StatusInternalServerError) + // Marshal the comments to indented json. + commentData, err = json.MarshalIndent(comments, "", " ") + if err != nil { + http.Error(w, fmt.Sprintf("Unable to marshal comments to json: %s", err), http.StatusInternalServerError) return } - if r, err := cFile.Seek(0, 0); r != 0 && err != nil { - http.Error(w, fmt.Sprintf("Unable to seek to beginning of data file (%s): %s", dataFile, err), http.StatusInternalServerError) + + // Write out the comments to the file, preserving permissions + err := ioutil.WriteFile(dataFile, commentData, fi.Mode()) + if err != nil { + http.Error(w, fmt.Sprintf("Unable to write comments to data file (%s): %s", dataFile, err), http.StatusInternalServerError) return } - // Write out the json response - commentsEncoder := json.NewEncoder(cFile) - commentsEncoder.Encode(comments) - case "GET": // stream the contents of the file to the response - io.Copy(w, cFile) + io.Copy(w, bytes.NewReader(commentData)) default: // Don't know the method, so error From 18725ddc5d49e689699fa8f8bd7b47dcf3a84f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Wed, 25 Feb 2015 17:45:06 -0800 Subject: [PATCH 029/103] Update editorconfig for go --- .editorconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index bd901785..23f1adc7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,4 +10,8 @@ insert_final_newline = true trim_trailing_whitespace = true [*.{js,rb}] -indent_size=2 +indent_size = 2 + +[*.go] +indent_size = 8 +indent_style = tab From 45c8e6640bdc384b3496c3c82b001ef58e4e9773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Fri, 27 Feb 2015 13:40:47 -0800 Subject: [PATCH 030/103] Improve Go server - log to stdout when starting the server - send updated data on POST - set content type headers --- server.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server.go b/server.go index 86a53e5f..74dd06a1 100644 --- a/server.go +++ b/server.go @@ -68,7 +68,11 @@ func handleComments(w http.ResponseWriter, r *http.Request) { return } + w.Header().Set("Content-Type", "application/json") + io.Copy(w, bytes.NewReader(commentData)) + case "GET": + w.Header().Set("Content-Type", "application/json") // stream the contents of the file to the response io.Copy(w, bytes.NewReader(commentData)) @@ -81,5 +85,6 @@ func handleComments(w http.ResponseWriter, r *http.Request) { func main() { http.HandleFunc("/comments.json", handleComments) http.Handle("/", http.FileServer(http.Dir("./public"))) + log.Println("Server started: http://localhost:3000") log.Fatal(http.ListenAndServe(":3000", nil)) } From 08945201c120fde1604af1407843d2980eb2dfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Fri, 27 Feb 2015 13:50:07 -0800 Subject: [PATCH 031/103] Set no-cache header --- server.go | 2 ++ server.js | 1 + server.php | 1 + server.py | 2 +- server.rb | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index 74dd06a1..41b3fa88 100644 --- a/server.go +++ b/server.go @@ -69,10 +69,12 @@ func handleComments(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") + w.Header().Set("Cache-Control", "no-cache") io.Copy(w, bytes.NewReader(commentData)) case "GET": w.Header().Set("Content-Type", "application/json") + w.Header().Set("Cache-Control", "no-cache") // stream the contents of the file to the response io.Copy(w, bytes.NewReader(commentData)) diff --git a/server.js b/server.js index 1f7a7f92..4f03a1e4 100644 --- a/server.js +++ b/server.js @@ -33,6 +33,7 @@ app.post('/comments.json', function(req, res) { comments.push(req.body); fs.writeFile('_comments.json', JSON.stringify(comments, null, 4), function(err) { res.setHeader('Content-Type', 'application/json'); + res.setHeader('Cache-Control', 'no-cache'); res.send(JSON.stringify(comments)); }); }); diff --git a/server.php b/server.php index 91fb4d1d..783cfdd5 100644 --- a/server.php +++ b/server.php @@ -26,6 +26,7 @@ function routeRequest() file_put_contents('_comments.json', $comments); } header('Content-Type: application/json'); + header('Cache-Control: no-cache'); echo $comments; break; default: diff --git a/server.py b/server.py index 4216b877..fcdc3d65 100644 --- a/server.py +++ b/server.py @@ -26,7 +26,7 @@ def comments_handler(): with open('_comments.json', 'w') as file: file.write(json.dumps(comments, indent=4, separators=(',', ': '))) - return Response(json.dumps(comments), mimetype='application/json') + return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache'}) if __name__ == '__main__': app.run(port=3000) diff --git a/server.rb b/server.rb index bc1157b0..f2a9c659 100644 --- a/server.rb +++ b/server.rb @@ -27,6 +27,7 @@ # always return json res['Content-Type'] = 'application/json' + res['Cache-Control'] = 'no-cache' res.body = JSON.generate(comments) end From fb15f9cc566a2d2eb705d9f0248fac1920d8c396 Mon Sep 17 00:00:00 2001 From: Matt Campbell Date: Wed, 11 Feb 2015 13:36:13 -0500 Subject: [PATCH 032/103] Remove confusing underscore from comments.json filename --- _comments.json => comments.json | 0 server.go | 2 +- server.js | 6 +++--- server.php | 4 ++-- server.py | 4 ++-- server.rb | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) rename _comments.json => comments.json (100%) diff --git a/_comments.json b/comments.json similarity index 100% rename from _comments.json rename to comments.json diff --git a/server.go b/server.go index 41b3fa88..fde1deae 100644 --- a/server.go +++ b/server.go @@ -17,7 +17,7 @@ type comment struct { Text string `json:"text"` } -const dataFile = "./_comments.json" +const dataFile = "./comments.json" var commentMutex = new(sync.Mutex) diff --git a/server.js b/server.js index 4f03a1e4..ac0c1950 100644 --- a/server.js +++ b/server.js @@ -21,17 +21,17 @@ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.get('/comments.json', function(req, res) { - fs.readFile('_comments.json', function(err, data) { + fs.readFile('comments.json', function(err, data) { res.setHeader('Content-Type', 'application/json'); res.send(data); }); }); app.post('/comments.json', function(req, res) { - fs.readFile('_comments.json', function(err, data) { + fs.readFile('comments.json', function(err, data) { var comments = JSON.parse(data); comments.push(req.body); - fs.writeFile('_comments.json', JSON.stringify(comments, null, 4), function(err) { + fs.writeFile('comments.json', JSON.stringify(comments, null, 4), function(err) { res.setHeader('Content-Type', 'application/json'); res.setHeader('Cache-Control', 'no-cache'); res.send(JSON.stringify(comments)); diff --git a/server.php b/server.php index 783cfdd5..462054ea 100644 --- a/server.php +++ b/server.php @@ -11,7 +11,7 @@ function routeRequest() { - $comments = file_get_contents('_comments.json'); + $comments = file_get_contents('comments.json'); switch($_SERVER["REQUEST_URI"]) { case '/': echo file_get_contents('./public/index.html'); @@ -23,7 +23,7 @@ function routeRequest() 'text' => $_POST['text']]; $comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT); - file_put_contents('_comments.json', $comments); + file_put_contents('comments.json', $comments); } header('Content-Type: application/json'); header('Cache-Control: no-cache'); diff --git a/server.py b/server.py index fcdc3d65..d5a9c6ee 100644 --- a/server.py +++ b/server.py @@ -17,13 +17,13 @@ @app.route('/comments.json', methods=['GET', 'POST']) def comments_handler(): - with open('_comments.json', 'r') as file: + with open('comments.json', 'r') as file: comments = json.loads(file.read()) if request.method == 'POST': comments.append(request.form.to_dict()) - with open('_comments.json', 'w') as file: + with open('comments.json', 'w') as file: file.write(json.dumps(comments, indent=4, separators=(',', ': '))) return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache'}) diff --git a/server.rb b/server.rb index f2a9c659..c7eeef90 100644 --- a/server.rb +++ b/server.rb @@ -17,12 +17,12 @@ server = WEBrick::HTTPServer.new :Port => 3000, :DocumentRoot => root server.mount_proc '/comments.json' do |req, res| - comments = JSON.parse(File.read('./_comments.json')) + comments = JSON.parse(File.read('./comments.json')) if req.request_method == 'POST' # Assume it's well formed comments << req.query - File.write('./_comments.json', JSON.pretty_generate(comments, :indent => ' ')) + File.write('./comments.json', JSON.pretty_generate(comments, :indent => ' ')) end # always return json From 8a3562070dd3e332d52e12a4a3991bf7373f34c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 10 Mar 2015 12:09:40 -0700 Subject: [PATCH 033/103] Point at 0.13 --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 0edd2ac5..0c3a3387 100644 --- a/public/index.html +++ b/public/index.html @@ -4,8 +4,8 @@ Codestin Search App - - + + From 33261a4a64f9c0d7b3d7926589663fdd003fa81d Mon Sep 17 00:00:00 2001 From: Arthur Verschaeve Date: Sat, 14 Mar 2015 22:01:51 +0100 Subject: [PATCH 034/103] Correct editorconfig --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 23f1adc7..052e5ee7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true -[*.{js,rb}] +[*.{js,rb,css,html}] indent_size = 2 [*.go] From 160de38800a2b8ee48f0cb5f98b829f89282d58a Mon Sep 17 00:00:00 2001 From: Bruno Coelho Date: Sat, 21 Mar 2015 18:32:32 -0300 Subject: [PATCH 035/103] Remove deprecated method --- public/scripts/example.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/scripts/example.js b/public/scripts/example.js index c912e497..4fa306b8 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -101,14 +101,14 @@ var CommentList = React.createClass({ var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); - var author = this.refs.author.getDOMNode().value.trim(); - var text = this.refs.text.getDOMNode().value.trim(); + var author = React.findDOMNode(this.refs.author).value.trim(); + var text = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); - this.refs.author.getDOMNode().value = ''; - this.refs.text.getDOMNode().value = ''; + React.findDOMNode(this.refs.author).value = ''; + React.findDOMNode(this.refs.text).value = ''; }, render: function() { return ( From 08619fc1be5735375119a26de4dfce15a21c8176 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Fri, 27 Mar 2015 18:24:31 -0700 Subject: [PATCH 036/103] Add app.json for easy deploy to Heroku --- app.json | 9 +++++++++ package.json | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 app.json diff --git a/app.json b/app.json new file mode 100644 index 00000000..407c3cf5 --- /dev/null +++ b/app.json @@ -0,0 +1,9 @@ +{ + "name": "React Tutorial Server", + "description": "Code from the React tutorial", + "keywords": [ "react", "reactjs", "tutorial" ], + "repository": "https://github.com/reactjs/react-tutorial", + "website": "http://facebook.github.io/react/docs/tutorial.html", + "success_url": "/" +} + diff --git a/package.json b/package.json index b92ebf6b..e7491981 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,8 @@ "bugs": { "url": "https://github.com/reactjs/react-tutorial/issues" }, - "homepage": "https://github.com/reactjs/react-tutorial" + "homepage": "https://github.com/reactjs/react-tutorial", + "engines" : { + "node" : "0.12.x" + } } From 1c2b58b14f7e7e1bf90a7fa2a15c114df157fdea Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Fri, 27 Mar 2015 18:25:18 -0700 Subject: [PATCH 037/103] Add deploy button --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7a6e518a..b7517b72 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) + # React Tutorial This is the React comment box example from [the React tutorial](http://facebook.github.io/react/docs/tutorial.html). From 6a58d4887e222b56fed6f987d19eac833e07e17e Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Fri, 27 Mar 2015 18:30:36 -0700 Subject: [PATCH 038/103] Pull port off the environment, default to 3000 --- server.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index ac0c1950..fd4b81dd 100644 --- a/server.js +++ b/server.js @@ -16,6 +16,8 @@ var express = require('express'); var bodyParser = require('body-parser'); var app = express(); +app.set('port', (process.env.PORT || 3000)); + app.use('/', express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); @@ -39,6 +41,7 @@ app.post('/comments.json', function(req, res) { }); }); -app.listen(3000); -console.log('Server started: http://localhost:3000/'); +app.listen(app.get('port'), function() { + console.log('Server started: http://localhost:' + app.get('port') + '/'); +}); From 1e3038280ab96c1c74a09fcc2468abe07ae35053 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Fri, 27 Mar 2015 18:33:33 -0700 Subject: [PATCH 039/103] Specify the buildpack_url so we use the node.js buildpack --- app.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app.json b/app.json index 407c3cf5..a2a7f892 100644 --- a/app.json +++ b/app.json @@ -4,6 +4,9 @@ "keywords": [ "react", "reactjs", "tutorial" ], "repository": "https://github.com/reactjs/react-tutorial", "website": "http://facebook.github.io/react/docs/tutorial.html", - "success_url": "/" + "success_url": "/", + "env" : { + "BUILDPACK_URL": "https://github.com/heroku/heroku-buildpack-nodejs.git" + } } From 3a54049ecfc6ce6a079550b10b574110ccfb338c Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Fri, 27 Mar 2015 18:51:06 -0700 Subject: [PATCH 040/103] Support different ports on the other servers NOTE: I don't know how to do this with php --- server.go | 6 +++++- server.py | 3 ++- server.rb | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/server.go b/server.go index fde1deae..922f675f 100644 --- a/server.go +++ b/server.go @@ -85,8 +85,12 @@ func handleComments(w http.ResponseWriter, r *http.Request) { } func main() { + port := os.Getenv("PORT") + if port == "" { + port = "3000" + } http.HandleFunc("/comments.json", handleComments) http.Handle("/", http.FileServer(http.Dir("./public"))) log.Println("Server started: http://localhost:3000") - log.Fatal(http.ListenAndServe(":3000", nil)) + log.Fatal(http.ListenAndServe(":"+port, nil)) } diff --git a/server.py b/server.py index d5a9c6ee..ea8f40a5 100644 --- a/server.py +++ b/server.py @@ -9,6 +9,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import json +import os from flask import Flask, Response, request app = Flask(__name__, static_url_path='', static_folder='public') @@ -29,4 +30,4 @@ def comments_handler(): return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache'}) if __name__ == '__main__': - app.run(port=3000) + app.run(port=os.environ.get("PORT",3000)) diff --git a/server.rb b/server.rb index c7eeef90..18099ae5 100644 --- a/server.rb +++ b/server.rb @@ -11,10 +11,12 @@ require 'webrick' require 'json' -puts 'Server started: http://localhost:3000/' +port = ENV['PORT'].nil? ? 3000 : ENV['PORT'].to_i + +puts "Server started: http://localhost:#{port}/" root = File.expand_path './public' -server = WEBrick::HTTPServer.new :Port => 3000, :DocumentRoot => root +server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => root server.mount_proc '/comments.json' do |req, res| comments = JSON.parse(File.read('./comments.json')) From 750d36a1b0d7f55e3f4b3ee222c9b6aa401c78f3 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Wed, 1 Apr 2015 13:20:48 -0700 Subject: [PATCH 041/103] Output the right port in server.go --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 922f675f..cba31fd9 100644 --- a/server.go +++ b/server.go @@ -91,6 +91,6 @@ func main() { } http.HandleFunc("/comments.json", handleComments) http.Handle("/", http.FileServer(http.Dir("./public"))) - log.Println("Server started: http://localhost:3000") + log.Println("Server started: http://localhost:" + port) log.Fatal(http.ListenAndServe(":"+port, nil)) } From 86fe55267d2758dad814237db6bbfd072926e5b4 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Wed, 1 Apr 2015 13:22:08 -0700 Subject: [PATCH 042/103] returns a string if set, so int() it --- server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.py b/server.py index ea8f40a5..730e39b3 100644 --- a/server.py +++ b/server.py @@ -30,4 +30,4 @@ def comments_handler(): return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache'}) if __name__ == '__main__': - app.run(port=os.environ.get("PORT",3000)) + app.run(port=int(os.environ.get("PORT",3000))) From e915760fc345db402c3786893d5e431e5c446c54 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Wed, 1 Apr 2015 13:29:38 -0700 Subject: [PATCH 043/103] Also do this for php --- server.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/server.php b/server.php index 462054ea..e140ea83 100644 --- a/server.php +++ b/server.php @@ -3,8 +3,13 @@ isset($_SERVER['argv'][0]) && $_SERVER['argv'][0] === 'server.php'; if($scriptInvokedFromCli) { - echo 'starting server on port 3000' . PHP_EOL; - exec('php -S localhost:3000 -t public server.php'); + $port = getenv('PORT'); + if (empty($port)) { + $port = "3000"; + } + + echo 'starting server on port '. $port . PHP_EOL; + exec('php -S localhost:'. $port . ' -t public server.php'); } else { return routeRequest(); } From 233dbf72df45d3b713fda0b8bf28c94c504defa5 Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Mon, 13 Apr 2015 15:53:27 -0700 Subject: [PATCH 044/103] Use marked instead of Showdown and escape HTML See facebook/react#3663. --- public/index.html | 2 +- public/scripts/example.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 0c3a3387..c6220169 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ - +
diff --git a/public/scripts/example.js b/public/scripts/example.js index 4fa306b8..c547e038 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -10,11 +10,9 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -var converter = new Showdown.converter(); - var Comment = React.createClass({ render: function() { - var rawMarkup = converter.makeHtml(this.props.children.toString()); + var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return (

From f250556452b11a729f5c34b51dacababeadd4948 Mon Sep 17 00:00:00 2001 From: Craig Kerstiens Date: Wed, 15 Apr 2015 18:31:26 -0700 Subject: [PATCH 045/103] adding logo for app.json for heroku button --- app.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app.json b/app.json index a2a7f892..aa3e6afd 100644 --- a/app.json +++ b/app.json @@ -3,6 +3,7 @@ "description": "Code from the React tutorial", "keywords": [ "react", "reactjs", "tutorial" ], "repository": "https://github.com/reactjs/react-tutorial", + "logo": "https://facebook.github.io/react/img/logo.svg", "website": "http://facebook.github.io/react/docs/tutorial.html", "success_url": "/", "env" : { From 162e4fb74d66811b9776a67f67b569885b74d231 Mon Sep 17 00:00:00 2001 From: Michael Hopkins Date: Fri, 8 May 2015 13:57:02 -0500 Subject: [PATCH 046/103] Update server.php This change allows requests for comments.json with a timestamp param at the end, which is how React requests it. --- server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.php b/server.php index e140ea83..7a5d5078 100644 --- a/server.php +++ b/server.php @@ -21,7 +21,7 @@ function routeRequest() case '/': echo file_get_contents('./public/index.html'); break; - case '/comments.json': + case (preg_match('/comments.json*/', $_SERVER["REQUEST_URI"]) ? true : false): if($_SERVER['REQUEST_METHOD'] === 'POST') { $commentsDecoded = json_decode($comments, true); $commentsDecoded[] = ['author' => $_POST['author'], From 72dbb92daed62d54d0b9e0e5ad60b3bd8d7084a8 Mon Sep 17 00:00:00 2001 From: Leon Brocard Date: Mon, 11 May 2015 14:56:43 +0100 Subject: [PATCH 047/103] Fix typo: "it's" -> "its" --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index cba31fd9..44bc0bfd 100644 --- a/server.go +++ b/server.go @@ -28,7 +28,7 @@ func handleComments(w http.ResponseWriter, r *http.Request) { commentMutex.Lock() defer commentMutex.Unlock() - // Stat the file, so we can find it's current permissions + // Stat the file, so we can find its current permissions fi, err := os.Stat(dataFile) if err != nil { http.Error(w, fmt.Sprintf("Unable to stat the data file (%s): %s", dataFile, err), http.StatusInternalServerError) From a97df5b0386b86923d13fef0cab4bb9f7400be0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 May 2015 14:19:17 -0700 Subject: [PATCH 048/103] Clean up php server code (don't use switch in routing) --- server.php | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/server.php b/server.php index 7a5d5078..25aa468e 100644 --- a/server.php +++ b/server.php @@ -17,25 +17,23 @@ function routeRequest() { $comments = file_get_contents('comments.json'); - switch($_SERVER["REQUEST_URI"]) { - case '/': - echo file_get_contents('./public/index.html'); - break; - case (preg_match('/comments.json*/', $_SERVER["REQUEST_URI"]) ? true : false): - if($_SERVER['REQUEST_METHOD'] === 'POST') { - $commentsDecoded = json_decode($comments, true); - $commentsDecoded[] = ['author' => $_POST['author'], - 'text' => $_POST['text']]; + $uri = $_SERVER['REQUEST_URI']; + if ($uri == '/') { + echo file_get_contents('./public/index.html'); + } elseif (preg_match('/\/comments.json(\?.*)?/', $uri)) { + if($_SERVER['REQUEST_METHOD'] === 'POST') { + $commentsDecoded = json_decode($comments, true); + $commentsDecoded[] = ['author' => $_POST['author'], + 'text' => $_POST['text']]; - $comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT); - file_put_contents('comments.json', $comments); - } - header('Content-Type: application/json'); - header('Cache-Control: no-cache'); - echo $comments; - break; - default: - return false; + $comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT); + file_put_contents('comments.json', $comments); + } + header('Content-Type: application/json'); + header('Cache-Control: no-cache'); + echo $comments; + } else { + return false; } } From e414ac6ce3445f1a64ce575e415ebac863de48e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 May 2015 14:20:00 -0700 Subject: [PATCH 049/103] Add cache: false to tutorial JS this matches what we do in the actual tutorial --- public/scripts/example.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/scripts/example.js b/public/scripts/example.js index c547e038..fad2ea73 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -29,6 +29,7 @@ var CommentBox = React.createClass({ $.ajax({ url: this.props.url, dataType: 'json', + cache: false, success: function(data) { this.setState({data: data}); }.bind(this), From 840951e5eba77e93e3c927e04404bab7a0592f63 Mon Sep 17 00:00:00 2001 From: sam Date: Sat, 16 May 2015 23:37:50 +0800 Subject: [PATCH 050/103] fix failed writing comments.json for utf-8 encoded characters --- server.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server.rb b/server.rb index 18099ae5..6bfb84a1 100644 --- a/server.rb +++ b/server.rb @@ -23,7 +23,11 @@ if req.request_method == 'POST' # Assume it's well formed - comments << req.query + comment = {} + req.query.each do |key, value| + comment[key] = value.force_encoding('UTF-8') + end + comments << comment File.write('./comments.json', JSON.pretty_generate(comments, :indent => ' ')) end From 1b3542d20fcf0de7c82251a00ce4e62ea4681429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=20R=C3=B8dseth?= Date: Wed, 20 May 2015 13:27:22 +0200 Subject: [PATCH 051/103] Added server.lua --- README.md | 7 +++++++ server.lua | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 server.lua diff --git a/README.md b/README.md index b7517b72..5ef81d76 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,13 @@ This is the React comment box example from [the React tutorial](http://facebook. There are several simple server implementations included. They all serve static files from `public/` and handle requests to `comments.json` to fetch or add data. Start a server with one of the following: +### Lua + +``` +go get github.com/xyproto/algernon +algernon server.lua +``` + ### Node ```sh diff --git a/server.lua b/server.lua new file mode 100644 index 00000000..53647d82 --- /dev/null +++ b/server.lua @@ -0,0 +1,22 @@ +-- +-- For use with Algernon / Lua +-- +-- Project page: https://github.com/xyproto/algernon +-- Web page: http://algernon.roboticoverlords.org/ +-- + +-- Set the headers +content("application/javascript") +setheader("Cache-Control", "no-cache") + +-- Use a Redis list for the comments +comments = List("comments") + +-- Handle requests +if method() == "POST" then + -- Add the form data to the comment list, as JSON + comments:add(JSON(formdata())) +else + -- Combine all the JSON comments to a JSON document + print("["..table.concat(comments:getall(), ",").."]") +end From fef639753c2cf6ac2d207f8d02dcaf2c4eec8938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 9 Jun 2015 11:01:37 -0700 Subject: [PATCH 052/103] Add license comments to php & go server implementations --- server.go | 12 ++++++++++++ server.php | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index 44bc0bfd..e36b5b21 100644 --- a/server.go +++ b/server.go @@ -1,3 +1,15 @@ +/** + * This file provided by Facebook is for non-commercial testing and evaluation purposes only. + * Facebook reserves all rights not expressly granted. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + package main import ( diff --git a/server.php b/server.php index 25aa468e..b6ab88f2 100644 --- a/server.php +++ b/server.php @@ -1,4 +1,15 @@ Date: Tue, 9 Jun 2015 11:10:35 -0700 Subject: [PATCH 053/103] [node] Use express's built-in json headers, set no cache on GET --- server.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index fd4b81dd..8ce83a0d 100644 --- a/server.js +++ b/server.js @@ -24,8 +24,8 @@ app.use(bodyParser.urlencoded({extended: true})); app.get('/comments.json', function(req, res) { fs.readFile('comments.json', function(err, data) { - res.setHeader('Content-Type', 'application/json'); - res.send(data); + res.setHeader('Cache-Control', 'no-cache'); + res.json(JSON.parse(data)); }); }); @@ -34,9 +34,8 @@ app.post('/comments.json', function(req, res) { var comments = JSON.parse(data); comments.push(req.body); fs.writeFile('comments.json', JSON.stringify(comments, null, 4), function(err) { - res.setHeader('Content-Type', 'application/json'); res.setHeader('Cache-Control', 'no-cache'); - res.send(JSON.stringify(comments)); + res.json(comments); }); }); }); From 5ed1252d3474ae537b3242da1ed64d834301e7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=20R=C3=B8dseth?= Date: Thu, 18 Jun 2015 01:30:00 +0200 Subject: [PATCH 054/103] Use the JSON document for storing comments --- server.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server.lua b/server.lua index 53647d82..96f65c27 100644 --- a/server.lua +++ b/server.lua @@ -9,14 +9,14 @@ content("application/javascript") setheader("Cache-Control", "no-cache") --- Use a Redis list for the comments -comments = List("comments") +-- Use a JSON file for the comments +comments = JFile("comments.json") -- Handle requests if method() == "POST" then - -- Add the form data to the comment list, as JSON - comments:add(JSON(formdata())) + -- Add the form data table to the JSON document + comments:add(ToJSON(formdata())) else - -- Combine all the JSON comments to a JSON document - print("["..table.concat(comments:getall(), ",").."]") + -- Return the contents of the JSON file + print(tostring(comments)) end From 83202d3063fdc06976646ecbcfe1cac72d298205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=20R=C3=B8dseth?= Date: Mon, 22 Jun 2015 03:27:05 +0200 Subject: [PATCH 055/103] Made the Lua sample work like the other samples --- server.lua | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/server.lua b/server.lua index 96f65c27..7492f1c2 100644 --- a/server.lua +++ b/server.lua @@ -1,22 +1,28 @@ -- -- For use with Algernon / Lua --- +-- -- Project page: https://github.com/xyproto/algernon -- Web page: http://algernon.roboticoverlords.org/ -- --- Set the headers -content("application/javascript") -setheader("Cache-Control", "no-cache") +handle("/comments.json", function() + + -- Set the headers + content("application/javascript") + setheader("Cache-Control", "no-cache") + + -- Use a JSON file for the comments + comments = JFile("comments.json") + + -- Handle requests + if method() == "POST" then + -- Add the form data table to the JSON document + comments:add(ToJSON(formdata())) + else + -- Return the contents of the JSON file + print(tostring(comments)) + end --- Use a JSON file for the comments -comments = JFile("comments.json") +end) --- Handle requests -if method() == "POST" then - -- Add the form data table to the JSON document - comments:add(ToJSON(formdata())) -else - -- Return the contents of the JSON file - print(tostring(comments)) -end +servedir("/", "public") From 0eb5dbd3b45e17fe6c8313b1359563fc8b948c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Wed, 8 Jul 2015 17:13:14 -0700 Subject: [PATCH 056/103] Fix lua server for POST, update readme --- README.md | 15 ++++++++------- server.lua | 8 ++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5ef81d76..f8aa5bc7 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,6 @@ This is the React comment box example from [the React tutorial](http://facebook. There are several simple server implementations included. They all serve static files from `public/` and handle requests to `comments.json` to fetch or add data. Start a server with one of the following: -### Lua - -``` -go get github.com/xyproto/algernon -algernon server.lua -``` - ### Node ```sh @@ -44,4 +37,12 @@ php server.php go run server.go ``` +### Lua + +```sh +go get github.com/xyproto/algernon +# or brew install algernon +algernon server.lua +``` + And visit . Try opening multiple tabs! diff --git a/server.lua b/server.lua index 7492f1c2..ec075eaa 100644 --- a/server.lua +++ b/server.lua @@ -17,12 +17,12 @@ handle("/comments.json", function() -- Handle requests if method() == "POST" then -- Add the form data table to the JSON document - comments:add(ToJSON(formdata())) - else - -- Return the contents of the JSON file - print(tostring(comments)) + comments:add(ToJSON(formdata(), 4)) end + -- Return the contents of the JSON file + print(tostring(comments)) + end) servedir("/", "public") From c122a906639fe528a0b5a6108ba0ed6d245d81d6 Mon Sep 17 00:00:00 2001 From: Sibi Date: Fri, 17 Jul 2015 00:50:10 +0530 Subject: [PATCH 057/103] Haskell code. --- README.md | 9 ++++++++ Server.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++++ react-scotty.cabal | 28 ++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 Server.hs create mode 100644 react-scotty.cabal diff --git a/README.md b/README.md index f8aa5bc7..80942982 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,15 @@ pip install -r requirements.txt python server.py ``` +### Haskell + +```sh +cabal sandbox init +cabal install --only-dependencies +ghc Server.hs +./Server +``` + ### Ruby ```sh ruby server.rb diff --git a/Server.hs b/Server.hs new file mode 100644 index 00000000..de416d7d --- /dev/null +++ b/Server.hs @@ -0,0 +1,54 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main (main) where + +import Web.Scotty + +import Control.Monad (mzero) +import Control.Monad.Trans +import Network.Wai.Middleware.Static +import Network.Wai.Middleware.RequestLogger (logStdoutDev) +import Data.ByteString.Lazy (readFile, writeFile, fromStrict) +import qualified Data.ByteString as BS (readFile) +import Prelude hiding (readFile, writeFile) +import Data.Aeson hiding (json) +import Data.Text +import Data.Maybe (fromJust) + +data Comment = Comment { + commentText :: Text, + author :: Text + } deriving (Eq, Show, Ord) + +instance FromJSON Comment where + parseJSON (Object v) = Comment <$> + v .: "text" <*> + v .: "author" + parseJSON _ = mzero + +instance ToJSON Comment where + toJSON (Comment ctext author) = object ["text" .= ctext, "author" .= author] + + +main :: IO () +main = scotty 3000 $ do + + middleware $ staticPolicy (noDots >-> addBase "public") + middleware logStdoutDev + + get "/" $ file "./public/index.html" + + get "/comments.json" $ do + comments <- liftIO $ readFile "comments.json" + json $ fromJust $ (decode comments :: Maybe [Comment]) + + post "/comments.json" $ do + comments <- liftIO $ BS.readFile "comments.json" + let jsonComments = fromJust $ (decode $ fromStrict comments :: Maybe [Comment]) + author <- param "author" + comment <- param "text" + let allComments = jsonComments ++ [Comment comment author] + liftIO $ writeFile "comments.json" (encode allComments) + json allComments + + diff --git a/react-scotty.cabal b/react-scotty.cabal new file mode 100644 index 00000000..a3024211 --- /dev/null +++ b/react-scotty.cabal @@ -0,0 +1,28 @@ +-- Initial react-scotty.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/ + +name: react-scotty +version: 0.1.0.0 +synopsis: React Haskell code with Scotty +-- description: +license: GPL-2 +license-file: LICENSE +author: Sibi +maintainer: sibi@psibi.in +-- copyright: +category: Web +build-type: Simple +-- extra-source-files: +cabal-version: >=1.10 + +executable react-scotty + main-is: Server.hs + -- other-modules: + -- other-extensions: + build-depends: base >=4.8 && <4.9, + scotty, wai-extra, + mtl, text, aeson, + bytestring, + wai-middleware-static + -- hs-source-dirs: + default-language: Haskell2010 From 45d17b7a8b6d79fa3d8d09b7ea08701ce75a9adf Mon Sep 17 00:00:00 2001 From: Joe Martella Date: Wed, 22 Jul 2015 14:32:13 -0700 Subject: [PATCH 058/103] Added Markdown content to comments.json. The React tutorial makes use of the marked library, but this test data in the repo doesn't include any Markdown. Just makes for a more interesting tutorial IMO. --- comments.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/comments.json b/comments.json index 32938452..61f5ef60 100644 --- a/comments.json +++ b/comments.json @@ -2,5 +2,9 @@ { "author": "Pete Hunt", "text": "Hey there!" + }, + { + "author": "Paul O’Shannessy", + "text": "React is *great*!" } ] From 72c4e7a1b952664419dcde39056e7c8f494c3cd6 Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Mon, 3 Aug 2015 19:26:59 +0300 Subject: [PATCH 059/103] Fix typo --- public/scripts/example.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/example.js b/public/scripts/example.js index fad2ea73..deb93047 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -43,8 +43,8 @@ var CommentBox = React.createClass({ comments.push(comment); this.setState({data: comments}, function() { // `setState` accepts a callback. To avoid (improbable) race condition, - // `we'll send the ajax request right after we optimistically set the new - // `state. + // we'll send the ajax request right after we optimistically set the new + // state. $.ajax({ url: this.props.url, dataType: 'json', From a8c9f89c45def9d54b8a8df5abdf6d846eeba9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Wed, 19 Aug 2015 09:38:26 -0700 Subject: [PATCH 060/103] Add LICENSE at root, fix license headers. Closes #70 --- LICENSE | 9 +++++++++ Server.hs | 16 ++++++++++++---- public/scripts/example.js | 4 ++-- server.go | 4 ++-- server.js | 4 ++-- server.lua | 10 ++++++++++ server.php | 4 ++-- server.py | 4 ++-- server.rb | 4 ++-- 9 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..87f537d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +The examples provided by Facebook are for non-commercial testing and evaluation +purposes only. Facebook reserves all rights not expressly granted. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Server.hs b/Server.hs index de416d7d..577622f8 100644 --- a/Server.hs +++ b/Server.hs @@ -1,3 +1,13 @@ +-- This file provided by Facebook is for non-commercial testing and evaluation +-- purposes only. Facebook reserves all rights not expressly granted. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +-- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + {-# LANGUAGE OverloadedStrings #-} module Main (main) where @@ -32,7 +42,7 @@ instance ToJSON Comment where main :: IO () main = scotty 3000 $ do - + middleware $ staticPolicy (noDots >-> addBase "public") middleware logStdoutDev @@ -41,7 +51,7 @@ main = scotty 3000 $ do get "/comments.json" $ do comments <- liftIO $ readFile "comments.json" json $ fromJust $ (decode comments :: Maybe [Comment]) - + post "/comments.json" $ do comments <- liftIO $ BS.readFile "comments.json" let jsonComments = fromJust $ (decode $ fromStrict comments :: Maybe [Comment]) @@ -50,5 +60,3 @@ main = scotty 3000 $ do let allComments = jsonComments ++ [Comment comment author] liftIO $ writeFile "comments.json" (encode allComments) json allComments - - diff --git a/public/scripts/example.js b/public/scripts/example.js index deb93047..4fefa535 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -1,6 +1,6 @@ /** - * This file provided by Facebook is for non-commercial testing and evaluation purposes only. - * Facebook reserves all rights not expressly granted. + * This file provided by Facebook is for non-commercial testing and evaluation + * purposes only. Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/server.go b/server.go index e36b5b21..146192d1 100644 --- a/server.go +++ b/server.go @@ -1,6 +1,6 @@ /** - * This file provided by Facebook is for non-commercial testing and evaluation purposes only. - * Facebook reserves all rights not expressly granted. + * This file provided by Facebook is for non-commercial testing and evaluation + * purposes only. Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/server.js b/server.js index 8ce83a0d..c439d59d 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,6 @@ /** - * This file provided by Facebook is for non-commercial testing and evaluation purposes only. - * Facebook reserves all rights not expressly granted. + * This file provided by Facebook is for non-commercial testing and evaluation + * purposes only. Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/server.lua b/server.lua index ec075eaa..e80bbc59 100644 --- a/server.lua +++ b/server.lua @@ -1,3 +1,13 @@ +-- This file provided by Facebook is for non-commercial testing and evaluation +-- purposes only. Facebook reserves all rights not expressly granted. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +-- FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +-- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +-- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + -- -- For use with Algernon / Lua -- diff --git a/server.php b/server.php index b6ab88f2..70301a3f 100644 --- a/server.php +++ b/server.php @@ -1,7 +1,7 @@ Date: Sun, 23 Aug 2015 19:29:24 -0500 Subject: [PATCH 061/103] Updating example.js to match tutorial example.js was out of sync with the tutorial; handleCommentSubmit does not need a call back. --- public/scripts/example.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/public/scripts/example.js b/public/scripts/example.js index 4fefa535..3d61ef33 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -40,23 +40,19 @@ var CommentBox = React.createClass({ }, handleCommentSubmit: function(comment) { var comments = this.state.data; - comments.push(comment); - this.setState({data: comments}, function() { - // `setState` accepts a callback. To avoid (improbable) race condition, - // we'll send the ajax request right after we optimistically set the new - // state. - $.ajax({ - url: this.props.url, - dataType: 'json', - type: 'POST', - data: comment, - success: function(data) { - this.setState({data: data}); - }.bind(this), - error: function(xhr, status, err) { - console.error(this.props.url, status, err.toString()); - }.bind(this) - }); + var newComments = comments.concat([comment]); + this.setState({data: newComments}); + $.ajax({ + url: this.props.url, + dataType: 'json', + type: 'POST', + data: comment, + success: function(data) { + this.setState({data: data}); + }.bind(this), + error: function(xhr, status, err) { + console.error(this.props.url, status, err.toString()); + }.bind(this) }); }, getInitialState: function() { From 3292397ae6b0341fb0a18743d9458eca495bf3f4 Mon Sep 17 00:00:00 2001 From: mitsuteru sawa Date: Tue, 8 Sep 2015 22:37:51 +0900 Subject: [PATCH 062/103] go lint - Simple declaration --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 146192d1..ef5f4666 100644 --- a/server.go +++ b/server.go @@ -57,7 +57,7 @@ func handleComments(w http.ResponseWriter, r *http.Request) { switch r.Method { case "POST": // Decode the JSON data - comments := make([]comment, 0) + var comments []comment if err := json.Unmarshal(commentData, &comments); err != nil { http.Error(w, fmt.Sprintf("Unable to Unmarshal comments from data file (%s): %s", dataFile, err), http.StatusInternalServerError) return From 0138d00fefbd8a9a8828293d6f12de991a1d1fe6 Mon Sep 17 00:00:00 2001 From: mitsuteru sawa Date: Tue, 8 Sep 2015 22:42:02 +0900 Subject: [PATCH 063/103] ruby lint - Apply new Hash style - {} is prefered for block in case of single line --- server.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server.rb b/server.rb index 8e40876d..b0e08601 100644 --- a/server.rb +++ b/server.rb @@ -16,7 +16,7 @@ puts "Server started: http://localhost:#{port}/" root = File.expand_path './public' -server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => root +server = WEBrick::HTTPServer.new Port: port, DocumentRoot: root server.mount_proc '/comments.json' do |req, res| comments = JSON.parse(File.read('./comments.json')) @@ -28,7 +28,7 @@ comment[key] = value.force_encoding('UTF-8') end comments << comment - File.write('./comments.json', JSON.pretty_generate(comments, :indent => ' ')) + File.write('./comments.json', JSON.pretty_generate(comments, indent: ' ')) end # always return json @@ -37,6 +37,6 @@ res.body = JSON.generate(comments) end -trap 'INT' do server.shutdown end +trap('INT') { server.shutdown } server.start From 150a05553498194943bbf77a919cb7fe34b34d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 22 Sep 2015 11:16:36 -0700 Subject: [PATCH 064/103] Update to match changes on website https://github.com/facebook/react/pull/4931 --- public/scripts/example.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/public/scripts/example.js b/public/scripts/example.js index 3d61ef33..a77a7c8a 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -11,14 +11,18 @@ */ var Comment = React.createClass({ - render: function() { + rawMarkup: function() { var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); + return { __html: rawMarkup }; + }, + + render: function() { return (

{this.props.author}

- +
); } From aa677d0eede03de24b44b3005904eab8140ec7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 24 Sep 2015 12:43:21 -0700 Subject: [PATCH 065/103] Use an API endpoint --- README.md | 2 +- Server.hs | 4 ++-- public/scripts/example.js | 2 +- server.go | 2 +- server.js | 4 ++-- server.lua | 2 +- server.php | 2 +- server.py | 2 +- server.rb | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 80942982..89ea4e77 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This is the React comment box example from [the React tutorial](http://facebook. ## To use -There are several simple server implementations included. They all serve static files from `public/` and handle requests to `comments.json` to fetch or add data. Start a server with one of the following: +There are several simple server implementations included. They all serve static files from `public/` and handle requests to `/api/comments` to fetch or add data. Start a server with one of the following: ### Node diff --git a/Server.hs b/Server.hs index 577622f8..9a5c747e 100644 --- a/Server.hs +++ b/Server.hs @@ -48,11 +48,11 @@ main = scotty 3000 $ do get "/" $ file "./public/index.html" - get "/comments.json" $ do + get "/api/comments" $ do comments <- liftIO $ readFile "comments.json" json $ fromJust $ (decode comments :: Maybe [Comment]) - post "/comments.json" $ do + post "/api/comments" $ do comments <- liftIO $ BS.readFile "comments.json" let jsonComments = fromJust $ (decode $ fromStrict comments :: Maybe [Comment]) author <- param "author" diff --git a/public/scripts/example.js b/public/scripts/example.js index a77a7c8a..95a19fb7 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -121,6 +121,6 @@ var CommentForm = React.createClass({ }); React.render( - , + , document.getElementById('content') ); diff --git a/server.go b/server.go index ef5f4666..9eb5d7d2 100644 --- a/server.go +++ b/server.go @@ -101,7 +101,7 @@ func main() { if port == "" { port = "3000" } - http.HandleFunc("/comments.json", handleComments) + http.HandleFunc("/api/comments", handleComments) http.Handle("/", http.FileServer(http.Dir("./public"))) log.Println("Server started: http://localhost:" + port) log.Fatal(http.ListenAndServe(":"+port, nil)) diff --git a/server.js b/server.js index c439d59d..1379adbb 100644 --- a/server.js +++ b/server.js @@ -22,14 +22,14 @@ app.use('/', express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); -app.get('/comments.json', function(req, res) { +app.get('/api/comments', function(req, res) { fs.readFile('comments.json', function(err, data) { res.setHeader('Cache-Control', 'no-cache'); res.json(JSON.parse(data)); }); }); -app.post('/comments.json', function(req, res) { +app.post('/api/comments', function(req, res) { fs.readFile('comments.json', function(err, data) { var comments = JSON.parse(data); comments.push(req.body); diff --git a/server.lua b/server.lua index e80bbc59..10df59fc 100644 --- a/server.lua +++ b/server.lua @@ -15,7 +15,7 @@ -- Web page: http://algernon.roboticoverlords.org/ -- -handle("/comments.json", function() +handle("/api/comments", function() -- Set the headers content("application/javascript") diff --git a/server.php b/server.php index 70301a3f..53c19104 100644 --- a/server.php +++ b/server.php @@ -31,7 +31,7 @@ function routeRequest() $uri = $_SERVER['REQUEST_URI']; if ($uri == '/') { echo file_get_contents('./public/index.html'); - } elseif (preg_match('/\/comments.json(\?.*)?/', $uri)) { + } elseif (preg_match('/\/api\/comments(\?.*)?/', $uri)) { if($_SERVER['REQUEST_METHOD'] === 'POST') { $commentsDecoded = json_decode($comments, true); $commentsDecoded[] = ['author' => $_POST['author'], diff --git a/server.py b/server.py index 7dc15c14..7b4920b9 100644 --- a/server.py +++ b/server.py @@ -15,7 +15,7 @@ app = Flask(__name__, static_url_path='', static_folder='public') app.add_url_rule('/', 'root', lambda: app.send_static_file('index.html')) -@app.route('/comments.json', methods=['GET', 'POST']) +@app.route('/api/comments', methods=['GET', 'POST']) def comments_handler(): with open('comments.json', 'r') as file: diff --git a/server.rb b/server.rb index b0e08601..29af13ee 100644 --- a/server.rb +++ b/server.rb @@ -18,7 +18,7 @@ root = File.expand_path './public' server = WEBrick::HTTPServer.new Port: port, DocumentRoot: root -server.mount_proc '/comments.json' do |req, res| +server.mount_proc '/api/comments' do |req, res| comments = JSON.parse(File.read('./comments.json')) if req.request_method == 'POST' From cc1328227f136b39fac1be9e1dd1fa30dd073c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 24 Sep 2015 15:34:08 -0700 Subject: [PATCH 066/103] Include empty script tag with comment for easier starting --- public/index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/index.html b/public/index.html index c6220169..09745d59 100644 --- a/public/index.html +++ b/public/index.html @@ -12,5 +12,9 @@
+ From 0ef9282bbfe0a8f87575ec2564261dd97e246ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Fri, 25 Sep 2015 14:48:48 -0700 Subject: [PATCH 067/103] Add charset, change page title --- public/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 09745d59..ab7f49e8 100644 --- a/public/index.html +++ b/public/index.html @@ -1,7 +1,8 @@ - Codestin Search App + + Codestin Search App From 871b940b3ada4fdb78a915656fb2ad50816d2002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 20 Aug 2015 14:47:28 -0700 Subject: [PATCH 068/103] Use Babel to transform JSX --- public/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/index.html b/public/index.html index ab7f49e8..da1c9a10 100644 --- a/public/index.html +++ b/public/index.html @@ -6,14 +6,14 @@ - +
- - + From 6647f84311c47450a0940a88dea1b06484b0a543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 29 Sep 2015 12:11:15 -0700 Subject: [PATCH 069/103] Ruby: specify UTF-8 encoding for file IO --- server.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server.rb b/server.rb index 29af13ee..4e9916b3 100644 --- a/server.rb +++ b/server.rb @@ -19,7 +19,7 @@ server = WEBrick::HTTPServer.new Port: port, DocumentRoot: root server.mount_proc '/api/comments' do |req, res| - comments = JSON.parse(File.read('./comments.json')) + comments = JSON.parse(File.read('./comments.json', encoding: 'UTF-8')) if req.request_method == 'POST' # Assume it's well formed @@ -28,7 +28,11 @@ comment[key] = value.force_encoding('UTF-8') end comments << comment - File.write('./comments.json', JSON.pretty_generate(comments, indent: ' ')) + File.write( + './comments.json', + JSON.pretty_generate(comments, indent: ' '), + encoding: 'UTF-8' + ) end # always return json From a52792bed34fc15ed519900853dd426d80df8b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 8 Oct 2015 13:30:52 -0700 Subject: [PATCH 070/103] Update for 0.14 Fixes #83 --- public/index.html | 3 ++- public/scripts/example.js | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/public/index.html b/public/index.html index da1c9a10..c6494446 100644 --- a/public/index.html +++ b/public/index.html @@ -5,7 +5,8 @@ Codestin Search App - + + diff --git a/public/scripts/example.js b/public/scripts/example.js index 95a19fb7..7e7bf35d 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -100,14 +100,14 @@ var CommentList = React.createClass({ var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); - var author = React.findDOMNode(this.refs.author).value.trim(); - var text = React.findDOMNode(this.refs.text).value.trim(); + var author = this.refs.author.value.trim(); + var text = this.refs.text.value.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); - React.findDOMNode(this.refs.author).value = ''; - React.findDOMNode(this.refs.text).value = ''; + this.refs.author.value = ''; + this.refs.text.value = ''; }, render: function() { return ( @@ -120,7 +120,7 @@ var CommentForm = React.createClass({ } }); -React.render( +ReactDOM.render( , document.getElementById('content') ); From 0444916c04c39bb27c1944f0e09219859ff5740c Mon Sep 17 00:00:00 2001 From: Rob McGuire-Dale Date: Fri, 9 Oct 2015 06:35:57 -0700 Subject: [PATCH 071/103] JS: Make comments file reference relative to server file --- server.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server.js b/server.js index 1379adbb..f4f331ea 100644 --- a/server.js +++ b/server.js @@ -16,6 +16,8 @@ var express = require('express'); var bodyParser = require('body-parser'); var app = express(); +var COMMENTS_FILE = path.join(__dirname, 'comments.json'); + app.set('port', (process.env.PORT || 3000)); app.use('/', express.static(path.join(__dirname, 'public'))); @@ -23,17 +25,17 @@ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.get('/api/comments', function(req, res) { - fs.readFile('comments.json', function(err, data) { + fs.readFile(COMMENTS_FILE, function(err, data) { res.setHeader('Cache-Control', 'no-cache'); res.json(JSON.parse(data)); }); }); app.post('/api/comments', function(req, res) { - fs.readFile('comments.json', function(err, data) { + fs.readFile(COMMENTS_FILE, function(err, data) { var comments = JSON.parse(data); comments.push(req.body); - fs.writeFile('comments.json', JSON.stringify(comments, null, 4), function(err) { + fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) { res.setHeader('Cache-Control', 'no-cache'); res.json(comments); }); From 8f4f0dbad9184114b743029837d996db729fc484 Mon Sep 17 00:00:00 2001 From: Rob McGuire-Dale Date: Fri, 9 Oct 2015 06:53:40 -0700 Subject: [PATCH 072/103] Add 'changining the port' section to the README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 89ea4e77..f72917ef 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,11 @@ algernon server.lua ``` And visit . Try opening multiple tabs! + +## Changing the port + +You can change the port number by setting the `$PORT` environment variable before invoking any of the scripts above, e.g., + +```sh +PORT=3001 node server.js +``` From 208e00fd909323f69be2cbad0c84c2f1336da9f6 Mon Sep 17 00:00:00 2001 From: David Farrell Date: Mon, 26 Oct 2015 14:47:44 -0400 Subject: [PATCH 073/103] Example web server in Perl --- README.md | 7 +++++++ server.pl | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 server.pl diff --git a/README.md b/README.md index f72917ef..44f65390 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,13 @@ go get github.com/xyproto/algernon algernon server.lua ``` +### Perl + +```sh +cpan Mojolicious +perl server.pl +``` + And visit . Try opening multiple tabs! ## Changing the port diff --git a/server.pl b/server.pl new file mode 100644 index 00000000..ce1783e7 --- /dev/null +++ b/server.pl @@ -0,0 +1,34 @@ +# This file provided by Facebook is for non-commercial testing and evaluation +# purposes only. Facebook reserves all rights not expressly granted. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +use Mojolicious::Lite; +use Mojo::JSON qw(encode_json decode_json); + +app->static->paths->[0] = './public'; + +any '/' => sub { $_[0]->reply->static('index.html') }; + +any [qw(GET POST)] => '/api/comments' => sub { + my $self = shift; + my $comments = decode_json (do { local(@ARGV,$/) = 'comments.json';<> }); + + if ($self->req->method eq 'POST') + { + push @$comments, { + author => $self->param('author'), + text => $self->param('text'), + }; + open my $FILE, '>', 'comments.json'; + print $FILE encode_json($comments); + } + $self->render(json => $comments); +}; +my $port = $ENV{PORT} || 3000; +app->start('daemon', '-l', "http://*:$port"); From eec66b187aa48374a6f9e9e078b8e8f53845925f Mon Sep 17 00:00:00 2001 From: Chris Tsongas Date: Mon, 26 Oct 2015 22:03:41 +0100 Subject: [PATCH 074/103] Fix failure to roll back optimistic update after error --- public/scripts/example.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/scripts/example.js b/public/scripts/example.js index 7e7bf35d..2e0ee2a8 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -55,6 +55,7 @@ var CommentBox = React.createClass({ this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { + this.setState({data: comments}); console.error(this.props.url, status, err.toString()); }.bind(this) }); From 2ddef372f1ed743471e21f1d5c610d7751b20d73 Mon Sep 17 00:00:00 2001 From: Varun Maudgalya Date: Mon, 2 Nov 2015 14:17:06 -0800 Subject: [PATCH 075/103] Added error handling --- server.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server.js b/server.js index f4f331ea..2946e370 100644 --- a/server.js +++ b/server.js @@ -26,6 +26,7 @@ app.use(bodyParser.urlencoded({extended: true})); app.get('/api/comments', function(req, res) { fs.readFile(COMMENTS_FILE, function(err, data) { + if (err) console.log(err); res.setHeader('Cache-Control', 'no-cache'); res.json(JSON.parse(data)); }); @@ -33,9 +34,11 @@ app.get('/api/comments', function(req, res) { app.post('/api/comments', function(req, res) { fs.readFile(COMMENTS_FILE, function(err, data) { + if (err) console.log(err); var comments = JSON.parse(data); comments.push(req.body); fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) { + if (err) console.log(err); res.setHeader('Cache-Control', 'no-cache'); res.json(comments); }); From 587268e6a2490afe2eb13f13ca359c29f6aa86a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 10 Nov 2015 15:34:13 -0800 Subject: [PATCH 076/103] Remove Lua server --- README.md | 8 -------- server.lua | 38 -------------------------------------- 2 files changed, 46 deletions(-) delete mode 100644 server.lua diff --git a/README.md b/README.md index 44f65390..72ce4462 100644 --- a/README.md +++ b/README.md @@ -46,14 +46,6 @@ php server.php go run server.go ``` -### Lua - -```sh -go get github.com/xyproto/algernon -# or brew install algernon -algernon server.lua -``` - ### Perl ```sh diff --git a/server.lua b/server.lua deleted file mode 100644 index 10df59fc..00000000 --- a/server.lua +++ /dev/null @@ -1,38 +0,0 @@ --- This file provided by Facebook is for non-commercial testing and evaluation --- purposes only. Facebook reserves all rights not expressly granted. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL --- FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN --- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION --- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE - --- --- For use with Algernon / Lua --- --- Project page: https://github.com/xyproto/algernon --- Web page: http://algernon.roboticoverlords.org/ --- - -handle("/api/comments", function() - - -- Set the headers - content("application/javascript") - setheader("Cache-Control", "no-cache") - - -- Use a JSON file for the comments - comments = JFile("comments.json") - - -- Handle requests - if method() == "POST" then - -- Add the form data table to the JSON document - comments:add(ToJSON(formdata(), 4)) - end - - -- Return the contents of the JSON file - print(tostring(comments)) - -end) - -servedir("/", "public") From 485052b520447f00578ceab58875b3422adaf7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 10 Nov 2015 15:36:20 -0800 Subject: [PATCH 077/103] Remove Haskell server --- README.md | 9 ------- Server.hs | 62 ---------------------------------------------- react-scotty.cabal | 28 --------------------- 3 files changed, 99 deletions(-) delete mode 100644 Server.hs delete mode 100644 react-scotty.cabal diff --git a/README.md b/README.md index 72ce4462..4862f5df 100644 --- a/README.md +++ b/README.md @@ -22,15 +22,6 @@ pip install -r requirements.txt python server.py ``` -### Haskell - -```sh -cabal sandbox init -cabal install --only-dependencies -ghc Server.hs -./Server -``` - ### Ruby ```sh ruby server.rb diff --git a/Server.hs b/Server.hs deleted file mode 100644 index 9a5c747e..00000000 --- a/Server.hs +++ /dev/null @@ -1,62 +0,0 @@ --- This file provided by Facebook is for non-commercial testing and evaluation --- purposes only. Facebook reserves all rights not expressly granted. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL --- FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN --- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION --- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE - -{-# LANGUAGE OverloadedStrings #-} - -module Main (main) where - -import Web.Scotty - -import Control.Monad (mzero) -import Control.Monad.Trans -import Network.Wai.Middleware.Static -import Network.Wai.Middleware.RequestLogger (logStdoutDev) -import Data.ByteString.Lazy (readFile, writeFile, fromStrict) -import qualified Data.ByteString as BS (readFile) -import Prelude hiding (readFile, writeFile) -import Data.Aeson hiding (json) -import Data.Text -import Data.Maybe (fromJust) - -data Comment = Comment { - commentText :: Text, - author :: Text - } deriving (Eq, Show, Ord) - -instance FromJSON Comment where - parseJSON (Object v) = Comment <$> - v .: "text" <*> - v .: "author" - parseJSON _ = mzero - -instance ToJSON Comment where - toJSON (Comment ctext author) = object ["text" .= ctext, "author" .= author] - - -main :: IO () -main = scotty 3000 $ do - - middleware $ staticPolicy (noDots >-> addBase "public") - middleware logStdoutDev - - get "/" $ file "./public/index.html" - - get "/api/comments" $ do - comments <- liftIO $ readFile "comments.json" - json $ fromJust $ (decode comments :: Maybe [Comment]) - - post "/api/comments" $ do - comments <- liftIO $ BS.readFile "comments.json" - let jsonComments = fromJust $ (decode $ fromStrict comments :: Maybe [Comment]) - author <- param "author" - comment <- param "text" - let allComments = jsonComments ++ [Comment comment author] - liftIO $ writeFile "comments.json" (encode allComments) - json allComments diff --git a/react-scotty.cabal b/react-scotty.cabal deleted file mode 100644 index a3024211..00000000 --- a/react-scotty.cabal +++ /dev/null @@ -1,28 +0,0 @@ --- Initial react-scotty.cabal generated by cabal init. For further --- documentation, see http://haskell.org/cabal/users-guide/ - -name: react-scotty -version: 0.1.0.0 -synopsis: React Haskell code with Scotty --- description: -license: GPL-2 -license-file: LICENSE -author: Sibi -maintainer: sibi@psibi.in --- copyright: -category: Web -build-type: Simple --- extra-source-files: -cabal-version: >=1.10 - -executable react-scotty - main-is: Server.hs - -- other-modules: - -- other-extensions: - build-depends: base >=4.8 && <4.9, - scotty, wai-extra, - mtl, text, aeson, - bytestring, - wai-middleware-static - -- hs-source-dirs: - default-language: Haskell2010 From 84129a5ed0dbd6e5b2f851d4bf41f4127cf894c8 Mon Sep 17 00:00:00 2001 From: Varun Maudgalya Date: Tue, 10 Nov 2015 16:50:17 -0800 Subject: [PATCH 078/103] revised error handling --- server.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/server.js b/server.js index 2946e370..2a1ae582 100644 --- a/server.js +++ b/server.js @@ -26,7 +26,10 @@ app.use(bodyParser.urlencoded({extended: true})); app.get('/api/comments', function(req, res) { fs.readFile(COMMENTS_FILE, function(err, data) { - if (err) console.log(err); + if (err) { + console.error(err); + process.exit(1); + } res.setHeader('Cache-Control', 'no-cache'); res.json(JSON.parse(data)); }); @@ -34,11 +37,17 @@ app.get('/api/comments', function(req, res) { app.post('/api/comments', function(req, res) { fs.readFile(COMMENTS_FILE, function(err, data) { - if (err) console.log(err); + if (err) { + console.error(err); + process.exit(1); + } var comments = JSON.parse(data); comments.push(req.body); fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) { - if (err) console.log(err); + if (err) { + console.error(err); + process.exit(1); + } res.setHeader('Cache-Control', 'no-cache'); res.json(comments); }); From 0e7f1b2f7d58a059a67da9604c84ab055fdf3b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Mon, 2 Nov 2015 17:20:56 -0800 Subject: [PATCH 079/103] Add ids to data server-side so that keys can be used client-side --- comments.json | 2 ++ public/scripts/example.js | 11 ++++++----- server.go | 4 +++- server.js | 10 +++++++++- server.php | 7 +++++-- server.pl | 2 ++ server.py | 5 ++++- server.rb | 2 +- 8 files changed, 32 insertions(+), 11 deletions(-) diff --git a/comments.json b/comments.json index 61f5ef60..7bef77ad 100644 --- a/comments.json +++ b/comments.json @@ -1,9 +1,11 @@ [ { + "id": 1388534400000, "author": "Pete Hunt", "text": "Hey there!" }, { + "id": 1420070400000, "author": "Paul O’Shannessy", "text": "React is *great*!" } diff --git a/public/scripts/example.js b/public/scripts/example.js index 2e0ee2a8..a3e5bc20 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -44,6 +44,10 @@ var CommentBox = React.createClass({ }, handleCommentSubmit: function(comment) { var comments = this.state.data; + // Optimistically set an id on the new comment. It will be replaced by an + // id generated by the server. In a production application you would likely + // not use Date.now() for this and would have a more robust system in place. + comment.id = Date.now(); var newComments = comments.concat([comment]); this.setState({data: newComments}); $.ajax({ @@ -80,12 +84,9 @@ var CommentBox = React.createClass({ var CommentList = React.createClass({ render: function() { - var commentNodes = this.props.data.map(function(comment, index) { + var commentNodes = this.props.data.map(function(comment) { return ( - // `key` is a React-specific concept and is not mandatory for the - // purpose of this tutorial. if you're curious, see more here: - // http://facebook.github.io/react/docs/multiple-components.html#dynamic-children - + {comment.text} ); diff --git a/server.go b/server.go index 9eb5d7d2..2224328d 100644 --- a/server.go +++ b/server.go @@ -22,9 +22,11 @@ import ( "net/http" "os" "sync" + "time" ) type comment struct { + ID int64 `json:"id"` Author string `json:"author"` Text string `json:"text"` } @@ -64,7 +66,7 @@ func handleComments(w http.ResponseWriter, r *http.Request) { } // Add a new comment to the in memory slice of comments - comments = append(comments, comment{Author: r.FormValue("author"), Text: r.FormValue("text")}) + comments = append(comments, comment{ID: time.Now().UnixNano() / 1000000, Author: r.FormValue("author"), Text: r.FormValue("text")}) // Marshal the comments to indented json. commentData, err = json.MarshalIndent(comments, "", " ") diff --git a/server.js b/server.js index 2a1ae582..ac87898a 100644 --- a/server.js +++ b/server.js @@ -42,7 +42,15 @@ app.post('/api/comments', function(req, res) { process.exit(1); } var comments = JSON.parse(data); - comments.push(req.body); + // NOTE: In a real implementation, we would likely rely on a database or + // some other approach (e.g. UUIDs) to ensure a globally unique id. We'll + // treat Date.now() as unique-enough for our purposes. + var newComment = { + id: Date.now(), + author: req.body.author, + text: req.body.text, + }; + comments.push(newComment); fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) { if (err) { console.error(err); diff --git a/server.php b/server.php index 53c19104..6b8880c8 100644 --- a/server.php +++ b/server.php @@ -34,8 +34,11 @@ function routeRequest() } elseif (preg_match('/\/api\/comments(\?.*)?/', $uri)) { if($_SERVER['REQUEST_METHOD'] === 'POST') { $commentsDecoded = json_decode($comments, true); - $commentsDecoded[] = ['author' => $_POST['author'], - 'text' => $_POST['text']]; + $commentsDecoded[] = [ + 'id' => round(microtime(true) * 1000), + 'author' => $_POST['author'], + 'text' => $_POST['text'] + ]; $comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT); file_put_contents('comments.json', $comments); diff --git a/server.pl b/server.pl index ce1783e7..517e1621 100644 --- a/server.pl +++ b/server.pl @@ -8,6 +8,7 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +use Time::HiRes qw(gettimeofday); use Mojolicious::Lite; use Mojo::JSON qw(encode_json decode_json); @@ -22,6 +23,7 @@ if ($self->req->method eq 'POST') { push @$comments, { + id => int(gettimeofday * 1000), author => $self->param('author'), text => $self->param('text'), }; diff --git a/server.py b/server.py index 7b4920b9..451fbacd 100644 --- a/server.py +++ b/server.py @@ -10,6 +10,7 @@ import json import os +import time from flask import Flask, Response, request app = Flask(__name__, static_url_path='', static_folder='public') @@ -22,7 +23,9 @@ def comments_handler(): comments = json.loads(file.read()) if request.method == 'POST': - comments.append(request.form.to_dict()) + newComment = request.form.to_dict() + newComment['id'] = int(time.time() * 1000) + comments.append(newComment) with open('comments.json', 'w') as file: file.write(json.dumps(comments, indent=4, separators=(',', ': '))) diff --git a/server.rb b/server.rb index 4e9916b3..eed401ae 100644 --- a/server.rb +++ b/server.rb @@ -23,7 +23,7 @@ if req.request_method == 'POST' # Assume it's well formed - comment = {} + comment = { id: (Time.now.to_f * 1000).to_i } req.query.each do |key, value| comment[key] = value.force_encoding('UTF-8') end From 91abec61ef61de2b7a6229ba65fb7b9804cf72db Mon Sep 17 00:00:00 2001 From: Tay Yang Shun Date: Wed, 18 Nov 2015 14:55:06 +0800 Subject: [PATCH 080/103] Use controlled components for form inputs --- public/scripts/example.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/public/scripts/example.js b/public/scripts/example.js index a3e5bc20..c249427a 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -100,22 +100,40 @@ var CommentList = React.createClass({ }); var CommentForm = React.createClass({ + getInitialState: function() { + return {author: '', text: ''}; + }, + handleAuthorChange: function(e) { + this.setState({author: e.target.value}); + }, + handleTextChange: function(e) { + this.setState({text: e.target.value}); + }, handleSubmit: function(e) { e.preventDefault(); - var author = this.refs.author.value.trim(); - var text = this.refs.text.value.trim(); + var author = this.state.author.trim(); + var text = this.state.text.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); - this.refs.author.value = ''; - this.refs.text.value = ''; + this.setState({author: '', text: ''}); }, render: function() { return (
- - + +
); From 0d7ca5b4553ab2649c8e8dbd97868fe86d49e4a9 Mon Sep 17 00:00:00 2001 From: Mantas Kaveckas Date: Wed, 6 Jan 2016 17:08:04 +0200 Subject: [PATCH 081/103] Remove unessessary px suffix from size of zero pixels --- public/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/css/base.css b/public/css/base.css index bf382be3..08de8f1b 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -23,7 +23,7 @@ code { font-family: "Bitstream Vera Sans Mono", Consolas, Courier, monospace; font-size: 12px; margin: 0 2px; - padding: 0px 5px; + padding: 0 5px; } h1, h2, h3, h4 { From 46a9a9a8bb2573f1960305825ff8e924aa17d338 Mon Sep 17 00:00:00 2001 From: Anthony Ross Date: Sat, 23 Jan 2016 20:05:05 -0500 Subject: [PATCH 082/103] nil is false in ruby nil is false in ruby so the ternary operator can be used with more idiomatic ruby. Also added a comment to show how to execute with a custom port. --- server.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server.rb b/server.rb index eed401ae..d7f1121e 100644 --- a/server.rb +++ b/server.rb @@ -11,7 +11,9 @@ require 'webrick' require 'json' -port = ENV['PORT'].nil? ? 3000 : ENV['PORT'].to_i +# default port to 3000 or overwrite with PORT variable by running +# $ PORT=3001 ruby server.rb +port = ENV['PORT'] ? ENV['PORT'].to_i : 3000 puts "Server started: http://localhost:#{port}/" From e50157d498bb3a9d80ae334594753b55abe78554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Sat, 23 Jan 2016 22:21:02 -0800 Subject: [PATCH 083/103] Ensure Ruby server doesn't have duplicate id fields in json Alternative approach to #115 --- server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.rb b/server.rb index eed401ae..d902b4f6 100644 --- a/server.rb +++ b/server.rb @@ -25,7 +25,7 @@ # Assume it's well formed comment = { id: (Time.now.to_f * 1000).to_i } req.query.each do |key, value| - comment[key] = value.force_encoding('UTF-8') + comment[key] = value.force_encoding('UTF-8') unless key == 'id' end comments << comment File.write( From 3fba2d4e1ee9b5ab5253a0c1cdcdcc9bd7879f7b Mon Sep 17 00:00:00 2001 From: maxbittker Date: Sun, 24 Jan 2016 14:57:56 -0500 Subject: [PATCH 084/103] added permissive CORS header middleware function --- server.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server.js b/server.js index ac87898a..c31d1e64 100644 --- a/server.js +++ b/server.js @@ -23,6 +23,11 @@ app.set('port', (process.env.PORT || 3000)); app.use('/', express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); +app.use(function(req, res, next) { + //set permissive CORS header + res.setHeader('Access-Control-Allow-Origin', '*'); + next(); +}); app.get('/api/comments', function(req, res) { fs.readFile(COMMENTS_FILE, function(err, data) { From d90d36b0c235d05d878837eca43f37a2421c32cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Mon, 25 Jan 2016 16:20:03 -0800 Subject: [PATCH 085/103] Clean up some code in the JS server, add comments --- server.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/server.js b/server.js index c31d1e64..b5a7218a 100644 --- a/server.js +++ b/server.js @@ -23,9 +23,15 @@ app.set('port', (process.env.PORT || 3000)); app.use('/', express.static(path.join(__dirname, 'public'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); + +// Additional middleware which will set headers that we need on each request. app.use(function(req, res, next) { - //set permissive CORS header + // Set permissive CORS header - this allows this server to be used only as + // an API server in conjunction with something like webpack-dev-server. res.setHeader('Access-Control-Allow-Origin', '*'); + + // Disable caching so we'll always get the latest comments. + res.setHeader('Cache-Control', 'no-cache'); next(); }); @@ -35,7 +41,6 @@ app.get('/api/comments', function(req, res) { console.error(err); process.exit(1); } - res.setHeader('Cache-Control', 'no-cache'); res.json(JSON.parse(data)); }); }); @@ -61,7 +66,6 @@ app.post('/api/comments', function(req, res) { console.error(err); process.exit(1); } - res.setHeader('Cache-Control', 'no-cache'); res.json(comments); }); }); From 304a251432b255635eeedccee23897c0d3684395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Mon, 25 Jan 2016 16:42:19 -0800 Subject: [PATCH 086/103] Add cache control headers to perl server --- server.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/server.pl b/server.pl index 517e1621..73c2713d 100644 --- a/server.pl +++ b/server.pl @@ -19,6 +19,7 @@ any [qw(GET POST)] => '/api/comments' => sub { my $self = shift; my $comments = decode_json (do { local(@ARGV,$/) = 'comments.json';<> }); + $self->res->headers->cache_control('no-cache'); if ($self->req->method eq 'POST') { From 7b675c89180cc50ce00fcf8f4bac39054102ec40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Mon, 25 Jan 2016 16:35:03 -0800 Subject: [PATCH 087/103] Add CORS headers to servers --- server.go | 2 ++ server.php | 1 + server.pl | 1 + server.py | 2 +- server.rb | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index 2224328d..934a4cfc 100644 --- a/server.go +++ b/server.go @@ -84,11 +84,13 @@ func handleComments(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Access-Control-Allow-Origin", "*") io.Copy(w, bytes.NewReader(commentData)) case "GET": w.Header().Set("Content-Type", "application/json") w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Access-Control-Allow-Origin", "*") // stream the contents of the file to the response io.Copy(w, bytes.NewReader(commentData)) diff --git a/server.php b/server.php index 6b8880c8..75fae215 100644 --- a/server.php +++ b/server.php @@ -45,6 +45,7 @@ function routeRequest() } header('Content-Type: application/json'); header('Cache-Control: no-cache'); + header('Access-Control-Allow-Origin: *'); echo $comments; } else { return false; diff --git a/server.pl b/server.pl index 73c2713d..c3212b9c 100644 --- a/server.pl +++ b/server.pl @@ -20,6 +20,7 @@ my $self = shift; my $comments = decode_json (do { local(@ARGV,$/) = 'comments.json';<> }); $self->res->headers->cache_control('no-cache'); + $self->res->headers->access_control_allow_origin('*'); if ($self->req->method eq 'POST') { diff --git a/server.py b/server.py index 451fbacd..5cf598df 100644 --- a/server.py +++ b/server.py @@ -30,7 +30,7 @@ def comments_handler(): with open('comments.json', 'w') as file: file.write(json.dumps(comments, indent=4, separators=(',', ': '))) - return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache'}) + return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache', 'Access-Control-Allow-Origin': '*'}) if __name__ == '__main__': app.run(port=int(os.environ.get("PORT",3000))) diff --git a/server.rb b/server.rb index fc81b701..698f4339 100644 --- a/server.rb +++ b/server.rb @@ -40,6 +40,7 @@ # always return json res['Content-Type'] = 'application/json' res['Cache-Control'] = 'no-cache' + res['Access-Control-Allow-Origin'] = '*' res.body = JSON.generate(comments) end From 19aadd8a295acbfefbfd1f562073b0685bf60528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 16 Feb 2016 13:20:50 -0800 Subject: [PATCH 088/103] Update CDN links to latest versions --- public/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index c6494446..21340e72 100644 --- a/public/index.html +++ b/public/index.html @@ -5,11 +5,11 @@ Codestin Search App - - + + - - + +
From 31fe8d2ad766853ac5427c2fef08f2cfd37dcc33 Mon Sep 17 00:00:00 2001 From: Fokko Driesprong Date: Thu, 31 Mar 2016 20:23:09 +0200 Subject: [PATCH 089/103] Update CDN links to latest versions --- public/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 21340e72..4a560b84 100644 --- a/public/index.html +++ b/public/index.html @@ -5,10 +5,10 @@ Codestin Search App - - - - + + + + From cd5dbc7a3c88aa60c04129310cac8f12af48c9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Thu, 7 Apr 2016 15:41:18 -0700 Subject: [PATCH 090/103] Use v15 --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 4a560b84..8b84e266 100644 --- a/public/index.html +++ b/public/index.html @@ -5,8 +5,8 @@ Codestin Search App - - + + From 2be1a2d6999b8f47c34e52e5a5b05bd6713343fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Fri, 8 Apr 2016 13:53:45 -0700 Subject: [PATCH 091/103] Use 15.0.1 --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 8b84e266..34ebddf4 100644 --- a/public/index.html +++ b/public/index.html @@ -5,8 +5,8 @@ Codestin Search App - - + + From 82424fa6ce90f384e418c54bd9bdc61216e550d8 Mon Sep 17 00:00:00 2001 From: Andrew Abraham Date: Tue, 10 May 2016 15:53:38 -0700 Subject: [PATCH 092/103] Remove shadowing of file builtin in server.py. PEP8 formatting --- server.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/server.py b/server.py index 5cf598df..fad15a66 100644 --- a/server.py +++ b/server.py @@ -16,21 +16,29 @@ app = Flask(__name__, static_url_path='', static_folder='public') app.add_url_rule('/', 'root', lambda: app.send_static_file('index.html')) + @app.route('/api/comments', methods=['GET', 'POST']) def comments_handler(): - - with open('comments.json', 'r') as file: - comments = json.loads(file.read()) + with open('comments.json', 'r') as f: + comments = json.loads(f.read()) if request.method == 'POST': - newComment = request.form.to_dict() - newComment['id'] = int(time.time() * 1000) - comments.append(newComment) + new_comment = request.form.to_dict() + new_comment['id'] = int(time.time() * 1000) + comments.append(new_comment) + + with open('comments.json', 'w') as f: + f.write(json.dumps(comments, indent=4, separators=(',', ': '))) - with open('comments.json', 'w') as file: - file.write(json.dumps(comments, indent=4, separators=(',', ': '))) + return Response( + json.dumps(comments), + mimetype='application/json', + headers={ + 'Cache-Control': 'no-cache', + 'Access-Control-Allow-Origin': '*' + } + ) - return Response(json.dumps(comments), mimetype='application/json', headers={'Cache-Control': 'no-cache', 'Access-Control-Allow-Origin': '*'}) if __name__ == '__main__': - app.run(port=int(os.environ.get("PORT",3000))) + app.run(port=int(os.environ.get("PORT", 3000))) From 4fa16fde3795ff7047322f28320cffc3b2b385ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Fri, 20 May 2016 10:28:43 -0700 Subject: [PATCH 093/103] Add private & license fields to package.json --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index e7491981..bf3360a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,8 @@ { "name": "react-tutorial", "version": "0.0.0", + "private": true, + "license": "see LICENSE file", "description": "Code from the React tutorial.", "main": "server.js", "dependencies": { From 06b89a1b5d1abe74f58163efeed80959c993ee52 Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Fri, 3 Jun 2016 14:35:54 -0700 Subject: [PATCH 094/103] Use remarkable instead of marked (#140) Closes #139. --- public/index.html | 2 +- public/scripts/example.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 34ebddf4..a76aaada 100644 --- a/public/index.html +++ b/public/index.html @@ -9,7 +9,7 @@ - +
diff --git a/public/scripts/example.js b/public/scripts/example.js index c249427a..6493fea9 100644 --- a/public/scripts/example.js +++ b/public/scripts/example.js @@ -12,7 +12,8 @@ var Comment = React.createClass({ rawMarkup: function() { - var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); + var md = new Remarkable(); + var rawMarkup = md.render(this.props.children.toString()); return { __html: rawMarkup }; }, From 64a6dfca72aca4d13ab4cbf23c50eba8b9fabe8a Mon Sep 17 00:00:00 2001 From: saiyam-gambhir Date: Wed, 8 Jun 2016 23:09:19 +0530 Subject: [PATCH 095/103] Removed duplicate CSS (#143) --- public/css/base.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/public/css/base.css b/public/css/base.css index 08de8f1b..c8cc35f7 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -35,9 +35,6 @@ h1, h2, h3, h4 { h1 { border-bottom: 1px solid #ddd; font-size: 2.5em; - font-weight: bold; - margin: 0 0 15px; - padding: 0; } h2 { From e5786f844bff18dfa3ff6330b67c9f856c5ebbf6 Mon Sep 17 00:00:00 2001 From: sthodup1 Date: Mon, 20 Jun 2016 15:13:45 -0500 Subject: [PATCH 096/103] Update React Dependency to 15.1.0 --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index a76aaada..ec158df2 100644 --- a/public/index.html +++ b/public/index.html @@ -5,8 +5,8 @@ Codestin Search App - - + + From 2f565db733f7614d19012f029a52f65d294b7db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Fri, 1 Jul 2016 12:29:47 -0700 Subject: [PATCH 097/103] Update for 15.2.0 --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index ec158df2..1ce8900c 100644 --- a/public/index.html +++ b/public/index.html @@ -5,8 +5,8 @@ Codestin Search App - - + + From 08115a6ec2df124bb03cc04974f2c5b9b290804e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 2 Aug 2016 13:50:54 -0700 Subject: [PATCH 098/103] Use npmcdn (#152) --- public/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/public/index.html b/public/index.html index 1ce8900c..5af72a45 100644 --- a/public/index.html +++ b/public/index.html @@ -5,11 +5,11 @@ Codestin Search App - - - - - + + + + +
From ddc30f08e010ca1401c7c9ef8f753c0749dbc499 Mon Sep 17 00:00:00 2001 From: Jonathan Herbert Date: Sat, 20 Aug 2016 20:00:30 -0400 Subject: [PATCH 099/103] Only Read Comments File On Comments Route (#154) --- server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.php b/server.php index 75fae215..e510136b 100644 --- a/server.php +++ b/server.php @@ -27,11 +27,11 @@ function routeRequest() { - $comments = file_get_contents('comments.json'); $uri = $_SERVER['REQUEST_URI']; if ($uri == '/') { echo file_get_contents('./public/index.html'); } elseif (preg_match('/\/api\/comments(\?.*)?/', $uri)) { + $comments = file_get_contents('comments.json'); if($_SERVER['REQUEST_METHOD'] === 'POST') { $commentsDecoded = json_decode($comments, true); $commentsDecoded[] = [ From 7d0728e6d9011658420b7b30463edb2163577a15 Mon Sep 17 00:00:00 2001 From: Mike Sukmanowsky Date: Mon, 29 Aug 2016 20:08:11 -0400 Subject: [PATCH 100/103] Set debug=True flag for Flask server (#156) --- server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.py b/server.py index fad15a66..03c6213d 100644 --- a/server.py +++ b/server.py @@ -41,4 +41,4 @@ def comments_handler(): if __name__ == '__main__': - app.run(port=int(os.environ.get("PORT", 3000))) + app.run(port=int(os.environ.get("PORT", 3000)), debug=True) From 35b5c0c77c0c5e4b159f78a85a66110086aaddfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Dani=C4=87?= Date: Tue, 30 Aug 2016 19:31:59 +0200 Subject: [PATCH 101/103] Use unpkg instead of npmcdn (#157) npmcdn.com is moving to unpkg.com and these links will eventually switch to 301. Better to switch to unpkg right away. https://twitter.com/mjackson/status/770424625754939394 --- public/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/public/index.html b/public/index.html index 5af72a45..ca5fb5fc 100644 --- a/public/index.html +++ b/public/index.html @@ -5,11 +5,11 @@ Codestin Search App - - - - - + + + + +
From 70f7e15f3d4b048625a712713a494f7860695255 Mon Sep 17 00:00:00 2001 From: Jisu Park Date: Wed, 7 Sep 2016 02:25:07 +0900 Subject: [PATCH 102/103] feat(babel): Bump up the babel version 5.x to 6.x (#158) --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index ca5fb5fc..b88096b6 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ - + From ec8d845a8a361abf86c11af2d693150697ef858a Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Mon, 3 Oct 2016 11:06:17 -0700 Subject: [PATCH 103/103] remarkable 1.7.1 --- comments.json | 17 ++++++++++++++++- public/index.html | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/comments.json b/comments.json index 7bef77ad..28816136 100644 --- a/comments.json +++ b/comments.json @@ -8,5 +8,20 @@ "id": 1420070400000, "author": "Paul O’Shannessy", "text": "React is *great*!" + }, + { + "id": 1464988635157, + "author": "ben", + "text": "*abc*" + }, + { + "id": 1464988636500, + "author": "ben", + "text": "*abc*" + }, + { + "id": 1464988717637, + "author": "evil", + "text": "alert(1)" } -] +] \ No newline at end of file diff --git a/public/index.html b/public/index.html index b88096b6..eb201204 100644 --- a/public/index.html +++ b/public/index.html @@ -9,7 +9,7 @@ - +