From dcc4b804d25383a855aaf8d5ffbf8f657bb8d5ce Mon Sep 17 00:00:00 2001 From: Wholesomedonut Date: Sun, 6 Sep 2020 19:35:18 -0600 Subject: [PATCH] Forked from solderpunk's repo Added all of my current changes to gemini-demo.py, updated README.md and LICENSE --- LICENSE | 6 ++-- README.md | 42 ++++++++++++++++-------- gemini-demo.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 113 insertions(+), 23 deletions(-) diff --git a/LICENSE b/LICENSE index c2e480e..21e3762 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) . All rights reserved. +Copyright (c) 2020 Wholesomedonut . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -10,7 +10,7 @@ this list of conditions and the following disclaimer. this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE @@ -19,4 +19,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md index d5c2eeb..d51ff80 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,27 @@ -# gemini-demo-1 +# asparagus -Minimal but usable interactive Gemini client in < 100 LOC of Python 3 +Larger, more functional version of solderpunk's gemini-demo-1, +which was a Gemini client in <=100 LOC in Python 3. -## Rationale +Mine is already 50% larger. -One of the original design criteria for the Gemini protocol was that -"a basic but usable (not ultra-spartan) client should fit comfortably -within 50 or so lines of code in a modern high-level language. -Certainly not more than 100". This client was written to gauge how -close to (or far from!) that goal the initial rough specification is. +## Why the fork? + +I really enjoyed solderpunk's work. Quick, clean, and tiny. + +I just wanted to try my luck at getting a more fleshed-out app going. + +I've never done FOSS contributions before today. Consider this repo my beginning! + +I'm literally developing this entirely on an iPad Pro for kicks and giggles, using: +* Pythonista +* Working Copy + +I have no idea how long it'll last, if it even will at all. ## Capabilities -This crude but functional client: +This fork has all of gemini-demo-1's functionality: * Has a minimal interactive interface for "Gemini maps" * Will print plain text in any encoding if it is properly declared in @@ -23,8 +32,11 @@ This crude but functional client: * Will report errors * Does NOT DO ANY validation of TLS certificates -It's a *snug* fit in 100 lines, but it's possible. A 50 LOC client -would need to be much simpler. +### IN addition to: + +* Has session-persistent history that you can repeatedly maneuver through +* Descriptive error texts +* More keyboard commands and CLI-accessible help text. ## Usage @@ -35,6 +47,10 @@ visit a Gemini location. If a Gemini menu is visited, you'll see numeric indices for links, ala VF-1 or AV-98. Type a number to visit that link. -There is very crude history: you can type `b` to go "back". +Press h to see a printout of your history, +b to go back a page, +and f to go forward a page. -Type `q` to quit. +Type ? to see a brief help text inside the client. + +Press q to quit. \ No newline at end of file diff --git a/gemini-demo.py b/gemini-demo.py index a91b563..cf87678 100644 --- a/gemini-demo.py +++ b/gemini-demo.py @@ -13,6 +13,31 @@ caps = mailcap.getcaps() menu = [] hist = [] +def printHelp(): + help = """ Type in a gemini:// address to go somewhere, + input 'b' to go back a page, + 'f' to go forward, + 'h' to show your history in order, + '?' to show this help again, + or 'q' to quit. + """ + print(help) + + +def printIntro(): + o = """ + Welcome to PyGemini, a single-file Python client for the Gemini protocol. + Original source code by, , at + forked by Wholesomedonut on Sep 6 2020. + + Questions about this fork? + Email with subject "PyGemini + whatever-you-need", + to wholesomedonut[at]tuta[dot]io . + """ + print(o) + printHelp() + + def absolutise_url(base, relative): # Absolutise relative links if "://" not in relative: @@ -21,6 +46,8 @@ def absolutise_url(base, relative): relative = urllib.parse.urljoin(base, relative) relative = relative.replace("http://", "gemini://") return relative + +printIntro() while True: # Get input @@ -34,16 +61,61 @@ while True: url = menu[int(cmd)-1] elif cmd.lower() == "b": # Yes, twice - url = hist.pop() - url = hist.pop() + # url = hist.pop() + # url = hist.pop() + + # updated to preserve history in list + # so you can use 'f' to go forward too. - WD + try: + url = hist[len(hist) - 2] + except IndexError as e: + print(e) + print('You do not have any history to go back to') + continue + elif cmd.lower() == "f": + # now you can go ahead in history too! - WD + try: + url = hist[url+1] + except NameError as e: + print(e) + print('You do not have any history') + except IndexError as e: + print(e) + print('You are at the front of your history already') + continue + elif cmd.lower() == "h": + # Will actually show history. - WD + try: + print("History:") + for x in range(len(hist)): + print('[',x,']',hist[x]) + except Exception as e: + print(e) + print('Looks like I dun goofed.') + elif cmd == "?": + try: + printHelp() + continue + except Exception as e: + print(e) else: - url = cmd - if not "://" in url: - url = "gemini://" + url - parsed_url = urllib.parse.urlparse(url) + url = cmd + if not "://" in url: + url = "gemini://" + url + # this try/except allows you to check for history with 'h' + # even if you have visited no pages yet, without crashing. - WD + try: + parsed_url = urllib.parse.urlparse(url) + except NameError as e: + print('Error:',e,'\nso try having some history first by visiting a page') + continue if parsed_url.scheme != "gemini": print("Sorry, Gemini links only.") + # break continue + # now it'll just loop again + # instead of quitting the program if you + # put the wrong thing in. - WD # Do the Gemini transaction try: while True: @@ -76,6 +148,8 @@ while True: # Fail if transaction was not successful if not status.startswith("2"): print("Error %s: %s" % (status, mime)) + # haha funny error code - WD + print("OH NO I didn't communicate with the Gemini server right") continue # Handle text if mime.startswith("text/"): @@ -113,4 +187,4 @@ while True: os.system(cmd_str) os.unlink(tmpfp.name) # Update history - hist.append(url) + hist.append(url) \ No newline at end of file