Skip to content

Commit

Permalink
Merge pull request #126 from Tunous/feat/featured-tags
Browse files Browse the repository at this point in the history
User featured tags
  • Loading branch information
davidgarywood committed Mar 19, 2023
2 parents e3e13e6 + d71b3d3 commit ac7ed71
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// GetFeaturedTags.swift
// Created by Łukasz Rutkowski on 18/03/2023.
//

import ArgumentParser
import Foundation
import TootSDK

struct GetFeaturedTags: 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: .customShort("i"), help: "id of the user")
var userID: String

mutating func run() async throws {
print("Getting featured tags of user with local id: \(userID)")
let client = TootClient(instanceURL: URL(string: url)!, accessToken: token)

let featuredTags = try await client.getFeaturedTags(forUser: userID)
print(featuredTags)
}
}
1 change: 1 addition & 0 deletions Examples/swiftyadmin/Sources/swiftyadmin/swiftyadmin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ struct SwiftyAdmin: AsyncParsableCommand {
GetPost.self,
GetFlavour.self,
RegisterAccount.self,
GetFeaturedTags.self,
])
}
20 changes: 20 additions & 0 deletions Sources/TootSDK/Extensions/Decoding+Helpers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Decoding+Helpers.swift
// Created by Łukasz Rutkowski on 18/03/2023.
//

import Foundation

extension KeyedDecodingContainerProtocol {
func decodeIntFromString(forKey key: Key) throws -> Int {
do {
return try decode(Int.self, forKey: key)
} catch {
let string = try decode(String.self, forKey: key)
if let int = Int(string) {
return int
}
throw error
}
}
}
20 changes: 20 additions & 0 deletions Sources/TootSDK/Models/FeaturedTag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
import Foundation

public struct FeaturedTag: Codable, Hashable, Identifiable {

/// ID of the featured tag in database.
public var id: String

/// Name of the tag being featured.
public var name: String

/// Link to all posts by a user that contain this tag.
public var url: String

/// Number of authored posts containing this tag.
public var postsCount: Int

/// The date of last authored post containing this tag.
public var lastPostAt: Date

public init(id: String, name: String, url: String, postsCount: Int, lastPostAt: Date) {
Expand All @@ -17,6 +27,16 @@ public struct FeaturedTag: Codable, Hashable, Identifiable {
self.postsCount = postsCount
self.lastPostAt = lastPostAt
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(String.self, forKey: .id)
self.name = try container.decode(String.self, forKey: .name)
self.url = try container.decode(String.self, forKey: .url)
// Mastodon incorrectly returns this count as string
self.postsCount = try container.decodeIntFromString(forKey: .postsCount)
self.lastPostAt = try container.decode(Date.self, forKey: .lastPostAt)
}

enum CodingKeys: String, CodingKey {
case id
Expand Down
15 changes: 13 additions & 2 deletions Sources/TootSDK/TootClient/TootClient+Account.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,22 @@ extension TootClient {
throw error
}
}

/// Get tags featured by user.
///
/// - Parameter userID: ID of user in database.
/// - Returns: The featured tags or an error if unable to retrieve.
public func getFeaturedTags(forUser userID: String) async throws -> [FeaturedTag] {
let req = HTTPRequestBuilder {
$0.url = getURL(["api", "v1", "accounts", userID, "featured_tags"])
$0.method = .get
}
return try await fetch([FeaturedTag].self, req)
}

// swiftlint:disable todo
// TODO: - Update account credentials

// TODO: - Get account’s featured tags

// TODO: - Get lists containing this account
// TODO: - Feature account on your profile
// TODO: - Unfeature account from profile
Expand Down
43 changes: 43 additions & 0 deletions Tests/TootSDKTests/DecodingTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// DecodingTests.swift
//
//
// Created by Łukasz Rutkowski on 18/03/2023.
//

import XCTest
@testable import TootSDK

final class DecodingTests: XCTestCase {

func testDecodeIntFromString() throws {
try assertDecodes(#"{"int": 2}"#, as: Element(2))
try assertDecodes(#"{"int": "5"}"#, as: Element(5))
try assertDecodes(#"{"int": -12}"#, as: Element(-12))
try assertDecodes(#"{"int": "-7"}"#, as: Element(-7))
}

private func assertDecodes(_ json: String, as element: Element) throws {
let decoder = JSONDecoder()
let data = Data(json.utf8)
let decodedElement = try decoder.decode(Element.self, from: data)
XCTAssertEqual(decodedElement, element)
}

struct Element: Decodable, Equatable {
let int: Int

init(_ int: Int) {
self.int = int
}

enum CodingKeys: CodingKey {
case int
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.int = try container.decodeIntFromString(forKey: .int)
}
}
}

0 comments on commit ac7ed71

Please sign in to comment.