Skip to content

Commit

Permalink
♻️ refactor code for better testability #23
Browse files Browse the repository at this point in the history
  • Loading branch information
McPringle committed Nov 30, 2024
1 parent 7d09c31 commit 1f2ec33
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Apus - A social wall for conferences with additional features.
* Copyright (C) Marcus Fihlon and the individual contributors to Apus.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package swiss.fihlon.apus.plugin.social.bluesky;

import org.jetbrains.annotations.NotNull;

public class BlueSkyException extends Exception {

public BlueSkyException(@NotNull final String message, @NotNull final Exception e) {
super(message, e);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Apus - A social wall for conferences with additional features.
* Copyright (C) Marcus Fihlon and the individual contributors to Apus.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package swiss.fihlon.apus.plugin.social.bluesky;

import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;

public interface BlueSkyLoader {

@NotNull JSONArray getPosts(@NotNull String instance, @NotNull String hashtag, @NotNull String postAPI) throws BlueSkyException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import swiss.fihlon.apus.configuration.Configuration;
import swiss.fihlon.apus.plugin.social.SocialPlugin;
import swiss.fihlon.apus.social.Post;
import swiss.fihlon.apus.util.DownloadUtil;

import java.time.ZonedDateTime;
import java.util.ArrayList;
Expand All @@ -36,15 +35,18 @@ public final class BlueSkyPlugin implements SocialPlugin {

private static final Logger LOGGER = LoggerFactory.getLogger(BlueSkyPlugin.class);

private final BlueSkyLoader blueSkyLoader;
private final String hashtags;
private final String instance;
private final String postAPI;

public BlueSkyPlugin(@NotNull final Configuration configuration) {
public BlueSkyPlugin(@NotNull final BlueSkyLoader blueSkyLoader,
@NotNull final Configuration configuration) {
this.blueSkyLoader = blueSkyLoader;
final var blueSkyConfig = configuration.getBlueSky();
hashtags = blueSkyConfig.hashtags();
instance = blueSkyConfig.instance();
postAPI = blueSkyConfig.postAPI();
this.hashtags = blueSkyConfig.hashtags();
this.instance = blueSkyConfig.instance();
this.postAPI = blueSkyConfig.postAPI();
}

@Override
Expand All @@ -56,19 +58,28 @@ public boolean isEnabled() {

@Override
public Stream<Post> getPosts() {
final var url = String.format(postAPI, instance, hashtags);
final var posts = new ArrayList<Post>();
try {
final var json = DownloadUtil.getString(url);
final var jsonPosts = new JSONObject(json).getJSONArray("posts");
for (var i = 0; i < jsonPosts.length(); i++) {
final var post = jsonPosts.getJSONObject(i);
posts.add(createPost(post));
final var posts = new ArrayList<Post>();

for (final String hashtag : hashtags.split(",")) {
if (hashtag.isBlank()) {
continue;
}
LOGGER.info("Starting download of posts with hashtag '{}' from instance '{}'", hashtag, instance);
final var jsonPosts = blueSkyLoader.getPosts(instance, hashtag.trim(), postAPI);
LOGGER.info("Successfully downloaded {} posts with hashtag '{}' from instance '{}'", jsonPosts.length(), hashtag, instance);

for (var i = 0; i < jsonPosts.length(); i++) {
final var post = jsonPosts.getJSONObject(i);
posts.add(createPost(post));
}
}
} catch (final Exception e) {

return posts.stream();
} catch (final BlueSkyException e) {
LOGGER.error(e.getMessage(), e);
return Stream.of();
}
return posts.stream();
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Apus - A social wall for conferences with additional features.
* Copyright (C) Marcus Fihlon and the individual contributors to Apus.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package swiss.fihlon.apus.plugin.social.bluesky;

import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import swiss.fihlon.apus.util.DownloadUtil;

@Service
public final class DefaultBlueSkyLoader implements BlueSkyLoader {

@Override
@NotNull
public JSONArray getPosts(@NotNull final String instance, @NotNull final String hashtag, @NotNull String postAPI) throws BlueSkyException {
try {
final var url = String.format(postAPI, instance, hashtag);
final var json = DownloadUtil.getString(url);
final var jsonPosts = new JSONObject(json).getJSONArray("posts");
if (jsonPosts != null) {
return jsonPosts;
}
throw new NullPointerException(String.format("No posts with hashtag '%s' from BlueSky instance '%s'", hashtag, instance));
} catch (final Exception e) {
throw new BlueSkyException(String.format("Unable to load posts with hashtag '%s' from BlueSky instance '%s'", hashtag, instance), e);
}
}

}

0 comments on commit 1f2ec33

Please sign in to comment.