From 02037e9ec8059ab8c751f5e7e49cd881b2fac6a0 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Tue, 27 Sep 2011 21:11:29 +0400 Subject: [PATCH] Initial support for creating gists --- plugins/github/src/META-INF/plugin.xml | 5 + .../github/GithubCreateGistAction.java | 143 ++++++++++++++++++ .../jetbrains/plugins/github/GithubUtil.java | 8 +- .../github/ui/GitHubCreateGistDialog.java | 68 +++++++++ .../github/ui/GitHubCreateGistPanel.form | 71 +++++++++ .../github/ui/GitHubCreateGistPanel.java | 58 +++++++ 6 files changed, 350 insertions(+), 3 deletions(-) create mode 100644 plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java create mode 100644 plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistDialog.java create mode 100644 plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.form create mode 100644 plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.java diff --git a/plugins/github/src/META-INF/plugin.xml b/plugins/github/src/META-INF/plugin.xml index eefac0624e76..db65ce0b988f 100644 --- a/plugins/github/src/META-INF/plugin.xml +++ b/plugins/github/src/META-INF/plugin.xml @@ -28,6 +28,11 @@ + + + + + \ No newline at end of file diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java new file mode 100644 index 000000000000..fb7a6e1a308f --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java @@ -0,0 +1,143 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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.jetbrains.plugins.github; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.PostMethod; +import org.jetbrains.plugins.github.ui.GitHubCreateGistDialog; +import org.jetbrains.plugins.github.ui.GithubLoginDialog; + +import javax.swing.*; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author oleg + * @date 9/27/11 + */ +public class GithubCreateGistAction extends DumbAwareAction { + public static final Icon ICON = IconLoader.getIcon("/icons/github.png"); + private static final Logger LOG = Logger.getInstance(GithubCreateGistAction.class); + + protected GithubCreateGistAction() { + super("Create gist", "Create github gist", ICON); + } + + @Override + public void update(final AnActionEvent e) { + final long startTime = System.nanoTime(); + try { + final Project project = e.getData(PlatformDataKeys.PROJECT); + if (project == null || project.isDefault()) { + e.getPresentation().setVisible(false); + e.getPresentation().setEnabled(false); + return; + } + final Editor editor = e.getData(PlatformDataKeys.EDITOR); + if (editor != null){ + e.getPresentation().setVisible(true); + e.getPresentation().setEnabled(true); + return; + } + e.getPresentation().setVisible(false); + e.getPresentation().setEnabled(false); + } + finally { + if (LOG.isDebugEnabled()) { + LOG.debug("GithubCreateGistAction#update finished in: " + (System.nanoTime() - startTime) / 10e6 + "ms"); + } + } + } + + @Override + public void actionPerformed(final AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); + if (project == null || project.isDefault()) { + return; + } + final Editor editor = e.getData(PlatformDataKeys.EDITOR); + if (editor == null){ + return; + } + final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE); + if (file == null) { + return; + } + final boolean useGitHubAccount; + if (!GithubUtil.checkCredentials(project)) { + final GithubLoginDialog dialog = new GithubLoginDialog(project); + dialog.show(); + useGitHubAccount = GithubUtil.checkCredentials(project); + } else { + useGitHubAccount = true; + } + + // Ask for description and other params + final GitHubCreateGistDialog dialog = new GitHubCreateGistDialog(project, useGitHubAccount); + dialog.show(); + if (!dialog.isOK()){ + return; + } + final String description = dialog.getDescription(); + final boolean isPrivate = dialog.isPrivate(); + final boolean anonymous = dialog.isAnonimous(); + + final SelectionModel selectionModel = editor.getSelectionModel(); + final String text = selectionModel.hasSelection() ? selectionModel.getSelectedText() : editor.getDocument().getText(); + final GithubSettings settings = GithubSettings.getInstance(); + final HttpClient client = anonymous ? GithubUtil.getHttpClient(null, null) : GithubUtil.getHttpClient(settings.getLogin(), settings.getPassword()); + client.getParams().setContentCharset("UTF-8"); + + final PostMethod method = new PostMethod("https://gist.github.com/gists"); + method.addParameters(new NameValuePair[]{ + new NameValuePair("description", description), + new NameValuePair("file_ext[gistfile1]", "." + file.getExtension()), + new NameValuePair("file_name[gistfile1]", file.getNameWithoutExtension()), + new NameValuePair("file_contents[gistfile1]", text) + }); + if (isPrivate){ + method.addParameter("action_button", "private"); + } + try { + client.executeMethod(method); + final String responce = method.getResponseBodyAsString(); + // TODO[oleg] fix it when github API v3 becomes public + // http://developer.github.com/v3/gists/ + final Matcher matcher = Pattern.compile("\\d+").matcher(responce); + matcher.find(); + BrowserUtil.launchBrowser("https://gist.github.com/" + matcher.group()); + } + catch (IOException e1) { + LOG.error("Failed to create gist: " + e1); + return; + } + finally { + method.releaseConnection(); + } + } +} diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 1bc4bff24336..32b69634b863 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -117,7 +117,7 @@ public class GithubUtil { return method; } - public static HttpClient getHttpClient(final String login, final String password) { + public static HttpClient getHttpClient(@Nullable final String login, @Nullable final String password) { final HttpClient client = new HttpClient(); // Configure proxySettings if it is required final HttpConfigurable proxySettings = HttpConfigurable.getInstance(); @@ -128,8 +128,10 @@ public class GithubUtil { proxySettings.getPlainProxyPassword())); } } - client.getParams().setAuthenticationPreemptive(true); - client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, password)); + if (login != null && password != null) { + client.getParams().setAuthenticationPreemptive(true); + client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, password)); + } return client; } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistDialog.java new file mode 100644 index 000000000000..336da1b4934b --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistDialog.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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.jetbrains.plugins.github.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; + +import javax.swing.*; + +/** + * @author oleg + * @date 9/27/11 + */ +public class GitHubCreateGistDialog extends DialogWrapper { + private final GitHubCreateGistPanel myGithubCreateGistPanel; + + public GitHubCreateGistDialog(final Project project, final boolean canBePersonal) { + super(project, true); + myGithubCreateGistPanel = new GitHubCreateGistPanel(); + myGithubCreateGistPanel.setCanBePersonal(canBePersonal); + setTitle("Create Gist"); + init(); + } + + protected Action[] createActions() { + return new Action[] {getOKAction(), getCancelAction(), getHelpAction()}; + } + + @Override + protected JComponent createCenterPanel() { + return myGithubCreateGistPanel.getPanel(); + } + + @Override + protected String getHelpId() { + return null; + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myGithubCreateGistPanel.getDescriptionTextArea(); + } + + public boolean isPrivate() { + return myGithubCreateGistPanel.isPrivate(); + } + + public boolean isAnonimous() { + return myGithubCreateGistPanel.isAnonymous(); + } + + public String getDescription() { + return myGithubCreateGistPanel.getDescriptionTextArea().getText(); + } +} diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.form new file mode 100644 index 000000000000..ba1e932e5693 --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.form @@ -0,0 +1,71 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.java new file mode 100644 index 000000000000..c3528e7f1dba --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GitHubCreateGistPanel.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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.jetbrains.plugins.github.ui; + +import javax.swing.*; + +/** + * @author oleg + * @date 9/27/11 + */ +public class GitHubCreateGistPanel { + private JTextArea myDescriptionTextArea; + private JTextPane myNoticeTextPane; + private JCheckBox myPrivateCheckBox; + private JPanel myPanel; + private JCheckBox myAnonymousCheckBox; + + public GitHubCreateGistPanel() { + myDescriptionTextArea.setBorder(BorderFactory.createEtchedBorder()); + } + + public boolean isPrivate(){ + return myPrivateCheckBox.isSelected(); + } + + public boolean isAnonymous(){ + return myAnonymousCheckBox.isSelected(); + } + + public JPanel getPanel() { + return myPanel; + } + + public JTextArea getDescriptionTextArea() { + return myDescriptionTextArea; + } + + public void setCanBePersonal(final boolean canBePersonal) { + if (!canBePersonal){ + myAnonymousCheckBox.setEnabled(false); + myAnonymousCheckBox.setSelected(true); + myNoticeTextPane.setText("Note you need to be logged in to github to create personal gists"); + } + } +}