Skip to content

Commit

Permalink
More detailed calendar (work in progress)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Filetti committed Feb 9, 2016
1 parent 641435b commit 23dd669
Show file tree
Hide file tree
Showing 10 changed files with 1,730 additions and 208 deletions.
179 changes: 17 additions & 162 deletions JustUsed.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

116 changes: 116 additions & 0 deletions JustUsed/DiMe Data/CalendarEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//
// Copyright (c) 2015 Aalto University
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

import Foundation
import EventKit

/// Represents an calendar event, as understood by dime
class CalendarEvent: Event {

private(set) var participants: [Person]?
private(set) var name: String
private(set) var calendar: String
private(set) var location: Location?
private(set) var locString: String?
let id: String

init(fromEKEvent event: EKEvent) {

self.id = event.eventIdentifier
self.name = event.title
self.calendar = event.calendar.title
if #available(OSX 10.11, *) {
if let structLoc = event.structuredLocation, clloc = structLoc.geoLocation {
location = Location(fromCLLocation: clloc)
}
}
self.locString = event.location

super.init()

setStart(event.startDate)
setEnd(event.endDate)

}

init(fromJSON json: JSON) {

self.id = json["appId"].stringValue
self.name = json["name"].stringValue
self.calendar = json["calendar"].stringValue
self.locString = json["locString"].string

if let participants = json["participants"].array {
if participants.count > 0 {
self.participants = [Person]()
for participant in participants {
self.participants!.append(Person(fromJson: participant))
}
}
}

if let _ = json["location"].dictionary {
location = Location(fromJSON: json["location"])
}

super.init()

let start = NSDate(timeIntervalSince1970: NSTimeInterval(json["start"].intValue / 1000))
let end = NSDate(timeIntervalSince1970: NSTimeInterval(json["end"].intValue / 1000))
setStart(start)
setEnd(end)

}

/// getDict for calendar is overridden to update return value with internal state.
override func getDict() -> [String : AnyObject] {
var retDict = theDictionary // fetch current values

// update values
retDict["calendar"] = calendar
retDict["name"] = name
if let participants = participants {
var partArray = [[String: AnyObject]]()
for participant in participants {
partArray.append(participant.getDict())
}
retDict["participants"] = partArray
}

if let loc = location {
retDict["location"] = loc.getDict()
}
if let ls = locString {
retDict["locString"] = ls
}

// required
retDict["appId"] = id
// re-define inherited fields
retDict["@type"] = "CalendarEvent"
retDict["type"] = "http://www.hiit.fi/ontologies/dime/#CalendarEvent"

return retDict
}
}
5 changes: 5 additions & 0 deletions JustUsed/DiMe Data/Event.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ class Event: DiMeBase {
func setEnd(endDate: NSDate) {
theDictionary["end"] = JustUsedConstants.diMeDateFormatter.stringFromDate(endDate)
}

/// Set a start date for this item (updates old value)
func setStart(endDate: NSDate) {
theDictionary["start"] = JustUsedConstants.diMeDateFormatter.stringFromDate(endDate)
}
}
47 changes: 27 additions & 20 deletions JustUsed/DiMe Data/HistoryManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import Foundation
import Alamofire

class HistoryManager: NSObject, RecentDocumentUpdateDelegate, BrowserHistoryUpdateDelegate {
class HistoryManager: NSObject {

/// Returns a shared instance of this class. This is the designed way of accessing the history manager.
static let sharedManager = HistoryManager()
Expand Down Expand Up @@ -91,25 +91,6 @@ class HistoryManager: NSObject, RecentDocumentUpdateDelegate, BrowserHistoryUpda
self.dimeConnectState(false)
}

// MARK: - Protocol implementation

func newHistoryItems(newURLs: [BrowserHistItem]) {
for newURL in newURLs {
let sendingToBrowser = NSUserDefaults.standardUserDefaults().valueForKey(JustUsedConstants.prefSendSafariHistory) as! Bool
if !newURL.excludedFromDiMe && sendingToBrowser {
let infoElem = DocumentInformationElement(fromSafariHist: newURL)
let event = DesktopEvent(infoElem: infoElem, ofType: TrackingType.Browser(newURL.browser), withDate: newURL.date, andLocation: newURL.location)
sendToDiMe(event)
}
}
}

func newRecentDocument(newItem: RecentDocItem) {
let infoElem = DocumentInformationElement(fromRecentDoc: newItem)
let event = DesktopEvent(infoElem: infoElem, ofType: TrackingType.Spotlight, withDate: newItem.lastAccessDate, andLocation: newItem.location)
sendToDiMe(event)
}

// MARK: - Internal functions

/// Connection to dime successful / failed
Expand Down Expand Up @@ -169,3 +150,29 @@ class HistoryManager: NSObject, RecentDocumentUpdateDelegate, BrowserHistoryUpda
}

}

// MARK: - Protocol implementations

/// Protocol implementations for browser and document history updates
extension HistoryManager: RecentDocumentUpdateDelegate, BrowserHistoryUpdateDelegate {

func newHistoryItems(newURLs: [BrowserHistItem]) {
for newURL in newURLs {
let sendingToBrowser = NSUserDefaults.standardUserDefaults().valueForKey(JustUsedConstants.prefSendSafariHistory) as! Bool
if !newURL.excludedFromDiMe && sendingToBrowser {
let infoElem = DocumentInformationElement(fromSafariHist: newURL)
let event = DesktopEvent(infoElem: infoElem, ofType: TrackingType.Browser(newURL.browser), withDate: newURL.date, andLocation: newURL.location)
sendToDiMe(event)
}
}
}

func newRecentDocument(newItem: RecentDocItem) {
let infoElem = DocumentInformationElement(fromRecentDoc: newItem)
let event = DesktopEvent(infoElem: infoElem, ofType: TrackingType.Spotlight, withDate: newItem.lastAccessDate, andLocation: newItem.location)
sendToDiMe(event)
}

}

/// Protocol implementations for calendar updating
11 changes: 11 additions & 0 deletions JustUsed/DiMe Data/Location.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ struct Location: Dictionariable, Equatable {
}
}

init(fromJSON json: JSON) {
latitude = json["latitude"].doubleValue
longitude = json["longitude"].doubleValue
altitude = json["altitude"].double
horizAccuracy = json["horizAccuracy"].doubleValue
vertAccuracy = json["vertAccuracy"].double
bearing = json["bearing"].double
speed = json["speed"].double
descriptionLine = json["descriptionLine"].string
}

/// Returns itself in a (json-able) dict
func getDict() -> [String: AnyObject] {
var retDict = [String: AnyObject]()
Expand Down
110 changes: 110 additions & 0 deletions JustUsed/DiMe Data/Person.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// Person.swift
// PeyeDF
//
// Created by Marco Filetti on 20/10/2015.
// Copyright © 2015 HIIT. All rights reserved.
//

import Foundation

/// A person is represented by this struct (not a class)
class Person: DiMeBase {

private(set) var firstName: String = "N/A"
private(set) var lastName: String = "N/A"
private(set) var middleNames: [String] = [String]()
private(set) var email: String?

/// Returns the name in a string separated by spaces, such as "FistName MiddleName1 MiddleName2 LastName"
override var description: String { get {
var outVal = firstName + " "
if middleNames.count > 0 {
for midName in middleNames {
outVal += midName + " "
}
}
outVal += lastName
return outVal
} }

/// Generates a person from a string. If there is a comma in the string, it is assumed that the first name after the comma, otherwise first name is the first non-whitespace separated string, and last name is the last. Middle names are assumed to all come after the first name if there was a comma, between first and last if there is no comma.
/// **Fails (returns nil) if the string could not be parsed.**
init?(fromString string: String) {
super.init()

if string.containsChar(",") {
let splitted = string.split(",")
guard let spl = splitted else {
return nil
}
if spl.count == 2 {
self.lastName = spl[0]

// check if there are middle names in the following part
if spl[1].containsChar(" ") {
var resplitted = spl[1].split(" ")
self.firstName = resplitted!.removeAtIndex(0)
if resplitted!.count > 0 {
for remName in resplitted! {
middleNames.append(remName)
}
}
}
else {
self.firstName = spl[1]
}
} else {
return nil
}
} else {
let splitted = string.split(" ")
guard let spl = splitted else {
return nil
}
if spl.count >= 2 {
self.firstName = spl.first!
self.lastName = spl.last!
if spl.count > 2 {
for i in 1..<spl.count - 1 {
middleNames.append(spl[i])
}
}
} else {
return nil
}
}

}

/// Creates a person from dime's json
init(fromJson json: JSON) {
self.firstName = json["firstName"].stringValue
self.lastName = json["lastName"].stringValue
if let midnames = json["middleNames"].array {
for midname in midnames {
self.middleNames.append(midname.stringValue)
}
}
if let em = json["emailAccount"].string {
self.email = em
}
}

override func getDict() -> [String : AnyObject] {
theDictionary["firstName"] = firstName
theDictionary["lastName"] = lastName
if middleNames.count > 0 {
theDictionary["middleNames"] = middleNames
}
if let em = self.email {
theDictionary["emailAccount"] = em
}

// dime-required
theDictionary["@type"] = "Person"
theDictionary["type"] = "http://www.hiit.fi/ontologies/dime/#Person"

return theDictionary
}
}
Loading

0 comments on commit 23dd669

Please sign in to comment.