forked from solderpunk/gemini-demo-1
Forked from solderpunk's repo
Added all of my current changes to gemini-demo.py, updated README.md and LICENSE
This commit is contained in:
parent
eca985da3e
commit
dcc4b804d2
6
LICENSE
6
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) <year> <owner> . 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.
|
42
README.md
42
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.
|
|
@ -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)
|
Loading…
Reference in New Issue