/*
* Copyright 2010 Jon S Akhtar (Sylvanaar)
*
* 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 com.sylvanaar.idea.errorreporting;
import com.intellij.diagnostic.IdeErrorsDialog;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.diagnostic.ErrorReportSubmitter;
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diagnostic.SubmittedReportInfo;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NonNls;
import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import static com.intellij.openapi.diagnostic.SubmittedReportInfo.SubmissionStatus.FAILED;
import static com.intellij.openapi.diagnostic.SubmittedReportInfo.SubmissionStatus.NEW_ISSUE;
/**
* Created by IntelliJ IDEA.
* User: Jon S Akhtar
* Date: Oct 19, 2010
* Time: 11:35:35 AM
*/
public class YouTrackBugReporter extends ErrorReportSubmitter {
private static final Logger log = Logger.getInstance(YouTrackBugReporter.class.getName());
@NonNls
private static final String SERVER_URL = "http://sylvanaar.myjetbrains.com/youtrack/";
private static final String SERVER_REST_URL = SERVER_URL + "rest/";
private static final String SERVER_ISSUE_URL = SERVER_REST_URL + "issue";
private static final String LOGIN_URL = SERVER_REST_URL + "user/login";
private static final String userName = "autosubmit";
private String description = null;
private String extraInformation = "";
private String affectedVersion = null;
private final CookieManager cookieManager = new CookieManager();
String submit() {
if (this.description == null || this.description.length() == 0) throw new RuntimeException("Description");
String project = "IDLua";
if (project == null || project.length() == 0) throw new RuntimeException("Project");
String area = "Main";
if (area == null || area.length() == 0) throw new RuntimeException("Area");
String response = "";
//Create Post String
String data;
try {
data = URLEncoder.encode("login", "UTF-8") + "=" + URLEncoder.encode(userName, "UTF-8");
data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode("root", "UTF-8");
// Send Data To Page
URL url = new URL(LOGIN_URL);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get The Response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
response += line;
}
log.info(response);
response = "";
// getting cookies:
// setting cookies
cookieManager.storeCookies(conn);
// project=TST&assignee=beto&summary=new issue&description=description of new issue
// #&priority=show-stopper&type=feature&subsystem=UI&state=Reopened&affectsVersion=2.0,
// 2.0.1&fixedVersions=2.0&fixedInBuild=2.0.1
// POST /rest/issue?{project}&{assignee}&{summary}&{description}&{priority}&{type}&{subsystem}&{state
// }&{affectsVersion}&{fixedVersions}&{attachments}&{fixedInBuild}
data = URLEncoder.encode("project", "UTF-8") + "=" + URLEncoder.encode(project, "UTF-8");
data += "&" + URLEncoder.encode("assignee", "UTF-8") + "=" + URLEncoder.encode("Unassigned", "UTF-8");
data += "&" + URLEncoder.encode("summary", "UTF-8") + "=" + URLEncoder.encode(description, "UTF-8");
data += "&" + URLEncoder.encode("description", "UTF-8") + "=" +
URLEncoder.encode(extraInformation, "UTF-8");
data += "&" + URLEncoder.encode("priority", "UTF-8") + "=" + URLEncoder.encode("4", "UTF-8");
data += "&" + URLEncoder.encode("type", "UTF-8") + "=" + URLEncoder.encode("Exception", "UTF-8");
if (this.affectedVersion != null) data += "&" + URLEncoder.encode("affectsVersion", "UTF-8") + "=" +
URLEncoder.encode(this.affectedVersion, "UTF-8");
// Send Data To Page
url = new URL(SERVER_ISSUE_URL);
conn = url.openConnection();
conn.setDoOutput(true);
cookieManager.setCookies(conn);
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get The Response
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null) {
response += line;
}
} catch (Exception e) {
log.info("Error creating issue", e);
}
return response;
}
// POST /rest/issue/{issue}/execute?{command}&{comment}&{group}&{disableNotifications}&{runAs}
private void runCommand(String issueID, String command) {
try {
log.debug(String.format("Run Command <%s> on issue <%s>", command, issueID));
URL url = new URL(SERVER_ISSUE_URL + "/" + issueID + "/execute");
String data = URLEncoder.encode("command", "UTF-8") + "=" + URLEncoder.encode(command, "UTF-8");
data += "&" + URLEncoder.encode("disableNotifications", "UTF-8") + "=" + URLEncoder.encode("true",
"UTF-8");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
cookieManager.setCookies(conn);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get The Response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
String response = "";
while ((line = rd.readLine()) != null) {
response += line;
}
log.debug(response);
} catch (IOException e) {
log.info("Command Failed", e);
}
}
@Override
public String getReportActionText() {
return "Report Error";
}
@Override
public SubmittedReportInfo submit(IdeaLoggingEvent[] ideaLoggingEvents, Component component) {
// show modal error submission dialog
PluginErrorSubmitDialog dialog = new PluginErrorSubmitDialog(component);
dialog.prepare();
dialog.show();
// submit error to server if user pressed SEND
int code = dialog.getExitCode();
if (code == DialogWrapper.OK_EXIT_CODE) {
dialog.persist();
String description = dialog.getDescription();
String user = dialog.getUser();
return submit(ideaLoggingEvents, description, user, component);
}
return null;
}
@Override
public void submitAsync(IdeaLoggingEvent[] events, String additionalInfo, Component parentComponent,
Consumer<SubmittedReportInfo> consumer) {
this.description = additionalInfo;
super.submitAsync(events, additionalInfo, parentComponent, consumer);
}
private SubmittedReportInfo submit(IdeaLoggingEvent[] ideaLoggingEvents, String description, String user,
Component component) {
final IdeaLoggingEvent ideaLoggingEvent = ideaLoggingEvents[0];
final String throwableText = ideaLoggingEvent.getThrowableText();
this.description = throwableText.substring(0, Math.min(Math.max(80, throwableText.length()), 80));
@NonNls StringBuilder descBuilder = new StringBuilder();
String platformBuild = ApplicationInfo.getInstance().getBuild().asString();
descBuilder.append("Platform Version: ").append(platformBuild).append('\n');
Throwable t = ideaLoggingEvent.getThrowable();
if (t != null) {
final PluginId pluginId = IdeErrorsDialog.findPluginId(t);
if (pluginId != null) {
final IdeaPluginDescriptor ideaPluginDescriptor = PluginManager.getPlugin(pluginId);
if (ideaPluginDescriptor != null && !ideaPluginDescriptor.isBundled()) {
descBuilder.append("Plugin ").append(ideaPluginDescriptor.getName()).append(" version: ")
.append(ideaPluginDescriptor.getVersion()).append("\n");
this.affectedVersion = ideaPluginDescriptor.getVersion();
}
}
}
if (description == null) description = "<none>";
descBuilder.append("\n\nDescription: ").append(description);
for (IdeaLoggingEvent e : ideaLoggingEvents)
descBuilder.append("\n\n").append(e.toString());
this.extraInformation = descBuilder.toString();
String result = submit();
log.debug("Error submitted, response: " + result);
if (result == null)
return new SubmittedReportInfo(SERVER_ISSUE_URL, "", FAILED);
String ResultString = null;
try {
Pattern regex = Pattern.compile("id=\"([^\"]+)\"", Pattern.DOTALL | Pattern.MULTILINE);
Matcher regexMatcher = regex.matcher(result);
if (regexMatcher.find()) {
ResultString = regexMatcher.group(1);
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
SubmittedReportInfo.SubmissionStatus status = NEW_ISSUE;
if (ResultString == null)
return new SubmittedReportInfo(SERVER_ISSUE_URL, "", FAILED);
final SubmittedReportInfo reportInfo = new SubmittedReportInfo(SERVER_URL + "issue/" + ResultString, ResultString, status);
/* Now try to set the autosubmit user using a custom command */
if (user != null)
runCommand(ResultString, "Autosubmit User " + user);
return reportInfo;
}
}