1 package net.pterodactylus.sone.template
3 import net.pterodactylus.sone.core.ElementLoader
4 import net.pterodactylus.sone.core.LinkedElement
5 import net.pterodactylus.sone.data.Sone
6 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.ALWAYS
7 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.FOLLOWED
8 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.MANUALLY_TRUSTED
9 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.NEVER
10 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.TRUSTED
11 import net.pterodactylus.sone.freenet.wot.OwnIdentity
12 import net.pterodactylus.sone.text.FreenetLinkPart
13 import net.pterodactylus.sone.text.Part
14 import net.pterodactylus.util.template.Filter
15 import net.pterodactylus.util.template.TemplateContext
18 * Filter that takes a number of pre-rendered [Part]s and replaces all identified links to freenet elements
19 * with [LinkedElement]s.
21 class LinkedElementsFilter(private val elementLoader: ElementLoader) : Filter {
23 @Suppress("UNCHECKED_CAST")
24 override fun format(templateContext: TemplateContext?, data: Any?, parameters: MutableMap<String, Any?>?) =
25 if (showLinkedImages(templateContext?.get("currentSone") as Sone?, parameters?.get("sone") as Sone?)) {
26 (data as? Iterable<Part>)
27 ?.filterIsInstance<FreenetLinkPart>()
28 ?.map { elementLoader.loadElement(it.link) }
29 ?.filter { !it.failed }
30 ?: listOf<LinkedElement>()
32 listOf<LinkedElement>()
35 private fun showLinkedImages(currentSone: Sone?, sone: Sone?): Boolean {
36 return (currentSone != null) && (sone != null) && ((currentSone == sone) || currentSoneAllowsImagesFromSone(currentSone, sone))
39 private fun currentSoneAllowsImagesFromSone(currentSone: Sone, externalSone: Sone) =
40 when (currentSone.options.loadLinkedImages) {
42 MANUALLY_TRUSTED -> externalSone.isLocal || currentSone.explicitelyTrusts(externalSone)
43 FOLLOWED -> externalSone.isLocal || currentSone.hasFriend(externalSone.id)
44 TRUSTED -> externalSone.isLocal || currentSone.implicitelyTrusts(externalSone)
48 private fun Sone.implicitelyTrusts(other: Sone): Boolean {
49 val explicitTrust = other.identity.getTrust(this.identity as OwnIdentity)?.explicit
50 val implicitTrust = other.identity.getTrust(this.identity as OwnIdentity)?.implicit
51 return ((explicitTrust != null) && (explicitTrust > 0)) || ((explicitTrust == null) && (implicitTrust != null) && (implicitTrust > 0))
54 private fun Sone.explicitelyTrusts(other: Sone) =
55 other.identity.getTrust(this.identity as OwnIdentity)?.explicit ?: -1 > 0