Skip to content

Commit

Permalink
Respect CancelObject plugin configuration and ignore configured eleme…
Browse files Browse the repository at this point in the history
…nts.

Closes #234
  • Loading branch information
gdombiak committed Dec 16, 2019
1 parent 73a16df commit 3bbb9db
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 66 deletions.
8 changes: 8 additions & 0 deletions OctoPod/Model/CancelObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ class CancelObject {
return nil
}

/// Returns array with strings that represent objects that cannot be cancelled. Whitespaces are trimmed
static func parseCancelObjectIgnore(ignored: String?) -> Array<String> {
if let ignored = ignored {
return ignored.components(separatedBy: ",").map { $0.trimmingCharacters(in: .whitespaces) }
}
return Array<String>()
}

private init(id: Int, object: String, cancelled: Bool, active: Bool, ignore: Bool) {
self.id = id
self.object = object
Expand Down
68 changes: 46 additions & 22 deletions OctoPod/Model/Printer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,77 @@ import CoreData
/// A Printer (term used in the UI) actually represents an OctoPrint server
class Printer: NSManagedObject {

@NSManaged var recordName: String? // Unique identifier of this record in CloudKit
@NSManaged var recordData: Data? // Encoded data of the iCloud record
@NSManaged var iCloudUpdate: Bool // Flag that indicates if this record needs to be created/updated in CloudKit
/// Unique identifier of this record in CloudKit
@NSManaged var recordName: String?
/// Encoded data of the iCloud record
@NSManaged var recordData: Data?
/// Flag that indicates if this record needs to be created/updated in CloudKit
@NSManaged var iCloudUpdate: Bool

@NSManaged var position: Int16 // Zero-index position of this printer in the list of printers
/// Zero-index position of this printer in the list of printers
@NSManaged var position: Int16
@NSManaged var name: String
@NSManaged var hostname: String
@NSManaged var streamUrl: String? // path to the webcam. Info discovered via api/settings
/// path to the webcam. Info discovered via api/settings
@NSManaged var streamUrl: String?
@NSManaged var apiKey: String
@NSManaged var defaultPrinter: Bool
@NSManaged var userModified: Date? // Date when user last modified this settings
/// Date when user last modified this settings
@NSManaged var userModified: Date?

@NSManaged var username: String?
@NSManaged var password: String?

@NSManaged var color: String? // Information configured in OctoPrint -> Appearance to control color of UI
/// Information configured in OctoPrint -> Appearance to control color of UI
@NSManaged var color: String?

@NSManaged var toolsNumber: Int16 // Number of detected tools (extruders). This information is discovered based on reported temperatures or printer profiles
@NSManaged var sharedNozzle: Bool // A printer may have many extruders but a single nozzle (e.g. MMU)
/// Number of detected tools (extruders). This information is discovered based on reported temperatures or printer profiles
@NSManaged var toolsNumber: Int16
/// A printer may have many extruders but a single nozzle (e.g. MMU)
@NSManaged var sharedNozzle: Bool

@NSManaged var firstCameraAspectRatio16_9: Bool // Remember aspect ratio of first camera so UI can adapt to proper aspect ratio
/// Remember aspect ratio of first camera so UI can adapt to proper aspect ratio
@NSManaged var firstCameraAspectRatio16_9: Bool
@NSManaged var sdSupport: Bool
@NSManaged var cameraOrientation: Int16 // Raw value of UIImageOrientation enum
@NSManaged var cameras: [String]? // Array that holds URLs to cameras. OctoPrint needs to use MultiCam plugin
/// Raw value of UIImageOrientation enum
@NSManaged var cameraOrientation: Int16
/// Array that holds URLs to cameras. OctoPrint needs to use MultiCam plugin
@NSManaged var cameras: [String]?

@NSManaged var invertX: Bool // Control of X is inverted
@NSManaged var invertY: Bool // Control of Y is inverted
@NSManaged var invertZ: Bool // Control of Z is inverted

// Track if the following plugins are installed and configured
@NSManaged var psuControlInstalled: Bool
@NSManaged var tpLinkSmartplugs: [[String]]? // Array of an Array with 2 strings (IP Address, Label)
@NSManaged var wemoplugs: [[String]]? // Array of an Array with 2 strings (IP Address, Label)
@NSManaged var domoticzplugs: [[String]]? // Array of an Array with 2 strings (IP Address, Label)
@NSManaged var tasmotaplugs: [[String]]? // Array of an Array with 2 strings (IP Address, Label)
/// Array of an Array with 2 strings (IP Address, Label)
@NSManaged var tpLinkSmartplugs: [[String]]?
/// Array of an Array with 2 strings (IP Address, Label)
@NSManaged var wemoplugs: [[String]]?
/// Array of an Array with 2 strings (IP Address, Label)
@NSManaged var domoticzplugs: [[String]]?
/// Array of an Array with 2 strings (IP Address, Label)
@NSManaged var tasmotaplugs: [[String]]?
/// Track if CancelObjects plugin is installed
@NSManaged var cancelObjectInstalled: Bool
/// Comma delimited list of objects that should be ignored (cannot be cancelled)
@NSManaged var cancelObjectIgnored: String?
@NSManaged var octopodPluginInstalled: Bool
@NSManaged var notificationToken: String? // APNS token that was last registered with this OctoPrint instance
@NSManaged var octopodPluginPrinterName: String? // APNS notifications will use printer name as title
@NSManaged var octopodPluginLanguage: String? // APNS notifications will be sent with the specified language
/// APNS token that was last registered with this OctoPrint instance
@NSManaged var notificationToken: String?
/// APNS notifications will use printer name as title
@NSManaged var octopodPluginPrinterName: String?
/// APNS notifications will be sent with the specified language
@NSManaged var octopodPluginLanguage: String?
@NSManaged var palette2Installed: Bool
@NSManaged var palette2AutoConnect: Bool
@NSManaged var palette2CanvasInstalled: Bool

// Plugin updates tracking
@NSManaged var pluginsUpdateNextCheck: Date? // Date when we can check again for plugin updates
@NSManaged var pluginsUpdateSnooze: String? // Hash of last found updates that user asked to stop showing
/// Date when we can check again for plugin updates
@NSManaged var pluginsUpdateNextCheck: Date?
/// Hash of last found updates that user asked to stop showing
@NSManaged var pluginsUpdateSnooze: String?

func getStreamPath() -> String {
if let path = streamUrl {
Expand All @@ -59,7 +83,7 @@ class Printer: NSManagedObject {
return "/webcam/?action=stream"
}

// Returns true if returned getStreamPath() is coming from what OctoPrint reported via /api/settings. False means that it is assumed one
/// Returns true if returned getStreamPath() is coming from what OctoPrint reported via /api/settings. False means that it is assumed one
func isStreamPathFromSettings() -> Bool {
return streamUrl != nil
}
Expand Down
79 changes: 40 additions & 39 deletions OctoPod/OctoPod.xcdatamodeld/OctoPod v9.xcdatamodel/contents
Original file line number Diff line number Diff line change
@@ -1,45 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14492.1" systemVersion="18G95" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15702" systemVersion="19C57" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Printer" representedClassName=".Printer" syncable="YES">
<attribute name="apiKey" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="cameraOrientation" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="cameras" optional="YES" attributeType="Transformable" customClassName="[String]" syncable="YES"/>
<attribute name="cancelObjectInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="color" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="defaultPrinter" optional="YES" attributeType="Boolean" usesScalarValueType="YES" syncable="YES"/>
<attribute name="domoticzplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]" syncable="YES"/>
<attribute name="firstCameraAspectRatio16_9" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hostname" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="iCloudUpdate" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="invertX" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="invertY" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="invertZ" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="notificationToken" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="octopodPluginInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="octopodPluginLanguage" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="octopodPluginPrinterName" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="palette2AutoConnect" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="palette2CanvasInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="palette2Installed" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="password" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="pluginsUpdateNextCheck" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
<attribute name="pluginsUpdateSnooze" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="position" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="psuControlInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="recordData" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="recordName" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="sdSupport" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="sharedNozzle" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="streamUrl" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="tasmotaplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]" syncable="YES"/>
<attribute name="toolsNumber" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="YES" syncable="YES"/>
<attribute name="tpLinkSmartplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]" syncable="YES"/>
<attribute name="userModified" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
<attribute name="username" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="wemoplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]" syncable="YES"/>
<attribute name="apiKey" optional="YES" attributeType="String"/>
<attribute name="cameraOrientation" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="cameras" optional="YES" attributeType="Transformable" customClassName="[String]"/>
<attribute name="cancelObjectIgnored" optional="YES" attributeType="String"/>
<attribute name="cancelObjectInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="color" optional="YES" attributeType="String"/>
<attribute name="defaultPrinter" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="domoticzplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]"/>
<attribute name="firstCameraAspectRatio16_9" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="hostname" optional="YES" attributeType="String"/>
<attribute name="iCloudUpdate" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="invertX" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="invertY" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="invertZ" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="name" optional="YES" attributeType="String"/>
<attribute name="notificationToken" optional="YES" attributeType="String"/>
<attribute name="octopodPluginInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="octopodPluginLanguage" optional="YES" attributeType="String"/>
<attribute name="octopodPluginPrinterName" optional="YES" attributeType="String"/>
<attribute name="palette2AutoConnect" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="palette2CanvasInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="palette2Installed" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="password" optional="YES" attributeType="String"/>
<attribute name="pluginsUpdateNextCheck" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="pluginsUpdateSnooze" optional="YES" attributeType="String"/>
<attribute name="position" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="psuControlInstalled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="recordData" optional="YES" attributeType="Binary"/>
<attribute name="recordName" optional="YES" attributeType="String"/>
<attribute name="sdSupport" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="sharedNozzle" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="streamUrl" optional="YES" attributeType="String"/>
<attribute name="tasmotaplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]"/>
<attribute name="toolsNumber" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="YES"/>
<attribute name="tpLinkSmartplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]"/>
<attribute name="userModified" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="username" optional="YES" attributeType="String"/>
<attribute name="wemoplugs" optional="YES" attributeType="Transformable" customClassName="[[String]]"/>
</entity>
<elements>
<element name="Printer" positionX="-63" positionY="-18" width="128" height="600"/>
<element name="Printer" positionX="-63" positionY="-18" width="128" height="613"/>
</elements>
</model>
12 changes: 9 additions & 3 deletions OctoPod/OctoPrint/OctoPrintClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,10 @@ class OctoPrintClient: WebSocketClientDelegate, AppConfigurationDelegate {

/// Get list of objects that are part of the current gcode being printed. Objects already cancelled will be part of the response
func getCancelObjects(callback: @escaping (Array<CancelObject>?, Error?, HTTPURLResponse) -> Void) {
octoPrintRESTClient.getCancelObjects(callback: callback)
if let printer = printerManager.getDefaultPrinter() {
let ignore = CancelObject.parseCancelObjectIgnore(ignored: printer.cancelObjectIgnored)
octoPrintRESTClient.getCancelObjects(ignore: ignore, callback: callback)
}
}

/// Cancel the requested object id.
Expand Down Expand Up @@ -868,15 +871,18 @@ class OctoPrintClient: WebSocketClientDelegate, AppConfigurationDelegate {

fileprivate func updatePrinterFromCancelObjectPlugin(printer: Printer, plugins: NSDictionary) {
var installed = false
if let _ = plugins[Plugins.CANCEL_OBJECT] as? NSDictionary {
var ignored: String?
if let cancelPlugin = plugins[Plugins.CANCEL_OBJECT] as? NSDictionary {
// Cancel Object plugin is installed
installed = true
ignored = cancelPlugin["ignored"] as? String
}
if printer.cancelObjectInstalled != installed {
if printer.cancelObjectInstalled != installed || printer.cancelObjectIgnored != ignored {
let newObjectContext = printerManager.newPrivateContext()
let printerToUpdate = newObjectContext.object(with: printer.objectID) as! Printer
// Update flag that tracks if Cancel Object plugin is installed
printerToUpdate.cancelObjectInstalled = installed
printer.cancelObjectIgnored = ignored
// Persist updated printer
printerManager.updatePrinter(printerToUpdate, context: newObjectContext)

Expand Down
5 changes: 3 additions & 2 deletions OctoPod/OctoPrint/OctoPrintRESTClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ class OctoPrintRESTClient {
// MARK: - Cancel Object Plugin operations

/// Get list of objects that are part of the current gcode being printed. Objects already cancelled will be part of the response
func getCancelObjects(callback: @escaping (Array<CancelObject>?, Error?, HTTPURLResponse) -> Void) {
func getCancelObjects(ignore: Array<String>, callback: @escaping (Array<CancelObject>?, Error?, HTTPURLResponse) -> Void) {
if let client = httpClient {
let json : NSMutableDictionary = NSMutableDictionary()
json["command"] = "objlist"
Expand All @@ -676,7 +676,8 @@ class OctoPrintRESTClient {
if let jsonArray = json["list"] as? NSArray {
var cancelObjects: Array<CancelObject> = Array()
for case let item as NSDictionary in jsonArray {
if let cancelObject = CancelObject.parse(json: item) {
if let cancelObject = CancelObject.parse(json: item), !ignore.contains(cancelObject.object) {
// Only add object if not present in ignored list
cancelObjects.append(cancelObject)
}
}
Expand Down

0 comments on commit 3bbb9db

Please sign in to comment.