2025-01-12 21:36:58 -08:00
#!/usr/bin/python3
2025-01-12 22:31:01 -08:00
import asyncio , traceback , socket , ssl
2025-01-12 22:00:24 -08:00
from flask import Flask , request , redirect
2025-01-12 21:36:58 -08:00
from hypercorn . config import Config
from hypercorn . asyncio import serve
app = Flask ( __name__ )
@app.route ( " / " )
def root ( ) :
2025-01-12 22:00:24 -08:00
return """
< ! DOCTYPE html >
< html >
< head >
< meta charset = " UTF-8 " >
< link rel = " stylesheet " href = " https://swee.codes/style.css " >
< title > Gem2Browser < / title >
< / head >
< body >
< center >
< h1 > Gem2Browser < / h1 >
< form action = " /gem " >
< p style = " font-size: 15pt; " > gemini : / / < input class = " input " value = " geminiprotocol.net " type = " text " name = " gemini " > < / p > < br >
2025-01-12 22:10:56 -08:00
< input type = " submit " class = " download " value = " Go! " >
2025-01-12 22:00:24 -08:00
< / form >
< / center >
< / body >
< / html >
"""
2025-01-12 21:51:59 -08:00
@app.route ( " /gem " )
def relay ( ) :
url = request . args . get ( ' gemini ' )
if url == None :
return redirect ( " / " )
2025-01-12 22:00:24 -08:00
code = " <h1>Something went wrong...</h1> \n "
2025-01-12 21:36:58 -08:00
title = " Something went wrong... "
try :
2025-01-12 22:31:01 -08:00
gsocket = socket . socket ( socket . AF_INET , socket . SOCK_STREAM )
2025-01-12 22:32:57 -08:00
gemsocket = ssl . create_default_context ( ) . wrap_socket ( gsocket )
2025-01-12 22:31:01 -08:00
gemsocket . connect ( ( url , 1965 ) )
gemsocket . send ( bytes ( " gemini:// " + url + " \r \n " , " UTF-8 " ) )
received = " "
while True :
gemresponse = gemsocket . recv ( 2048 )
if gemresponse :
received + = gemresponse . decode ( )
else :
break
received = received . replace ( " \r " , " " )
firstline = True
redirected = False
gemtext = True
code = " "
for i in received . split ( " \n " ) :
if firstline :
if i . split ( " " ) [ 0 ] [ 0 ] == " 3 " :
return redirect ( " /gem?gemini= " + i . split ( " " ) [ 1 ] )
elif i . split ( " " ) [ 0 ] [ 0 ] != " 2 " :
return f ' <!DOCTYPE html> \n <html><head><meta charset= " UTF-8 " ><link rel= " stylesheet " href= " https://swee.codes/style.css " ><title>Something went wrong...</title></head><body><h1>Something went wrong...</h1><p>The specified Gemini server returned a status of: { i } </p></body></html> '
else :
firstline = False
if i . split ( " " ) [ 1 ] != " text/gemini " :
return f ' <!DOCTYPE html> \n <html><head><meta charset= " UTF-8 " ><link rel= " stylesheet " href= " https://swee.codes/style.css " ><title>Something went wrong...</title></head><body><h1>Something went wrong...</h1><p>This path returned a file that isn \' t Gemtext, which Gem2Browser doesn \' t support downloading files.</p></body></html> '
else :
if i [ 0 : 1 ] == " # " :
if title == " Something went wrong... " :
title = i [ 2 : ]
temp = i [ 2 : ]
code + = f " <h1> { temp } </h1> \n "
2025-01-12 22:31:24 -08:00
elif i [ 0 : 2 ] == " ## " :
2025-01-12 22:31:01 -08:00
temp = i [ 3 : ]
code + = f " <h2> { temp } </h2> \n "
elif i [ 0 : 3 ] == " ### " :
temp = i [ 4 : ]
code + = f " <h3> { temp } </h3> \n "
elif i [ 0 : 1 ] == " * " :
temp = i [ 2 : ]
code + = f " <ul><li> { temp } </li></ul> "
else :
code + = f " <p> { code } </p> \n "
if title == " Something went wrong... " :
title = " gemini:// " + url
2025-01-12 21:36:58 -08:00
except :
2025-01-12 22:00:24 -08:00
code + = traceback . format_exc ( )
2025-01-12 22:01:13 -08:00
return f ' <!DOCTYPE html> \n <html><head><meta charset= " UTF-8 " ><link rel= " stylesheet " href= " https://swee.codes/style.css " ><title> { title } </title></head><body> { code } </body></html> '
2025-01-12 21:36:58 -08:00
# Run the Hypercorn ASGI server
2025-01-12 21:49:36 -08:00
conf = Config ( )
conf . bind = " 0.0.0.0:2009 "
asyncio . run ( serve ( app , conf ) )