-
Notifications
You must be signed in to change notification settings - Fork 142
/
wwdc2014.swift
executable file
·204 lines (170 loc) · 7.79 KB
/
wwdc2014.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/swift -swift-version 4
/*
Author: Olivier HO-A-CHUCK
Date: June 17th 2016
About this script:
WWDC 2016 is ending today and even if there are some great tools out there (https://github.com/insidegui/WWDC) that allow to see and download video sessions,
I Still need to get my video doggy bag to fly back home. And Moscone alsways provide with great bandwidth.
So as I had never really started to code in Swift I decided to start here (I know it's late - but I'm no more a developer) and copy/pasted some internet peace
of codes to get a Swift Script that bulk download all sessions.
You may have understand my usual disclamer : "I'm a Marketing guy" so don't blame my messy (Swift beginer) code.
Please feel free to make this script better if you feel like so. There is plenty to do.
License: Do what you want with it. But notice that this script comes with no warranty and will not be maintained.
Usage: wwdc2016.swift
Default behavior: without any options the script will download all available hd videos. And will re-take non fully downloaded ones.
Please use --help option to get currently available options
TODO:
- basically all previous script option (previuous years, checks, cleaner code, etc.)
*/
import Cocoa
enum VideoQuality: String {
case HD = "hd"
case SD = "sd"
}
class wwdcVideosController {
class func getHDorSDdURLsFromStringAndFormat(_ testStr: String, format: VideoQuality) -> (String) {
let pat = "\\b.*(http.*_" + format.rawValue + "[_.].*\\.{0,1}mov)\\b"
let regex = try! NSRegularExpression(pattern: pat, options: [])
let matches = regex.matches(in: testStr, options: [], range: NSRange(location: 0, length: testStr.count))
var videoURL = ""
if !matches.isEmpty {
let range = matches[0].range(at: 1)
let r = testStr.index(testStr.startIndex, offsetBy: range.location) ..<
testStr.index(testStr.startIndex, offsetBy: range.location+range.length)
videoURL = String(testStr[r])
}
return videoURL
}
class func getPDFResourceURLFromString(_ testStr: String) -> (String) {
let pat = "\\b.*(http.*\\.pdf)\\b"
let regex = try! NSRegularExpression(pattern: pat, options: [])
let matches = regex.matches(in: testStr, options: [], range: NSRange(location: 0, length: testStr.count))
var pdfResourceURL = ""
if !matches.isEmpty {
let range = matches[0].range(at: 1)
let r = testStr.index(testStr.startIndex, offsetBy: range.location) ..<
testStr.index(testStr.startIndex, offsetBy: range.location+range.length)
pdfResourceURL = String(testStr[r])
}
return pdfResourceURL
}
class func getStringContentFromURL(_ wwdcUrl: String) -> (String) {
guard let url = URL(string: wwdcUrl) else {
return ""
}
var result = ""
do {
let data = try Data(contentsOf: url)
result = String(data: data, encoding: .ascii)!
} catch let error {
print("URL Session Task Failed: %@", error.localizedDescription)
}
return result
}
class func getSessionsListFromString(_ htmlSessionList: String) -> Array<String> {
let pat = "/videos/play/wwdc2014/([0-9]*)/\">"
let regex = try! NSRegularExpression(pattern: pat, options: [])
let matches = regex.matches(in: htmlSessionList, options: [], range: NSRange(location: 0, length: htmlSessionList.count))
var sessionsListArray = [String]()
for match in matches {
for n in 0..<match.numberOfRanges {
let range = match.range(at: n)
let r = htmlSessionList.index(htmlSessionList.startIndex, offsetBy: range.location) ..<
htmlSessionList.index(htmlSessionList.startIndex, offsetBy: range.location+range.length)
switch n {
case 1:
//print(htmlSessionList.substringWithRange(r))
sessionsListArray.append(String(htmlSessionList[r]))
default: break
}
}
}
return sessionsListArray
}
class func system(_ command: String) {
var args = command.components(separatedBy: " ")
let path = args.first
args.remove(at: 0)
let task = Process()
task.launchPath = path
task.arguments = args
task.launch()
task.waitUntilExit()
}
class func downloadFileFromURLString(_ urlString: String, forSession session: String = "???") {
let fileName = URL(fileURLWithPath: urlString).lastPathComponent
let fileManager = FileManager.default
if fileManager.fileExists(atPath: "./" + fileName) {
print("\(fileName): already exists, nothing to do!")
} else {
print("[Session \(session)] Getting \(fileName) (\(urlString)):")
let cmd = "/usr/bin/curl \(urlString) -o ./\(fileName).download"
system(cmd)
print("moving ./\(fileName).download to ./\(fileName)")
do {
try fileManager.moveItem(atPath: "./\(fileName).download", toPath: "./\(fileName)")
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
print("Done!")
}
}
}
/* Managing options */
var format = VideoQuality.HD
var shouldDownloadPDFResource = false
var shouldDownloadVideoResource = true
for argument in CommandLine.arguments {
switch argument {
case "-h", "--help":
print("wwdc2016 - a simple swifty video sessions bulk download.\nJust Get'em all!")
print("usage: wwdc2006.swift [--hd] [--sd] [--pdf] [--pdf-only] [--help]\n")
exit(0)
case "--hd":
print("Downloading HD videos in current directory")
format = .HD
case "--sd":
print("Downloading SD videos in current directory")
format = .SD
case "--pdf":
shouldDownloadPDFResource = true
case "--pdf-only":
shouldDownloadPDFResource = true
shouldDownloadVideoResource = false
default:
break
}
}
func sortFunc(value1: String, value2: String) -> Bool {
let filteredVal1 = String(value1[..<value1.index(value1.startIndex, offsetBy:3)])
let filteredVal2 = String(value2[..<value2.index(value2.startIndex, offsetBy:3)])
return filteredVal1 < filteredVal2;
}
/* Retreiving list of all video session */
let htmlSessionListString = wwdcVideosController.getStringContentFromURL("https://developer.apple.com/videos/wwdc2014/")
print("Let me ask Apple about currently available sessions. This can take some time (15 to 20 sec.) ...")
var sessionsListArray = wwdcVideosController.getSessionsListFromString(htmlSessionListString)
sessionsListArray.sort(by: sortFunc)
/* getting individual videos */
for (_, value) in sessionsListArray.enumerated() {
let baseURL = "https://developer.apple.com/videos/play/wwdc2014/" + value + "/"
let htmlText = wwdcVideosController.getStringContentFromURL(baseURL)
if shouldDownloadVideoResource {
let videoURLString = wwdcVideosController.getHDorSDdURLsFromStringAndFormat(htmlText, format: format)
if videoURLString.isEmpty {
print("[Session \(baseURL)] NO VIDEO YET AVAILABLE !!!")
exit(0)
} else {
wwdcVideosController.downloadFileFromURLString(videoURLString, forSession: value)
}
}
if shouldDownloadPDFResource {
let pdfResourceURLString = wwdcVideosController.getPDFResourceURLFromString(htmlText)
if pdfResourceURLString.isEmpty {
print("[Session \(value)] PDF RESOURCE NOT (YET?) AVAILABLE !!!")
} else {
wwdcVideosController.downloadFileFromURLString(pdfResourceURLString, forSession: value)
}
}
}