diff --git a/mac/Bagel.xcodeproj/project.pbxproj b/mac/Bagel.xcodeproj/project.pbxproj index 17153c7..f76e3f6 100644 --- a/mac/Bagel.xcodeproj/project.pbxproj +++ b/mac/Bagel.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1191142A21F8B9CB00BFCA48 /* CURLRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */; }; 9AAA3A9C54B46F8D2C8DD674 /* Pods_Bagel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00E3BE2EECB0984D92EFCA30 /* Pods_Bagel.framework */; }; BC1F5B37216746D30045C871 /* FontManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC1F5B36216746D30045C871 /* FontManager.swift */; }; BC32643621738AF0006452FE /* KeyValueRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC32643521738AF0006452FE /* KeyValueRepresentation.swift */; }; @@ -114,6 +115,7 @@ /* Begin PBXFileReference section */ 00E3BE2EECB0984D92EFCA30 /* Pods_Bagel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Bagel.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CURLRepresentation.swift; sourceTree = ""; }; BC1F5B36216746D30045C871 /* FontManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontManager.swift; sourceTree = ""; }; BC32643521738AF0006452FE /* KeyValueRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueRepresentation.swift; sourceTree = ""; }; BC5E76C8216A64DB000F658D /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; @@ -236,6 +238,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1191142821F8B9AB00BFCA48 /* CURLRepresentation */ = { + isa = PBXGroup; + children = ( + 1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */, + ); + path = CURLRepresentation; + sourceTree = ""; + }; 659EF5768D424A8F8EEB1541 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -489,6 +499,7 @@ BCEB9AA4217C951C008BBF3C /* ContentRepresentation */ = { isa = PBXGroup; children = ( + 1191142821F8B9AB00BFCA48 /* CURLRepresentation */, BCEB9AA5217C9532008BBF3C /* ContentRepresentation.swift */, BCEB9AA9217CB0BB008BBF3C /* OverviewRepresentation */, BC32643421738AB5006452FE /* ParameterRepresentation */, @@ -857,6 +868,7 @@ BCFC853021383267001EC6D7 /* ProjectsViewController.swift in Sources */, BCA60B442162395000B9DCAD /* DevicesViewModel.swift in Sources */, BC73DFAE215BFB18002E533B /* BagelPublisher.swift in Sources */, + 1191142A21F8B9CB00BFCA48 /* CURLRepresentation.swift in Sources */, BCA60B41216201B900B9DCAD /* BagelConfiguration.swift in Sources */, BC61DA752162B976000F6D2F /* DetailViewModel.swift in Sources */, BC9C77B22163897600E8ADE8 /* DataTextViewModel.swift in Sources */, diff --git a/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewController.swift b/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewController.swift index 7db543b..1dab33d 100644 --- a/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewController.swift +++ b/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewController.swift @@ -13,9 +13,11 @@ class OverviewViewController: BaseViewController { @IBOutlet var overviewTextView: NSTextView! + @IBOutlet weak var curlButton: NSButton! @IBOutlet weak var copyToClipboardButton: NSButton! var viewModel: OverviewViewModel? + private var isCurl: Bool = false override func setup() { @@ -32,11 +34,27 @@ class OverviewViewController: BaseViewController { func refresh() { - self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.overviewRepresentation?.rawString ?? "")) + if isCurl { + + self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.curlRepresentation?.rawString ?? "")) + curlButton.state = .on + } else { + + self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.overviewRepresentation?.rawString ?? "")) + curlButton.state = .off + } } + @IBAction func curlButtonAction(_ sender: Any) { + self.isCurl.toggle() + self.refresh() + } + @IBAction func copyButtonAction(_ sender: Any) { - - self.viewModel?.copyToClipboard() + if isCurl { + self.viewModel?.copyCURLToClipboard() + } else { + self.viewModel?.copyTextToClipboard() + } } } diff --git a/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewModel.swift b/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewModel.swift index da0fcb5..bd023e5 100644 --- a/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewModel.swift +++ b/mac/Bagel/Components/Details/DetailSections/OverviewViewController/OverviewViewModel.swift @@ -12,6 +12,7 @@ class OverviewViewModel: BaseViewModel { var packet: BagelPacket? var overviewRepresentation: OverviewRepresentation? + var curlRepresentation: CURLRepresentation? func register() { @@ -26,12 +27,17 @@ class OverviewViewModel: BaseViewModel { if let requestInfo = self.packet?.requestInfo { self.overviewRepresentation = OverviewRepresentation(requestInfo: requestInfo) + self.curlRepresentation = CURLRepresentation(requestInfo: requestInfo) } self.onChange?() } - func copyToClipboard() { + func copyTextToClipboard() { self.overviewRepresentation?.copyToClipboard() } + + func copyCURLToClipboard() { + self.curlRepresentation?.copyToClipboard() + } } diff --git a/mac/Bagel/Components/Details/Details.storyboard b/mac/Bagel/Components/Details/Details.storyboard index 78f21df..7314891 100644 --- a/mac/Bagel/Components/Details/Details.storyboard +++ b/mac/Bagel/Components/Details/Details.storyboard @@ -207,8 +207,21 @@ + + + @@ -241,6 +254,7 @@ + diff --git a/mac/Bagel/Workers/ContentRepresentation/ContentRepresentation/CURLRepresentation/CURLRepresentation.swift b/mac/Bagel/Workers/ContentRepresentation/ContentRepresentation/CURLRepresentation/CURLRepresentation.swift new file mode 100644 index 0000000..938d974 --- /dev/null +++ b/mac/Bagel/Workers/ContentRepresentation/ContentRepresentation/CURLRepresentation/CURLRepresentation.swift @@ -0,0 +1,52 @@ +// +// CURLRepresentation.swift +// Bagel +// +// Created by Mathias Amnell on 2019-01-23. +// Copyright © 2019 Yagiz Lab. All rights reserved. +// + +import Cocoa + +class CURLRepresentation: ContentRepresentation { + + init(requestInfo: BagelRequestInfo?) { + + super.init() + + if let requestInfo = requestInfo { + self.rawString = requestInfo.curlString + } + } +} + +extension BagelRequestInfo { + // Credits to shaps80 + // https://gist.github.com/shaps80/ba6a1e2d477af0383e8f19b87f53661d + fileprivate var curlString: String { + guard let url = url else { return "" } + var baseCommand = "curl \(url)" + + if requestMethod == "HEAD" { + baseCommand += " --head" + } + + var command = [baseCommand] + + if let method = self.requestMethod, method != "GET" && method != "HEAD" { + command.append("-X \(method)") + } + + if let headers = requestHeaders { + for (key, value) in headers where key != "Cookie" { + command.append("-H '\(key): \(value)'") + } + } + + if let data = requestBody { + command.append("-d '\(data)'") + } + + return command.joined(separator: " \\\n\t") + } +}