Skip to content

Commit

Permalink
Merge pull request #144 from daprice/trends
Browse files Browse the repository at this point in the history
Get trending tags, posts, and links
  • Loading branch information
kkostov committed Apr 16, 2023
2 parents 9b9e1f0 + 8248fde commit 73d396c
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ArgumentParser
import Foundation
import TootSDK

struct GetTrendingLinks: AsyncParsableCommand {

@Option(name: .short, help: "URL to the instance to connect to")
var url: String

@Option(name: .short, help: "Access token for an account with sufficient permissions.")
var token: String

@Option(name: .shortAndLong, help: "Maximum number of results to return")
var limit: Int?

@Option(name: .shortAndLong, help: "Skip the first n results")
var offset: Int?

mutating func run() async throws {
print("Listing trending links")
let client = try await TootClient(connect: URL(string: url)!, accessToken: token)

let results = try await client.getTrendingLinks(limit: limit, offset: offset)
for link in results {
let json = String.init(data: try TootEncoder().encode(link), encoding: .utf8)
print(json ?? "")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ArgumentParser
import Foundation
import TootSDK

struct GetTrendingPosts: AsyncParsableCommand {

@Option(name: .short, help: "URL to the instance to connect to")
var url: String

@Option(name: .short, help: "Access token for an account with sufficient permissions.")
var token: String

@Option(name: .shortAndLong, help: "Maximum number of results to return")
var limit: Int?

@Option(name: .shortAndLong, help: "Skip the first n results")
var offset: Int?

mutating func run() async throws {
print("Listing trending posts")
let client = try await TootClient(connect: URL(string: url)!, accessToken: token)

let results = try await client.getTrendingPosts(limit: limit, offset: offset)
for post in results {
let json = String.init(data: try TootEncoder().encode(post), encoding: .utf8)
print(json ?? "")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import ArgumentParser
import Foundation
import TootSDK

struct GetTrendingTags: AsyncParsableCommand {

@Option(name: .short, help: "URL to the instance to connect to")
var url: String

@Option(name: .short, help: "Access token for an account with sufficient permissions.")
var token: String

@Option(name: .shortAndLong, help: "Maximum number of results to return")
var limit: Int?

@Option(name: .shortAndLong, help: "Skip the first n results")
var offset: Int?

mutating func run() async throws {
print("Listing trending tags")
let client = try await TootClient(connect: URL(string: url)!, accessToken: token)

let results = try await client.getTrendingTags(limit: limit, offset: offset)
for tag in results {
print("\(tag.name) (\(tag.url))")
if let history = tag.history {
for day in history {
print("\t\(day)")
}
}
}
}
}
3 changes: 3 additions & 0 deletions Examples/swiftyadmin/Sources/swiftyadmin/swiftyadmin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ struct SwiftyAdmin: AsyncParsableCommand {
GetFlavour.self,
RegisterAccount.self,
GetFeaturedTags.self,
GetTrendingTags.self,
GetTrendingPosts.self,
GetTrendingLinks.self,
])
}
4 changes: 2 additions & 2 deletions Sources/TootSDK/Models/Tag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Foundation

/// Represents a hashtag used within the content of a post.
public struct Tag: Codable, Hashable, Sendable {
public init(name: String, url: String, history: [TagHistory]? = nil) {
public init(name: String, url: String, history: [History]? = nil) {
self.name = name
self.url = url
self.history = history
Expand All @@ -16,5 +16,5 @@ public struct Tag: Codable, Hashable, Sendable {
/// A link to the hashtag on the instance.
public let url: String
/// Usage statistics for given days.
public let history: [TagHistory]?
public let history: [History]?
}
32 changes: 17 additions & 15 deletions Sources/TootSDK/Models/TagHistory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@

import Foundation

/// Represents daily usage history of a hashtag.
public struct TagHistory: Codable, Hashable, Sendable {
public init(day: String,
uses: String,
accounts: String) {
self.day = day
self.uses = uses
self.accounts = accounts
public extension Tag {
/// Represents daily usage history of a hashtag.
struct History: Codable, Hashable, Sendable {
public init(day: String,
uses: String,
accounts: String) {
self.day = day
self.uses = uses
self.accounts = accounts
}

/// UNIX timestamp on midnight of the given day.
public let day: String
/// the counted usage of the hashtag within that day.
public let uses: String
/// the total of accounts using the hashtag within that day.
public let accounts: String
}

/// UNIX timestamp on midnight of the given day.
public let day: String
/// the counted usage of the tag within that day.
public let uses: String
/// the total of accounts using the tag within that day.
public let accounts: String
}
55 changes: 55 additions & 0 deletions Sources/TootSDK/Models/TrendingLink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// TrendingLink.swift
//
//
// Created by Dale Price on 4/7/23.
//

import Foundation

public struct TrendingLink: Codable, Hashable {
public init(url: String,
title: String,
description: String,
authorName: String? = nil,
authorUrl: String? = nil,
providerName: String? = nil,
providerUrl: String? = nil,
html: String? = nil,
width: Int? = nil,
height: Int? = nil,
image: String? = nil,
embedUrl: String? = nil,
blurhash: String? = nil,
history: [History]? = nil) {
self.url = url
self.title = title
self.description = description
self.authorName = authorName
self.authorUrl = authorUrl
self.providerName = providerName
self.providerUrl = providerUrl
self.html = html
self.width = width
self.height = height
self.image = image
self.embedUrl = embedUrl
self.blurhash = blurhash
self.history = history
}

public var url: String
public var title: String
public var description: String
public var authorName: String?
public var authorUrl: String?
public var providerName: String?
public var providerUrl: String?
public var html: String?
public var width: Int?
public var height: Int?
public var image: String?
public var embedUrl: String?
public var blurhash: String?
public var history: [History]?
}
28 changes: 28 additions & 0 deletions Sources/TootSDK/Models/TrendingLinkHistory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// TrendingLinkHistory.swift
//
//
// Created by Dale Price on 4/11/23.
//

import Foundation

public extension TrendingLink {
/// Represents daily usage history of a link.
struct History: Codable, Hashable, Sendable {
public init(day: String,
uses: String,
accounts: String) {
self.day = day
self.uses = uses
self.accounts = accounts
}

/// UNIX timestamp on midnight of the given day.
public let day: String
/// the counted usage of the link within that day.
public let uses: String
/// the total of accounts posting the link within that day.
public let accounts: String
}
}
74 changes: 74 additions & 0 deletions Sources/TootSDK/TootClient/TootClient+Trends.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// TootClient+Trends.swift
//
//
// Created by Dale Price on 4/7/23.
//

import Foundation

public extension TootClient {

/// Get trending tags
///
/// - Parameters:
/// - limit: Maximum number of results to return. Defaults to 10, max 20.
/// - offset: Skip the first n results.
/// - Returns: Array of ``Tag``.
func getTrendingTags(limit: Int? = nil, offset: Int? = nil) async throws -> [Tag] {
do {
try requireFlavour([.mastodon, .friendica])
} catch TootSDKError.unsupportedFlavour(_, _) {
return []
}
let req = HTTPRequestBuilder {
$0.url = getURL(["api", "v1", "trends", "tags"])
$0.method = .get
$0.query = getQueryParams(limit: limit, offset: offset)
}

return try await fetch([Tag].self, req)
}

/// Get trending posts
///
/// - Parameters:
/// - limit: Maximum number of results to return. Defaults to 20, max 40.
/// - offset: Skip the first n results.
/// - Returns: Array of ``Post``.
func getTrendingPosts(limit: Int? = nil, offset: Int? = nil) async throws -> [Post] {
do {
try requireFlavour([.mastodon, .friendica])
} catch TootSDKError.unsupportedFlavour(_, _) {
return []
}
let req = HTTPRequestBuilder {
$0.url = getURL(["api", "v1", "trends", "statuses"])
$0.method = .get
$0.query = getQueryParams(limit: limit, offset: offset)
}

return try await fetch([Post].self, req)
}

/// Get trending links
///
/// - Parameters:
/// - limit: Maximum number of results to return. Defaults to 10, max 20.
/// - offset: Skip the first n results.
/// - Returns: Array of ``TrendingLink``.
func getTrendingLinks(limit: Int? = nil, offset: Int? = nil) async throws -> [TrendingLink] {
do {
try requireFlavour([.mastodon, .friendica])
} catch TootSDKError.unsupportedFlavour(_, _) {
return []
}
let req = HTTPRequestBuilder {
$0.url = getURL(["api", "v1", "trends", "links"])
$0.method = .get
$0.query = getQueryParams(limit: limit, offset: offset)
}

return try await fetch([TrendingLink].self, req)
}
}

0 comments on commit 73d396c

Please sign in to comment.