Requests WIP: logIn, getRantsFeed, getWeeklies
This commit is contained in:
parent
1b51316ab6
commit
f5aa7823cc
@ -1,10 +0,0 @@
|
||||
public struct AuthToken: Codable, Hashable {
|
||||
public struct Container: Codable {
|
||||
public let auth_token: AuthToken
|
||||
}
|
||||
|
||||
public let id: Int
|
||||
public let key: String
|
||||
public let expire_time: Int
|
||||
public let user_id: Int
|
||||
}
|
15
Sources/SwiftDevRant/DevRantApiError.swift
Normal file
15
Sources/SwiftDevRant/DevRantApiError.swift
Normal file
@ -0,0 +1,15 @@
|
||||
public struct DevRantApiError: Swift.Error {
|
||||
let message: String
|
||||
}
|
||||
|
||||
public extension DevRantApiError {
|
||||
struct CodingData: Decodable, Swift.Error {
|
||||
let error: String
|
||||
}
|
||||
}
|
||||
|
||||
public extension DevRantApiError.CodingData {
|
||||
var decoded: DevRantApiError {
|
||||
.init(message: error)
|
||||
}
|
||||
}
|
43
Sources/SwiftDevRant/Models/AuthToken.swift
Normal file
43
Sources/SwiftDevRant/Models/AuthToken.swift
Normal file
@ -0,0 +1,43 @@
|
||||
import Foundation
|
||||
|
||||
public struct AuthToken: Hashable {
|
||||
public let id: Int
|
||||
public let key: String
|
||||
public let expireTime: Date
|
||||
public let userId: Int
|
||||
|
||||
public init(id: Int, key: String, expireTime: Date, userId: Int) {
|
||||
self.id = id
|
||||
self.key = key
|
||||
self.expireTime = expireTime
|
||||
self.userId = userId
|
||||
}
|
||||
|
||||
public var isExpired: Bool {
|
||||
expireTime < Date()
|
||||
}
|
||||
}
|
||||
|
||||
extension AuthToken {
|
||||
struct CodingData: Codable {
|
||||
struct Container: Codable {
|
||||
let auth_token: AuthToken.CodingData
|
||||
}
|
||||
|
||||
let id: Int
|
||||
let key: String
|
||||
let expire_time: Int
|
||||
let user_id: Int
|
||||
}
|
||||
}
|
||||
|
||||
extension AuthToken.CodingData {
|
||||
var decoded: AuthToken {
|
||||
.init(
|
||||
id: id,
|
||||
key: key,
|
||||
expireTime: Date(timeIntervalSince1970: TimeInterval(expire_time)),
|
||||
userId: user_id
|
||||
)
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ public struct Request {
|
||||
}
|
||||
}
|
||||
|
||||
public struct EmptyError: Decodable {
|
||||
public struct EmptyError: Decodable, Swift.Error {
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,85 @@
|
||||
public struct SwiftDevRant {
|
||||
let request = Request(encoder: .devRant, decoder: .devRant)
|
||||
let backend = DevRantBackend()
|
||||
|
||||
func makeConfig(_ method: Request.Method, path: String, urlParameters: [String: String] = [:], headers: [String: String] = [:], token: AuthToken? = nil) -> Request.Config {
|
||||
var urlParameters = urlParameters
|
||||
urlParameters["app"] = "3"
|
||||
if let token {
|
||||
urlParameters["token_id"] = String(token.id)
|
||||
urlParameters["token_key"] = token.key
|
||||
urlParameters["user_id"] = String(token.userId)
|
||||
}
|
||||
|
||||
var headers = headers
|
||||
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
|
||||
return .init(method: method, backend: backend, path: path, urlParameters: urlParameters, headers: headers)
|
||||
}
|
||||
|
||||
public func logIn(username: String, password: String) async throws -> AuthToken {
|
||||
var parameters: [String: String] = [:]
|
||||
parameters["username"] = username
|
||||
parameters["password"] = password
|
||||
|
||||
let config = makeConfig(.post, path: "users/auth-token", urlParameters: parameters)
|
||||
|
||||
let response: AuthToken.CodingData.Container = try await request.requestJson(config: config, apiError: DevRantApiError.CodingData.self)
|
||||
|
||||
return response.auth_token.decoded
|
||||
}
|
||||
|
||||
/// Gets a personalized feed of rants.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - token: The token from the `logIn` call response.
|
||||
/// - limit: The number of rants to get for pagination.
|
||||
/// - skip: How many rants to skip for pagination.
|
||||
/// - sessionHash: Pass the session hash value from the last rant feed response or `nil` if calling for the first time.
|
||||
public func getRantFeed(token: AuthToken, sort: RantFeed.Sort = .algorithm, limit: Int = 20, skip: Int, sessionHash: String?) async throws -> RantFeed {
|
||||
var parameters: [String: String] = [:]
|
||||
|
||||
parameters["sort"] = switch sort {
|
||||
case .algorithm: "algo"
|
||||
case .recent: "recent"
|
||||
case .top: "top"
|
||||
}
|
||||
|
||||
switch sort {
|
||||
case .top(range: let range):
|
||||
parameters["range"] = switch range {
|
||||
case .day: "day"
|
||||
case .week: "week"
|
||||
case .month: "month"
|
||||
case .all: "all"
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
parameters["limit"] = String(limit)
|
||||
parameters["skip"] = String(skip)
|
||||
parameters["prev_set"] = sessionHash
|
||||
|
||||
parameters["plat"] = "1" // I don't know wtf that is.
|
||||
parameters["nari"] = "1" // I don't know wtf that is.
|
||||
|
||||
let config = makeConfig(.get, path: "devrant/rants", urlParameters: parameters)
|
||||
|
||||
let response: RantFeed.CodingData = try await request.requestJson(config: config, apiError: DevRantApiError.CodingData.self)
|
||||
|
||||
return response.decoded
|
||||
}
|
||||
|
||||
/// Get all weeklies as a list.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - token: The token from the `logIn` call response.
|
||||
public func getWeeklies(token: AuthToken) async throws -> [Weekly] {
|
||||
let config = makeConfig(.get, path: "devrant/weekly-list")
|
||||
|
||||
let response: Weekly.CodingData.List = try await request.requestJson(config: config, apiError: DevRantApiError.CodingData.self)
|
||||
|
||||
return response.weeks.map(\.decoded)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user