Skip to content

Commit

Permalink
Use proper HTTP client and fix multiple plugin.xml problems.
Browse files Browse the repository at this point in the history
  • Loading branch information
azenla committed Apr 8, 2021
1 parent 0b43b22 commit c89c27b
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 18 deletions.
24 changes: 24 additions & 0 deletions .run/Checks.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Checks" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="check" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
24 changes: 24 additions & 0 deletions .run/IDE.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDE" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
24 changes: 24 additions & 0 deletions .run/Plugin Verifier.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Plugin Verifier" type="GradleRunConfiguration" factoryName="Gradle">
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runPluginVerifier" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Hacker News IDEA

## [Unreleased]

### Added

- `{by}` and `{id}` format specifiers.

### Fixed

- Change "Top Stories on Hacker News" to "Top Stories" as menu item title for popup.
- Use java.net.http to fetch data, which allows specifying user agent.

## [1.3.0]

### Added
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ tasks {
patchPluginXml {
version(properties("pluginVersion"))
sinceBuild(properties("pluginSinceBuild"))
untilBuild(properties("pluginUntilBuild"))

changeNotes(
closure {
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pluginGroup=sh.spinlock.idea.hackernews
pluginName=Hacker News
pluginVersion=1.3.0
pluginVersion=1.4.0
pluginSinceBuild=203
pluginUntilBuild=300
pluginVerifierIdeVersions=2020.3.2, 2021.1
platformType=IC
platformVersion=2020.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public void loadState(@NotNull State state) {
}

public static class State {

public Integer itemLimit = 30;
public String itemTextFormat = "{index}. {title}";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import javax.swing.JPanel;

public class ConfigurationExtensionUI {

public JPanel panel;
public ComboBox<Integer> itemLimitSelector;
public JBTextField itemTextFormat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.NotNull;

public abstract class HackerNewsAction extends AnAction {
public abstract class HackerNewsAction extends AnAction implements DumbAware {
@Override
public void update(@NotNull AnActionEvent e) {
e.getPresentation().setEnabled(true);
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/sh/spinlock/idea/hackernews/ItemPopupStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ public ItemPopupStep(Configuration configuration, String title, List<HackerNewsI
public String getTextFor(HackerNewsItem value) {
return configuration
.getItemTextFormat()
.replace("{id}", Integer.toString(value.id))
.replace("{index}", Integer.toString(value.indexInList))
.replace("{score}", Integer.toString(value.score))
.replace("{title}", value.title == null ? "" : value.title)
.replace("{text}", value.text == null ? "" : value.text)
.replace("{by}", value.by == null ? "" : value.by)
.replace("{url}", value.getAnyUrl())
.replace("{attached-url}", value.url == null ? "" : value.url)
.replace("{item-url}", value.getItemUrl());
.replace("{item-url}", value.getItemUrl())
.replace("{newline}", "\n");
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public class TopStoriesAction extends HackerNewsAction {
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
Configuration configuration = getCurrentConfiguration();

List<HackerNewsItem> items = HackerNewsClient.loadTopStories(configuration.getItemLimit());
List<HackerNewsItem> items =
HackerNewsClient.shared().loadTopStories(configuration.getItemLimit());

ListPopup popup =
JBPopupFactory.getInstance()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.intellij.openapi.util.Pair;
import java.io.IOException;
import java.net.URL;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
Expand All @@ -16,14 +20,27 @@ public class HackerNewsClient {
public static final String ITEM_BASE_URL = String.format("%s/item", BASE_URL);
public static final String TOP_STORIES_URL = String.format("%s/topstories.json", BASE_URL);

private static final ObjectMapper mapper =
private static final @NotNull HackerNewsClient SHARED =
new HackerNewsClient(HttpClient.newHttpClient());

public static @NotNull HackerNewsClient shared() {
return SHARED;
}

private final @NotNull HttpClient httpClient;
private final @NotNull ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);

public HackerNewsClient(@NotNull HttpClient httpClient) {
this.httpClient = httpClient;
}

@NotNull
public static List<Integer> getTopStories() {
public List<Integer> getTopStoriesIds() {
try {
String content = fetch(TOP_STORIES_URL);
List<Integer> items = new ArrayList<>();
for (Object object : mapper.readValue(new URL(TOP_STORIES_URL), List.class)) {
for (Object object : mapper.readValue(content, List.class)) {
if (object instanceof Integer) {
items.add((Integer) object);
}
Expand All @@ -34,31 +51,50 @@ public static List<Integer> getTopStories() {
}
}

@NotNull
public static List<HackerNewsItem> loadTopStories(int limit) {
List<Integer> stories = HackerNewsClient.getTopStories();
public @NotNull List<@NotNull HackerNewsItem> loadTopStories(int limit) {
List<Integer> stories = getTopStoriesIds();

return stories.stream()
.limit(limit)
.map((id) -> new Pair<>(stories.indexOf(id) + 1, id))
.parallel()
.map(
(pair) -> {
HackerNewsItem item = HackerNewsClient.getItem(pair.getSecond());
HackerNewsItem item = getStoryItem(pair.getSecond());
item.indexInList = pair.first;
return item;
})
.sorted(Comparator.comparingInt((item) -> item.indexInList))
.collect(Collectors.toList());
}

@NotNull
public static HackerNewsItem getItem(int id) {
public @NotNull HackerNewsItem getStoryItem(int id) {
try {
return mapper.readValue(
new URL(String.format("%s/%s.json", ITEM_BASE_URL, id)), HackerNewsItem.class);
String content = fetch(String.format("%s/%s.json", ITEM_BASE_URL, id));
return mapper.readValue(content, HackerNewsItem.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private @NotNull String fetch(@NotNull String url) {
try {
HttpRequest request =
HttpRequest.newBuilder()
.GET()
.uri(URI.create(url))
.header("User-Agent", "github.com/SpinlockLabs/idea-hacker-news")
.build();
HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());

if (response.statusCode() != 200) {
throw new RuntimeException(
String.format("Failed to fetch URL %s (status code: %d)", url, response.statusCode()));
}

return response.body();
} catch (IOException | InterruptedException e) {
throw new RuntimeException("Failed to fetch URL " + url, e);
}
}
}
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<action
id="sh.spinlock.idea.hackernews.TopStoriesAction"
class="sh.spinlock.idea.hackernews.TopStoriesAction"
text="Top Stories on Hacker News"
text="Top Stories"
description="View the top stories on Hacker News.">
</action>

Expand Down

0 comments on commit c89c27b

Please sign in to comment.