Skip to content

Commit d10e71e

Browse files
committed
Initial try. But the github library used doesn't work.
1 parent 68ac75f commit d10e71e

8 files changed

Lines changed: 504 additions & 12 deletions

File tree

Mathematica-IntelliJ-Plugin.iml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
</library>
2121
</orderEntry>
2222
<orderEntry type="library" exported="" name="com.google.guava:guava:r09" level="project" />
23+
<orderEntry type="library" name="com.jcabi:jcabi-github:0.9.4" level="project" />
2324
</component>
2425
</module>

resources/META-INF/plugin.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
<extensions defaultExtensionNs="com.intellij">
8383
<internalFileTemplate name="Package"/>
8484

85-
<errorHandler implementation="de.halirutan.mathematica.errorreporting.YouTrackBugReporter"/>
85+
<errorHandler implementation="de.halirutan.mathematica.errorreporting.ErrorReporter"/>
8686
<fileTypeFactory implementation="de.halirutan.mathematica.MathematicaFileTypeFactory"/>
8787
<lang.parserDefinition language="Mathematica"
8888
implementationClass="de.halirutan.mathematica.parsing.prattparser.MathematicaParserDefinition"/>
@@ -211,11 +211,11 @@
211211
<!--<add-to-group group-id="EditMenu" anchor="after" relative-to-action="TemplateParametersNavigation"/>-->
212212
<!--</action>-->
213213

214-
<!--Action for throwing an exception just to test the reporting of errors into the YouTrack database-->
215-
<!--<action id="de.halirutan.mathematica.errorreporting.TriggerExceptionAction"-->
216-
<!--class="de.halirutan.mathematica.errorreporting.TriggerExceptionAction" text="FireArtificialException">-->
217-
<!--<keyboard-shortcut keymap="$default" first-keystroke="shift ctrl alt F12"/>-->
218-
<!--</action>-->
214+
Action for throwing an exception just to test the reporting of errors into the YouTrack database
215+
<action id="de.halirutan.mathematica.errorreporting.TriggerExceptionAction"
216+
class="de.halirutan.mathematica.errorreporting.TriggerExceptionAction" text="FireArtificialException">
217+
<keyboard-shortcut keymap="$default" first-keystroke="shift ctrl alt F12"/>
218+
</action>
219219
<group id="MathematicaMenu" text="Mathematica" popup="true">
220220
<action id="Mathematica.ExpandNamedCharacters"
221221
class="de.halirutan.mathematica.actions.ExpandNamedCharactersAction"
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* Copyright (c) 2017 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.errorreporting;
23+
24+
import com.google.gson.Gson;
25+
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
26+
import com.intellij.ide.plugins.PluginManager;
27+
import com.intellij.openapi.extensions.PluginId;
28+
import com.jcabi.aspects.Loggable;
29+
import com.jcabi.github.*;
30+
import com.jcabi.http.wire.RetryWire;
31+
import org.jetbrains.annotations.NotNull;
32+
33+
import java.io.IOException;
34+
import java.io.OutputStream;
35+
import java.net.HttpURLConnection;
36+
import java.net.URL;
37+
import java.nio.charset.Charset;
38+
import java.util.HashMap;
39+
import java.util.LinkedHashMap;
40+
import java.util.Map.Entry;
41+
42+
@Loggable(Loggable.DEBUG)
43+
class AnonymousFeedback {
44+
45+
private final static String gitUser = "Mathematica-IntelliJ-Plugin";
46+
private final static String gitAccessToken = "4a78410ba07788116772376360a55e25263e7cec";
47+
private final static String gitRepo = "Mathematica-IntelliJ-Plugin";
48+
49+
private Github myGitHub;
50+
private Repo myRepository;
51+
private Issues myIssues;
52+
53+
public AnonymousFeedback() {
54+
myGitHub = new RtGithub(new RtGithub(gitAccessToken).entry().through(RetryWire.class));
55+
myRepository = myGitHub.repos().get(new Coordinates.Simple(gitUser, gitRepo));
56+
myIssues = myRepository.issues();
57+
}
58+
59+
public int findDuplicate(@NotNull final String titel) {
60+
final HashMap<String, String> filter = new HashMap<>();
61+
filter.put("filter", "all");
62+
for (Issue issue : myIssues.iterate(filter)) {
63+
System.out.println(issue);
64+
}
65+
return 0;
66+
}
67+
68+
public String sendFeedback(LinkedHashMap<String, String> environmentDetails) {
69+
String errorMessage = environmentDetails.get("error.message");
70+
if (errorMessage == null || errorMessage.isEmpty()) {
71+
errorMessage = "Unspecified error";
72+
}
73+
74+
final String body = generateGithubIssueBody(environmentDetails);
75+
try {
76+
final Issue newIssue = myIssues.create(ErrorReportBundle.message("issue.title", errorMessage), body);
77+
final int issueNumber = newIssue.number();
78+
final Repo issueRepo = newIssue.repo();
79+
return "Created issue #" + issueNumber + " on " + issueRepo;
80+
} catch (IOException e) {
81+
return "Failed to create issue on GitHub";
82+
}
83+
}
84+
85+
static String sendFeedback(
86+
HttpConnectionFactory httpConnectFactory,
87+
LinkedHashMap<String, String> environmentDetails) throws IOException {
88+
89+
sendFeedback(httpConnectFactory, convertToGitHubIssueFormat(environmentDetails));
90+
91+
return Long.toString(System.currentTimeMillis());
92+
}
93+
94+
private static byte[] convertToGitHubIssueFormat(LinkedHashMap<String, String> environmentDetails) {
95+
LinkedHashMap<String, String> result = new LinkedHashMap<>(5);
96+
97+
String errorMessage = environmentDetails.get("error.message");
98+
if (errorMessage == null || errorMessage.isEmpty()) {
99+
errorMessage = "Unspecified error";
100+
}
101+
environmentDetails.remove("error.message");
102+
103+
result.put("title", ErrorReportBundle.message("issue.title", errorMessage));
104+
result.put("label", ErrorReportBundle.message("issue.label"));
105+
result.put("body", generateGithubIssueBody(environmentDetails));
106+
107+
return ((new Gson()).toJson(result)).getBytes(Charset.forName("UTF-8"));
108+
}
109+
110+
private static String generateGithubIssueBody(LinkedHashMap<String, String> body) {
111+
String errorDescription = body.get("error.description");
112+
if (errorDescription == null) {
113+
errorDescription = "";
114+
}
115+
body.remove("error.description");
116+
117+
String stackTrace = body.get("error.stacktrace");
118+
if (stackTrace == null || stackTrace.isEmpty()) {
119+
stackTrace = "invalid stacktrace";
120+
}
121+
body.remove("error.stacktrace");
122+
123+
StringBuilder result = new StringBuilder();
124+
125+
if (!errorDescription.isEmpty()) {
126+
result.append(errorDescription);
127+
result.append("\n\n");
128+
}
129+
130+
for (Entry<String, String> entry : body.entrySet()) {
131+
result.append(entry.getKey());
132+
result.append(": ");
133+
result.append(entry.getValue());
134+
result.append("\n");
135+
}
136+
137+
result.append("\n```\n");
138+
result.append(stackTrace);
139+
result.append("\n```\n");
140+
141+
return result.toString();
142+
}
143+
144+
private static void sendFeedback(HttpConnectionFactory httpConnectFactory, byte[] payload) throws IOException {
145+
String url = "https://api.github.com/repos/halirutan/Mathematica-IntelliJ-Plugin/issues?access_token=3d23871d02daa221d2270b0df18196ba821628f5";
146+
String userAgent = "Mathematica IntelliJ IDEA plugin";
147+
148+
IdeaPluginDescriptorImpl pluginDescriptor = (IdeaPluginDescriptorImpl) PluginManager.getPlugin(PluginId.getId("de.halirutan.mathematica"));
149+
if (pluginDescriptor != null) {
150+
String name = pluginDescriptor.getName();
151+
String version = pluginDescriptor.getVersion();
152+
userAgent = name + " (" + version + ")";
153+
}
154+
155+
HttpURLConnection httpURLConnection = connect(httpConnectFactory, url);
156+
httpURLConnection.setDoOutput(true);
157+
httpURLConnection.setRequestMethod("POST");
158+
httpURLConnection.setRequestProperty("User-Agent", userAgent);
159+
httpURLConnection.setRequestProperty("Content-Type", "application/json");
160+
161+
try (OutputStream outputStream = httpURLConnection.getOutputStream()) {
162+
outputStream.write(payload);
163+
}
164+
165+
int responseCode = httpURLConnection.getResponseCode();
166+
if (responseCode != 201) {
167+
throw new RuntimeException("Expected HTTP_CREATED (201), obtained " + responseCode);
168+
}
169+
}
170+
171+
private static HttpURLConnection connect(HttpConnectionFactory httpConnectFactory, String url) throws IOException {
172+
HttpURLConnection httpURLConnection = httpConnectFactory.openHttpConnection(url);
173+
httpURLConnection.setConnectTimeout(5000);
174+
httpURLConnection.setReadTimeout(5000);
175+
return httpURLConnection;
176+
}
177+
178+
public static class HttpConnectionFactory {
179+
HttpConnectionFactory() {
180+
}
181+
182+
protected HttpURLConnection openHttpConnection(String url) throws IOException {
183+
return (HttpURLConnection) ((new URL(url)).openConnection());
184+
}
185+
}
186+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2017 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.errorreporting;
23+
24+
import com.intellij.openapi.progress.ProgressIndicator;
25+
import com.intellij.openapi.progress.Task.Backgroundable;
26+
import com.intellij.openapi.project.Project;
27+
import com.intellij.util.Consumer;
28+
import com.intellij.util.net.HttpConfigurable;
29+
import de.halirutan.mathematica.errorreporting.AnonymousFeedback.HttpConnectionFactory;
30+
import org.jetbrains.annotations.NotNull;
31+
import org.jetbrains.annotations.Nullable;
32+
33+
import java.io.IOException;
34+
import java.net.HttpURLConnection;
35+
import java.util.LinkedHashMap;
36+
37+
38+
/**
39+
* Sends crash reports to Github. Extensively inspired by the one used in the Android Studio.
40+
* https://android.googlesource.com/platform/tools/adt/idea/+/master/android/src/com/android/tools/idea/diagnostics/error/ErrorReporter.java
41+
* As per answer from here: http://devnet.jetbrains.com/message/5526206;jsessionid=F5422B4AF1AFD05AAF032636E5455E90#5526206
42+
*/
43+
public class AnonymousFeedbackTask extends Backgroundable {
44+
private final Consumer<String> myCallback;
45+
private final Consumer<Exception> myErrorCallback;
46+
private final LinkedHashMap<String, String> myParams;
47+
48+
AnonymousFeedbackTask(@Nullable Project project,
49+
@NotNull String title,
50+
boolean canBeCancelled,
51+
LinkedHashMap<String, String> params,
52+
final Consumer<String> callback,
53+
final Consumer<Exception> errorCallback) {
54+
super(project, title, canBeCancelled);
55+
56+
myParams = params;
57+
myCallback = callback;
58+
myErrorCallback = errorCallback;
59+
}
60+
61+
@Override
62+
public void run(@NotNull ProgressIndicator indicator) {
63+
indicator.setIndeterminate(true);
64+
AnonymousFeedback feedback = new AnonymousFeedback();
65+
try {
66+
String token = feedback.sendFeedback(myParams);
67+
myCallback.consume(token);
68+
} catch (Exception e) {
69+
myErrorCallback.consume(e);
70+
}
71+
}
72+
73+
private static class ProxyHttpConnectionFactory extends HttpConnectionFactory {
74+
@Override
75+
protected HttpURLConnection openHttpConnection(String url) throws IOException {
76+
return HttpConfigurable.getInstance().openHttpConnection(url);
77+
}
78+
}
79+
}

src/de/halirutan/mathematica/errorreporting/PluginErrorReportSubmitterBundle.java renamed to src/de/halirutan/mathematica/errorreporting/ErrorReportBundle.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,34 @@
2323
import com.intellij.CommonBundle;
2424
import org.jetbrains.annotations.PropertyKey;
2525

26+
import java.lang.ref.Reference;
27+
import java.lang.ref.SoftReference;
2628
import java.util.ResourceBundle;
2729

2830
/**
2931
* This class allows for i18n of the messages displayed by the error report submitter.
3032
*
3133
* @author <a href="mailto:intellij@studer.nu">Etienne Studer</a>, Jun 13, 2006
3234
*/
33-
class PluginErrorReportSubmitterBundle {
34-
private static final ResourceBundle OUR_BUNDLE = ResourceBundle.getBundle("com.sylvanaar.idea.errorreporting.PluginErrorReportSubmitterBundle");
35+
class ErrorReportBundle {
36+
private static final String BUNDLE = "de.halirutan.mathematica.errorreporting.ErrorReportBundle";
37+
private static Reference<ResourceBundle> ourBundle = null;
3538

36-
private PluginErrorReportSubmitterBundle() {
39+
private ErrorReportBundle() {
3740
}
3841

39-
public static String message(@PropertyKey(resourceBundle = "com.sylvanaar.idea.errorreporting.PluginErrorReportSubmitterBundle") String key,
40-
Object... params) {
41-
return CommonBundle.message(OUR_BUNDLE, key, params);
42+
public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) {
43+
return CommonBundle.message(getBundle(), key, params);
44+
}
45+
46+
47+
private static ResourceBundle getBundle() {
48+
ResourceBundle bundle = null;
49+
if (ourBundle != null) bundle = ourBundle.get();
50+
if (bundle == null) {
51+
bundle = ResourceBundle.getBundle(BUNDLE);
52+
ourBundle = new SoftReference<>(bundle);
53+
}
54+
return bundle;
4255
}
4356
}

src/de/halirutan/mathematica/errorreporting/PluginErrorReportSubmitterBundle.properties renamed to src/de/halirutan/mathematica/errorreporting/ErrorReportBundle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ error.dialog.connection.0.error=Cannot reach server at {0}. Make sure the proxy
3030

3131
successful.dialog.title=Plugin Error Submission
3232
successful.dialog.message=Error report has been submitted successfully. Thank you for your feedback!
33+
issue.title=[auto-generated] {0}
34+
issue.label=auto-generated
3335

0 commit comments

Comments
 (0)