Skip to content

Commit 1fccb08

Browse files
Fixed error when cropping images
Fixed notifications not being sent if the image of the new website state was too big for telegram to handle as an image. Now images too large will be sent as files instead
1 parent 44c1a9e commit 1fccb08

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

urlwatcher/Sources/urlwatcher/Functions.swift

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,74 @@ func cropScreenshot(path: String, output: String? = nil, x: Int, y: Int, width:
5858

5959
return try bash("convert", arguments: [
6060
path,
61-
"-crop", "\"\(width)x\(height)+\(x)+\(y)\"",
61+
"-crop", "\(width)x\(height)+\(x)+\(y)",
6262
output ?? path
6363
])
6464
}
6565

66+
func imageSize(path: String) throws -> (width: Int, height: Int) {
67+
let pipe = Pipe()
68+
// Sample Output:
69+
// PNG image data, 2938 x 16300, 8-bit/color RGBA, non-interlaced
70+
try bash("file", arguments: [path, "-b"], standardOutput: pipe)
71+
72+
let outputData = pipe.fileHandleForReading.readDataToEndOfFile()
73+
guard let outputString = String(data: outputData, encoding: .utf8) else {
74+
return (0, 0)
75+
}
76+
77+
let components = outputString.components(separatedBy: ", ")
78+
guard components.count >= 2 else {
79+
return (0, 0)
80+
}
81+
82+
let sizeComponents = components[1].components(separatedBy: "x").map({ $0.trimmingCharacters(in: .whitespaces) })
83+
guard sizeComponents.count == 2 else {
84+
return (0, 0)
85+
}
86+
guard let width = Int(sizeComponents[0]), let height = Int(sizeComponents[1]) else {
87+
return (0, 0)
88+
}
89+
90+
return (width, height)
91+
}
92+
6693
func sendTelegramMessage(_ message: String, to chatID: Int, image: String? = nil, file: String? = nil) throws {
6794
var arguments: [String] = [
6895
"-t", telegramBotToken!,
6996
"-c", "\(chatID)"
7097
]
7198
if let image = image {
99+
// https://core.telegram.org/bots/api#sendphoto
100+
// > The photo must be at most 10 MB in size.
101+
// > The photo's width and height must not exceed 10000 in total.
102+
// > Width and height ratio must be at most 20.
103+
// If any of these requirements are not met, send the image as a file
104+
let attr = try fileManager.attributesOfItem(atPath: image)
105+
// File size in MB
106+
var fileSize = attr[.size] as? Float ?? 0
107+
fileSize /= 1024 * 1024
108+
// Make sure the file is under the 10 MB limit (plus 0.1 MB extra)
109+
guard fileSize < 9.9 else {
110+
try sendTelegramMessage(message, to: chatID, file: image)
111+
return
112+
}
113+
114+
let imSize = try imageSize(path: image)
115+
guard imSize.width <= 10_000 && imSize.height <= 10_000 else {
116+
try sendTelegramMessage(message, to: chatID, file: image)
117+
return
118+
}
119+
120+
if imSize.width != imSize.height {
121+
// Width and height ratio = max / min
122+
guard max(imSize.width, imSize.height) / min(imSize.width, imSize.height) <= 20 else {
123+
try sendTelegramMessage(message, to: chatID, file: image)
124+
return
125+
}
126+
}
127+
128+
// If all requirements are met, we can send the image
72129
arguments.append(contentsOf: ["-i", image])
73130
}
74131
if let file = file {

0 commit comments

Comments
 (0)