Merge branch 'release-0.9.7'
[Sone.git] / src / main / kotlin / net / pterodactylus / sone / template / LinkedElementsFilter.kt
1 package net.pterodactylus.sone.template
2
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
16
17 /**
18  * Filter that takes a number of pre-rendered [Part]s and replaces all identified links to freenet elements
19  * with [LinkedElement]s.
20  */
21 class LinkedElementsFilter(private val elementLoader: ElementLoader) : Filter {
22
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>()
31                         } else {
32                                 listOf<LinkedElement>()
33                         }
34
35         private fun showLinkedImages(currentSone: Sone?, sone: Sone?): Boolean {
36                 return (currentSone != null) && (sone != null) && ((currentSone == sone) || currentSoneAllowsImagesFromSone(currentSone, sone))
37         }
38
39         private fun currentSoneAllowsImagesFromSone(currentSone: Sone, externalSone: Sone) =
40                         when (currentSone.options.loadLinkedImages) {
41                                 NEVER -> false
42                                 MANUALLY_TRUSTED -> externalSone.isLocal || currentSone.explicitelyTrusts(externalSone)
43                                 FOLLOWED -> externalSone.isLocal || currentSone.hasFriend(externalSone.id)
44                                 TRUSTED -> externalSone.isLocal || currentSone.implicitelyTrusts(externalSone)
45                                 ALWAYS -> true
46                         }
47
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))
52         }
53
54         private fun Sone.explicitelyTrusts(other: Sone) =
55                         other.identity.getTrust(this.identity as OwnIdentity)?.explicit ?: -1 > 0
56
57 }