added login functionality

This commit is contained in:
Jens Timmerman 2020-10-04 18:23:39 +02:00
parent 4c5f0864bb
commit 9ad5e657d4
3 changed files with 120 additions and 97 deletions

View File

@ -9,12 +9,39 @@ import SwiftUI
import AVKit
import AVFoundation
import Combine
import TVUIKit
struct ContentView: View {
@ViewBuilder
var body: some View {
let vrtNu = VRTNu()
if vrtNu.loggedIN() {
VRTNuView(vrtNu: vrtNu)
}else{
LoginView(vrtNu: vrtNu)
}
}
}
struct LoginView: View{
var vrtNu: VRTNu
@State private var password: String = ""
@State private var username: String = ""
var body: some View {
TextField("VRTNu username", text: $username)
SecureField("VRTNu password", text: $password)
Button("Inloggen", action: {
vrtNu.login(username: username, password: password)
})
}
}
struct VRTNuView: View{
var vrtNu: VRTNu
var body: some View {
NavigationView(){
List(VRTNu().shows, id: \.self){ show in
List(vrtNu.getShows(), id: \.self){ show in
NavigationLink(destination: ShowView(show: show)){
HStack{
AsyncImage(url: show.imageURL,placeholder: {
@ -28,7 +55,6 @@ struct ContentView: View {
}
}
}
struct ShowView: View {
var show: Show
var body: some View {
@ -102,7 +128,7 @@ struct VideoView: View {
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
SeasonView(season: VRTNu().shows[0].getSeasons()[0])
SeasonView(season: VRTNu().getShows()[0].getSeasons()[0])
//ContentView()
}
}

View File

@ -7,8 +7,10 @@
import Foundation
let just = JustOf<HTTP>()
struct Episode: Hashable, Comparable{
static func < (lhs: Episode, rhs: Episode) -> Bool {
return lhs.name < rhs.name
}
@ -19,10 +21,11 @@ struct Episode: Hashable, Comparable{
lazy var video: Video = {
let just = JustOf<HTTP>()
let token = self.season.show.vrtNu.getToken()
//`requests.get('https://www.vrt.be/vrtnu/a-z/%s/%s/%s.mssecurevideo.json' % (show, season, episode)).json()`
let url = "https://www.vrt.be/vrtnu/a-z/" + season.show.showName + "/" + season.seasonName + "/" + name + ".mssecurevideo.json"
print(url)
let msecjson = just.get(url).json!
let mssecdict = msecjson as! NSDictionary
print(msecjson)
@ -30,74 +33,9 @@ struct Episode: Hashable, Comparable{
let videoid = intmssecdict.value(forKey: "videoid") as! String
let clientid = intmssecdict.value(forKey: "clientid") as! String
/*
get login token
```
session = requests.session()
username = urllib.parse.quote('<vrtnu username here>', safe='')
password = urllib.parse.quote('<vrtnu password here>', safe='')
auth_data = {
'APIKey': '3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy',
'targetEnv': 'jssdk',
'loginID': username,
'password': password,
'authMode': 'cookie',
}
auth_info = requests.post('https://accounts.eu1.gigya.com/accounts.login', data=auth_data).json()
# When requesting a token, no actual token is returned, but the
# necessary cookies are set.
session.post('https://token.vrt.be',
headers={
'Content-Type': 'application/json',
'Referer': 'https://www.vrt.be/vrtnu/',
},
data=json.dumps({
'uid': auth_info['UID'],
'uidsig': auth_info['UIDSignature'],
'ts': auth_info['signatureTimestamp'],
'email': auth_info['profile']['email'],
}).encode('utf-8'))
token = session.post('https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens', headers={'Content-Type': 'application/json'}, data=b'').json()['vrtPlayerToken']
```*/
let username = "testuser"
let password = "testpw"
let auth_data = [
"ApiKey": "3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy",
"targetEnv": "jssdk",
"loginID": username,
"password": password,
"authMode": "cookie",
]
let auth_json = just.post("https://accounts.eu1.gigya.com/accounts.login", data: auth_data).json!
let auth_info = auth_json as! NSDictionary
print(auth_info)
// no token is returnd but necessary cookies are set
just.post("https://token.vrt.be", json:[
"uid": auth_info.value(forKey: "UID"),
"uidsig": auth_info.value(forKey: "UIDSignature"),
"ts": auth_info.value(forKey: "signatureTimestamp"),
//"email": auth_info.value(forKey: "profile"['email'],
"email": username
],
headers: [
"Conetnt-Type": "application/json",
"Referer": "https://www.vrt.be/vrtnu/",
]
)
///token = session.post('https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens', headers={'Content-Type': 'application/json'}, data=b'').json()['vrtPlayerToken']
let tokenjson = just.post("https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens", headers:["Content-Type": "application/json"]).json!
let tokendict = tokenjson as! NSDictionary
let token = tokendict.value(forKey: "vrtPlayerToken") as! String
print(token)
var mediaurl = "https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/videos/" + videoid
mediaurl = mediaurl + "?vrtPlayerToken="
mediaurl = mediaurl + token + "&client="
mediaurl = mediaurl + self.season.show.vrtNu.getToken() + "&client="
mediaurl = mediaurl + clientid + "@PROD"
print(mediaurl)
let videojson = just.get(mediaurl).json!
@ -207,6 +145,7 @@ struct Show: Hashable, Comparable{
let showURL: URL
let title: String
let imageURL: URL
let vrtNu: VRTNu
lazy var seasons: [Season] = {
//`re.findall('value="#parsys_container_banner_%s_(.*)">' % show, requests.get('https://www.vrt.be/vrtnu/a-z/%s/' % show).text)`
@ -229,12 +168,13 @@ struct Show: Hashable, Comparable{
}()
init(showName: String, title: String, imageURL: URL) {
init(vrtNu: VRTNu, showName: String, title: String, imageURL: URL) {
self.showURL = URL(string: "https://www.vrt.be/vrtnu/a-z/" + showName)!
self.showName = showName
self.title = title
//TODO: get image urls for shows
self.imageURL = imageURL
self.vrtNu = vrtNu
}
@ -256,11 +196,10 @@ extension NSTextCheckingResult {
}
}
struct VRTNu {
let shows: [Show]
struct VRTNu: Hashable {
lazy var loggedin: Bool = loggedIN()
init() {
print("init")
lazy var shows: [Show] = {
let regexPattern = "a href=\"/vrtnu/a-z/(.*).relevant"
let imageregexPattern = "data-responsive-image=\".*(jpg|png)"
let data = Just.get("https://www.vrt.be/vrtnu/a-z/").text!
@ -276,23 +215,81 @@ struct VRTNu {
for i in 0 ..< output.count{
show = output[i].replacingOccurrences(of: ".relevant", with: "").replacingOccurrences(of: "a href=\"/vrtnu/a-z/", with: "")
image = imageoutput[i].replacingOccurrences(of: "https:", with: "").replacingOccurrences(of: "http:", with: "").replacingOccurrences(of: "data-responsive-image=\"", with: "https:")
myshows.append(Show(showName: show, title: show, imageURL: URL(string: image)!))
myshows.append(Show(vrtNu: self, showName: show, title: show, imageURL: URL(string: image)!))
}
myshows.sort()
self.shows = myshows
//print(self.shows)
return myshows
}()
func getToken() -> String {
///token = session.post('https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens', headers={'Content-Type': 'application/json'}, data=b'').json()['vrtPlayerToken']
let tokenjson = just.post("https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens", headers:["Content-Type": "application/json"]).json!
let tokendict = tokenjson as! NSDictionary
let token = tokendict.value(forKey: "vrtPlayerToken") as! String
print(token)
return token
}
func loggedIN() -> Bool{
//check if current token is valid
let testtoken = self.getToken()
let testurl = URL(string: "https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/videos/pbs-pub-414bb095-6c5c-4c0e-b998-649fe03f07d7$vid-7ed5d7e0-e284-4df0-a76d-ff497e667d04?vrtPlayerToken=" + testtoken + "&client=vrtvideo@PROD")!
let videojson = just.get(testurl).json! as! NSDictionary
if videojson.object(forKey: "code") != nil{
if videojson.value(forKey: "code") as! String == "AUTHENTICATION_REQUIRED"
{
print("not authenticated")
return false
}
print("maybe vrt authentication logic changed? please report this")
}
return true
/*self.shows = [
Show(showUrl: URL(string: "a-z/het-peulengaleis/")!, title: "Het Peulengaleis"),
Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis2/")!, title: "Het Peulengaleis 2"),
Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis3/")!, title: "Het Peulengaleis 3"),
Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis4/")!, title: "Het Peulengaleis 4"),
// Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis5/")!, title: "Het Peulengaleis 5"),
//Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis6/")!, title: "Het Peulengaleis 6"),
//Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis7/")!, title: "Het Peulengaleis 7"),
//Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis8/")!, title: "Het Peulengaleis 8"),
]*/
}
func login(username: String, password:String) -> Bool {
let auth_data = [
"ApiKey": "3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy",
"targetEnv": "jssdk",
"loginID": username,
"password": password,
"authMode": "cookie",
]
let auth_json = just.post("https://accounts.eu1.gigya.com/accounts.login", data: auth_data).json!
let auth_info = auth_json as! NSDictionary
print(auth_info)
if auth_info.object(forKey: "statusCode") != nil{
if auth_info.value(forKey: "statusCode") as! Int == 403
{
print("not authenticated")
return false
}
}
// no token is returnd but necessary cookies are set
just.post("https://token.vrt.be", json:[
"uid": auth_info.value(forKey: "UID"),
"uidsig": auth_info.value(forKey: "UIDSignature"),
"ts": auth_info.value(forKey: "signatureTimestamp"),
//"email": auth_info.value(forKey: "profile"['email'],
"email": username
],
headers: [
"Conetnt-Type": "application/json",
"Referer": "https://www.vrt.be/vrtnu/",
]
)
return loggedIN()
}
init() {
print("init")
}
func getShows() -> [Show]{
var mutableself = self
return mutableself.shows
}
}

View File

@ -18,13 +18,13 @@ struct vrtnuApp: App {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.playback, mode: .moviePlayback)
}
catch {
print("Setting category to AVAudioSessionCategoryPlayback failed.")
}
//let audioSession = AVAudioSession.sharedInstance()
//do {
// try audioSession.setCategory(.playback, mode: .moviePlayback)
//}
//catch {
// print("Setting category to AVAudioSessionCategoryPlayback failed.")
//}
return true
}
}