blob: ab54dc6b665c052b60371d6575eafca48ac218b4 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jf.smalidea.errorReporting;
import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.Map;
public class GithubFeedbackTask extends Task.Backgroundable {
private final Consumer<String> myCallback;
private final Consumer<Exception> myErrorCallback;
private final Map<String, String> myParams;
public GithubFeedbackTask(@Nullable Project project,
@NotNull String title,
boolean canBeCancelled,
Map<String, String> params,
final Consumer<String> callback,
final Consumer<Exception> errorCallback) {
super(project, title, canBeCancelled);
myParams = params;
myCallback = callback;
myErrorCallback = errorCallback;
}
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
try {
String token = sendFeedback(myParams);
myCallback.consume(token);
}
catch (Exception e) {
myErrorCallback.consume(e);
}
}
private static String getToken() {
InputStream stream = GithubFeedbackTask.class.getClassLoader().getResourceAsStream("token");
if (stream == null) {
return null;
}
try {
return CharStreams.toString(new InputStreamReader(stream, "UTF-8"));
} catch (IOException ex) {
return null;
}
}
public static String sendFeedback(Map<String, String> environmentDetails) throws IOException {
String url = "https://api.github.com/repos/JesusFreke/smalidea-issues/issues";
String userAgent = "smalidea plugin";
IdeaPluginDescriptorImpl pluginDescriptor =
(IdeaPluginDescriptorImpl) PluginManager.getPlugin(PluginId.getId("org.jf.smalidea"));
if (pluginDescriptor != null) {
String name = pluginDescriptor.getName();
String version = pluginDescriptor.getVersion();
userAgent = name + " (" + version + ")";
}
HttpURLConnection httpURLConnection = connect(url);
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("User-Agent", userAgent);
httpURLConnection.setRequestProperty("Content-Type", "application/json");
String token = getToken();
if (token != null) {
httpURLConnection.setRequestProperty("Authorization", "token " + token);
}
OutputStream outputStream = httpURLConnection.getOutputStream();
try {
outputStream.write(convertToGithubIssueFormat(environmentDetails));
} finally {
outputStream.close();
}
int responseCode = httpURLConnection.getResponseCode();
if (responseCode != 201) {
throw new RuntimeException("Expected HTTP_CREATED (201), obtained " + responseCode);
}
return Long.toString(System.currentTimeMillis());
}
private static byte[] convertToGithubIssueFormat(Map<String, String> environmentDetails) {
LinkedHashMap<String, String> result = new LinkedHashMap<String, String>(5);
result.put("title", "[auto-generated] Crash in plugin");
result.put("body", generateGithubIssueBody(environmentDetails));
return ((new Gson()).toJson(result)).getBytes(Charset.forName("UTF-8"));
}
private static String generateGithubIssueBody(Map<String, String> body) {
String errorDescription = body.get("error.description");
if (errorDescription == null) {
errorDescription = "";
}
body.remove("error.description");
String errorMessage = body.get("error.message");
if (errorMessage == null || errorMessage.isEmpty()) {
errorMessage = "invalid error";
}
body.remove("error.message");
String stackTrace = body.get("error.stacktrace");
if (stackTrace == null || stackTrace.isEmpty()) {
stackTrace = "invalid stacktrace";
}
body.remove("error.stacktrace");
String result = "";
if (!errorDescription.isEmpty()) {
result += errorDescription + "\n\n";
}
for (Map.Entry<String, String> entry : body.entrySet()) {
result += entry.getKey() + ": " + entry.getValue() + "\n";
}
result += "\n```\n" + stackTrace + "\n```\n";
result += "\n```\n" + errorMessage + "\n```";
return result;
}
private static HttpURLConnection connect(String url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) ((new URL(url)).openConnection());
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
return connection;
}
}