diff --git a/Assets/LiquidMenu StatusIcon.afdesign b/Assets/LiquidMenu StatusIcon.afdesign new file mode 100644 index 0000000..3671ba1 Binary files /dev/null and b/Assets/LiquidMenu StatusIcon.afdesign differ diff --git a/Assets/TeamLiquidLogo.svg b/Assets/TeamLiquidLogo.svg new file mode 100644 index 0000000..3abd7dc --- /dev/null +++ b/Assets/TeamLiquidLogo.svg @@ -0,0 +1,913 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Team_liquid_logo_2017_light_blue.png b/Assets/Team_liquid_logo_2017_light_blue.png new file mode 100644 index 0000000..bf54d24 Binary files /dev/null and b/Assets/Team_liquid_logo_2017_light_blue.png differ diff --git a/Assets/statusBarIcon.png b/Assets/statusBarIcon.png new file mode 100644 index 0000000..25dac6d Binary files /dev/null and b/Assets/statusBarIcon.png differ diff --git a/Assets/statusBarIcon@2x.png b/Assets/statusBarIcon@2x.png new file mode 100644 index 0000000..abee0e7 Binary files /dev/null and b/Assets/statusBarIcon@2x.png differ diff --git a/LiquipediaMenu.xcodeproj/project.pbxproj b/LiquipediaMenu.xcodeproj/project.pbxproj index 0f6b6fe..a78c56b 100644 --- a/LiquipediaMenu.xcodeproj/project.pbxproj +++ b/LiquipediaMenu.xcodeproj/project.pbxproj @@ -88,6 +88,24 @@ path = LiquipediaMenuTests; sourceTree = ""; }; + 3F933FF721E3958000C0EEF3 /* Match */ = { + isa = PBXGroup; + children = ( + 3FF66CDE21DE80BA005A93D0 /* MatchMenuItem.swift */, + 3F563E06216E640D00AA3C06 /* MatchView.swift */, + 3F49E945216B86150047B0FE /* Match.swift */, + ); + path = Match; + sourceTree = ""; + }; + 3F933FF821E395AB00C0EEF3 /* API */ = { + isa = PBXGroup; + children = ( + 3F49E949216BE87B0047B0FE /* MatchesAPI.swift */, + ); + path = API; + sourceTree = ""; + }; 3FB6BB3B216B8594000BF5AA = { isa = PBXGroup; children = ( @@ -111,12 +129,11 @@ 3FB6BB46216B8594000BF5AA /* LiquipediaMenu */ = { isa = PBXGroup; children = ( + 3F933FF821E395AB00C0EEF3 /* API */, + 3F933FF721E3958000C0EEF3 /* Match */, 3FB6BB47216B8594000BF5AA /* AppDelegate.swift */, 3F49E947216B862B0047B0FE /* StatusBarController.swift */, - 3F49E949216BE87B0047B0FE /* LiquipediaMatchesAPI.swift */, - 3F49E945216B86150047B0FE /* Match.swift */, - 3FF66CDE21DE80BA005A93D0 /* MatchMenuItem.swift */, - 3F563E06216E640D00AA3C06 /* MatchView.swift */, + 3FB6BB49216B8595000BF5AA /* Assets.xcassets */, 3FB6BB4B216B8595000BF5AA /* MainMenu.xib */, 3FB6BB4E216B8595000BF5AA /* Info.plist */, diff --git a/LiquipediaMenu/API/MatchesAPI.swift b/LiquipediaMenu/API/MatchesAPI.swift new file mode 100644 index 0000000..685c7a3 --- /dev/null +++ b/LiquipediaMenu/API/MatchesAPI.swift @@ -0,0 +1,79 @@ +// +// MatchesAPI.swift +// LiquipediaMenu +// +// Created by Felix Förtsch on 08.10.18. +// Copyright © 2018 Felix Förtsch. All rights reserved. +// + +import Foundation +import SwiftSoup + +class MatchesAPI { + + func fetchMatches(for game: String) -> [Match]? { + let games = ["dota2", "starcraft", "starcraft2", "heroes", "counterstrike", "rocketleague", "rainbowsix", "overwatch"] + if !games.contains(game) { return nil } + if let data = fetchData(for: game) { + return extractMatches(from: data) + } + return nil + } + + private func fetchData(for game: String) -> String? { + let url = constructURL(for: game) + if let data = try? String(contentsOf: url) { + return data + } + return nil + } + + private func extractMatches(from data: String) -> [Match]? { + var tmp = data.replacingOccurrences(of: "\\n", with: "") + tmp = tmp.replacingOccurrences(of: "\\", with: "") + + do { + let doc: Document = try SwiftSoup.parse(tmp) + let ongoing: Element = try doc.getElementById("infobox_matches")! + let matchString: Elements = try ongoing.getElementsByTag("table") + + var matches = [Match]() + for match in matchString { + + let score = try match.getElementsByClass("versus").text() + let split = score.split(separator: ":") + let leftscore = String(split[0]) + let rightscore = String(split[1]) + + let newMatch = Match() + newMatch.ongoing = true + // TODO: Handle what happens when there is no twitch page. Currently it just opens Twicht main page. + newMatch.streamLink = try "https://twitch.tv/" + match.getElementsByClass("timer-object").attr("data-stream-twitch") + newMatch.league = try match.select("tr > td > div > div > a").text() + newMatch.team1name = try match.getElementsByClass("team-left").text() + newMatch.team1score = leftscore + newMatch.team2name = try match.getElementsByClass("team-right").text() + newMatch.team2score = rightscore + matches.append(newMatch) + } + if matches.count == 0 { + return nil + } + return matches + } catch Exception.Error(_, _) { + print("") + return nil + } catch { + print("") + return nil + } + } + + private func constructURL(for game: String) -> URL { + let baseURL = "https://liquipedia.net/" + let query = "/api.php?action=parse&page=Liquipedia:Upcoming_and_ongoing_matches&format=json&prop=text" + return URL(string: baseURL + game + query)! + } +} + + diff --git a/LiquipediaMenu/Base.lproj/MainMenu.xib b/LiquipediaMenu/Base.lproj/MainMenu.xib index 4d20b4c..5ff4dc9 100644 --- a/LiquipediaMenu/Base.lproj/MainMenu.xib +++ b/LiquipediaMenu/Base.lproj/MainMenu.xib @@ -15,7 +15,11 @@ - + + + + + @@ -774,7 +778,7 @@ - + diff --git a/LiquipediaMenu/Match.swift b/LiquipediaMenu/Match/Match.swift similarity index 100% rename from LiquipediaMenu/Match.swift rename to LiquipediaMenu/Match/Match.swift diff --git a/LiquipediaMenu/MatchMenuItem.swift b/LiquipediaMenu/Match/MatchMenuItem.swift similarity index 78% rename from LiquipediaMenu/MatchMenuItem.swift rename to LiquipediaMenu/Match/MatchMenuItem.swift index d2efc02..41402d2 100644 --- a/LiquipediaMenu/MatchMenuItem.swift +++ b/LiquipediaMenu/Match/MatchMenuItem.swift @@ -9,17 +9,17 @@ import Cocoa class MatchMenuItem: NSMenuItem { + + var streamLink = "" init(for match: Match, action selector: Selector?) { - // TODO: Add custom view to MatchMenuItem -// let customView = MatchView() -// customView.updateView(for: match) - super.init(title: match.league + match.team1name + match.team1score + ":" + match.team2score + match.team2name, action: selector, keyEquivalent: "") self.streamLink = match.streamLink -// self.view = customView - + } + + func setView(to customView: MatchView) { + self.view = customView } // TODO: find out what that means diff --git a/LiquipediaMenu/MatchView.swift b/LiquipediaMenu/Match/MatchView.swift similarity index 73% rename from LiquipediaMenu/MatchView.swift rename to LiquipediaMenu/Match/MatchView.swift index ba9cc41..20987e5 100644 --- a/LiquipediaMenu/MatchView.swift +++ b/LiquipediaMenu/Match/MatchView.swift @@ -22,10 +22,6 @@ class MatchView: NSView { self.league = NSTextField() self.league.stringValue = match.league -// self.team1name.stringValue = match.team1name -// self.team1score.stringValue = match.team1score -// self.team2name.stringValue = match.team2name -// self.team2score.stringValue = match.team2score } } } diff --git a/LiquipediaMenu/StatusBarController.swift b/LiquipediaMenu/StatusBarController.swift index 31c9250..c2d373c 100644 --- a/LiquipediaMenu/StatusBarController.swift +++ b/LiquipediaMenu/StatusBarController.swift @@ -10,6 +10,8 @@ import Cocoa class StatusBarController: NSObject, NSMenuItemValidation { + @IBOutlet weak var matchView: MatchView! + func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { return true } @@ -54,11 +56,16 @@ class StatusBarController: NSObject, NSMenuItemValidation { } } +<<<<<<< HEAD if let matches = self.matchesAPI.fetchMatches(for: "counterstrike") { +======= + if let matches = self.matchesAPI.fetchMatches(for: "starcraft2") { +>>>>>>> 7de8fd2c2bd41baf8480580a6392c8c7869919a6 for match in matches { let newItem = MatchMenuItem.init(for: match, action: #selector(self.openStreamLink)) newItem.tag = 1 newItem.target = self + newItem.view = matchView self.statusBar.addItem(newItem) } } else {