This repository was archived by the owner on Sep 15, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathStatsTopAuthorsTimeIntervalData.swift
More file actions
142 lines (123 loc) · 3.8 KB
/
Copy pathStatsTopAuthorsTimeIntervalData.swift
File metadata and controls
142 lines (123 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
public struct StatsTopAuthorsTimeIntervalData {
public let period: StatsPeriodUnit
public let periodEndDate: Date
public let topAuthors: [StatsTopAuthor]
public init(period: StatsPeriodUnit,
periodEndDate: Date,
topAuthors: [StatsTopAuthor]) {
self.period = period
self.periodEndDate = periodEndDate
self.topAuthors = topAuthors
}
}
public struct StatsTopAuthor {
public let name: String
public let iconURL: URL?
public let viewsCount: Int
public let posts: [StatsTopPost]
public init(name: String,
iconURL: URL?,
viewsCount: Int,
posts: [StatsTopPost]) {
self.name = name
self.iconURL = iconURL
self.viewsCount = viewsCount
self.posts = posts
}
}
public struct StatsTopPost {
@frozen public enum Kind {
case unknown
case post
case page
case homepage
}
public let title: String
public var date: String?
public let postID: Int
public let postURL: URL?
public let viewsCount: Int
public let kind: Kind
public init(title: String,
date: String?,
postID: Int,
postURL: URL?,
viewsCount: Int,
kind: Kind) {
self.title = title
self.date = date
self.postID = postID
self.postURL = postURL
self.viewsCount = viewsCount
self.kind = kind
}
}
extension StatsTopAuthorsTimeIntervalData: StatsTimeIntervalData {
public static var pathComponent: String {
return "stats/top-authors/"
}
public init?(date: Date, period: StatsPeriodUnit, jsonDictionary: [String: AnyObject]) {
guard
let unwrappedDays = type(of: self).unwrapDaysDictionary(jsonDictionary: jsonDictionary),
let authors = unwrappedDays["authors"] as? [[String: AnyObject]]
else {
return nil
}
self.period = period
self.periodEndDate = date
self.topAuthors = authors.compactMap { StatsTopAuthor(jsonDictionary: $0) }
}
}
extension StatsTopAuthor {
init?(jsonDictionary: [String: AnyObject]) {
guard
let name = jsonDictionary["name"] as? String,
let views = jsonDictionary["views"] as? Int,
let avatar = jsonDictionary["avatar"] as? String,
let posts = jsonDictionary["posts"] as? [[String: AnyObject]]
else {
return nil
}
let url: URL?
if var components = URLComponents(string: avatar) {
components.query = "d=mm&s=60"
url = components.url
} else {
url = nil
}
let mappedPosts = posts.compactMap { StatsTopPost(jsonDictionary: $0) }
self.name = name
self.viewsCount = views
self.iconURL = url
self.posts = mappedPosts
}
}
extension StatsTopPost {
init?(jsonDictionary: [String: AnyObject]) {
guard
let title = jsonDictionary["title"] as? String,
let postID = jsonDictionary["id"] as? Int,
let viewsCount = jsonDictionary["views"] as? Int,
let postURL = jsonDictionary["url"] as? String
else {
return nil
}
self.title = title
self.postID = postID
self.viewsCount = viewsCount
self.postURL = URL(string: postURL)
self.kind = type(of: self).kind(from: jsonDictionary["type"] as? String)
}
static func kind(from kindString: String?) -> Kind {
switch kindString {
case "post":
return .post
case "homepage":
return .homepage
case "page":
return .page
default:
return .unknown
}
}
}