X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fkotlin%2Fnet%2Fpterodactylus%2Fsone%2Ftext%2FSoneTextParser.kt;h=b711ca8fdbd760782d702c57640dbbf8ad683647;hp=64125c1d50dee77d3863f3c250048633635f332a;hb=faf66247a34f64946990a985d2ea3003465969cb;hpb=8e313509a42a8c638fcac018dd73dd975bf9cb68 diff --git a/src/main/kotlin/net/pterodactylus/sone/text/SoneTextParser.kt b/src/main/kotlin/net/pterodactylus/sone/text/SoneTextParser.kt index 64125c1..b711ca8 100644 --- a/src/main/kotlin/net/pterodactylus/sone/text/SoneTextParser.kt +++ b/src/main/kotlin/net/pterodactylus/sone/text/SoneTextParser.kt @@ -1,28 +1,21 @@ package net.pterodactylus.sone.text -import freenet.keys.FreenetURI -import freenet.support.Base64 -import net.pterodactylus.sone.data.Sone -import net.pterodactylus.sone.data.impl.IdOnlySone -import net.pterodactylus.sone.database.PostProvider -import net.pterodactylus.sone.database.SoneProvider -import net.pterodactylus.sone.text.LinkType.CHK -import net.pterodactylus.sone.text.LinkType.FREEMAIL -import net.pterodactylus.sone.text.LinkType.HTTP -import net.pterodactylus.sone.text.LinkType.HTTPS -import net.pterodactylus.sone.text.LinkType.KSK -import net.pterodactylus.sone.text.LinkType.POST -import net.pterodactylus.sone.text.LinkType.SONE -import net.pterodactylus.sone.text.LinkType.SSK +import freenet.keys.* +import freenet.support.* +import net.pterodactylus.sone.data.* +import net.pterodactylus.sone.data.impl.* +import net.pterodactylus.sone.database.* +import net.pterodactylus.sone.text.LinkType.* import net.pterodactylus.sone.text.LinkType.USK -import net.pterodactylus.sone.utils.let -import org.bitpedia.util.Base32 -import java.net.MalformedURLException +import net.pterodactylus.sone.utils.* +import org.bitpedia.util.* +import java.net.* +import javax.inject.* /** * [Parser] implementation that can recognize Freenet URIs. */ -class SoneTextParser(private val soneProvider: SoneProvider?, private val postProvider: PostProvider?) { +class SoneTextParser @Inject constructor(private val soneProvider: SoneProvider?, private val postProvider: PostProvider?) { fun parse(source: String, context: SoneTextParserContext?) = source.split("\n") @@ -50,27 +43,39 @@ class SoneTextParser(private val soneProvider: SoneProvider?, private val postPr } }.map { it.first }.toList() + private val NextLink.linkWithoutBacklink: String + get() { + val backlink = link.indexOf("/../") + val query = link.indexOf("?") + return if ((backlink > -1) && ((query == -1) || (query > -1) && (backlink < query))) + link.substring(0, backlink) + else + link + } + private fun NextLink.toPart(context: SoneTextParserContext?) = when (linkType) { KSK, CHK -> try { - FreenetURI(link).let { freenetUri -> + FreenetURI(linkWithoutBacklink).let { freenetUri -> FreenetLinkPart( - link, - if (freenetUri.isKSK) { - freenetUri.guessableKey - } else { - freenetUri.metaString ?: freenetUri.docName ?: link.substring(0, 9) - }, - link.split('?').first() + linkWithoutBacklink, + freenetUri.allMetaStrings?.lastOrNull { it != "" } ?: freenetUri.docName ?: linkWithoutBacklink.substring(0, 9), + linkWithoutBacklink.split('?').first() ) } } catch (e: MalformedURLException) { - PlainTextPart(link) + PlainTextPart(linkWithoutBacklink) } SSK, USK -> try { - FreenetLinkPart(link, FreenetURI(link).docName, trusted = context?.routingKey?.contentEquals(FreenetURI(link).routingKey) == true) + FreenetURI(linkWithoutBacklink).let { uri -> + uri.allMetaStrings + ?.takeIf { (it.size > 1) || ((it.size == 1) && (it.single() != "")) } + ?.lastOrNull() + ?: uri.docName + ?: "${uri.keyType}@${uri.routingKey.asFreenetBase64}" + }.let { FreenetLinkPart(linkWithoutBacklink.removeSuffix("/"), it, trusted = context?.routingKey?.contentEquals(FreenetURI(linkWithoutBacklink).routingKey) == true) } } catch (e: MalformedURLException) { - PlainTextPart(link) + PlainTextPart(linkWithoutBacklink) } SONE -> link.substring(7).let { SonePart(soneProvider?.getSone(it) ?: IdOnlySone(it)) } POST -> postProvider?.getPost(link.substring(7))?.let { PostPart(it) } ?: PlainTextPart(link) @@ -111,7 +116,7 @@ private fun List.mergeAdjacentPlainTextParts() = fold(emptyList()) { private fun List.removeEmptyPlainTextParts() = filterNot { it == PlainTextPart("") } -private val String.decodedId: String get() = Base64.encode(Base32.decode(this)) +private val String.decodedId: String get() = Base32.decode(this).asFreenetBase64 private val String.withoutProtocol get() = substring(indexOf("//") + 2) private val String.withoutUrlParameters get() = split('?').first() @@ -134,7 +139,7 @@ private val String.withoutMiddlePathComponents } private val String.withoutTrailingSlash get() = if (endsWith("/")) substring(0, length - 1) else this private val SoneTextParserContext.routingKey: ByteArray? get() = postingSone?.routingKey -private val Sone.routingKey: ByteArray get() = Base64.decode(id) +private val Sone.routingKey: ByteArray get() = id.fromFreenetBase64 private enum class LinkType(private val scheme: String, private val freenetLink: Boolean) {