Skip to content

Commit

Permalink
✨ read posts from Mastodon
Browse files Browse the repository at this point in the history
Signed-off-by: Marcus Fihlon <[email protected]>
  • Loading branch information
McPringle committed Mar 25, 2024
1 parent 2a71a89 commit 7f568b1
Show file tree
Hide file tree
Showing 12 changed files with 342 additions and 2 deletions.
22 changes: 22 additions & 0 deletions frontend/themes/apus/views/post-view.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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/>.
*/

.post-view {
background-color: #84ddee;
border-radius: 5px;
}
18 changes: 18 additions & 0 deletions frontend/themes/apus/views/posts-view.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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/>.
*/

17 changes: 17 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@
<enabled>false</enabled>
</snapshots>
</repository>
<!-- Enable snapshots to use BigBone Mastodon client API -->
<repository>
<id>maven-central-snapshots</id>
<name>Maven Central Snapshot Repository</name>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>

<pluginRepositories>
Expand Down Expand Up @@ -160,6 +172,11 @@
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
<dependency>
<groupId>social.bigbone</groupId>
<artifactId>bigbone</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
32 changes: 32 additions & 0 deletions src/main/bundles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
This directory is automatically generated by Vaadin and contains the pre-compiled
frontend files/resources for your project (frontend development bundle).

It should be added to Version Control System and committed, so that other developers
do not have to compile it again.

Frontend development bundle is automatically updated when needed:
- an npm/pnpm package is added with @NpmPackage or directly into package.json
- CSS, JavaScript or TypeScript files are added with @CssImport, @JsModule or @JavaScript
- Vaadin add-on with front-end customizations is added
- Custom theme imports/assets added into 'theme.json' file
- Exported web component is added.

If your project development needs a hot deployment of the frontend changes,
you can switch Flow to use Vite development server (default in Vaadin 23.3 and earlier versions):
- set `vaadin.frontend.hotdeploy=true` in `application.properties`
- configure `vaadin-maven-plugin`:
```
<configuration>
<frontendHotdeploy>true</frontendHotdeploy>
</configuration>
```
- configure `jetty-maven-plugin`:
```
<configuration>
<systemProperties>
<vaadin.frontend.hotdeploy>true</vaadin.frontend.hotdeploy>
</systemProperties>
</configuration>
```

Read more [about Vaadin development mode](https://vaadin.com/docs/next/configuration/development-mode/#pre-compiled-front-end-bundle-for-faster-start-up).
Binary file added src/main/bundles/dev.bundle
Binary file not shown.
41 changes: 41 additions & 0 deletions src/main/java/swiss/fihlon/apus/service/SocialService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.service;

import org.springframework.stereotype.Service;
import swiss.fihlon.apus.social.Post;
import swiss.fihlon.apus.social.mastodon.MastodonAPI;

import java.util.Collections;
import java.util.List;

@Service
public final class SocialService {

private final List<Post> posts;

public SocialService() {
final MastodonAPI mastodonAPI = new MastodonAPI("mastodon.social");
posts = mastodonAPI.getPosts("java");
}

public List<Post> getPosts() {
return Collections.unmodifiableList(posts);
}

}
30 changes: 30 additions & 0 deletions src/main/java/swiss/fihlon/apus/social/Post.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.social;

import org.jetbrains.annotations.NotNull;

import java.time.LocalDateTime;

public record Post(String id, LocalDateTime date, String author, String avatar, String html)
implements Comparable<Post> {
@Override
public int compareTo(@NotNull final Post other) {
return date.compareTo(other.date);
}
}
70 changes: 70 additions & 0 deletions src/main/java/swiss/fihlon/apus/social/mastodon/MastodonAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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.social.mastodon;

import org.jetbrains.annotations.NotNull;
import social.bigbone.MastodonClient;
import social.bigbone.api.Pageable;
import social.bigbone.api.entity.Account;
import social.bigbone.api.entity.Status;
import social.bigbone.api.exception.BigBoneRequestException;
import swiss.fihlon.apus.social.Post;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

import static social.bigbone.api.method.TimelineMethods.StatusOrigin.LOCAL_AND_REMOTE;

public final class MastodonAPI {

private final String instance;

public MastodonAPI(@NotNull final String instance) {
this.instance = instance;
}

public List<Post> getPosts(@NotNull final String hashtag) {
try {
final MastodonClient client = new MastodonClient.Builder(instance).build();
final Pageable<Status> statuses = client.timelines().getTagTimeline(hashtag, LOCAL_AND_REMOTE).execute();
return statuses.getPart().stream()
.map(this::convertToPost)
.sorted()
.toList()
.reversed();
} catch (final BigBoneRequestException e) {
// TODO
}
return List.of();
}

private Post convertToPost(@NotNull final Status status) {
final Account account = status.getAccount();
final Instant instant = status.getCreatedAt().mostPreciseInstantOrNull();
final LocalDateTime date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return new Post(
status.getId(),
date,
account.getDisplayName(),
account.getAvatar(),
status.getContent());
}

}
34 changes: 34 additions & 0 deletions src/main/java/swiss/fihlon/apus/ui/view/PostView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.ui.view;

import com.vaadin.flow.component.Html;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.html.Div;
import org.jetbrains.annotations.NotNull;
import swiss.fihlon.apus.social.Post;

@CssImport(value = "./themes/apus/views/post-view.css")
public final class PostView extends Div {

public PostView(@NotNull final Post post) {
addClassName("post-view");
add(new Html("<div>" + post.html() + "</div>"));
}

}
36 changes: 36 additions & 0 deletions src/main/java/swiss/fihlon/apus/ui/view/PostsView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.ui.view;

import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import org.jetbrains.annotations.NotNull;
import swiss.fihlon.apus.service.SocialService;
import swiss.fihlon.apus.social.Post;

@CssImport(value = "./themes/apus/views/posts-view.css")
public final class PostsView extends VerticalLayout {

public PostsView(@NotNull final SocialService socialService) {
setId("posts");
for (final Post post : socialService.getPosts()) {
add(new PostView(post));
}
}

}
6 changes: 4 additions & 2 deletions src/main/java/swiss/fihlon/apus/ui/view/SocialWall.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.vaadin.flow.router.Route;
import org.jetbrains.annotations.NotNull;
import swiss.fihlon.apus.service.ConferenceService;
import swiss.fihlon.apus.service.SocialService;

import java.io.Serial;

Expand All @@ -34,12 +35,13 @@ public class SocialWall extends VerticalLayout {
@Serial
private static final long serialVersionUID = 7909437130138135008L;

public SocialWall(@NotNull final ConferenceService conferenceService) {
public SocialWall(@NotNull final ConferenceService conferenceService,
@NotNull final SocialService socialService) {
setId("social-wall");
setSizeFull();
add(new HorizontalLayout(
new SessionsView(conferenceService),
new Div("Posts")));
new PostsView(socialService)));
add(new Div("Footer"));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.social.mastodon;

import org.junit.jupiter.api.Test;
import swiss.fihlon.apus.social.Post;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertNotNull;

class MastodonAPITest {

@Test
void getPosts() {
final MastodonAPI mastodonAPI = new MastodonAPI("mastodon.social");
final List<Post> posts = mastodonAPI.getPosts("java");
assertNotNull(posts);
for (final Post post : posts) {
System.out.println(post);
}
}
}

0 comments on commit 7f568b1

Please sign in to comment.