This commit is contained in:
Gerrit Linnemann 2016-12-14 14:50:21 +01:00
parent aa33de26c9
commit 84138a8b49
8 changed files with 234 additions and 12 deletions

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
8505EACF1E01441F002A0BFB /* ViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8505EACE1E01441F002A0BFB /* ViewControllerExtension.swift */; };
854A87B01DF6BD9A00904B3E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854A87AF1DF6BD9A00904B3E /* AppDelegate.swift */; }; 854A87B01DF6BD9A00904B3E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854A87AF1DF6BD9A00904B3E /* AppDelegate.swift */; };
854A87B21DF6BD9A00904B3E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854A87B11DF6BD9A00904B3E /* ViewController.swift */; }; 854A87B21DF6BD9A00904B3E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854A87B11DF6BD9A00904B3E /* ViewController.swift */; };
854A87B41DF6BD9A00904B3E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 854A87B31DF6BD9A00904B3E /* Assets.xcassets */; }; 854A87B41DF6BD9A00904B3E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 854A87B31DF6BD9A00904B3E /* Assets.xcassets */; };
@ -37,6 +38,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
8505EACE1E01441F002A0BFB /* ViewControllerExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewControllerExtension.swift; path = Extension/ViewControllerExtension.swift; sourceTree = "<group>"; };
854A87AC1DF6BD9A00904B3E /* OTRS-Watch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OTRS-Watch.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 854A87AC1DF6BD9A00904B3E /* OTRS-Watch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OTRS-Watch.app"; sourceTree = BUILT_PRODUCTS_DIR; };
854A87AF1DF6BD9A00904B3E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 854A87AF1DF6BD9A00904B3E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
854A87B11DF6BD9A00904B3E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; }; 854A87B11DF6BD9A00904B3E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@ -80,6 +82,14 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
8505EAD01E014486002A0BFB /* Extension */ = {
isa = PBXGroup;
children = (
8505EACE1E01441F002A0BFB /* ViewControllerExtension.swift */,
);
name = Extension;
sourceTree = "<group>";
};
854A87A31DF6BD9900904B3E = { 854A87A31DF6BD9900904B3E = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -103,6 +113,7 @@
854A87AE1DF6BD9A00904B3E /* OTRS-Watch */ = { 854A87AE1DF6BD9A00904B3E /* OTRS-Watch */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8505EAD01E014486002A0BFB /* Extension */,
857EB22A1DF9748B00CCA941 /* Model */, 857EB22A1DF9748B00CCA941 /* Model */,
854A87AF1DF6BD9A00904B3E /* AppDelegate.swift */, 854A87AF1DF6BD9A00904B3E /* AppDelegate.swift */,
854A87B11DF6BD9A00904B3E /* ViewController.swift */, 854A87B11DF6BD9A00904B3E /* ViewController.swift */,
@ -285,6 +296,7 @@
files = ( files = (
854A87B21DF6BD9A00904B3E /* ViewController.swift in Sources */, 854A87B21DF6BD9A00904B3E /* ViewController.swift in Sources */,
857EB22F1DF9845200CCA941 /* TicketExtension.swift in Sources */, 857EB22F1DF9845200CCA941 /* TicketExtension.swift in Sources */,
8505EACF1E01441F002A0BFB /* ViewControllerExtension.swift in Sources */,
854A87DD1DF6DC7500904B3E /* OTRS.swift in Sources */, 854A87DD1DF6DC7500904B3E /* OTRS.swift in Sources */,
857EB22C1DF974F500CCA941 /* Ticket.swift in Sources */, 857EB22C1DF974F500CCA941 /* Ticket.swift in Sources */,
854A87B01DF6BD9A00904B3E /* AppDelegate.swift in Sources */, 854A87B01DF6BD9A00904B3E /* AppDelegate.swift in Sources */,

View File

@ -10,11 +10,11 @@
ignoreCount = "0" ignoreCount = "0"
continueAfterRunningActions = "No" continueAfterRunningActions = "No"
filePath = "OTRS-Watch/OTRS.swift" filePath = "OTRS-Watch/OTRS.swift"
timestampString = "502885498.221741" timestampString = "503411749.778027"
startingColumnNumber = "9223372036854775807" startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807"
startingLineNumber = "46" startingLineNumber = "48"
endingLineNumber = "46" endingLineNumber = "48"
landmarkName = "get(forQue:)" landmarkName = "get(forQue:)"
landmarkType = "7"> landmarkType = "7">
</BreakpointContent> </BreakpointContent>
@ -26,11 +26,11 @@
ignoreCount = "0" ignoreCount = "0"
continueAfterRunningActions = "No" continueAfterRunningActions = "No"
filePath = "OTRS-Watch/OTRS.swift" filePath = "OTRS-Watch/OTRS.swift"
timestampString = "502893913.377215" timestampString = "503411749.778027"
startingColumnNumber = "9223372036854775807" startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807"
startingLineNumber = "53" startingLineNumber = "56"
endingLineNumber = "53" endingLineNumber = "56"
landmarkName = "get(forQue:)" landmarkName = "get(forQue:)"
landmarkType = "7"> landmarkType = "7">
</BreakpointContent> </BreakpointContent>

View File

@ -709,6 +709,105 @@
<view key="view" ambiguous="YES" id="3eX-zs-jOD"> <view key="view" ambiguous="YES" id="3eX-zs-jOD">
<rect key="frame" x="10" y="33" width="692" height="417"/> <rect key="frame" x="10" y="33" width="692" height="417"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YH5-XW-yde">
<rect key="frame" x="-3" y="-3" width="698" height="417"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" ambiguous="YES" id="SBI-Qa-8Gy">
<rect key="frame" x="1" y="0.0" width="696" height="416"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="arE-Wm-4FI" viewBased="YES" id="uqq-D2-JrZ">
<rect key="frame" x="0.0" y="0.0" width="696" height="393"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="116" minWidth="40" maxWidth="1000" id="KZ0-pD-Gxd">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Ticket Nummer">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Gel-yq-FMp">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="OTRSTicketNumber" id="2Z7-ua-4Vs">
<rect key="frame" x="1" y="1" width="116" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="npm-YV-jB4">
<rect key="frame" x="0.0" y="0.0" width="116" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Exg-AG-gCr">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="npm-YV-jB4" id="yP8-XQ-6QD"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn width="574" minWidth="40" maxWidth="1000" id="I6P-hp-NkB">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Details">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="dT5-Hz-uPG">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="OTRSTicketDetails" id="52t-AD-QAD">
<rect key="frame" x="120" y="1" width="574" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3SI-Bc-aJ1">
<rect key="frame" x="0.0" y="0.0" width="574" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="yup-lF-FZ8">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="3SI-Bc-aJ1" id="G9x-8y-9ns"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
</tableView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="yAG-0l-MrF">
<rect key="frame" x="1" y="119" width="223" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="0Mc-1B-cqp">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="arE-Wm-4FI">
<rect key="frame" x="0.0" y="0.0" width="696" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
</subviews>
</view> </view>
</tabViewItem> </tabViewItem>
<tabViewItem label="Einstellungen" identifier="2" id="yzk-gj-wT8"> <tabViewItem label="Einstellungen" identifier="2" id="yzk-gj-wT8">
@ -812,6 +911,7 @@
</subviews> </subviews>
</view> </view>
<connections> <connections>
<outlet property="ticketTableView" destination="uqq-D2-JrZ" id="Csb-WI-8ex"/>
<outlet property="txtPassword" destination="dBq-YZ-1Lb" id="zcP-17-bRV"/> <outlet property="txtPassword" destination="dBq-YZ-1Lb" id="zcP-17-bRV"/>
<outlet property="txtQueue" destination="l3M-cB-NAW" id="ljI-tu-VOS"/> <outlet property="txtQueue" destination="l3M-cB-NAW" id="ljI-tu-VOS"/>
<outlet property="txtUsername" destination="CWI-hQ-L71" id="3oJ-D0-5fl"/> <outlet property="txtUsername" destination="CWI-hQ-L71" id="3oJ-D0-5fl"/>
@ -819,7 +919,7 @@
</viewController> </viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="75" y="790"/> <point key="canvasLocation" x="75" y="789.5"/>
</scene> </scene>
</scenes> </scenes>
<resources> <resources>

View File

@ -25,4 +25,16 @@ struct Constants {
static let QUEUE = "user::setting::otrs::queue" static let QUEUE = "user::setting::otrs::queue"
} }
} }
struct NOTIFICATION {
struct TICKET {
struct LIST {
static let UPDATED = "nf::ticket::list::updated"
}
static let IN = "nf::ticket::in"
}
}
} }

View File

@ -0,0 +1,52 @@
//
// ViewControllerExtension.swift
// OTRS-Watch
//
// Created by Gerrit Linnemann on 14.12.16.
// Copyright © 2016 Adawim UG (haftungsbeschränkt). All rights reserved.
//
import Cocoa
extension ViewController: NSTableViewDataSource, NSTableViewDelegate {
fileprivate enum CellIdentifiers {
static let OTRSTicketNumber = "OTRSTicketNumber"
static let OTRSTicketDetails = "OTRSTicketDetails"
}
func numberOfRows(in tableView: NSTableView) -> Int {
return self.ticketDictionary.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
var image: NSImage?
var text: String = ""
var cellIdentifier: String = ""
print("row: \(row)")
guard let item = ticketDictionary.first else {
return nil
}
if tableColumn == self.ticketTableView.tableColumns[0] {
cellIdentifier = CellIdentifiers.OTRSTicketNumber
image = nil
text = item.value.ticketNumber
} else if tableColumn == self.ticketTableView.tableColumns[1] {
cellIdentifier = CellIdentifiers.OTRSTicketDetails
image = nil
text = item.value.title
}
if let cell = tableView.make(withIdentifier: cellIdentifier, owner: nil) as? NSTableCellView {
cell.textField?.stringValue = text
cell.imageView?.image = image ?? nil
return cell
}
return nil
}
}

View File

@ -43,16 +43,24 @@ class OTRS {
// work with json ... // work with json ...
//print(json) //print(json)
var cnt = 0;
for object in json { for object in json {
let ticketIDs = object.value as! Array<String> let ticketIDs = object.value as! Array<String>
//print(ticketIDs) //print(ticketIDs)
for ticketID in ticketIDs { for ticketID in ticketIDs {
if let tID:Int = Int(ticketID) { if let tID:Int = Int(ticketID) {
self.fetch(ticket: tID) self.fetch(ticket: tID, session: session)
cnt = cnt+1;
} }
} }
} }
let nc = NotificationCenter.default
nc.post(name:Notification.Name(rawValue:Constants.NOTIFICATION.TICKET.LIST.UPDATED),
object: nil,
userInfo: ["count":cnt])
} }
} catch { } catch {
print("Error in JSONSerialization") print("Error in JSONSerialization")
@ -63,9 +71,7 @@ class OTRS {
task.resume() task.resume()
} }
func fetch(ticket:Int) { func fetch(ticket:Int, session:URLSession) {
let config = URLSessionConfiguration.default // Session configuration
let session = URLSession(configuration: config) // Load configuration into session
let url = URL(string: buildURLForGettingTicketInfo(ticketID: ticket)) let url = URL(string: buildURLForGettingTicketInfo(ticketID: ticket))
let task = session.dataTask(with: url!, completionHandler: { // see: https://developer.apple.com/swift/blog/?id=37 let task = session.dataTask(with: url!, completionHandler: { // see: https://developer.apple.com/swift/blog/?id=37
@ -78,7 +84,13 @@ class OTRS {
let dictionary = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String : AnyObject] let dictionary = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String : AnyObject]
let ticketData : Dictionary = dictionary["Ticket"]?.firstObject as! [String : AnyObject] let ticketData : Dictionary = dictionary["Ticket"]?.firstObject as! [String : AnyObject]
let ticket = try Ticket(source: ticketData) let ticket = try Ticket(source: ticketData)
print(ticket) //print(ticket)
let nc = NotificationCenter.default
nc.post(name:Notification.Name(rawValue:Constants.NOTIFICATION.TICKET.IN),
object: nil,
userInfo: ["message":ticket.id, "ticket":ticket])
} catch SerializationError.missing(let marker) { } catch SerializationError.missing(let marker) {
print("Error in JSONSerialization for ticket #\(ticket) at \"\(marker)\"") print("Error in JSONSerialization for ticket #\(ticket) at \"\(marker)\"")
} catch { } catch {

View File

@ -13,10 +13,16 @@ class ViewController: NSViewController {
@IBOutlet weak var txtUsername: NSTextField! @IBOutlet weak var txtUsername: NSTextField!
@IBOutlet weak var txtPassword: NSSecureTextField! @IBOutlet weak var txtPassword: NSSecureTextField!
@IBOutlet weak var txtQueue: NSTextField! @IBOutlet weak var txtQueue: NSTextField!
@IBOutlet weak var ticketTableView: NSTableView!
var ticketDictionary: Dictionary<String, Ticket> = [:]
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
ticketTableView.delegate = self
ticketTableView.dataSource = self
// Do any additional setup after loading the view. // Do any additional setup after loading the view.
if UserDefaults.standard.string(forKey: Constants.USER_SETTINGS.CREDENTIALS.USER) != nil { if UserDefaults.standard.string(forKey: Constants.USER_SETTINGS.CREDENTIALS.USER) != nil {
@ -31,6 +37,15 @@ class ViewController: NSViewController {
txtQueue.stringValue = UserDefaults.standard.string(forKey: Constants.USER_SETTINGS.OTRS.QUEUE)! txtQueue.stringValue = UserDefaults.standard.string(forKey: Constants.USER_SETTINGS.OTRS.QUEUE)!
} }
let nc = NotificationCenter.default
nc.addObserver(forName:Notification.Name(rawValue:Constants.NOTIFICATION.TICKET.IN),
object:nil, queue:nil,
using:catchNewIncomingTicket)
nc.addObserver(forName:Notification.Name(rawValue:Constants.NOTIFICATION.TICKET.LIST.UPDATED),
object:nil, queue:nil,
using:catchTicketsUpdated)
reload() reload()
} }
@ -56,5 +71,24 @@ class ViewController: NSViewController {
otrs.get(forQue: que) otrs.get(forQue: que)
} }
} }
// MARK: Notification
func catchNewIncomingTicket(notification:Notification) -> Void {
guard let userInfo = notification.userInfo,
let message:String = userInfo["message"] as? String,
let ticket:Ticket = userInfo["ticket"] as? Ticket else {
return
}
self.ticketDictionary.updateValue(ticket, forKey: message)
reload()
}
func catchTicketsUpdated(notification:Notification) -> Void {
}
} }