-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.swift
executable file
·178 lines (153 loc) · 5.19 KB
/
main.swift
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env swift
import Foundation
// MARK: All structs
struct Config {
static let key: String = ""
}
struct Tasks: Codable {
let tasks: [Task]
}
struct Projects: Codable {
let projects: [Task]
}
struct Task: Codable {
let id: Int?
let name, code: String?
enum CodingKeys: String, CodingKey {
case id, name, code
}
}
struct CommandLineArgs {
let command: String
let parameters: [String]
}
func getCurrentDateString() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = dateFormatter.string(from: Date())
return dateString
}
func parseCommandLine() -> CommandLineArgs {
let arguments = CommandLine.arguments
guard arguments.count >= 2 else {
return CommandLineArgs(command: "--help", parameters: [])
}
if arguments[1].hasPrefix("-") {
return CommandLineArgs(command: arguments[1], parameters: Array(arguments.dropFirst(2)))
} else {
return CommandLineArgs(command: arguments[1], parameters: Array(arguments.dropFirst(2)))
}
}
func request<T: Decodable>(configuration: URLRequest) async throws -> Result<T, Error> {
do {
let session = URLSession.shared
let (data, _) = try await session.data(for: configuration)
return try .success(JSONDecoder().decode(T.self, from: data))
} catch {
return .failure(error)
}
}
func prepare(url: String,
method: String = "GET",
data: [String: Any] = [:],
key: String = Config.key) -> URLRequest?
{
guard let url = URL(string: url) else {
return nil
}
var request = URLRequest(url: url)
let loginString = "\(key):\(key)"
guard let loginData = loginString.data(using: .utf8) else {
print("Invalid username or password")
return nil
}
let credentials = loginData.base64EncodedString()
request.setValue("Basic \(credentials)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = method
if !data.isEmpty {
do {
let jsonData = try JSONSerialization.data(withJSONObject: data)
request.httpBody = jsonData
} catch {}
}
return request
}
func handleCommand(command: String, parameters: [String]) async {
switch command {
case "-h", "--help":
printUsage()
case "projects":
if let urlRequest = prepare(url: "https://app.paymoapp.com/api/projects") {
do {
let result: Result<Projects, Error> = try await request(configuration: urlRequest)
switch result {
case let .success(response):
for value in response.projects {
print(value.id ?? 0, " -- ", value.name ?? "")
}
case .failure:
break
}
} catch {}
}
case "tasks":
if let urlRequest = prepare(url: "https://app.paymoapp.com/api/tasks") {
do {
let result: Result<Tasks, Error> = try await request(configuration: urlRequest)
switch result {
case let .success(response):
for value in response.tasks {
print(value.id ?? 0, " -- ", value.name ?? "")
}
case .failure:
break
}
} catch {}
}
case "add":
guard parameters.count >= 4 else {
print("Insufficient parameters provided.")
return
}
var components = URLComponents(string: "https://app.paymoapp.com/api/entries")!
var date: String = getCurrentDateString()
if parameters[1] != "today" {
date = parameters[1]
}
let queryItems: [URLQueryItem] = [
URLQueryItem(name: "task_id", value: parameters[0]),
URLQueryItem(name: "date", value: date),
URLQueryItem(name: "duration", value: parameters[2]),
URLQueryItem(name: "description", value: parameters[3]),
]
components.queryItems = queryItems
if let urlRequest = prepare(url: components.string ?? "", method: "POST") {
do {
let session = URLSession.shared
let (data, _) = try await session.data(for: urlRequest)
print(String(data: data, encoding: .utf8) ?? "")
} catch {
print(error)
}
}
default:
print("Unknown command: \(command)", parameters)
}
}
func printUsage() {
print("Usage: ./main.swift <command> <parameters>")
print("Available commands:")
print()
print("app tasks - show all tasks")
print("app projects - show all projects")
print("app add - add time to paymo with any format")
print("set task id, date (also you can set today), duration, comment")
print("./main.swift add 25548372 \"2024-04-25\" 32400 \"hello world\"")
}
func main() async {
let commandLineArgs = parseCommandLine()
await handleCommand(command: commandLineArgs.command,
parameters: commandLineArgs.parameters)
}
await main()