diff --git a/README.md b/README.md new file mode 100644 index 0000000..460a17a --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +py-i2phosts +===== +Overview +----- +**py-i2phosts** is a hostnames registration application for I2P. It is open source (licensed under GPL). Web interface and database structure are made using django web framework. Other scripts are plain python programs, however, they are intergated with django app. Current status: all of base features are implemented and project is ready for production use. Tested with python 2.7 and django 1.8.x. There are working instances of py-i2phosts: http://inr.i2p/ and http://no.i2p/ + +Features +----- +* Web interface is made using django (a set of templates included) + * Hosts submission page with local policy and form with fields Hostname, Destination and Description + * Page for verification of upper-level domain when addind a subdomain + * Index page + * Navigation menu + * Language switcher, multi-language interface (currently available in english and russian) + * Browsing alive and recently added hosts (URLs are provided with addresshelpers) + * RSS feeds for all active hosts and freshly added hosts + * Searching by hostname +* Admin interface (via django admin) features: + * browsing all hosts with various filtering and ordering options + * manual hosts editing and approving recently added hosts + * preview b32 links for all hosts + * managing external sources from which hosts.txt should be fetched +* Validation of hostname and destination as described in I2P naming rules both in web interface and in admin interface. Also some additional validation (see http://zzz.i2p/topics/739 for details) is present in web interface. +* Injector program: it parses hosts.txt files and adds hosts from them into database +* hosts.txt fetcher: it fetches hosts.txt from another services and runs injector on them. Fetcher uses Last-Modified and ETag http headers for safe bandwith. +* Hosts checker: it does availability check of each host using SAM python interface and updates "last seen" timestamp in database +* hosts.txt builder: it queries database and builds a hosts.txt file +* Hosts maintainer: it implements logic for all host-maintainance operations (activating, deactivating, deleting, setting expiration date) +* Master daemon: it runs as unix daemon and periodically launches all other py-i2phosts programs. +* All scripts (except injector and builder) can write all activity to log files. Web interface can log all submission attempts and all validation errors. +* All scripts are supports command-line options and config files +* Built-in jump service +* Install script (using distutils) + +Source code +----- +Sources available in 2 places: +* github: https://github.com/i2phosts/py-i2phosts +* git.repo.i2p: http://git.repo.i2p/w/py-i2phosts.git + +Documentation +----- +See the [Documentation page](http://py-i2phosts.i2p/docs/). + +Discussion area +---- +Here: http://zzz.i2p/topics/733 + +TODO and ideas +----- +**Web interface** +* Add hostname reservation feature into admin interface +* Improve design +* Add categorisation by tags +* Add news +* Lookup tool b32->b64 in web-interface +* Add option "share subdomains" to add form: everyone will be permitted to add subdomains in this domain +* Register multiple subdomains in the same time with primary domain registration +* Search: show b32 also +* Implement flexible API for exchanging between registrators +* Show meaningfull error pages instead of redirects to / + +**Internals** +* Parallel lookups in checker +* Add "last probe" timestamp for hosts. It will help to reduce lookups frequency for inactive hosts. +* Display "key conflict" errors in admin interface or send email to admin +* Probe alive hosts for http service, and provide http:// links at browse page only for them +* Implement json-rpc API for inter-registration services communications. + +**Other** +* Write some documentation ("how it works" for each component, INSTALL, README and so on) diff --git a/pyi2phosts/api/urls.py b/pyi2phosts/api/urls.py index fb0217c..91d0e7c 100644 --- a/pyi2phosts/api/urls.py +++ b/pyi2phosts/api/urls.py @@ -2,4 +2,5 @@ from django.conf.urls import * urlpatterns = patterns('pyi2phosts.api.views', url(r'^all/$', 'all'), + url(r'^status/$', 'status'), ) diff --git a/pyi2phosts/api/views.py b/pyi2phosts/api/views.py index 70dc4d4..dac277d 100644 --- a/pyi2phosts/api/views.py +++ b/pyi2phosts/api/views.py @@ -14,3 +14,49 @@ def all(request): # pass last_seen to json in unixtime json_dict[get_b32(host.b64hash)] = host.last_seen.strftime("%s") return HttpResponse(json.dumps(json_dict), content_type="application/json") + +def status(request): + """ + Return all hosts in { + "hostname": hostname, + "b64": b64, + "b32": b32, + "last-seen": timestamp + } form. + Implemented by MXPLRS|Kirill request. + """ + # host status + if 'q' in request.GET and request.GET['q'] is not None and request.GET['q'] != '': + hostname = request.GET['q'] + else: + json_dict = { + 'error': 'Bad request', + } + return HttpResponse(json.dumps(json_dict), content_type="application/json") + + try: + host = i2phost.objects.get(name=hostname) + except: + host = None + + if host and host.last_seen: + json_dict = { + 'hostname': host.name, + 'b64': host.b64hash, + 'b32': get_b32(host.b64hash), + 'last-seen': host.last_seen.strftime("%s"), + } + elif host and not host.last_seen: + json_dict = { + 'hostname': host.name, + 'b64': host.b64hash, + 'b32': get_b32(host.b64hash), + 'error': 'Never seen', + } + else: + json_dict = { + 'hostname': hostname, + 'error': 'Not found', + } + + return HttpResponse(json.dumps(json_dict), content_type="application/json") diff --git a/pyi2phosts/templates/404.html b/pyi2phosts/templates/404.html index 5c2b33a..8a05b63 100644 --- a/pyi2phosts/templates/404.html +++ b/pyi2phosts/templates/404.html @@ -1,5 +1,5 @@ {% extends "base.html" %} {% block content %} -
{% trans "Host" %} | {% trans "Last seen" %} | {% trans "Date added" %} | {% trans "Description" %} |
{% trans "Host" %} | {% trans "Last seen" %} | {% trans "Date added" %} | {% trans "Description" %} |
{{ host.name }} | {{ host.last_seen }} | -{{ host.date_added }} | {{ host.description }} |
{{ host.name }} | {{ host.last_seen }} | +{{ host.date_added }} | {{ host.description }} |
Admin's approval isn't really necessary, it is only needed in order to eliminate possible hijacking and mass registration attempts. diff --git a/pyi2phosts/templates/index.html b/pyi2phosts/templates/index.html index d604a7c..17edb91 100644 --- a/pyi2phosts/templates/index.html +++ b/pyi2phosts/templates/index.html @@ -2,55 +2,55 @@ {% load i18n %} {% block content %} - {% url 'faq' as faq_url %} - {% blocktrans %} -
{{ title }} is a domain name registration service for I2P. Hostnames in I2P aren't - globally unique. {{ title }} doesn't act as "central authority", it only provides a - way to publish hosts as an easy means of access to them. You can read more about how - I2P naming works in the official - docs. -
+ {% url 'faq' as faq_url %} + {% blocktrans %} +{{ title }} is a domain name registration service for I2P. Hostnames in I2P aren't + globally unique. {{ title }} doesn't act as "central authority", it only provides a + way to publish hosts as an easy means of access to them. You can read more about how + I2P naming works in the official + docs. +
-To find out how we're registering and publishing hosts, look at - FAQ page. -
- {% endblocktrans %} +To find out how we're registering and publishing hosts, look at + FAQ page. +
+ {% endblocktrans %} - {% blocktrans %} -- To start getting new hostnames from {{ title }}, add this - subscription link into your router's - addressbook. Of course, you should add INR's destination before. -
- {% endblocktrans %} + {% blocktrans %} ++ To start getting new hostnames from {{ title }}, add this + subscription link into your router's + addressbook. Of course, you should add INR's destination before. +
+ {% endblocktrans %} - {% url 'pyi2phosts.jump.views.jumper' 'example.i2p' as jump_url %} - {% url 'pyi2phosts.jump.views.index' as jump_index %} - {% blocktrans %} -- {{ title }} also provides a jump service. For accessing hosts through it, - use urls like - - http://{{ domain }}{{ jump_url }}. - I2P since 0.8.3 gives possibility to add a custom jump-servers. Go to the i2ptunnel - eeproxy configuration page - and add http://{{ domain }}{{ jump_index }} to "Jump URL List" section. -
- {% endblocktrans %} + {% url 'pyi2phosts.jump.views.jumper' 'example.i2p' as jump_url %} + {% url 'pyi2phosts.jump.views.index' as jump_index %} + {% blocktrans %} ++ {{ title }} also provides a jump service. For accessing hosts through it, + use urls like + + http://{{ domain }}{{ jump_url }}. + I2P since 0.8.3 gives possibility to add a custom jump-servers. Go to the i2ptunnel + eeproxy configuration page + and add http://{{ domain }}{{ jump_index }} to "Jump URL List" section. +
+ {% endblocktrans %} - {% url 'pyi2phosts.postkey.views.addkey' as addkey_url %} - {% blocktrans %} -If you are running an eepsite or another service and want a human-readable domain name - for them, consider registering it. -
- {% endblocktrans %} + {% url 'pyi2phosts.postkey.views.addkey' as addkey_url %} + {% blocktrans %} +If you are running an eepsite or another service and want a human-readable domain name + for them, consider registering it. +
+ {% endblocktrans %} {% endblock %} {% block footer-addon %} - b32 | {% trans "add" %} | + b32 | {% trans "add" %} | {% endblock %} diff --git a/pyi2phosts/templates/latest.html b/pyi2phosts/templates/latest.html index 35592e4..013696d 100644 --- a/pyi2phosts/templates/latest.html +++ b/pyi2phosts/templates/latest.html @@ -9,5 +9,5 @@ {% endblock %} {% block table_header %}{% trans "Host" %} | {% trans "Last seen" %} | {% trans "Date added" %} | {% trans "Description" %} |
{% trans "Host" %} | {% trans "Last seen" %} | {% trans "Date added" %} | {% trans "Description" %} |