// OpenTween - Client of Twitter // Copyright (c) 2015 kim_upsilon (@kim_upsilon) // All rights reserved. // // This file is part of OpenTween. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 3 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see , or write to // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, // Boston, MA 02110-1301, USA. #nullable enable using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.IO.Compression; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OpenTween.Api.DataModel; namespace OpenTween { public partial class SendErrorReportForm : OTBaseForm { public ErrorReport ErrorReport { get => this._errorReport; set { this._errorReport = value; this.bindingSource.DataSource = value; } } private ErrorReport _errorReport = null!; public SendErrorReportForm() => this.InitializeComponent(); private void SendErrorReportForm_Shown(object sender, EventArgs e) { this.pictureBoxIcon.Image = SystemIcons.Error.ToBitmap(); this.textBoxErrorReport.DeselectAll(); } private void buttonReset_Click(object sender, EventArgs e) => this.ErrorReport.Reset(); private async void buttonSendByMail_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.OK; await this.ErrorReport.SendByMailAsync(); } private async void buttonSendByDM_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.OK; try { await this.ErrorReport.SendByDmAsync(); MessageBox.Show(Properties.Resources.SendErrorReport_DmSendCompleted, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (WebApiException ex) { var message = Properties.Resources.SendErrorReport_DmSendError + Environment.NewLine + "Err:" + ex.Message; MessageBox.Show(message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void buttonNotSend_Click(object sender, EventArgs e) => this.DialogResult = DialogResult.Cancel; } public class ErrorReport : NotifyPropertyChangedBase { public string ReportText { get => this._reportText; set { this.SetProperty(ref this._reportText, value); this.UpdateEncodedReport(); } } private string _reportText = ""; public bool AnonymousReport { get => this._anonymousReport; set { this.SetProperty(ref this._anonymousReport, value); this.UpdateEncodedReport(); } } private bool _anonymousReport = true; public bool CanSendByDM { get => this._canSendByDm; private set => this.SetProperty(ref this._canSendByDm, value); } private bool _canSendByDm; public string EncodedReportForDM { get => this._encodedReportForDM; private set => this.SetProperty(ref this._encodedReportForDM, value); } private string _encodedReportForDM = ""; private readonly Twitter? tw; private readonly string originalReportText; public ErrorReport(string reportText) : this(null, reportText) { } public ErrorReport(Twitter? tw, string reportText) { this.tw = tw; this.originalReportText = reportText; this.Reset(); } public void Reset() => this.ReportText = this.originalReportText; public async Task SendByMailAsync() { var toAddress = ApplicationSettings.FeedbackEmailAddress; var subject = $"{ApplicationSettings.ApplicationName} {MyCommon.GetReadableVersion()} エラーログ"; var body = this.ReportText; var mailto = $"mailto:{Uri.EscapeDataString(toAddress)}?subject={Uri.EscapeDataString(subject)}&body={Uri.EscapeDataString(body)}"; await Task.Run(() => Process.Start(mailto)); } public async Task SendByDmAsync() { if (!this.CheckDmAvailable()) return; await this.tw!.SendDirectMessage(this.EncodedReportForDM); } private void UpdateEncodedReport() { if (!this.CheckDmAvailable()) { this.CanSendByDM = false; return; } var body = $"Anonymous: {this.AnonymousReport}" + Environment.NewLine + this.ReportText; var originalBytes = Encoding.UTF8.GetBytes(body); using (var outputStream = new MemoryStream()) { using (var gzipStream = new GZipStream(outputStream, CompressionMode.Compress, leaveOpen: true)) { gzipStream.Write(originalBytes, 0, originalBytes.Length); } var encodedReport = Convert.ToBase64String(outputStream.ToArray()); var destScreenName = ApplicationSettings.FeedbackTwitterName.Substring(1); this.EncodedReportForDM = $"D {destScreenName} ErrorReport: {encodedReport}"; } this.CanSendByDM = this.tw!.GetTextLengthRemain(this.EncodedReportForDM) >= 0; } private bool CheckDmAvailable() { if (!ApplicationSettings.AllowSendErrorReportByDM) return false; if (this.tw == null || !this.tw.AccessLevel.HasFlag(TwitterApiAccessLevel.DirectMessage)) return false; if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return false; return true; } } }