Fine-grain report attachments
- Debug log - .ovpn profile (if any)
This commit is contained in:
parent
821393af70
commit
dfde9c51e3
|
@ -27,6 +27,22 @@ import Foundation
|
|||
import MessageUI
|
||||
|
||||
class IssueReporter: NSObject {
|
||||
struct Attachments {
|
||||
let debugLog: Bool
|
||||
|
||||
let configurationURL: URL?
|
||||
|
||||
init(debugLog: Bool, configurationURL: URL?) {
|
||||
self.debugLog = debugLog
|
||||
self.configurationURL = configurationURL
|
||||
}
|
||||
|
||||
init(debugLog: Bool, profile: ConnectionProfile) {
|
||||
let url = TransientStore.shared.service.configurationURL(for: profile)
|
||||
self.init(debugLog: debugLog, configurationURL: url)
|
||||
}
|
||||
}
|
||||
|
||||
static let shared = IssueReporter()
|
||||
|
||||
private weak var viewController: UIViewController?
|
||||
|
@ -35,7 +51,7 @@ class IssueReporter: NSObject {
|
|||
super.init()
|
||||
}
|
||||
|
||||
func present(in viewController: UIViewController) {
|
||||
func present(in viewController: UIViewController, withAttachments attachments: Attachments) {
|
||||
guard MFMailComposeViewController.canSendMail() else {
|
||||
let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.Alerts.EmailNotConfigured.message)
|
||||
alert.addCancelAction(L10n.Global.ok)
|
||||
|
@ -45,17 +61,21 @@ class IssueReporter: NSObject {
|
|||
|
||||
self.viewController = viewController
|
||||
|
||||
let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.message)
|
||||
alert.addDefaultAction(L10n.IssueReporter.Buttons.accept) {
|
||||
VPN.shared.requestDebugLog(fallback: AppConstants.Log.debugSnapshot) {
|
||||
self.composeEmail(withDebugLog: $0)
|
||||
if attachments.debugLog {
|
||||
let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.message)
|
||||
alert.addDefaultAction(L10n.IssueReporter.Buttons.accept) {
|
||||
VPN.shared.requestDebugLog(fallback: AppConstants.Log.debugSnapshot) {
|
||||
self.composeEmail(withDebugLog: $0, configurationURL: attachments.configurationURL)
|
||||
}
|
||||
}
|
||||
alert.addCancelAction(L10n.Global.cancel)
|
||||
viewController.present(alert, animated: true, completion: nil)
|
||||
} else {
|
||||
composeEmail(withDebugLog: nil, configurationURL: attachments.configurationURL)
|
||||
}
|
||||
alert.addCancelAction(L10n.Global.cancel)
|
||||
viewController.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
private func composeEmail(withDebugLog debugLog: String?) {
|
||||
private func composeEmail(withDebugLog debugLog: String?, configurationURL: URL?) {
|
||||
let metadata = DebugLog(raw: "--").decoratedString()
|
||||
|
||||
let vc = MFMailComposeViewController()
|
||||
|
@ -64,7 +84,10 @@ class IssueReporter: NSObject {
|
|||
vc.setMessageBody(L10n.IssueReporter.Email.body(metadata), isHTML: false)
|
||||
if let raw = debugLog {
|
||||
let attachment = DebugLog(raw: raw).decoratedData()
|
||||
vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.attachmentMIME, fileName: AppConstants.Log.debugFilename)
|
||||
vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.debugLog, fileName: AppConstants.IssueReporter.Filenames.debugLog)
|
||||
}
|
||||
if let cfg = configurationURL, let attachment = try? Data(contentsOf: cfg) {
|
||||
vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.configuration, fileName: AppConstants.IssueReporter.Filenames.configuration)
|
||||
}
|
||||
vc.mailComposeDelegate = self
|
||||
vc.apply(Theme.current)
|
||||
|
|
|
@ -64,7 +64,7 @@ class DebugLogViewController: UIViewController {
|
|||
}
|
||||
let data = DebugLog(raw: raw).decoratedData()
|
||||
|
||||
let path = NSTemporaryDirectory().appending(AppConstants.Log.debugFilename)
|
||||
let path = NSTemporaryDirectory().appending(AppConstants.IssueReporter.Filenames.debugLog)
|
||||
let url = URL(fileURLWithPath: path)
|
||||
do {
|
||||
try data.write(to: url)
|
||||
|
|
|
@ -361,7 +361,8 @@ class ServiceViewController: UIViewController, TableModelHost {
|
|||
}
|
||||
|
||||
private func reportConnectivityIssue() {
|
||||
IssueReporter.shared.present(in: self)
|
||||
let attach = IssueReporter.Attachments(debugLog: true, profile: uncheckedProfile)
|
||||
IssueReporter.shared.present(in: self, withAttachments: attach)
|
||||
}
|
||||
|
||||
// MARK: Notifications
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
"issue_reporter.message" = "The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous.";
|
||||
"issue_reporter.buttons.accept" = "I understand";
|
||||
"issue_reporter.alerts.email_not_configured.message" = "No e-mail account is configured.";
|
||||
"issue_reporter.email.subject" = "%@ - Debug log";
|
||||
"issue_reporter.email.subject" = "%@ - Report issue";
|
||||
"issue_reporter.email.body" = "Hi,\n\ndescription of the issue:\n\n%@\n\nRegards";
|
||||
|
||||
"about.title" = "About";
|
||||
|
|
|
@ -96,13 +96,6 @@ class AppConstants {
|
|||
|
||||
static var debugSnapshot: () -> String = { TransientStore.shared.service.vpnLog }
|
||||
|
||||
static var debugFilename: String {
|
||||
let fmt = DateFormatter()
|
||||
fmt.dateFormat = "yyyyMMdd-HHmmss"
|
||||
let iso = fmt.string(from: Date())
|
||||
return "debug-\(iso).txt"
|
||||
}
|
||||
|
||||
static let viewerRefreshInterval: TimeInterval = 3.0
|
||||
|
||||
static func configure() {
|
||||
|
@ -116,7 +109,22 @@ class AppConstants {
|
|||
class IssueReporter {
|
||||
static let recipient = "issues@\(Domain.name)"
|
||||
|
||||
static let attachmentMIME = "text/plain"
|
||||
class Filenames {
|
||||
static var debugLog: String {
|
||||
let fmt = DateFormatter()
|
||||
fmt.dateFormat = "yyyyMMdd-HHmmss"
|
||||
let iso = fmt.string(from: Date())
|
||||
return "debug-\(iso).txt"
|
||||
}
|
||||
|
||||
static let configuration = "profile.ovpn"
|
||||
}
|
||||
|
||||
class MIME {
|
||||
static let debugLog = "text/plain"
|
||||
|
||||
static let configuration = "application/x-openvpn-profile"
|
||||
}
|
||||
}
|
||||
|
||||
class URLs {
|
||||
|
|
|
@ -324,7 +324,7 @@ internal enum L10n {
|
|||
internal static func body(_ p1: String) -> String {
|
||||
return L10n.tr("Localizable", "issue_reporter.email.body", p1)
|
||||
}
|
||||
/// %@ - Debug log
|
||||
/// %@ - Report issue
|
||||
internal static func subject(_ p1: String) -> String {
|
||||
return L10n.tr("Localizable", "issue_reporter.email.subject", p1)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue