OSDN Git Service

htn.to の展開時にHTTPSを強制的に使用する
[opentween/open-tween.git] / OpenTween / SendErrorReportForm.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2015 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.Collections.Generic;
24 using System.ComponentModel;
25 using System.Data;
26 using System.Diagnostics;
27 using System.Drawing;
28 using System.IO;
29 using System.IO.Compression;
30 using System.Linq;
31 using System.Runtime.CompilerServices;
32 using System.Text;
33 using System.Threading.Tasks;
34 using System.Windows.Forms;
35 using OpenTween.Api.DataModel;
36
37 namespace OpenTween
38 {
39     public partial class SendErrorReportForm : OTBaseForm
40     {
41         public ErrorReport ErrorReport
42         {
43             get => this._errorReport;
44             set
45             {
46                 this._errorReport = value;
47                 this.bindingSource.DataSource = value;
48             }
49         }
50         private ErrorReport _errorReport;
51
52         public SendErrorReportForm()
53             => this.InitializeComponent();
54
55         private void SendErrorReportForm_Shown(object sender, EventArgs e)
56         {
57             this.pictureBoxIcon.Image = SystemIcons.Error.ToBitmap();
58             this.textBoxErrorReport.DeselectAll();
59         }
60
61         private void buttonReset_Click(object sender, EventArgs e)
62             => this.ErrorReport.Reset();
63
64         private async void buttonSendByMail_Click(object sender, EventArgs e)
65         {
66             this.DialogResult = DialogResult.OK;
67             await this.ErrorReport.SendByMailAsync();
68         }
69
70         private async void buttonSendByDM_Click(object sender, EventArgs e)
71         {
72             this.DialogResult = DialogResult.OK;
73
74             try
75             {
76                 await this.ErrorReport.SendByDmAsync();
77
78                 MessageBox.Show(Properties.Resources.SendErrorReport_DmSendCompleted, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
79             }
80             catch (WebApiException ex)
81             {
82                 var message = Properties.Resources.SendErrorReport_DmSendError + Environment.NewLine + "Err:" + ex.Message;
83                 MessageBox.Show(message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
84             }
85         }
86
87         private void buttonNotSend_Click(object sender, EventArgs e)
88             => this.DialogResult = DialogResult.Cancel;
89     }
90
91     public class ErrorReport : NotifyPropertyChangedBase
92     {
93         public string ReportText
94         {
95             get => this._reportText;
96             set
97             {
98                 this.SetProperty(ref this._reportText, value);
99                 this.UpdateEncodedReport();
100             }
101         }
102         private string _reportText;
103
104         public bool AnonymousReport
105         {
106             get => this._anonymousReport;
107             set
108             {
109                 this.SetProperty(ref this._anonymousReport, value);
110                 this.UpdateEncodedReport();
111             }
112         }
113         private bool _anonymousReport = true;
114
115         public bool CanSendByDM
116         {
117             get => this._canSendByDm;
118             private set => this.SetProperty(ref this._canSendByDm, value);
119         }
120         private bool _canSendByDm;
121
122         public string EncodedReportForDM
123         {
124             get => this._encodedReportForDM;
125             private set => this.SetProperty(ref this._encodedReportForDM, value);
126         }
127         private string _encodedReportForDM;
128
129         private readonly Twitter tw;
130         private readonly string originalReportText;
131
132         public ErrorReport(string reportText)
133             : this(null, reportText)
134         {
135         }
136
137         public ErrorReport(Twitter tw, string reportText)
138         {
139             this.tw = tw;
140             this.originalReportText = reportText;
141
142             this.Reset();
143         }
144
145         public void Reset()
146             => this.ReportText = this.originalReportText;
147
148         public async Task SendByMailAsync()
149         {
150             var toAddress = ApplicationSettings.FeedbackEmailAddress;
151             var subject = $"{ApplicationSettings.ApplicationName} {MyCommon.GetReadableVersion()} エラーログ";
152             var body = this.ReportText;
153
154             var mailto = $"mailto:{Uri.EscapeDataString(toAddress)}?subject={Uri.EscapeDataString(subject)}&body={Uri.EscapeDataString(body)}";
155             await Task.Run(() => Process.Start(mailto));
156         }
157
158         public async Task SendByDmAsync()
159             => await this.tw.SendDirectMessage(this.EncodedReportForDM);
160
161         private void UpdateEncodedReport()
162         {
163             if (!this.CheckDmAvailable())
164             {
165                 this.CanSendByDM = false;
166                 return;
167             }
168
169             var body = $"Anonymous: {this.AnonymousReport}" + Environment.NewLine + this.ReportText;
170             var originalBytes = Encoding.UTF8.GetBytes(body);
171
172             using (var outputStream = new MemoryStream())
173             {
174                 using (var gzipStream = new GZipStream(outputStream, CompressionMode.Compress, leaveOpen: true))
175                 {
176                     gzipStream.Write(originalBytes, 0, originalBytes.Length);
177                 }
178
179                 var encodedReport = Convert.ToBase64String(outputStream.ToArray());
180                 var destScreenName = ApplicationSettings.FeedbackTwitterName.Substring(1);
181                 this.EncodedReportForDM = $"D {destScreenName} ErrorReport: {encodedReport}";
182             }
183
184             this.CanSendByDM = this.tw.GetTextLengthRemain(this.EncodedReportForDM) >= 0;
185         }
186
187         private bool CheckDmAvailable()
188         {
189             if (!ApplicationSettings.AllowSendErrorReportByDM)
190                 return false;
191
192             if (this.tw == null || !this.tw.AccessLevel.HasFlag(TwitterApiAccessLevel.DirectMessage))
193                 return false;
194
195             if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid)
196                 return false;
197
198             return true;
199         }
200     }
201 }