feat(commands|Network>dig): feat dig command

This commit is contained in:
Romain J 2021-01-26 17:11:30 +01:00
parent 1d37dc1961
commit 554c0b52d5
13 changed files with 202 additions and 58 deletions

View file

@ -32,6 +32,7 @@
<w>postgre</w> <w>postgre</w>
<w>postgresql</w> <w>postgresql</w>
<w>pred</w> <w>pred</w>
<w>pydig</w>
<w>pylint</w> <w>pylint</w>
<w>releaselevel</w> <w>releaselevel</w>
<w>rprint</w> <w>rprint</w>

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

View file

@ -2,7 +2,11 @@ import re
from discord.ext import commands from discord.ext import commands
from tuxbot.cogs.Network.functions.exceptions import InvalidIp from tuxbot.cogs.Network.functions.exceptions import (
InvalidIp,
InvalidDomain,
InvalidQueryType,
)
def _(x): def _(x):
@ -30,22 +34,48 @@ class IPConverter(commands.Converter):
class IPCheckerConverter(commands.Converter): class IPCheckerConverter(commands.Converter):
async def convert(self, ctx, argument): # skipcq: PYL-W0613 async def convert(self, ctx, argument): # skipcq: PYL-W0613
argument_back = argument if not argument.startswith("http"):
return f"http://{argument}"
return argument
class DomainCheckerConverter(commands.Converter):
async def convert(self, ctx, argument): # skipcq: PYL-W0613
argument = argument.replace("http://", "").replace("https://", "") argument = argument.replace("http://", "").replace("https://", "")
check_domain = re.match(DOMAIN_PATTERN, argument) check_domain = re.match(DOMAIN_PATTERN, argument)
check_ipv4 = re.match(IPV4_PATTERN, argument)
check_ipv6 = re.match(IPV6_PATTERN, argument)
if check_domain or check_ipv4 or check_ipv6: if check_domain:
if argument_back.startswith("https://"): return argument
return "https://" + argument
return "http://" + ( raise InvalidDomain(_("Invalid domain"))
argument if not check_ipv6 else f"[{argument}]"
class QueryTypeConverter(commands.Converter):
async def convert(self, ctx, argument): # skipcq: PYL-W0613
argument = argument.lower()
query_types = [
"a",
"aaaa",
"cname",
"ns",
"ds",
"dnskey",
"soa",
"txt",
"ptr",
"mx",
]
if argument in query_types:
return argument
raise InvalidQueryType(
_(
"Supported queries : A, AAAA, CNAME, NS, DS, DNSKEY, SOA, TXT, PTR, MX"
) )
)
raise InvalidIp(_("Invalid ip or domain"))
class IPVersionConverter(commands.Converter): class IPVersionConverter(commands.Converter):

View file

@ -9,5 +9,13 @@ class InvalidIp(commands.BadArgument):
pass pass
class InvalidDomain(commands.BadArgument):
pass
class InvalidQueryType(commands.BadArgument):
pass
class VersionNotFound(commands.BadArgument): class VersionNotFound(commands.BadArgument):
pass pass

View file

@ -3,6 +3,7 @@ from typing import Union, NoReturn
import ipinfo import ipinfo
import ipwhois import ipwhois
import pydig
from ipinfo.exceptions import RequestQuotaExceededError from ipinfo.exceptions import RequestQuotaExceededError
from ipwhois import Net from ipwhois import Net
@ -98,3 +99,19 @@ def merge_ipinfo_ipwhois(ipinfo_result: dict, ipwhois_result: dict) -> dict:
] = f"https://www.countryflags.io/{asn_country}/shiny/64.png" ] = f"https://www.countryflags.io/{asn_country}/shiny/64.png"
return output return output
def get_pydig_result(
domain: str, query_type: str, dnssec: Union[str, bool]
) -> list:
additional_args = [] if dnssec is False else ["+dnssec"]
resolver = pydig.Resolver(
nameservers=[
"80.67.169.40",
"80.67.169.12",
],
additional_args=additional_args,
)
return resolver.query(domain, query_type)

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: 2021-01-19 14:39+0100\n" "PO-Revision-Date: 2021-01-19 14:39+0100\n"
"Last-Translator: Automatically generated\n" "Last-Translator: Automatically generated\n"
"Language-Team: none\n" "Language-Team: none\n"
@ -18,50 +18,62 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: tuxbot/cogs/Network/functions/converters.py:28 #: tuxbot/cogs/Network/functions/converters.py:32
#: tuxbot/cogs/Network/functions/converters.py:48 #: tuxbot/cogs/Network/functions/converters.py:52
msgid "Invalid ip or domain" msgid "Invalid ip or domain"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/functions/converters.py:59 #: tuxbot/cogs/Network/functions/converters.py:64
msgid "Invalid domain"
msgstr ""
#: tuxbot/cogs/Network/functions/converters.py:88
msgid "Supported queries : A, AAAA, CNAME, NS, DS, DNSKEY, SOA, TXT, PTR, MX"
msgstr ""
#: tuxbot/cogs/Network/functions/converters.py:101
msgid "Invalid ip version" msgid "Invalid ip version"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/functions/utils.py:31 #: tuxbot/cogs/Network/functions/utils.py:32
msgid "Impossible to collect information on this in the given version" msgid "Impossible to collect information on this in the given version"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/functions/utils.py:54 #: tuxbot/cogs/Network/functions/utils.py:55
#, python-brace-format #, python-brace-format
msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918." msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918."
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:74 #: tuxbot/cogs/Network/network.py:89
msgid "*Retrieving information...*" msgid "*Retrieving information...*"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:90 #: tuxbot/cogs/Network/network.py:107
#, python-brace-format #, python-brace-format
msgid "Information for ``{ip} ({ip_address})``" msgid "Information for ``{ip} ({ip_address})``"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:100 tuxbot/cogs/Network/network.py:130 #: tuxbot/cogs/Network/network.py:113
msgid "Belongs to:" msgid "Belongs to:"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:113 tuxbot/cogs/Network/network.py:142 #: tuxbot/cogs/Network/network.py:123
msgid "Region:" msgid "Region:"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:152 #: tuxbot/cogs/Network/network.py:131
#, python-brace-format #, python-brace-format
msgid "Hostname: {hostname}" msgid "Hostname: {hostname}"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:182 #: tuxbot/cogs/Network/network.py:161
msgid "[show all]({})" msgid "[show all]({})"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:192 #: tuxbot/cogs/Network/network.py:171
msgid "Cannot connect to host {}" msgid "Cannot connect to host {}"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:195
msgid "No result..."
msgstr ""

View file

@ -18,50 +18,62 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: tuxbot/cogs/Network/functions/converters.py:28 #: tuxbot/cogs/Network/functions/converters.py:32
#: tuxbot/cogs/Network/functions/converters.py:48 #: tuxbot/cogs/Network/functions/converters.py:52
msgid "Invalid ip or domain" msgid "Invalid ip or domain"
msgstr "Nome de domaine ou adresse IP invalide" msgstr "Nom de domaine ou adresse IP invalide"
#: tuxbot/cogs/Network/functions/converters.py:59 #: tuxbot/cogs/Network/functions/converters.py:64
msgid "Invalid domain"
msgstr "Domaine invalide"
#: tuxbot/cogs/Network/functions/converters.py:88
msgid "Supported queries : A, AAAA, CNAME, NS, DS, DNSKEY, SOA, TXT, PTR, MX"
msgstr "Requêtes supportées : A, AAAA, CNAME, NS, DS, DNSKEY, SOA, TXT, PTR, MX"
#: tuxbot/cogs/Network/functions/converters.py:101
msgid "Invalid ip version" msgid "Invalid ip version"
msgstr "Version d'adresse IP invalide" msgstr "Version d'adresse IP invalide"
#: tuxbot/cogs/Network/functions/utils.py:31 #: tuxbot/cogs/Network/functions/utils.py:32
msgid "Impossible to collect information on this in the given version" msgid "Impossible to collect information on this in the given version"
msgstr "Impossible de collecter des informations pour cette IP avec la version donnée" msgstr "Impossible de collecter des informations pour cette IP avec la version donnée"
#: tuxbot/cogs/Network/functions/utils.py:54 #: tuxbot/cogs/Network/functions/utils.py:55
#, python-brace-format #, python-brace-format
msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918." msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918."
msgstr "L'adresse ip {ip_address} est est reservée à un usage local selon la RFC 1918" msgstr "L'adresse ip {ip_address} est est reservée à un usage local selon la RFC 1918"
#: tuxbot/cogs/Network/network.py:74 #: tuxbot/cogs/Network/network.py:89
msgid "*Retrieving information...*" msgid "*Retrieving information...*"
msgstr "*Récupération des informations...*" msgstr "*Récupération des informations...*"
#: tuxbot/cogs/Network/network.py:90 #: tuxbot/cogs/Network/network.py:107
#, python-brace-format #, python-brace-format
msgid "Information for ``{ip} ({ip_address})``" msgid "Information for ``{ip} ({ip_address})``"
msgstr "Informations pour ``{ip} ({ip_address})``" msgstr "Informations pour ``{ip} ({ip_address})``"
#: tuxbot/cogs/Network/network.py:100 tuxbot/cogs/Network/network.py:130 #: tuxbot/cogs/Network/network.py:113
msgid "Belongs to:" msgid "Belongs to:"
msgstr "Appartient à :" msgstr "Appartient à :"
#: tuxbot/cogs/Network/network.py:113 tuxbot/cogs/Network/network.py:142 #: tuxbot/cogs/Network/network.py:123
msgid "Region:" msgid "Region:"
msgstr "Région :" msgstr "Région :"
#: tuxbot/cogs/Network/network.py:152 #: tuxbot/cogs/Network/network.py:131
#, python-brace-format #, python-brace-format
msgid "Hostname: {hostname}" msgid "Hostname: {hostname}"
msgstr "Nom d'hôte : {hostname}" msgstr "Nom d'hôte : {hostname}"
#: tuxbot/cogs/Network/network.py:182 #: tuxbot/cogs/Network/network.py:161
msgid "[show all]({})" msgid "[show all]({})"
msgstr "[tout afficher]({})" msgstr "[tout afficher]({})"
#: tuxbot/cogs/Network/network.py:192 #: tuxbot/cogs/Network/network.py:171
msgid "Cannot connect to host {}" msgid "Cannot connect to host {}"
msgstr "Impossible de se connecter à l'hôte {}" msgstr "Impossible de se connecter à l'hôte {}"
#: tuxbot/cogs/Network/network.py:195
msgid "No result..."
msgstr "Aucun résultat..."

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,50 +17,62 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: tuxbot/cogs/Network/functions/converters.py:28 #: tuxbot/cogs/Network/functions/converters.py:32
#: tuxbot/cogs/Network/functions/converters.py:48 #: tuxbot/cogs/Network/functions/converters.py:52
msgid "Invalid ip or domain" msgid "Invalid ip or domain"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/functions/converters.py:59 #: tuxbot/cogs/Network/functions/converters.py:64
msgid "Invalid domain"
msgstr ""
#: tuxbot/cogs/Network/functions/converters.py:88
msgid "Supported queries : A, AAAA, CNAME, NS, DS, DNSKEY, SOA, TXT, PTR, MX"
msgstr ""
#: tuxbot/cogs/Network/functions/converters.py:101
msgid "Invalid ip version" msgid "Invalid ip version"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/functions/utils.py:31 #: tuxbot/cogs/Network/functions/utils.py:32
msgid "Impossible to collect information on this in the given version" msgid "Impossible to collect information on this in the given version"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/functions/utils.py:54 #: tuxbot/cogs/Network/functions/utils.py:55
#, python-brace-format #, python-brace-format
msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918." msgid "IP address {ip_address} is already defined as Private-Use Networks via RFC 1918."
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:74 #: tuxbot/cogs/Network/network.py:89
msgid "*Retrieving information...*" msgid "*Retrieving information...*"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:90 #: tuxbot/cogs/Network/network.py:107
#, python-brace-format #, python-brace-format
msgid "Information for ``{ip} ({ip_address})``" msgid "Information for ``{ip} ({ip_address})``"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:100 tuxbot/cogs/Network/network.py:130 #: tuxbot/cogs/Network/network.py:113
msgid "Belongs to:" msgid "Belongs to:"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:113 tuxbot/cogs/Network/network.py:142 #: tuxbot/cogs/Network/network.py:123
msgid "Region:" msgid "Region:"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:152 #: tuxbot/cogs/Network/network.py:131
#, python-brace-format #, python-brace-format
msgid "Hostname: {hostname}" msgid "Hostname: {hostname}"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:182 #: tuxbot/cogs/Network/network.py:161
msgid "[show all]({})" msgid "[show all]({})"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:192 #: tuxbot/cogs/Network/network.py:171
msgid "Cannot connect to host {}" msgid "Cannot connect to host {}"
msgstr "" msgstr ""
#: tuxbot/cogs/Network/network.py:195
msgid "No result..."
msgstr ""

View file

@ -1,5 +1,7 @@
import functools import functools
import logging import logging
from typing import Union
import discord import discord
from aiohttp import ClientConnectorError from aiohttp import ClientConnectorError
from discord.ext import commands from discord.ext import commands
@ -9,11 +11,15 @@ from tuxbot.cogs.Network.functions.converters import (
IPConverter, IPConverter,
IPVersionConverter, IPVersionConverter,
IPCheckerConverter, IPCheckerConverter,
DomainCheckerConverter,
QueryTypeConverter,
) )
from tuxbot.cogs.Network.functions.exceptions import ( from tuxbot.cogs.Network.functions.exceptions import (
RFC18, RFC18,
InvalidIp, InvalidIp,
VersionNotFound, VersionNotFound,
InvalidDomain,
InvalidQueryType,
) )
from tuxbot.core.bot import Tux from tuxbot.core.bot import Tux
from tuxbot.core.i18n import ( from tuxbot.core.i18n import (
@ -32,6 +38,7 @@ from .functions.utils import (
get_ipinfo_result, get_ipinfo_result,
get_ipwhois_result, get_ipwhois_result,
merge_ipinfo_ipwhois, merge_ipinfo_ipwhois,
get_pydig_result,
) )
log = logging.getLogger("tuxbot.cogs.Network") log = logging.getLogger("tuxbot.cogs.Network")
@ -54,7 +61,14 @@ class Network(commands.Cog, name="Network"):
async def cog_command_error(self, ctx, error): async def cog_command_error(self, ctx, error):
if isinstance( if isinstance(
error, error,
(RequestQuotaExceededError, RFC18, InvalidIp, VersionNotFound), (
RequestQuotaExceededError,
RFC18,
InvalidIp,
InvalidDomain,
InvalidQueryType,
VersionNotFound,
),
): ):
if self._tmp: if self._tmp:
await self._tmp.delete() await self._tmp.delete()
@ -128,9 +142,19 @@ class Network(commands.Cog, name="Network"):
): ):
try: try:
headers = {"User-Agent": user_agent} headers = {"User-Agent": user_agent}
colors = {
"1": 0x17A2B8,
"2": 0x28A745,
"3": 0xFFC107,
"4": 0xDC3545,
"5": 0x343A40,
}
async with ctx.session.get(str(ip), headers=headers) as s: async with ctx.session.get(str(ip), headers=headers) as s:
e = discord.Embed(title=f"Headers : {ip}", color=0xD75858) e = discord.Embed(
title=f"Headers : {ip}",
color=colors.get(str(s.status)[0], 0x6C757D),
)
e.add_field( e.add_field(
name="Status", value=f"```{s.status}```", inline=True name="Status", value=f"```{s.status}```", inline=True
) )
@ -151,8 +175,36 @@ class Network(commands.Cog, name="Network"):
e.add_field(name=key, value=value, inline=True) e.add_field(name=key, value=value, inline=True)
await ctx.send(embed=e, deletable=False) await ctx.send(embed=e)
except ClientConnectorError: except ClientConnectorError:
await ctx.send( await ctx.send(
_("Cannot connect to host {}", ctx, self.bot.config).format(ip) _("Cannot connect to host {}", ctx, self.bot.config).format(ip)
) )
@command_extra(name="dig", deletable=True)
async def _dig(
self,
ctx: ContextPlus,
domain: DomainCheckerConverter,
query_type: QueryTypeConverter,
dnssec: Union[str, bool] = False,
):
pydig_result = await self.bot.loop.run_in_executor(
None,
functools.partial(get_pydig_result, domain, query_type, dnssec),
)
e = discord.Embed(title=f"DIG {domain} {query_type}", color=0x5858D7)
for value in pydig_result:
e.add_field(
name=f"DIG {domain} IN {query_type}", value=f"```{value}```"
)
if not pydig_result:
e.add_field(
name=f"DIG {domain} IN {query_type}",
value=_("No result...", ctx, self.bot.config),
)
await ctx.send(embed=e)

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tuxbot-bot\n" "Project-Id-Version: Tuxbot-bot\n"
"Report-Msgid-Bugs-To: rick@gnous.eu\n" "Report-Msgid-Bugs-To: rick@gnous.eu\n"
"POT-Creation-Date: 2021-01-26 15:18+0100\n" "POT-Creation-Date: 2021-01-26 16:12+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"