diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..bc3e420 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Alex Kelly + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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/README.md b/README.md new file mode 100644 index 0000000..a032e78 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +Chainlink +========= + +Chainlink is a utility that will run on a webserver to handle crypto-backed +domain names Specifically this works with +[Unstoppable Domains](https://unstoppabledomains.com) +This utilizes public IPFS gateways to display IPFS content, or will redirect to +whatever the URL is set to in the Unstoppable Domain management. + +Installation +============ + +To install this on your own server: + +1. Clone this repository +2. Install the python dependancies via `pip install -r requirements.txt` +3. Run the server with `./chainlink.py` +4. You can now hit the app at http://localhost:5000 + +Testing on a running instance +============================= + +Assuming that it is running (I could be messing with it, or it might just be +broken), you may try this without installing by going to +https://chainlink.arachnitech.com/ + +URL Patterns +============ + +The general format is http://localhost:5000/{domain}/{action} +where {domain} is a .crypto or .zil name registered with Unstoppable +Domains and {action} can be +* html - uses the IPFS hash set in Unstoppable Domains management +* redir - uses the redirect_url set in Unstoppable Domains management +* raw - displays an HTML table view of the full JSON returned from Unstoppable + Domains API + +The default action is "html", so if you don't specify anything it will attempt +to use that field. + +Browser Search Engine +===================== + +I added a browser search engine for each of the UD domains (.zil and .crypto) so +that, when I type `.crypto domain` The browser will automatically redirect based +on the output from my chainlink script. + +The settings to make that work for .crypto is:
+![.crypto search registration][crypto] + +It's basically the same for .zil:
+![.crypto search registration][zil] + + +[crypto]: images/cryptosearch.png +[zil]: images/zilsearch.png diff --git a/chainlink.py b/chainlink.py index ebd5f33..6157fd1 100755 --- a/chainlink.py +++ b/chainlink.py @@ -1,25 +1,34 @@ #!/usr/bin/env python """Utilize crypto domains DNS and either redirect, or display information.""" -from bottle import Bottle, run, response, request +from bottle import Bottle, run, response, request, static_file, redirect import json import requests import json2html -VERSION = '0.0.1' +VERSION = '0.1.0' app = Bottle() def domainLookup(domain): - apibase = 'https://unstoppabledomains.com/api/v1/' - dnslookup = requests.get(apibase + domain) - domainJSON = json.loads(dnslookup.content) - print(domainJSON) - return domainJSON + """Return a dictionary from JSON results of API call + or return False if there is an error + """ + try: + apibase = 'https://unstoppabledomains.com/api/v1/' + dnslookup = requests.get(apibase + domain) + if dnslookup.status_code == 200: + domainInfo = json.loads(dnslookup.content) + return domainInfo + else: + return False + except requests.exceptions.ConnectionError: + return False @app.route("/") def root(): + """Index page, just displays information about URL formatting""" host = request.get_header('host') helptext = f"""
General format is {host}/<domain>/<action> @@ -33,7 +42,7 @@ def root():