Skip to content

Commit bbaf3ec

Browse files
committed
Add image support
1 parent 19222f7 commit bbaf3ec

8 files changed

+80
-19
lines changed

Patch.xcodeproj/project.pbxproj

+2
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,13 @@
349349
"${PODS_ROOT}/Target Support Files/Pods-Patch/Pods-Patch-frameworks.sh",
350350
"${BUILT_PRODUCTS_DIR}/BlueSocket/Socket.framework",
351351
"${BUILT_PRODUCTS_DIR}/ReactiveSwift/ReactiveSwift.framework",
352+
"${BUILT_PRODUCTS_DIR}/Swime/Swime.framework",
352353
);
353354
name = "[CP] Embed Pods Frameworks";
354355
outputPaths = (
355356
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Socket.framework",
356357
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactiveSwift.framework",
358+
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Swime.framework",
357359
);
358360
runOnlyForDeploymentPostprocessing = 0;
359361
shellPath = /bin/sh;

Patch/GopherPage.swift

+32-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import Foundation
1010
import ReactiveSwift
11+
import Swime
1112

1213
class GopherPage {
1314
var request: GopherRequest?
@@ -29,23 +30,32 @@ class GopherPage {
2930
}
3031

3132
var contentHtml: String
33+
var contentType: String
3234

3335
if (self.status.value == GopherStatus.Failed) {
3436
print("Showing error...")
3537
contentHtml = "Could not load \(self.request!.url)"
38+
contentType = "error"
39+
}
40+
else if (self.response?.isBinary)! {
41+
print("Showing binary...")
42+
contentHtml = parseBinary()
43+
contentType = "image"
3644
}
3745
else if (self.response?.isDirectory)! {
3846
print("Showing directory...")
3947
contentHtml = parseDirectory().map({
4048
$0.html
4149
}).joined()
50+
contentType = "directory"
4251
}
4352
else {
4453
print("Showing file...")
45-
contentHtml = parseRaw()
54+
contentHtml = parsePlain()
55+
contentType = "text"
4656
}
4757

48-
return "<html><head><style>" + styles + "</style></head><body>" + contentHtml + "</body></html>"
58+
return "<html><head><style>" + styles + "</style></head><body class=\"type-" + contentType + "\">" + contentHtml + "</body></html>"
4959
}
5060

5161
let lineSeparator = String(bytes: [13, 10], encoding: String.Encoding.ascii)!
@@ -74,8 +84,25 @@ class GopherPage {
7484
}
7585
}
7686

77-
private func parseRaw() -> String {
78-
guard let body = self.response?.body else {
87+
private func parseBinary() -> String {
88+
guard let data = self.response?.data else {
89+
return ""
90+
}
91+
let mimeType = Swime.mimeType(data: data)
92+
let encodedData = data.base64EncodedString()
93+
switch mimeType?.type {
94+
case .gif?, .jpg?, .png?, .webp?:
95+
guard let mime = mimeType?.mime else {
96+
return ""
97+
}
98+
return "<img src=\"data:" + mime + ";base64," + encodedData + "\">"
99+
default:
100+
return ""
101+
}
102+
}
103+
104+
private func parsePlain() -> String {
105+
guard let body = self.response?.text else {
79106
return ""
80107
}
81108

@@ -87,7 +114,7 @@ class GopherPage {
87114
}
88115

89116
private func parseDirectory() -> [GopherResponsePart] {
90-
guard let parts = self.response?.body.components(separatedBy: lineSeparator) else {
117+
guard let parts = self.response?.text?.components(separatedBy: lineSeparator) else {
91118
return []
92119
}
93120

Patch/GopherPageStyle-Dark.css

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ body {
33
color: white;
44
font-family: monospace;
55
margin: 0 auto;
6-
padding: 1em;
7-
max-width: 40em;
86
white-space: pre;
97
}
8+
9+
body .type-text, .type-directory {
10+
padding: 1em;
11+
}
12+
13+
img {
14+
max-width: 100%;
15+
max-height: 100%;
16+
}

Patch/GopherPageStyle-Light.css

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
body {
22
font-family: monospace;
33
margin: 0 auto;
4-
padding: 1em;
5-
max-width: 40em;
64
white-space: pre;
75
}
6+
7+
body .type-text, .type-directory {
8+
padding: 1em;
9+
}
10+
11+
img {
12+
max-width: 100%;
13+
max-height: 100%;
14+
}

Patch/GopherResponse.swift

+18-8
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@ import Foundation
1010

1111
class GopherResponse {
1212

13-
let body: String
13+
let text: String?
14+
let data: Data?
1415
var error: GopherResponseError?
1516
let lineSeparator = String(bytes: [13, 10], encoding: String.Encoding.ascii)!
1617

18+
var isText: Bool { text != nil }
19+
var isBinary: Bool { data != nil }
20+
1721
var isDirectory: Bool {
18-
if self.body.contains("\n\n") {
22+
guard let text = text else {
23+
return false
24+
}
25+
26+
if text.contains("\n\n") {
1927
return false
2028
}
2129

22-
let parts = self.body.components(separatedBy: lineSeparator)
30+
let parts = text.components(separatedBy: lineSeparator)
2331

2432
for part in parts.dropLast() {
2533
// if there's an empty line, this cannot be a directory listing
@@ -31,13 +39,15 @@ class GopherResponse {
3139
return true
3240
}
3341

34-
init?(data: Data) {
35-
guard let body = String(data: data, encoding: .utf8) else {
36-
self.error = .Encoding
37-
return nil
42+
init(data: Data) {
43+
guard let text = String(data: data, encoding: .utf8) else {
44+
self.data = data
45+
self.text = nil
46+
return
3847
}
3948

40-
self.body = body
49+
self.text = text
50+
self.data = nil
4151
}
4252

4353
}

Patch/GopherResponsePart.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ class GopherResponsePart {
1515
let url: URL?
1616

1717
var html: String {
18-
if type == "0" || type == "1" {
18+
if type == "0" || type == "1" { // file or directory
1919
return "<p><a href=\"\(url!.absoluteString)\">" + content + "</a></p>"
2020
}
21+
else if type == "g" || type == "I" { // GIF or image
22+
return "<p><a href=\"\(url!.absoluteString)\">Image: " + content + "</a></p>"
23+
}
2124

2225
return "<p>" + content + "</p>"
2326
}

Podfile

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ target 'Patch' do
99

1010
pod 'BlueSocket', '~> 1.0'
1111
pod 'ReactiveSwift', '~> 7.0'
12+
pod 'Swime', '~> 3.0'
1213

1314
# Pods for Patch
1415

Podfile.lock

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
PODS:
22
- BlueSocket (1.0.52)
33
- ReactiveSwift (7.0.0)
4+
- Swime (3.0.6)
45

56
DEPENDENCIES:
67
- BlueSocket (~> 1.0)
78
- ReactiveSwift (~> 7.0)
9+
- Swime (~> 3.0)
810

911
SPEC REPOS:
1012
trunk:
1113
- BlueSocket
1214
- ReactiveSwift
15+
- Swime
1316

1417
SPEC CHECKSUMS:
1518
BlueSocket: 1acd943acb07b55905291d608649fcfbf8cbd57d
1619
ReactiveSwift: 48c4b9d3b497e8dd20b10300bb1a28ff93550f13
20+
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
1721

18-
PODFILE CHECKSUM: e96beb2bc2b2e664d7e5156df65996a21a326d36
22+
PODFILE CHECKSUM: ab1ebfbac945a0cdfbfd9e467b46d13708eb018e
1923

2024
COCOAPODS: 1.11.3

0 commit comments

Comments
 (0)