Warning, /network/kdeconnect-ios/KDE Connect/KDE Connect/Plugins and Plugin Views/RunCommand/RunCommand.swift is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Lucas Wang <lucas.wang@tuta.io>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 // Original header below:
0008 //
0009 //  RunCommand.swift
0010 //  KDE Connect Test
0011 //
0012 //  Created by Lucas Wang on 2021-09-16.
0013 //
0014 
0015 import SwiftUI
0016 
0017 // TODO: rename to RunCommandPlugin
0018 @objc class RunCommand: NSObject, ObservablePlugin {
0019     @objc weak var controlDevice: Device!
0020     @Published
0021     var commandEntries: [CommandEntry] = []
0022     private let logger = Logger()
0023     
0024     @objc init(controlDevice: Device) {
0025         self.controlDevice = controlDevice
0026     }
0027     
0028     typealias CommandsDictionary = [String: [String: String]]
0029     
0030     @objc func onDevicePackageReceived(np: NetworkPackage) {
0031         if (np.type == .runCommand) {
0032             if np.bodyHasKey("commandList") {
0033                 // Process the received commandList here
0034                 let commandsDict: CommandsDictionary
0035                 switch np.object(forKey: "commandList") {
0036                 case let jsonString as String:
0037                     commandsDict = processCommandsJSON(jsonString)
0038                 case let dict as CommandsDictionary:
0039                     logger.fault("out of date GSConnect with wrong RunCommand implementation")
0040                     commandsDict = dict
0041                 case let somethingElse:
0042                     logger.fault("unexpected commandList format \(type(of: somethingElse), privacy: .public)")
0043                     commandsDict = [:]
0044                 }
0045                 let newCommandEntries = processCommandsDict(commandsDict)
0046                 DispatchQueue.main.async { [weak self] in
0047                     self?.commandEntries = newCommandEntries
0048                 }
0049             } else {
0050                 logger.info("RunCommand packet received with no commandList, ignoring")
0051             }
0052         }
0053     }
0054     
0055     @objc func runCommand(cmdKey: String) {
0056         let np: NetworkPackage = NetworkPackage(type: .runCommandRequest)
0057         np.setObject(cmdKey, forKey: "key")
0058         controlDevice.send(np, tag: Int(PACKAGE_TAG_NORMAL))
0059     }
0060     
0061     @objc func requestCommandList() {
0062         let np: NetworkPackage = NetworkPackage(type: .runCommandRequest)
0063         np.setBool(true, forKey: "requestCommandList")
0064         controlDevice.send(np, tag: Int(PACKAGE_TAG_NORMAL))
0065     }
0066     
0067     @objc func sendSetupPackage() {
0068         let np: NetworkPackage = NetworkPackage(type: .runCommandRequest)
0069         np.setBool(true, forKey: "setup")
0070         controlDevice.send(np, tag: Int(PACKAGE_TAG_NORMAL))
0071     }
0072     
0073     private func processCommandsJSON(_ json: String) -> CommandsDictionary {
0074         let jsonData = Data(json.utf8)
0075         do {
0076             let json = try JSONSerialization.jsonObject(with: jsonData)
0077             guard let commandsDict = json as? CommandsDictionary else {
0078                 logger.fault("commandList JSON is \(type(of: json), privacy: .public), not CommandsDictionary")
0079                 return [:]
0080             }
0081             return commandsDict
0082         } catch {
0083             logger.fault("commandList string failed to decode as JSON due to \(error.localizedDescription, privacy: .public)")
0084             return [:]
0085         }
0086     }
0087     
0088     private func processCommandsDict(_ commandsDict: CommandsDictionary) -> [CommandEntry] {
0089         return commandsDict.compactMap { commandKey, commandInfo in
0090             if let commandName = commandInfo["name"],
0091                let command = commandInfo["command"] {
0092                 let commandEntry = CommandEntry(name: commandName, command: command, key: commandKey)
0093                 return commandEntry
0094             } else {
0095                 logger.error("Command or CommandName for \(commandKey, privacy: .public) is nil")
0096                 return nil
0097             }
0098         }
0099     }
0100 }