add source code

This commit is contained in:
2EEEB 2019-10-18 19:07:45 +02:00
parent 1458f269cf
commit b412ffe595
7 changed files with 287 additions and 0 deletions

60
AstroData.swift Normal file
View File

@ -0,0 +1,60 @@
import Foundation
class AstroData: Presentable, Fetchable {
var error: String?
var year: Int?
var month: Int?
var day: Int?
var dayOfWeek: String?
var sunData: SunData?
var moonData: MoonData?
var closestPhaseName: String?
var closestPhaseDate: String?
var closestPhaseTime: String?
var fracillum: String?
var curPhase: String?
func present() {
print("--------Astronomical Data--------")
if year != nil && month != nil && day != nil && dayOfWeek != nil {
print("Requested date is \(String(day!))/\(String(month!))/\(String(year!)) which is (was/will be) a \(String(dayOfWeek!))")
}
else {
print("o fug")
}
if self.sunData != nil {
self.sunData!.present()
}
if self.moonData != nil {
self.moonData!.present()
}
if fracillum != nil {
print("Illumination of the moon is (was/will be) \(String(fracillum!))")
}
if curPhase != nil {
print("The moon is (was/will be) in its \(String(curPhase!)) phase.")
}
if closestPhaseName != nil && closestPhaseDate != nil && closestPhaseTime != nil {
print("Closest moon phase is (was/will be) \(String(closestPhaseName!)), occuring on \(String(closestPhaseDate!)) at \(String(closestPhaseTime!))")
}
}
func fetch(apiData: NSDictionary) {
self.error = apiData.value(forKey: "error") as? String
self.year = apiData.value(forKey: "year") as? Int
self.month = apiData.value(forKey: "month") as? Int
self.day = apiData.value(forKey: "day") as? Int
self.dayOfWeek = apiData.value(forKey: "dayofweek") as? String
self.fracillum = apiData.value(forKey: "fracillum") as? String
self.curPhase = apiData.value(forKey: "curphase") as? String
let tmpDict = apiData.value(forKey: "closestphase") as? NSDictionary
self.closestPhaseName = tmpDict?.value(forKey: "phase") as? String
self.closestPhaseDate = tmpDict?.value(forKey: "date") as? String
self.closestPhaseTime = tmpDict?.value(forKey: "time") as? String
self.sunData = SunData()
self.sunData!.fetch(apiData: apiData)
self.moonData = MoonData()
self.moonData!.fetch(apiData: apiData)
}
}

6
Fetchable.swift Normal file
View File

@ -0,0 +1,6 @@
import Foundation
protocol Fetchable {
func fetch(apiData: NSDictionary)
}

28
MoonData.swift Normal file
View File

@ -0,0 +1,28 @@
import Foundation
class MoonData: SunMoonData {
override func present() {
print("---- Moon Data ----")
if riseTime != nil {
print("The moon will rise (rose) at \(String(riseTime!))")
}
if upperTransitTime != nil {
print("The moon will reach (reached) its highest point at \(String(upperTransitTime!))")
}
if setTime != nil {
print("The moon will set (set) at \(String(setTime!))")
}
}
override func fetch(apiData: NSDictionary) {
let tmpArry = apiData.value(forKey: "moondata") as? [NSDictionary]
for dict in tmpArry! {
switch dict.value(forKey: "phen") as? String {
case "R": self.riseTime = dict.value(forKey: "time") as? String
case "U": self.upperTransitTime = dict.value(forKey: "time") as? String
case "S": self.setTime = dict.value(forKey: "time") as? String
default: break
}
}
}
}

7
Presentable.swift Normal file
View File

@ -0,0 +1,7 @@
import Foundation
protocol Presentable {
func present()
}

40
SunData.swift Normal file
View File

@ -0,0 +1,40 @@
import Foundation
class SunData: SunMoonData {
var beginCivilTwilight: String?
var endCivilTwilight: String?
override func present() {
print("---- Sun Data ----")
if beginCivilTwilight != nil {
print("First light will be (was) visible at \(String(beginCivilTwilight!))")
}
if riseTime != nil {
print("The sun will rise (rose) at \(String(riseTime!))")
}
if upperTransitTime != nil {
print("The sun will reach (reached) its highest point at \(String(upperTransitTime!))")
}
if setTime != nil {
print("The sun will set (set) at \(String(setTime!))")
}
if endCivilTwilight != nil{
print("It will be (was) dark at \(String(endCivilTwilight!))")
}
}
override func fetch(apiData: NSDictionary) {
let tmpArry = apiData.value(forKey: "sundata") as? [NSDictionary]
for dict in tmpArry! {
switch dict.value(forKey: "phen") as? String {
case "R": self.riseTime = dict.value(forKey: "time") as? String
case "U": self.upperTransitTime = dict.value(forKey: "time") as? String
case "S": self.setTime = dict.value(forKey: "time") as? String
case "BC": self.beginCivilTwilight = dict.value(forKey: "time") as? String
case "EC": self.endCivilTwilight = dict.value(forKey: "time") as? String
default: break
}
}
}
}

16
SunMoonData.swift Normal file
View File

@ -0,0 +1,16 @@
import Foundation
class SunMoonData: Presentable, Fetchable {
var riseTime: String?
var upperTransitTime: String?
var setTime: String?
func present() {
// overriden
}
func fetch(apiData: NSDictionary) {
}
}

130
main.swift Normal file
View File

@ -0,0 +1,130 @@
/*
program takes 2 arguments: date and location, in that order. pass parameters as strings only.
at the time, location is hardcoded for brno and bratislava. if you are feeling adventurous,
uncomment the relevant parts and input location as coordinates in XX.XXN/S,YY.YYE/W format.
be aware though, absolutely NO input sanitization or checking is present at the time, use with caution!
the program should crash cleanly if an error occurs but no guarantees.
The api used in this program is described in detail here: https://aa.usno.navy.mil/data/docs/api.php
*/
import Foundation
var args:[String] = []
if CommandLine.arguments.count < 2 {
args.append("default")
}
else {
CommandLine.arguments.forEach {
args.append($0)
}
args.remove(at: 0)
}
var COORDS: String? = nil
var TZ: String = "2" //timezone: hardcoded for now to CEST
var DATE: String? = nil
var url = URL(string:"")
var quit: Bool = false
var gtg: Bool = false
var dfltSet: Bool = false
var errInInp: Bool = false
if args.count > 2 {
print("Invalid parameter count!")
errInInp = true
}
switch args[0] {
case "default" :
COORDS = "49.19N,16.60E" //Brno
DATE = "today"
gtg = true
dfltSet = true
print("No location or date provided, using today's date. Data for Brno")
case "yesterday":
DATE = "yesterday"
case "today" :
DATE = "today"
case "tomorrow":
DATE = "tomorrow"
default:
if !errInInp {
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "MM/DD/YYYY" //Api only accepts date in this format, sorry
let argDate = args[0]
if dateFormatterGet.date(from: argDate) != nil {
DATE = args[0]
} else {
DATE = "today"
print("Invalid date format, proceeding with today's date (input date as MM/DD/YYYY or today, tomorrow, yesterday)")
}
}
}
if args.count > 1 {
switch args[1] {
case "Brno" :
COORDS = "49.19N,16.60E" //Brno
gtg = true
case "brno":
COORDS = "49.19N,16.60E" //Brno
gtg = true
case "Bratislava":
COORDS = "48.15N,17.09E" //Bratislava
gtg = true
case "bratislava":
COORDS = "48.15N,17.09E" //Bratislava
gtg = true
default:
if !errInInp {
COORDS = "49.19N,16.60E" //Brno
print("Invalid location argument, data for Brno")
gtg = true
//comment out the above and uncomment this for coordinate input as unsanitized launch parameter
/*
COORDS = args[1] //pass location argument as coordinates in XX.XXN/S,YY.YYE/W format. no correctness check, be careful!
gtg = true
*/
}
}
}
if args.count < 2 {
if !dfltSet {
if !errInInp {
COORDS = "49.19N,16.60E" //Brno
gtg = true
print("No location provided, data for Brno")
}
}
}
if errInInp {
quit = true
}
else if DATE != nil && COORDS != nil && gtg == true {
url = URL(string: "http://api.usno.navy.mil/rstt/oneday?date=\(String(DATE!))&coords=\(String(COORDS!))&tz=\(TZ)&ID=dpt")
func getJsonFromUrl() {
let dlTask = URLSession.shared.dataTask(with: url!) {(data, response, error) in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
//print(jsonObj!.value(forKey: "apiversion")!)
let astroData = AstroData()
astroData.fetch(apiData: jsonObj!)
astroData.present()
}
quit = true
}
dlTask.resume()
}
getJsonFromUrl()
}
else {
print("Missing or invalid parameters!")
quit = true
}
while !quit {
sleep(1)
}