Initial support for creating gists

This commit is contained in:
Oleg Shpynov
2011-09-27 21:11:55 +04:00
parent abdee03c37
commit 02037e9ec8
6 changed files with 350 additions and 3 deletions
+5
View File
@@ -28,6 +28,11 @@
<add-to-group group-id="ProjectViewPopupMenu"/>
<add-to-group group-id="EditorTabPopupMenu"/>
</action>
<action id="Github.Create.Gist" class="org.jetbrains.plugins.github.GithubCreateGistAction">
<add-to-group group-id="EditorPopupMenu"/>
<add-to-group group-id="ProjectViewPopupMenu"/>
<add-to-group group-id="EditorTabPopupMenu"/>
</action>
<action id="Github.Rebase.Internal" class="org.jetbrains.plugins.github.GithubRebase"/>
</actions>
</idea-plugin>
@@ -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();
}
}
}
@@ -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;
}
@@ -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();
}
}
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.github.ui.GitHubCreateGistPanel">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="1202b">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="2ac57" class="javax.swing.JTextPane" binding="myNoticeTextPane">
<constraints>
<grid row="3" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<contentType value="text/html"/>
<editable value="false"/>
</properties>
<clientProperties>
<JEditorPane.honorDisplayProperties class="java.lang.Boolean" value="true"/>
<caretAspectRatio class="java.lang.Float" value="0.04"/>
</clientProperties>
</component>
<component id="51bc1" class="javax.swing.JTextArea" binding="myDescriptionTextArea">
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="50"/>
</grid>
</constraints>
<properties/>
<clientProperties>
<caretAspectRatio class="java.lang.Float" value="0.04"/>
</clientProperties>
</component>
<component id="b0e4d" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Description:"/>
</properties>
</component>
<component id="5586a" class="javax.swing.JCheckBox" binding="myAnonymousCheckBox">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Anonimous"/>
</properties>
</component>
<hspacer id="192a4">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="3fe2f" class="javax.swing.JCheckBox" binding="myPrivateCheckBox">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Private"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -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("<html><body><b>Note</b> you need to be logged in to github to create personal gists</body></html>");
}
}
}