From 720f70966ce9f9097b03eeb893382d2b7424482d Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 00:05:59 -0500 Subject: [PATCH 01/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9913809..e9145d6 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ## About -Flask-Gopher is an extension library for the Python Flask web microframework that adds support for gopher request handling. The Gopher Protocol is an alternative to HTTP that peaked in popularity in the mid 90's. There are still a handful of gopher sites maintained by enthusiasts; you can learn more about the history of the protocol at http://gopher.floodgap.com/gopher/. +Flask-Gopher is an extension library for the Python Flask web microframework that adds support for gopher request handling. The Gopher Protocol is an alternative to HTTP that peaked in popularity in the mid 90's. There are still a handful of gopher sites maintained by enthusiasts; you can learn more about its history at http://gopher.floodgap.com/gopher/. This extension works by adding a thin Gopher => HTTP compatability layer into the built-in WSGI server. It turns gopher requests into pseudo HTTP GET requests so they can be handled by Flask (or any other python WSGI app) natively. This means that you get full access to Flask's routing, templating engine, debugger, and other tools to build your gopher server. From 0574eeea0adb03c8712e61ad37fc951a3a1e7dd8 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 00:06:11 -0500 Subject: [PATCH 02/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9145d6..2172983 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ## About -Flask-Gopher is an extension library for the Python Flask web microframework that adds support for gopher request handling. The Gopher Protocol is an alternative to HTTP that peaked in popularity in the mid 90's. There are still a handful of gopher sites maintained by enthusiasts; you can learn more about its history at http://gopher.floodgap.com/gopher/. +Flask-Gopher is an extension library for the Python Flask web microframework that adds support for gopher request handling. The Gopher Protocol is an alternative to HTTP that peaked in popularity in the mid 90's. There are still a handful of gopher sites maintained by enthusiasts; you can learn more about its history at http://gopher.floodgap.com/gopher/ This extension works by adding a thin Gopher => HTTP compatability layer into the built-in WSGI server. It turns gopher requests into pseudo HTTP GET requests so they can be handled by Flask (or any other python WSGI app) natively. This means that you get full access to Flask's routing, templating engine, debugger, and other tools to build your gopher server. From 67f26e93d95e4ae05319a6ad9ee477600ff20f12 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 00:06:56 -0500 Subject: [PATCH 03/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2172983..646e718 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Flask-Gopher is an extension library for the Python Flask web microframework that adds support for gopher request handling. The Gopher Protocol is an alternative to HTTP that peaked in popularity in the mid 90's. There are still a handful of gopher sites maintained by enthusiasts; you can learn more about its history at http://gopher.floodgap.com/gopher/ -This extension works by adding a thin Gopher => HTTP compatability layer into the built-in WSGI server. It turns gopher requests into pseudo HTTP GET requests so they can be handled by Flask (or any other python WSGI app) natively. This means that you get full access to Flask's routing, templating engine, debugger, and other tools to build your gopher server. +This extension works by adding a thin Gopher => HTTP compatability layer into Flask's built-in WSGI server. It turns gopher requests into pseudo HTTP GET requests so they can be handled by Flask (or any other python WSGI app) natively. This means that you get full access to Flask's routing, templating engine, debugger, and other tools to build your gopher server. ## Installation From 324d9208f32afc649ca1cf5df66355d3a179730f Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:15:27 -0500 Subject: [PATCH 04/56] Update README.md --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 646e718..11213d6 100644 --- a/README.md +++ b/README.md @@ -44,15 +44,68 @@ gopher = GopherExtension(app) @app.route('/') def index(): - return gopher.render_menu( - gopher.title('Menu Page'), - gopher.submenu('Home', url_for('index')), - gopher.info("Look Ma, it's a gopher server!")) + return gopher.render_menu( + gopher.title('Menu Page'), + gopher.submenu('Home', url_for('index')), + gopher.info("Look Ma, it's a gopher server!")) if __name__ == '__main__': app.run('127.0.0.1', 70, request_handler=GopherRequestHandler) ``` +## Gopher and WSGI + +The python WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. + +WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more primative and doesn't use these components. Here's an example of the difference in fetching a document: + + + + + + + + + +
HTTPGopher
requestresponserequestresponse
+GET /path HTTP/1.1
+Accept: text/plain
+Accept-Charset: utf-8
+...more headers
+
+HTTP/1.1 200 OK
+Server: Apache
+Content-Type: text/html
+...more headers
+(body) +
/path\r\n
(body)
+ +In order to resolve the differences between gopher and HTTP, this library provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the connection is using. If the connection is using gopher, the following assumptions are made: + +- Set the request's *REQUEST_METHOD* to ``GET`` +- Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` +- Set the request's *wsgi.url_scheme* (e.g. *https*) to ``gopher`` +- Discard the response status line +- Discard all response headers + +Doing this makes gopher connections *appear* like normal HTTP requests from the perspective of the WSGI application. It also gives you hooks that can be used from within Flask routes. + +```python +from flask import Flask, request +from flask_gopher import GopherExtension + +app = Flask(__name__) +gopher = GopherExtension(app) + +@app.route('/') +def index(): + if request.scheme == 'gopher': + return "iThis was a gopher request\tfake\texample.com\t0\r\n" + else: + return "This was a HTTP connection" +``` + + ## Gopher Protocol References - https://tools.ietf.org/html/rfc1436 (1993) From 136452a68c75e235573c073f5abe925f19cdb53d Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:16:32 -0500 Subject: [PATCH 05/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 11213d6..50acf74 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ if __name__ == '__main__': The python WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. -WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more primative and doesn't use these components. Here's an example of the difference in fetching a document: +WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more primative and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: From 2d7ce81958edfb67b677b297d80df7241dcbeccb Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:17:40 -0500 Subject: [PATCH 06/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50acf74..aff167a 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ In order to resolve the differences between gopher and HTTP, this library provid - Discard the response status line - Discard all response headers -Doing this makes gopher connections *appear* like normal HTTP requests from the perspective of the WSGI application. It also gives you hooks that can be used from within Flask routes. +Doing this makes a gopher connections *appear* like a normal HTTP request from the perspective of the WSGI application. It also gives you hooks that can be used from within Flask routes. ```python from flask import Flask, request From de6b43790e039c22eaf019d57b7fe5814853db2f Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:19:47 -0500 Subject: [PATCH 07/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aff167a..1cd7c0e 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ In order to resolve the differences between gopher and HTTP, this library provid - Discard the response status line - Discard all response headers -Doing this makes a gopher connections *appear* like a normal HTTP request from the perspective of the WSGI application. It also gives you hooks that can be used from within Flask routes. +Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides hooks into the connection type that can be accessed from the Flask request object. ```python from flask import Flask, request From 74f3d6a844ca5caa3fc160c4a83fc1ea93e13481 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:20:20 -0500 Subject: [PATCH 08/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cd7c0e..47a0a4b 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ In order to resolve the differences between gopher and HTTP, this library provid - Discard the response status line - Discard all response headers -Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides hooks into the connection type that can be accessed from the Flask request object. +Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides metadata that can be accessed from the Flask request object. ```python from flask import Flask, request From 948ed384a18f17d53f0da207a44e5377d972ad61 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:20:51 -0500 Subject: [PATCH 09/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47a0a4b..64c0329 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ def index(): if request.scheme == 'gopher': return "iThis was a gopher request\tfake\texample.com\t0\r\n" else: - return "This was a HTTP connection" + return "This was an HTTP request" ``` From 729c8361af0676d55cf4457d1283a39b724665db Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:31:39 -0500 Subject: [PATCH 10/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64c0329..f054562 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ if __name__ == '__main__': The python WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. -WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more primative and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: +WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more basic and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols:
HTTPGopher
From 6031cb003b7e80e3f34bb3a9b2e60723ee8e3244 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:32:22 -0500 Subject: [PATCH 11/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f054562..1ac939a 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ if __name__ == '__main__': ## Gopher and WSGI -The python WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. +Python's WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more basic and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: From e915467c39f68d10245df585b7dadc2a04d369c8 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:33:52 -0500 Subject: [PATCH 12/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ac939a..ad06de6 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Content-Type: text/html
HTTPGopher
(body)
-In order to resolve the differences between gopher and HTTP, this library provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the connection is using. If the connection is using gopher, the following assumptions are made: +In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the connection is using. If the connection is using gopher, the following assumptions are made: - Set the request's *REQUEST_METHOD* to ``GET`` - Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` From 3770e271a874309fab722546f8ac853ceafc0252 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:34:29 -0500 Subject: [PATCH 13/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad06de6..14722a9 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Content-Type: text/html
(body)
-In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the connection is using. If the connection is using gopher, the following assumptions are made: +In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the connection is using gopher, the following assumptions are made: - Set the request's *REQUEST_METHOD* to ``GET`` - Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` From e9223ecae0f469f1d2d5b3ba856d5a355da72670 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:34:53 -0500 Subject: [PATCH 14/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14722a9..89fecd2 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Content-Type: text/html
(body)
-In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the connection is using gopher, the following assumptions are made: +In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the client is using gopher, the following assumptions are made: - Set the request's *REQUEST_METHOD* to ``GET`` - Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` From 84e656889887f1d0982cbd6432974949fa31caa1 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:37:34 -0500 Subject: [PATCH 15/56] Update README.md --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 89fecd2..22307f1 100644 --- a/README.md +++ b/README.md @@ -91,15 +91,9 @@ In order to resolve the differences between gopher and HTTP, **Flask-Gopher** pr Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides metadata that can be accessed from the Flask request object. ```python -from flask import Flask, request -from flask_gopher import GopherExtension - -app = Flask(__name__) -gopher = GopherExtension(app) - @app.route('/') def index(): - if request.scheme == 'gopher': + if flask.request.scheme == 'gopher': return "iThis was a gopher request\tfake\texample.com\t0\r\n" else: return "This was an HTTP request" From 7fc1f20c3dd674b2cd0e09f0d947ffa5949ccc14 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:39:24 -0500 Subject: [PATCH 16/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22307f1..5cc213f 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Content-Type: text/html In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the client is using gopher, the following assumptions are made: -- Set the request's *REQUEST_METHOD* to ``GET`` +- Set the request's *REQUEST_METHOD* (e.g. *GET*, *POST*) to ``GET`` - Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` - Set the request's *wsgi.url_scheme* (e.g. *https*) to ``gopher`` - Discard the response status line From 2ac33034f93ee80dc34a948f2cd63542e758d671 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 02:39:50 -0500 Subject: [PATCH 17/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cc213f..22307f1 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Content-Type: text/html In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the client is using gopher, the following assumptions are made: -- Set the request's *REQUEST_METHOD* (e.g. *GET*, *POST*) to ``GET`` +- Set the request's *REQUEST_METHOD* to ``GET`` - Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` - Set the request's *wsgi.url_scheme* (e.g. *https*) to ``gopher`` - Discard the response status line From 28fe75672f67a7ba93079a99cd48c6d608e16f7c Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:11:18 -0500 Subject: [PATCH 18/56] Update README.md --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/README.md b/README.md index 22307f1..1d1fd71 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,62 @@ def index(): return "This was an HTTP request" ``` +## Building Gopher Menus + +Gopher menus are structured text files that display information about the current page and links to other gopher resources. A gopher menu is loosely equivalent to an HTML document with only ```` and ```` tags. Each line in the menu has a *type* that decribes what kind of resource it links to (text, binary, html, telnet, etc.). + +Flask-Gopher provides several helper methods for constructing gopher menu lines of different types: + +| Method | Link Descriptor | Meaning | +| ------------- | ------------------- | -------- | +| gopher.file | 0 | Plain text file | +| gopher.submenu | 1 | Gopher menu | +| gopher.csso | 2 | CSSO database; other databases | +| gopher.error | 3 | Error message | +| gopher.binhex | 4 | Macintosh BinHex file | +| gopher.archive | 5 | Archive file (zip, tar, gzip) | +| gopher.uuencoded | 6 | UUEncoded file | +| gopher.query | 7 | Search query | +| gopher.telnet | 8 | Telnet session | +| gopher.binary | 9 | Binary file | +| gopher.gif | g | GIF format graphics file | +| gopher.image | I | Other Image file | +| gopher.doc | d | Word processing document (ps, pdf, doc) | +| gopher.sound | s | Sound file | +| gopher.video | ; | Video file | +| gopher.info | i | Information line | +| gopher.title | i | Title line | +| gopher.html | h | HTML document | + +Most of these methods require a text description of the link, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the complete response text for the menu. + +```python +@app.route('/home') +def home(): + menu = gopher.render_menu( + # Link to an internal gopher menu + gopher.submenu('Home', '/home'), + + # Link to an external gopher menu + gopher.submenu('XKCD comics', '/fun/xkcd', host='gopher.floodgap.com', port=70), + + # Link to a static file, using flask.url_for() to build a relative path + gopher.image('Picture of a cat', url_for('static', filename='cat.png')), + + # Link to an external web page + gopher.html('Project source', 'https://github.com/michael-lazar/flask-gopher'), + + # Informational lines display text in the menu but don't have a link + gopher.info('Hello world!'), + + # Unformatted text will be automatically converted into info lines + "You can also use \n unformatted lines of text", + + # Or you can choose to format the menu line manually + "iOr format the line manually\tfake\texample.com\t0") + + return menu +``` ## Gopher Protocol References From 52bc2e29cf04af08c3f5e56ef969c9acffa02773 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:11:52 -0500 Subject: [PATCH 19/56] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1d1fd71..eb6db33 100644 --- a/README.md +++ b/README.md @@ -129,11 +129,11 @@ Flask-Gopher provides several helper methods for constructing gopher menu lines Most of these methods require a text description of the link, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the complete response text for the menu. ```python -@app.route('/home') -def home(): +@app.route('/') +def index(): menu = gopher.render_menu( # Link to an internal gopher menu - gopher.submenu('Home', '/home'), + gopher.submenu('Home', '/'), # Link to an external gopher menu gopher.submenu('XKCD comics', '/fun/xkcd', host='gopher.floodgap.com', port=70), From 1aa00f2df6b5ed6cbd70e964dd5f44503bd1be83 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:12:19 -0500 Subject: [PATCH 20/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb6db33..7cd1834 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ def index(): ## Building Gopher Menus -Gopher menus are structured text files that display information about the current page and links to other gopher resources. A gopher menu is loosely equivalent to an HTML document with only ```` and ```` tags. Each line in the menu has a *type* that decribes what kind of resource it links to (text, binary, html, telnet, etc.). +Gopher menus are structured text files that display information about the current page and contain links to other gopher resources. A gopher menu is loosely equivalent to an HTML document with only ```` and ```` tags. Each line in the menu has a *type* that decribes what kind of resource it links to (text, binary, html, telnet, etc.). Flask-Gopher provides several helper methods for constructing gopher menu lines of different types: From e11e8f297d0c8801da412dec7543184394e534e9 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:13:44 -0500 Subject: [PATCH 21/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7cd1834..e528ab7 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ def index(): Gopher menus are structured text files that display information about the current page and contain links to other gopher resources. A gopher menu is loosely equivalent to an HTML document with only ```` and ```` tags. Each line in the menu has a *type* that decribes what kind of resource it links to (text, binary, html, telnet, etc.). -Flask-Gopher provides several helper methods for constructing gopher menu lines of different types: +Flask-Gopher provides several helper methods for constructing gopher menu lines: | Method | Link Descriptor | Meaning | | ------------- | ------------------- | -------- | From 3058f85f87190e112dbdd9930a8da319ed1b1ec8 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:14:12 -0500 Subject: [PATCH 22/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e528ab7..af9da63 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ Flask-Gopher provides several helper methods for constructing gopher menu lines: | gopher.title | i | Title line | | gopher.html | h | HTML document | -Most of these methods require a text description of the link, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the complete response text for the menu. +Most of these methods require a text description for the line, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the complete response text for the menu. ```python @app.route('/') From f2300db19752255a76a4c68fa99896bcaa07eb07 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:24:37 -0500 Subject: [PATCH 23/56] Update README.md --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index af9da63..f045bfd 100644 --- a/README.md +++ b/README.md @@ -147,15 +147,30 @@ def index(): # Informational lines display text in the menu but don't have a link gopher.info('Hello world!'), - # Unformatted text will be automatically converted into info lines - "You can also use \n unformatted lines of text", + # Un-formatted text will be automatically converted into info lines + "You can also use\nUn-formatted lines of text", - # Or you can choose to format the menu line manually - "iOr format the line manually\tfake\texample.com\t0") - + # Or you can format the line manually + "iFormatted line\tfake\texample.com\t0") return menu ``` +Here's what the rendered document looks like: + +``` +$ curl gopher://localhost:8007 + +1Home / 127.0.0.1 8007 +1XKCD comics /fun/xkcd gopher.floodgap.com 70 +IPicture of a cat /static/cat.png 127.0.0.1 8007 +hProject source URL:https://github.com/michael-lazar/flask-gopher 127.0.0.1 8007 +iHello world! fake example.com 0 +iYou can also use fake example.com 0 +iUn-formatted lines of text fake example.com 0 +iFormatted line fake example.com 0 +. +``` + ## Gopher Protocol References - https://tools.ietf.org/html/rfc1436 (1993) From b09e16a26e4be14ac2a5e6bf5089b3d0d1eafbd6 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:24:59 -0500 Subject: [PATCH 24/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f045bfd..8699e65 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ def index(): return menu ``` -Here's what the rendered document looks like: +Here's what the rendered menu looks like: ``` $ curl gopher://localhost:8007 From dec904c9c22d35294722c27d697fd6888b5e750e Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:26:54 -0500 Subject: [PATCH 25/56] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 8699e65..4e5dc05 100644 --- a/README.md +++ b/README.md @@ -134,22 +134,16 @@ def index(): menu = gopher.render_menu( # Link to an internal gopher menu gopher.submenu('Home', '/'), - # Link to an external gopher menu gopher.submenu('XKCD comics', '/fun/xkcd', host='gopher.floodgap.com', port=70), - # Link to a static file, using flask.url_for() to build a relative path gopher.image('Picture of a cat', url_for('static', filename='cat.png')), - # Link to an external web page gopher.html('Project source', 'https://github.com/michael-lazar/flask-gopher'), - # Informational lines display text in the menu but don't have a link gopher.info('Hello world!'), - # Un-formatted text will be automatically converted into info lines "You can also use\nUn-formatted lines of text", - # Or you can format the line manually "iFormatted line\tfake\texample.com\t0") return menu From a86c73708ff53dbfa031c1d2c3555c82ff8d31c2 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:28:09 -0500 Subject: [PATCH 26/56] Update README.md --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4e5dc05..65493ab 100644 --- a/README.md +++ b/README.md @@ -131,22 +131,29 @@ Most of these methods require a text description for the line, and will accept a ```python @app.route('/') def index(): - menu = gopher.render_menu( + lines = [ # Link to an internal gopher menu gopher.submenu('Home', '/'), + # Link to an external gopher menu gopher.submenu('XKCD comics', '/fun/xkcd', host='gopher.floodgap.com', port=70), + # Link to a static file, using flask.url_for() to build a relative path gopher.image('Picture of a cat', url_for('static', filename='cat.png')), + # Link to an external web page gopher.html('Project source', 'https://github.com/michael-lazar/flask-gopher'), + # Informational lines display text in the menu but don't have a link gopher.info('Hello world!'), + # Un-formatted text will be automatically converted into info lines "You can also use\nUn-formatted lines of text", + # Or you can format the line manually - "iFormatted line\tfake\texample.com\t0") - return menu + "iFormatted line\tfake\texample.com\t0" + ] + return gopher.render_menu(*lines) ``` Here's what the rendered menu looks like: From 4061b32d7e86b9d36e6479996c1e54b9d265e13b Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:28:35 -0500 Subject: [PATCH 27/56] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 65493ab..98088fa 100644 --- a/README.md +++ b/README.md @@ -151,8 +151,7 @@ def index(): "You can also use\nUn-formatted lines of text", # Or you can format the line manually - "iFormatted line\tfake\texample.com\t0" - ] + "iFormatted line\tfake\texample.com\t0"] return gopher.render_menu(*lines) ``` From 75d30e75f689f465f60c24096140c4244a5cb177 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 22:29:25 -0500 Subject: [PATCH 28/56] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 98088fa..c87010f 100644 --- a/README.md +++ b/README.md @@ -147,10 +147,10 @@ def index(): # Informational lines display text in the menu but don't have a link gopher.info('Hello world!'), - # Un-formatted text will be automatically converted into info lines + # Plain text will be automatically converted into INFO "You can also use\nUn-formatted lines of text", - # Or you can format the line manually + # Or you can format the link manually "iFormatted line\tfake\texample.com\t0"] return gopher.render_menu(*lines) ``` From a8d15ed4239b09f967bf02211f07f5fd580d92ae Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:13:29 -0500 Subject: [PATCH 29/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c87010f..ef78566 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ Flask-Gopher provides several helper methods for constructing gopher menu lines: | gopher.title | i | Title line | | gopher.html | h | HTML document | -Most of these methods require a text description for the line, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the complete response text for the menu. +Most of these methods require a text description for the line, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the response body. ```python @app.route('/') From 84224b9a96b4a000d369a306e65e073dc64b9d73 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:14:41 -0500 Subject: [PATCH 30/56] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ef78566..ddbf029 100644 --- a/README.md +++ b/README.md @@ -144,13 +144,13 @@ def index(): # Link to an external web page gopher.html('Project source', 'https://github.com/michael-lazar/flask-gopher'), - # Informational lines display text in the menu but don't have a link + # Informational text gopher.info('Hello world!'), - # Plain text will be automatically converted into INFO + # Plain text will be automatically converted into info lines "You can also use\nUn-formatted lines of text", - # Or you can format the link manually + # You can also format the lines manually "iFormatted line\tfake\texample.com\t0"] return gopher.render_menu(*lines) ``` From 95480f5aa902af1af9afde338ac8bd257dd7ad13 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:14:57 -0500 Subject: [PATCH 31/56] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ddbf029..8b25a1a 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,8 @@ def index(): "You can also use\nUn-formatted lines of text", # You can also format the lines manually - "iFormatted line\tfake\texample.com\t0"] + "iFormatted line\tfake\texample.com\t0"] + return gopher.render_menu(*lines) ``` From fbbe284b53efc945121be9aa729c66d534094567 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:16:10 -0500 Subject: [PATCH 32/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b25a1a..6181a3e 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ if __name__ == '__main__': Python's WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. -WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more basic and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: +WSGI was designed to be a very simple and flexible API, but at its heart it's built to handle HTTP requests. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more basic and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: From 3de8160448c39dfce1f12e5d55486098513bd262 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:18:08 -0500 Subject: [PATCH 33/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6181a3e..d297acd 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ In order to resolve the differences between gopher and HTTP, **Flask-Gopher** pr - Discard the response status line - Discard all response headers -Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides metadata that can be accessed from the Flask request object. +Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides hooks for metadata that can be accessed from the Flask request object. ```python @app.route('/') From 529e8d440d42f322449ab129f39e70fdf6c0e198 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:19:05 -0500 Subject: [PATCH 34/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d297acd..b22866b 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ Flask-Gopher provides several helper methods for constructing gopher menu lines: | gopher.title | i | Title line | | gopher.html | h | HTML document | -Most of these methods require a text description for the line, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines into ``gopher.render_menu()`` to build the response body. +Most of these methods require a text description for the link, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass along all of the lines into ``gopher.render_menu()`` to build the response body. ```python @app.route('/') From dfe74635eb866375a9e2fc25a394520815b81331 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:44:26 -0500 Subject: [PATCH 35/56] Update README.md --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b22866b..be53bb5 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Most of these methods require a text description for the link, and will accept a ```python @app.route('/') def index(): - lines = [ + return gopher.render_menu( # Link to an internal gopher menu gopher.submenu('Home', '/'), @@ -151,9 +151,8 @@ def index(): "You can also use\nUn-formatted lines of text", # You can also format the lines manually - "iFormatted line\tfake\texample.com\t0"] - - return gopher.render_menu(*lines) + "iFormatted line\tfake\texample.com\t0" + ) ``` Here's what the rendered menu looks like: From 2ddc266c46e4d147998931839b2b11e8581c0027 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sat, 6 Jan 2018 23:44:44 -0500 Subject: [PATCH 36/56] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index be53bb5..0af722a 100644 --- a/README.md +++ b/README.md @@ -151,8 +151,7 @@ def index(): "You can also use\nUn-formatted lines of text", # You can also format the lines manually - "iFormatted line\tfake\texample.com\t0" - ) + "iFormatted line\tfake\texample.com\t0") ``` Here's what the rendered menu looks like: From 9604d9d4eb324da3fa23de847113d2d702e8738b Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 00:22:55 -0500 Subject: [PATCH 37/56] Update README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 0af722a..5b23bad 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,34 @@ iFormatted line fake example.com 0 . ``` +## Using Templates + +You can also use Flask's templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. + +**templates/example_menu.gopher** +``` +{{ 'Centered Title' | center }} +{{ '--------------' | center }} + +{{ gopher.submenu('Home', url_for('index')) }} + +Hello from my gopher template! +Your IP address is {{ request.remote_addr }} + +{{ '_' * gopher.width }} +{{ request.environ['SERVER_SOFTWARE'] | rjust }} + +``` + +Use ``gopher.render_menu_template()`` to render the template as a gopher menu: + +```python +@app.route('/') +def index(): + return gopher.render_menu_template('example_menu.gopher') +``` + + ## Gopher Protocol References - https://tools.ietf.org/html/rfc1436 (1993) From 61800a1c0c28fab1a132fc3165a1dd34478fbaf0 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 00:27:23 -0500 Subject: [PATCH 38/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b23bad..f1eb97b 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ Your IP address is {{ request.remote_addr }} ``` -Use ``gopher.render_menu_template()`` to render the template as a gopher menu: +Call ``gopher.render_menu_template()`` from inside of your route to compile a template into a gopher menu. ```python @app.route('/') From a60058f67f2d046511d0328d598432ebf98f2873 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 00:29:01 -0500 Subject: [PATCH 39/56] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1eb97b..97e3137 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ iFormatted line fake example.com 0 ## Using Templates -You can also use Flask's templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. +You can also use Flask's templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. An example template file is shown below: **templates/example_menu.gopher** ``` @@ -189,7 +189,7 @@ Your IP address is {{ request.remote_addr }} ``` -Call ``gopher.render_menu_template()`` from inside of your route to compile a template into a gopher menu. +Call ``gopher.render_menu_template()`` from inside of your route to compile the template into a gopher menu. ```python @app.route('/') From 3b2250cedc8c81b0c100acfcf95b9ff19086db20 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 00:30:30 -0500 Subject: [PATCH 40/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97e3137..99aa1b5 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ Hello from my gopher template! Your IP address is {{ request.remote_addr }} {{ '_' * gopher.width }} -{{ request.environ['SERVER_SOFTWARE'] | rjust }} +{{ ('Served by ' + request.environ['SERVER_SOFTWARE']) | rjust }} ``` From 0740093b29c9359985d986aaaeb2a2cd6c324296 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 00:30:43 -0500 Subject: [PATCH 41/56] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 99aa1b5..c090389 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,6 @@ Your IP address is {{ request.remote_addr }} {{ '_' * gopher.width }} {{ ('Served by ' + request.environ['SERVER_SOFTWARE']) | rjust }} - ``` Call ``gopher.render_menu_template()`` from inside of your route to compile the template into a gopher menu. From bdf16b46c2f9be81b7e6131fbbfde6eb59b08ca0 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:10:51 -0500 Subject: [PATCH 42/56] Update README.md --- README.md | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c090389..f61e564 100644 --- a/README.md +++ b/README.md @@ -156,19 +156,17 @@ def index(): Here's what the rendered menu looks like: -``` -$ curl gopher://localhost:8007 - -1Home / 127.0.0.1 8007 -1XKCD comics /fun/xkcd gopher.floodgap.com 70 -IPicture of a cat /static/cat.png 127.0.0.1 8007 -hProject source URL:https://github.com/michael-lazar/flask-gopher 127.0.0.1 8007 -iHello world! fake example.com 0 -iYou can also use fake example.com 0 -iUn-formatted lines of text fake example.com 0 -iFormatted line fake example.com 0 -. -``` +> $ curl gopher://localhost:8007 +> +> 1Home / 127.0.0.1 8007 +> 1XKCD comics /fun/xkcd gopher.floodgap.com 70 +> IPicture of a cat /static/cat.png 127.0.0.1 8007 +> hProject source URL:https://github.com/michael-lazar/flask-gopher 127.0.0.1 8007 +> iHello world! fake example.com 0 +> iYou can also use fake example.com 0 +> iUn-formatted lines of text fake example.com 0 +> iFormatted line fake example.com 0 +> . ## Using Templates @@ -196,7 +194,6 @@ def index(): return gopher.render_menu_template('example_menu.gopher') ``` - ## Gopher Protocol References - https://tools.ietf.org/html/rfc1436 (1993) @@ -204,3 +201,13 @@ def index(): - https://tools.ietf.org/html/draft-matavka-gopher-ii-03 (2015) - https://www.w3.org/Addressing/URL/4_1_Gopher+.html +An interesting side note, the python standard library used to contain a gopher module. It was deprecated in 2.5, and removed in 2.6. (https://www.python.org/dev/peps/pep-0004/) + + +> Module name: gopherlib +> Rationale: The gopher protocol is not in active use anymore. +> Date: 1-Oct-2000. +> Documentation: Documented as deprecated since Python 2.5. Removed +> in Python 2.6. + +There's also a reference gopher client in the old python SVN trunk: https://svn.python.org/projects/python/trunk/Demo/sockets/gopher.py From 9a67bc963d2b2623acbe803199340aa61c9b6e46 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:11:54 -0500 Subject: [PATCH 43/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f61e564..0af309e 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Content-Type: text/html
HTTPGopher
(body)
-In order to resolve the differences between gopher and HTTP, **Flask-Gopher** provides a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the client is using gopher, the following assumptions are made: +In order to resolve the differences between gopher and HTTP, **Flask-Gopher** implements a custom ``GopherRequestHandler``. The handler hooks into the WSGI server (``werkzeug.BaseWSGIServer``). It reads the first line of every TCP connection and determines which protocol the client is attempting to use. If the client is using gopher, the following assumptions are made: - Set the request's *REQUEST_METHOD* to ``GET`` - Set the request's *SERVER_PROTOCOL* (e.g. *HTTP/1.1*) to ``gopher`` From 7d5f5880e78f7bd6e84b20813e60f52889377925 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:13:13 -0500 Subject: [PATCH 44/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0af309e..c19ac86 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ In order to resolve the differences between gopher and HTTP, **Flask-Gopher** im - Discard the response status line - Discard all response headers -Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides hooks for metadata that can be accessed from the Flask request object. +Doing this makes a gopher connection *appear* like a normal HTTP request from the perspective of the WSGI application. It also provides metadata hooks that can be accessed from the Flask request. ```python @app.route('/') From 721fdfea1704c2edee9318eae8f11fa8157eaac0 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:15:08 -0500 Subject: [PATCH 45/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c19ac86..3c4146d 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ Flask-Gopher provides several helper methods for constructing gopher menu lines: | gopher.title | i | Title line | | gopher.html | h | HTML document | -Most of these methods require a text description for the link, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass along all of the lines into ``gopher.render_menu()`` to build the response body. +Most of these methods require a text description for the link, and will accept a path selector and a host/port. They return a line of text that has been pre-formatted for a gopher menu. You can then pass all of the lines along into ``gopher.render_menu()`` to build the response body. ```python @app.route('/') From b3c18cdc321fb67b83c1a04abd6b66f10b4be0a5 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:15:43 -0500 Subject: [PATCH 46/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c4146d..ff56693 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ def index(): "iFormatted line\tfake\texample.com\t0") ``` -Here's what the rendered menu looks like: +Here's what the example menu looks like after it has been rendered: > $ curl gopher://localhost:8007 > From 119d29bda5587c7bc48f54afe560cb9856c12ca3 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:16:53 -0500 Subject: [PATCH 47/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff56693..3ad400e 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,6 @@ An interesting side note, the python standard library used to contain a gopher m > Rationale: The gopher protocol is not in active use anymore. > Date: 1-Oct-2000. > Documentation: Documented as deprecated since Python 2.5. Removed -> in Python 2.6. +> in Python 2.6. There's also a reference gopher client in the old python SVN trunk: https://svn.python.org/projects/python/trunk/Demo/sockets/gopher.py From 98e41e4650b714fe2790f87f4c81fa8fa5d8b2ea Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:27:21 -0500 Subject: [PATCH 48/56] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ad400e..f54b7bf 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ Flask-Gopher is an extension library for the Python Flask web microframework tha This extension works by adding a thin Gopher => HTTP compatability layer into Flask's built-in WSGI server. It turns gopher requests into pseudo HTTP GET requests so they can be handled by Flask (or any other python WSGI app) natively. This means that you get full access to Flask's routing, templating engine, debugger, and other tools to build your gopher server. +This project exists because I wanted a modern python gopher server with support for dynamic routing. At first I was considering writing one from scratch with the same stucture as Flask, but then I thought *"Why not just use Flask?"* + ## Installation This package requires **python 3** @@ -210,4 +212,4 @@ An interesting side note, the python standard library used to contain a gopher m > Documentation: Documented as deprecated since Python 2.5. Removed > in Python 2.6. -There's also a reference gopher client in the old python SVN trunk: https://svn.python.org/projects/python/trunk/Demo/sockets/gopher.py +There's also still a reference gopher client in the old python SVN trunk: https://svn.python.org/projects/python/trunk/Demo/sockets/gopher.py From fe527ce5ec12f30615bddd092b9d5b50da78d2d8 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:28:22 -0500 Subject: [PATCH 49/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f54b7bf..4a1b505 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Flask-Gopher is an extension library for the Python Flask web microframework tha This extension works by adding a thin Gopher => HTTP compatability layer into Flask's built-in WSGI server. It turns gopher requests into pseudo HTTP GET requests so they can be handled by Flask (or any other python WSGI app) natively. This means that you get full access to Flask's routing, templating engine, debugger, and other tools to build your gopher server. -This project exists because I wanted a modern python gopher server with support for dynamic routing. At first I was considering writing one from scratch with the same stucture as Flask, but then I thought *"Why not just use Flask?"* +This project exists because I wanted a modern python gopher server with support for dynamic routing. At first I was considering writing one from scratch in the same vein as Flask, but then I thought *"Why not just use Flask?"* ## Installation From 8e529d9fe739d9064599058e0f2675651ea14bd2 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:29:13 -0500 Subject: [PATCH 50/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a1b505..dfe8ef4 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ gopher = GopherExtension(app) @app.route('/') def index(): return gopher.render_menu( - gopher.title('Menu Page'), + gopher.title('This is a Gopher Menu Page'), gopher.submenu('Home', url_for('index')), gopher.info("Look Ma, it's a gopher server!")) From a4fba560f232c1315ed4943773bd854dde7f64dc Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:30:14 -0500 Subject: [PATCH 51/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfe8ef4..055adbb 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ gopher = GopherExtension(app) @app.route('/') def index(): return gopher.render_menu( - gopher.title('This is a Gopher Menu Page'), + gopher.title('My GopherHole'), gopher.submenu('Home', url_for('index')), gopher.info("Look Ma, it's a gopher server!")) From bfbb8e40c228babc3dc8ca9a1f2ceef02daee3fa Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:31:00 -0500 Subject: [PATCH 52/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 055adbb..543484f 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ if __name__ == '__main__': Python's WSGI (Web Server Gateway Interface) is an established API that defines how python web servers (gunicorn, mod_wsgi, etc) communicate with application frameworks (Flask, Django, etc). It defines a clean boundary between low-level socket and request handling, and high-level application logic. -WSGI was designed to be a very simple and flexible API, but at its heart it's built to handle HTTP requests. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more basic and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: +WSGI was designed to be a very simple and flexible API, but at its heart it's built around HTTP requests. As such, it incorperates some HTTP specific components like request/response headers and status codes. Gopher is more basic and doesn't use these components. Here's an example of the difference in fetching a document with the two protocols: From f40a70e9387f5d76a6233d5ae135e27421952fd3 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:34:16 -0500 Subject: [PATCH 53/56] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 543484f..5c603c9 100644 --- a/README.md +++ b/README.md @@ -149,10 +149,10 @@ def index(): # Informational text gopher.info('Hello world!'), - # Plain text will be automatically converted into info lines + # Raw text will automatically be converted into informational text "You can also use\nUn-formatted lines of text", - # You can also format the lines manually + # You can also format the lines manually if you desire "iFormatted line\tfake\texample.com\t0") ``` From 7dc081bebd71bd345bdfea8f25a82916166341ca Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:35:03 -0500 Subject: [PATCH 54/56] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5c603c9..0fe4dfa 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ def index(): "iFormatted line\tfake\texample.com\t0") ``` -Here's what the example menu looks like after it has been rendered: +Here's what the example menu looks like after it's been rendered: > $ curl gopher://localhost:8007 > @@ -172,7 +172,7 @@ Here's what the example menu looks like after it has been rendered: ## Using Templates -You can also use Flask's templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. An example template file is shown below: +You can use Flask's templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. An example template file is shown below: **templates/example_menu.gopher** ``` From 76af6408ef21cb492840537401dcb55b9671c46a Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:35:15 -0500 Subject: [PATCH 55/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fe4dfa..fc6534e 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ Here's what the example menu looks like after it's been rendered: ## Using Templates -You can use Flask's templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. An example template file is shown below: +You can use Flask's Jinja2 templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. An example template file is shown below: **templates/example_menu.gopher** ``` From 6bbde8fc6002607f147e49d4905a5d65fd63c35c Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Sun, 7 Jan 2018 01:35:54 -0500 Subject: [PATCH 56/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc6534e..3223c3d 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ Here's what the example menu looks like after it's been rendered: ## Using Templates -You can use Flask's Jinja2 templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add the *.gopher* suffix. An example template file is shown below: +You can use Flask's Jinja2 templating engine to layout gopher menus. Flask-Gopher will automatically inject the ``gopher`` object to the template namespace so you can access the menu helper functions. The recommended naming convention for gopher template files is to add a *.gopher* suffix. An example template file is shown below: **templates/example_menu.gopher** ```
HTTPGopher