Skip to content

Commit

Permalink
Implement Trends API (#360)
Browse files Browse the repository at this point in the history
* Update documentation to reflect what the classes do

This goes against Mastodon’s documentation, but their documentation
seems to be outdated here.

---------

Co-authored-by: Gasser André <[email protected]>
  • Loading branch information
PattaFeuFeu and Gasser André authored Dec 1, 2023
1 parent c6d650e commit c0dc78f
Show file tree
Hide file tree
Showing 10 changed files with 526 additions and 8 deletions.
63 changes: 63 additions & 0 deletions bigbone-rx/src/main/kotlin/social/bigbone/rx/RxTrendMethods.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package social.bigbone.rx

import io.reactivex.rxjava3.core.Single
import social.bigbone.MastodonClient
import social.bigbone.api.entity.Status
import social.bigbone.api.entity.Tag
import social.bigbone.api.entity.TrendsLink
import social.bigbone.api.method.TrendMethods

/**
* Reactive implementation of [TrendMethods].
*
* View trending tags, statuses, or links, i.e. those that are currently being used more frequently than usual.
* @see <a href="https://docs.joinmastodon.org/methods/trends/">Mastodon trends API methods</a>
*/
class RxTrendMethods(client: MastodonClient) {

private val trendMethods = TrendMethods(client)

/**
* Tags that are being used more frequently within the past week.
*
* @param offset Skip the first n results.
* @param limit Maximum number of results to return. Defaults to 10 tags. Max 20 tags.
* @see <a href="https://docs.joinmastodon.org/methods/trends/#tags">Mastodon API documentation: methods/trends/#tags</a>
*/
@JvmOverloads
fun getTrendingTags(
offset: Int? = null,
limit: Int = 10
): Single<List<Tag>> = Single.fromCallable {
trendMethods.getTrendingTags(offset, limit).execute()
}

/**
* Statuses that have been interacted with more than others.
*
* @param offset Skip the first n results.
* @param limit Maximum number of results to return. Defaults to 20 statuses. Max 40 statuses.
* @see <a href="https://docs.joinmastodon.org/methods/trends/#statuses">Mastodon API documentation: methods/trends/#statuses</a>
*/
fun getTrendingStatuses(
offset: Int? = null,
limit: Int = 20
): Single<List<Status>> = Single.fromCallable {
trendMethods.getTrendingStatuses(offset, limit).execute()
}

/**
* Links that have been shared more than others.
*
* @param offset Skip the first n results.
* @param limit Maximum number of results to return. Defaults to 10 links. Max 20 links.
* @see <a href="https://docs.joinmastodon.org/methods/trends/#links">Mastodon API documentation: methods/trends/#links</a>
*/
@JvmOverloads
fun getTrendingLinks(
offset: Int? = null,
limit: Int = 10
): Single<List<TrendsLink>> = Single.fromCallable {
trendMethods.getTrendingLinks(offset, limit).execute()
}
}
8 changes: 8 additions & 0 deletions bigbone/src/main/kotlin/social/bigbone/MastodonClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import social.bigbone.api.method.StreamingMethods
import social.bigbone.api.method.SuggestionMethods
import social.bigbone.api.method.TagMethods
import social.bigbone.api.method.TimelineMethods
import social.bigbone.api.method.TrendMethods
import social.bigbone.api.method.admin.AdminDimensionMethods
import social.bigbone.api.method.admin.AdminMeasureMethods
import social.bigbone.api.method.admin.AdminRetentionMethods
Expand Down Expand Up @@ -336,6 +337,13 @@ private constructor(
@get:JvmName("timelines")
val timelines: TimelineMethods by lazy { TimelineMethods(this) }

/**
* Access API methods under the "trends" endpoint.
*/
@Suppress("unused") // public API
@get:JvmName("trends")
val trends: TrendMethods by lazy { TrendMethods(this) }

/**
* Specifies the HTTP methods / HTTP verb that can be used by this class.
*/
Expand Down
106 changes: 106 additions & 0 deletions bigbone/src/main/kotlin/social/bigbone/api/entity/TrendsLink.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package social.bigbone.api.entity

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import social.bigbone.api.entity.PreviewCard.CardType
import social.bigbone.api.entity.data.History

/**
* Represents a rich preview card that is generated using OpenGraph tags from a URL.
* @see <a href="https://docs.joinmastodon.org/entities/PreviewCard/#trends-link">Mastodon API PreviewCard/Trends::Link</a>
*/
@Serializable
data class TrendsLink(
/**
* Location of linked resource.
*/
@SerialName("url")
val url: String? = null,

/**
* Title of linked resource.
*/
@SerialName("title")
val title: String? = null,

/**
* Description of preview.
*/
@SerialName("description")
val description: String? = null,

/**
* The type of the preview card.
* @see CardType
*/
@SerialName("type")
val type: CardType = CardType.LINK,

/**
* The author of the original resource.
*/
@SerialName("author_name")
val authorName: String? = null,

/**
* A link to the author of the original resource.
*/
@SerialName("author_url")
val authorUrl: String? = null,

/**
* The provider of the original resource.
*/
@SerialName("provider_name")
val providerName: String? = null,

/**
* A link to the provider of the original resource.
*/
@SerialName("provider_url")
val providerUrl: String? = null,

/**
* HTML to be used for generating the preview card.
*/
@SerialName("html")
val html: String? = null,

/**
* Width of preview, in pixels.
*/
@SerialName("width")
val width: Int? = null,

/**
* Height of preview, in pixels.
*/
@SerialName("height")
val height: Int? = null,

/**
* Preview thumbnail.
*/
@SerialName("image")
val image: String? = null,

/**
* Used for photo embeds, instead of custom html.
*/
@SerialName("embed_url")
val embedUrl: String? = null,

/**
* A hash computed by the BlurHash algorithm,
* for generating colorful preview thumbnails
* when media has not been downloaded yet.
*/
@SerialName("blurhash")
val blurhash: String? = null,

/**
* Usage statistics for given days (typically the past week).
*/
@SerialName("history")
val history: List<History>? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.serialization.Serializable
/**
* Usage statistics for given days (typically the past week).
* @see <a href="https://docs.joinmastodon.org/entities/Tag/#history">Mastodon API Tag history</a>
* @see <a href="https://docs.joinmastodon.org/entities/PreviewCard/#history">Mastodon API PreviewCard history
*/
@Serializable
data class History(
Expand All @@ -17,13 +18,15 @@ data class History(
val day: String = "",

/**
* The counted usage of the tag within that day, string cast from integer.
* The counted statuses or usages of the tag within that day.
* String cast from integer.
*/
@SerialName("uses")
val uses: String = "",

/**
* The total of accounts using the tag within that day, string cast from integer.
* The total of accounts using the tag or link within that day.
* String cast from integer.
*/
@SerialName("accounts")
val accounts: String = ""
Expand Down
82 changes: 82 additions & 0 deletions bigbone/src/main/kotlin/social/bigbone/api/method/TrendMethods.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package social.bigbone.api.method

import social.bigbone.MastodonClient
import social.bigbone.MastodonRequest
import social.bigbone.Parameters
import social.bigbone.api.entity.Status
import social.bigbone.api.entity.Tag
import social.bigbone.api.entity.TrendsLink

/**
* View trending tags, statuses, or links, i.e. those that are currently being used more frequently than usual.
* @see <a href="https://docs.joinmastodon.org/methods/trends/">Mastodon trends API methods</a>
*/
class TrendMethods(private val client: MastodonClient) {

private val trendsEndpoint = "api/v1/trends"

/**
* Tags that are being used more frequently within the past week.
*
* @param offset Skip the first n results.
* @param limit Maximum number of results to return. Defaults to 10 tags. Max 20 tags.
* @see <a href="https://docs.joinmastodon.org/methods/trends/#tags">Mastodon API documentation: methods/trends/#tags</a>
*/
@JvmOverloads
fun getTrendingTags(
offset: Int? = null,
limit: Int = 10
): MastodonRequest<List<Tag>> {
return client.getMastodonRequestForList(
endpoint = "$trendsEndpoint/tags",
method = MastodonClient.Method.GET,
parameters = Parameters().apply {
append("limit", limit)
offset?.let { append("offset", offset) }
}
)
}

/**
* Statuses that have been interacted with more than others.
*
* @param offset Skip the first n results.
* @param limit Maximum number of results to return. Defaults to 20 statuses. Max 40 statuses.
* @see <a href="https://docs.joinmastodon.org/methods/trends/#statuses">Mastodon API documentation: methods/trends/#statuses</a>
*/
fun getTrendingStatuses(
offset: Int? = null,
limit: Int = 20
): MastodonRequest<List<Status>> {
return client.getMastodonRequestForList(
endpoint = "$trendsEndpoint/statuses",
method = MastodonClient.Method.GET,
parameters = Parameters().apply {
append("limit", limit)
offset?.let { append("offset", offset) }
}
)
}

/**
* Links that have been shared more than others.
*
* @param offset Skip the first n results.
* @param limit Maximum number of results to return. Defaults to 10 links. Max 20 links.
* @see <a href="https://docs.joinmastodon.org/methods/trends/#links">Mastodon API documentation: methods/trends/#links</a>
*/
@JvmOverloads
fun getTrendingLinks(
offset: Int? = null,
limit: Int = 10
): MastodonRequest<List<TrendsLink>> {
return client.getMastodonRequestForList(
endpoint = "$trendsEndpoint/links",
method = MastodonClient.Method.GET,
parameters = Parameters().apply {
append("limit", limit)
offset?.let { append("offset", offset) }
}
)
}
}
55 changes: 55 additions & 0 deletions bigbone/src/test/assets/trends_view_trending_links_success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[
{
"url": "https://www.nbcnews.com/specials/plan-your-vote-2022-elections/index.html",
"title": "Plan Your Vote: 2022 Elections",
"description": "Everything you need to know about the voting rules where you live, including registration, mail-in voting, changes since 2020, and more.",
"type": "link",
"author_name": "NBC News",
"author_url": "",
"provider_name": "NBC News",
"provider_url": "",
"html": "",
"width": 400,
"height": 225,
"image": "https://files.mastodon.social/cache/preview_cards/images/045/027/478/original/0783d5e91a14fd49.jpeg",
"embed_url": "",
"blurhash": "UcQmF#ay~qofj[WBj[j[~qof9Fayofofayay",
"history": [
{
"day": "1661817600",
"accounts": "7",
"uses": "7"
},
{
"day": "1661731200",
"accounts": "23",
"uses": "23"
},
{
"day": "1661644800",
"accounts": "0",
"uses": "0"
},
{
"day": "1661558400",
"accounts": "0",
"uses": "0"
},
{
"day": "1661472000",
"accounts": "0",
"uses": "0"
},
{
"day": "1661385600",
"accounts": "0",
"uses": "0"
},
{
"day": "1661299200",
"accounts": "0",
"uses": "0"
}
]
}
]
10 changes: 10 additions & 0 deletions bigbone/src/test/assets/trends_view_trending_statuses_success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"id": "108910940413327534",
"created_at": "2022-08-30T08:44:26.366Z",
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"sensitive": false,
"content": "<p>In order to prevent such incidents from happening in the future, we are implementing a fixed set of internal guidelines which must be met before any media content can be shared on our social media platforms. The distribution of material which promotes a message of racism or sexism is unacceptable. We can do better and in the future we will do better.</p><p>We apologize again for this incident and can assure you that it will not happen again.</p><p>Your Tutanota Team</p>"
}
]
Loading

0 comments on commit c0dc78f

Please sign in to comment.