Added plain text (gemtext like) templates

This commit is contained in:
Slatian 2023-02-25 15:42:59 +01:00
parent aa384c9eff
commit 896564791e
11 changed files with 265 additions and 24 deletions

View File

@ -177,7 +177,7 @@ async fn main() {
},
},
};
let template_glob = template_base_dir.clone()+"*.html";
let template_glob = template_base_dir.clone()+"*";
println!("Parsing Templates from '{}' ...", &template_glob);
let res = Tera::new((template_glob).as_str());
let tera = match res {

View File

@ -38,6 +38,16 @@ impl ToString for ResponseFormat {
}
}
impl ResponseFormat {
fn to_file_extension(&self) -> String {
match self {
ResponseFormat::TextPlain => ".txt",
ResponseFormat::TextHtml => ".html",
ResponseFormat::ApplicationJson => ".json",
}.to_string()
}
}
/* Template Settings */
#[derive(serde::Deserialize, serde::Serialize, Clone)]
@ -88,7 +98,7 @@ impl Engine {
view: &View,
) -> Response {
let mut response = match settings.format {
ResponseFormat::TextHtml => {
ResponseFormat::TextHtml | ResponseFormat::TextPlain => {
let template_name = view.template_name();
let mut context = tera::Context::new();
@ -99,18 +109,23 @@ impl Engine {
context.insert("data", &view);
context.insert("extra", &self.template_config);
match self.tera.render(&(template_name+".html"), &context) {
Ok(html) => Html(html).into_response(),
match self.tera.render(&(template_name+&settings.format.to_file_extension()), &context) {
Ok(text) =>
match settings.format {
ResponseFormat::TextHtml => Html(text).into_response(),
_ => text.into_response(),
}
Err(e) => {
println!("There was an error while rendering index.html: {e:?}");
let mut response = "Template error, contact owner or see logs.".into_response();
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
return response;
(
StatusCode::INTERNAL_SERVER_ERROR,
"Template error, contact owner or see logs.\n"
).into_response()
}
}
}
//TODO: Plain Text should have its own matcher
ResponseFormat::ApplicationJson | ResponseFormat::TextPlain => {
ResponseFormat::ApplicationJson => {
match view {
View::Dig{result, ..} => {
Json(result).into_response()

7
templates/404.txt Normal file
View File

@ -0,0 +1,7 @@
{% extends "base.txt" %}
{% block content %}
# Nothing here!
{% endblock %}
{% block json_notice %}{%endblock%}

View File

@ -9,18 +9,6 @@
{% block og_path %}/?query=AS{{ data.asn }}{% endblock %}
{% block content %}
{% if data.result.idn %}
{% set idn = data.result.idn %}
<section>
<h2>Internationalized Domain Names</h2>
<p>Because of some limitations the DNS has, Unicode caracters need a special encoding.</p>
{% if idn.original_was == "unicode" %}
<p>Your Unicode query has been encoded as the <i>IDN</i> <code>{{ idn.idn }}</code> to generate the results below.</p>
{% else %}
<p>Your <i>IDN</i> would decode to <code>{{ idn.unicode }}</code>.</p>
{% endif %}
</section>
{% endif %}
<section>
<h2>Other Services</h2>

6
templates/asn.txt Normal file
View File

@ -0,0 +1,6 @@
# AS{{ data.asn }}
please visit the html version of this page to get a list of links to services that can help you with your ASN query.
You could also contribute to echoip-slatecave if you have ideas on how to get useful information on this page ;)
=> https://codeberg.org/slatian/service.echoip-slatecave

25
templates/base.txt Normal file
View File

@ -0,0 +1,25 @@
{%- block content %}
Greetings from the base template!
{% endblock -%}
{%- block json_notice %}
You can get the json version:
=> {{ extra.base_url }}/{% block path %}{% endblock %}?format=json
{% endblock -%}
{%- if view == "404" %}
## Usage
You can query this service using the folowing endpoints …
=> {{ extra.base_url }}/ip/<address> … to query for an ip-address
=> {{ extra.base_url }}/dig/<name> … to query for a domain-name
=> {{ extra.base_url }}/ua … to get your user agent
## About
You can find the echoip-slatecave sourcecode on Codeberg.
=> https://codeberg.org/slatian/service.echoip-slatecave
If you found a bug or have an idea, feature, etc. please get in touch (I also accept E-Mails!).
This service works in its current form because nobody is abusing it, please keep that in mind. If you want to do frequent automated requests please host your own instace. Thank you for being awesome!
{% endif %}

125
templates/dig.txt Normal file
View File

@ -0,0 +1,125 @@
{% extends "base.txt" %}
{% block path %}dig/{{ data.query | urlencode_strict }}{% endblock %}
{% block content -%}
# dig {{data.query}}
{% if data.result.idn -%}
{%- set idn = data.result.idn -%}
## Internationalized Domain Names
Because of some limitations the DNS has, Unicode caracters need a special encoding.
{%- if idn.original_was == "unicode" -%}
Your Unicode query has been encoded as an IDN to generate the results below.
```
{{ idn.idn }}
```
{%- else -%}
Your IDN would decode to
```
{{ idn.unicode }}
```
{%- endif -%}
{% endif -%}
{% set r = data.result.records -%}
## DNS Records
{% if r.nxdomain %}
Our DNS-Server claims that this domain doesn't exist, you shouldn't see any results below.
{%- elif r.timeout -%}
There was at least one timeout error while resolving this domain, the results below are incomplete.
{%- elif r.other_error -%}
An error happened while resolving this name, the results below are incomplete. There was probably some IO issue, the error has been written to the log to help with debugging.
{% endif -%}
{%- if r.dns_error %}
The DNS-Server returned an error code that is not NXDomain, the results are probably incomplete. To help with debugging this has been written to the log.
{%- endif -%}
{%- if r.cname %}
### CNAME
This domain has a cname set, this means its contents are full replaced by the linked record.
{{ r.cname[0] }}
Usually you get the A and AAAA records for the linked record to avoid uneccessary requests. If anything else resolves, that is a violation of the DNS specification.
{% if r.cname | length > 1 -%}
This domain resolves to multiple CNAMEs, this is not allowed by the DNS specification!
{%- endif %}
{% endif -%}
{%- if r.aname %}
This domain has one or multiple ANAME (or ALIAS) records set that the DNS server communicates:
{%- for aname in r.aname -%}
* {{aname}}
{%- endfor -%}
{% endif -%}
{%- if r.a %}
A (IPv4) records:
{% for address in r.a -%}
* {{ address }}
{% endfor %}
{%- else %}
No A (IPv4) Records.
{% endif -%}
{%- if r.aaaa %}
AAAA (IPv6) records:
{% for address in r.aaaa -%}
* {{ address }}
{% endfor %}
{%- else %}
No AAAA (IPv6) Records.
{% endif -%}
{%- if not data.result.partial_lookup -%}
{%- if r.mx %}
MX (Mail Exchange) records:
{% for mx in r.mx | sort(attribute="preference") | reverse -%}
* {{ mx.preference }} {{ mx.exchange }}
{% endfor %}
{%- else %}
No MX (Mail Exchange) records.
{% endif %}
{%- if r.caa %}
CAA (Certification Authority Authorization) records:
{% for caa in r.caa -%}
* {{caa}}
{% endfor %}
{%- else %}
No CAA (Certification Authority Authorization) records.
{% endif %}
{%- if r.txt %}
TXT records:
{% for txt in r.txt -%}
* {{txt}}
{% endfor %}
{%- else -%}
No TXT records.
{% endif %}
{%- if r.srv %}
SRV records:
{% for srv in r.srv %}
* Priority: {{srv.priority}}
* Weight: {{srv.weight}}
* Port: {{srv.port}}
* Target: {{srv.target}}
{% endfor %}
{%- else %}
No SRV records.
SRV or Service records usually live on their own subdomains like {{ "_xmpp-client._tcp."~data.query }}.
{% endif %}
{%- else %}{# if data.partial_lookup #}
To save resources the above is only a partial lookup.
=> {{ helper::dig_link(extra=extra, name=data.query) }}
{%- endif -%}
{% endblock %}

View File

@ -1,9 +1,13 @@
{% macro place_dl(place, label="", iso_code_prefix="") %}
{% if place %}
{% macro place_dl(place, label="", iso_code_prefix="") -%}
{%- if place -%}
{%- if format=="text/html" %}
{% if label %}<dt>{{label}}</dt>{% endif %}
<dd>{{place.name}} {% if place.iso_code%}({% if iso_code_prefix %}{{iso_code_prefix}}-{% endif %}{{place.iso_code}}){% endif %}</dd>
{% endif %}
{% endmacro place_dl %}
{% else -%}
* {% if label %}{{label}}: {% endif %}{{place.name}}{% if place.iso_code%} ({% if iso_code_prefix %}{{iso_code_prefix}}-{% endif %}{{place.iso_code}}){% endif %}
{%- endif -%}
{%- endif -%}
{%- endmacro place_dl %}
{% macro dig_link(extra, name) %}
{{ extra.base_url }}/dig/{{ name | trim_end_matches(pat=".") | urlencode_strict | replace(from="%2e", to=".") | safe }}
@ -28,3 +32,7 @@
{% endfor %}
{% endmacro breadcrumb_domain %}
{% macro ip_info(ip_info) -%}
{{ip_info.scope | title}} {{ip_info.cast | title}} IPv{% if ip_info.is_v6_address %}6{% else %}4{% endif %}
{%- endmacro ip_info %}

5
templates/index.txt Normal file
View File

@ -0,0 +1,5 @@
{% extends "ip.txt" %}
{% block title -%}
Your IP-Adress is: {{ data.result.address }}
{%- endblock %}

60
templates/ip.txt Normal file
View File

@ -0,0 +1,60 @@
{% extends "base.txt" %}
{% import "helpers.html" as helper %}
{% block path %}ip/{{ data.result.address }}{% endblock %}
{% block content %}
{% set r = data.result -%}
# {% block title %}Lookup {{ data.result.address }}{% endblock %}
## Network information
* Type of Address: {{ helper::ip_info(ip_info=r.ip_info) }}
{% if r.hostname -%}
* Hostname: {{ r.hostname }}
{%- endif %}
{% if r.asn -%}
* ASN: AS{{ r.asn.asn }}
* AS Name: {{r.asn.name}}
{%- endif -%}
{%- if r.location -%}
## Geolocation
{{ helper::place_dl(place=r.location.continent, label="Continent") }}
{{ helper::place_dl(place=r.location.country, label="Country") }}
{% if r.location.country.iso_code | default(value="") != r.location.registered_country.iso_code | default(value="") -%}
{{ helper::place_dl(place=r.location.registered_country, label="Registred in") }}
{%- endif %}
{% if r.location.country.iso_code | default(value="") != r.location.represented_country.iso_code | default(value="") -%}
{{ helper::place_dl(place=r.location.represented_country, label="Represents") }}
{%- endif %}
{% if r.location.subdivisions -%}
{%- for sd in r.location.subdivisions -%}
{{ helper::place_dl(place=sd, label="Subdivision", iso_code_prefix=r.location.country.iso_code|default(value="")) }}
{%- endfor -%}
{%- endif %}
{{ helper::place_dl(place=r.location.city, label="City") }}
{% if r.location.postal_code -%}
* Postal Code: {{r.location.postal_code}}
{%- endif %}
{% if r.location.time_zone -%}
* Timezone: {{r.location.time_zone}}
{% endif -%}
{% if r.location.accuracy -%}
* Accuaracy: ~{{r.location.accuracy}}km<
{%- endif %}
{% if r.location.coordinates %}
### Coordinates
lat: {{r.location.coordinates.lat}}, lon: {{r.location.coordinates.lon}}
=> {{ links::map_link(lat=r.location.coordinates.lat, lon=r.location.coordinates.lon)}}">
{% endif %}
The GeopIP and ASN information is provided by the GeoLite2 database created by MaxMind.
{% endif -%}
{%- block extra_content %}{% endblock -%}
{%- endblock %}

2
templates/message.txt Normal file
View File

@ -0,0 +1,2 @@
# {{ data.title }}
{{ data.message }}