Skip to content

Commit

Permalink
Add footnotes to posts and revisions
Browse files Browse the repository at this point in the history
  • Loading branch information
ustc-zzzz committed Nov 25, 2023
1 parent 22ae34e commit 8676d6f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ CREATE TABLE chahoutan_post_anchors
CONSTRAINT fk66omt1yfcmam8rn9s3f5qh6pq FOREIGN KEY (revision_id) REFERENCES chahoutan_revisions (id)
);

CREATE TABLE chahoutan_post_footnotes
(
revision_id uuid NOT NULL,
footnote text NOT NULL,
footnote_ordinal int4 NOT NULL,
CONSTRAINT chahoutan_post_footnotes_pkey PRIMARY KEY (revision_id, footnote_ordinal),
CONSTRAINT fk7epb56mbnx4mqd2vvu5k7fv46 FOREIGN KEY (revision_id) REFERENCES chahoutan_revisions (id)
);

CREATE TABLE chahoutan_post_images
(
revision_id uuid NOT NULL,
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/teacon/chahoutan/entity/Revision.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ public class Revision
@OrderBy("uploadDate ASC")
private List<Correction> corrections = new ArrayList<>();

@ElementCollection
@OrderColumn(name = "footnote_ordinal", columnDefinition = "int")
@Column(name = "footnote", columnDefinition = "text", nullable = false)
@CollectionTable(name = "chahoutan_post_footnotes", joinColumns = @JoinColumn(name = "revision_id"))
private List<String> footnotes = new ArrayList<>();

@ElementCollection
@MapKeyColumn(name = "anchor", columnDefinition = "text")
@Column(name = "link", columnDefinition = "text", nullable = false)
Expand Down Expand Up @@ -106,6 +112,16 @@ public List<Image> getImages()
return List.copyOf(this.images);
}

public Map<String, String> getFootnotes()
{
var footnoteCount = this.footnotes.size();
var map = new LinkedHashMap<String, String>(footnoteCount);
for (int i = 0; i < footnoteCount; ++i) {
map.put(String.format("[%d]", i + 1), this.footnotes.get(i));
}
return Map.copyOf(map);
}

public String getRssPlainText()
{
var editors = this.post.getEditors();
Expand Down Expand Up @@ -201,6 +217,14 @@ public void setCreationTime(Instant time)
this.creationTime = time.atZone(ChahoutanConfig.POST_ZONE_ID);
}

public void setFootnotes(Map<String, String> footnotes) {
var array = new String[footnotes.size()];
for (var i = 0; i < array.length; ++i) {
array[i] = Objects.requireNonNull(footnotes.get(String.format("[%d]", i + 1)));
}
this.footnotes = List.of(array);
}

public void setAnchors(List<String> anchors)
{
var entries = new HashMap<String, String>();
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/teacon/chahoutan/network/PostRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@

import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@JsonIgnoreProperties(ignoreUnknown = true)
public record PostRequest(@JsonProperty(value = "id", required = true) int id,
@JsonProperty(value = "text", required = true) String text,
@JsonProperty(value = "editors") List<String> editors,
@JsonProperty(value = "anchors") List<String> anchors,
@JsonProperty(value = "footnotes") Map<String, String> footnotes,
@JsonProperty(value = "images") List<ImageRequest> images)
{
private static <T> Stream<T> nullToEmpty(List<T> input)
{
return input == null ? Stream.empty() : input.stream();
}

private static <S, T> Stream<Map.Entry<T, S>> nullToEmpty(Map<T, S> input)
{
return input == null ? Stream.empty() : input.entrySet().stream();
}

private static String normalize(String text)
{
return String.join("\u00a0", text.split("\\s"));
Expand All @@ -40,6 +48,9 @@ public Post toPost(ImageRepository repo)
revision.setText(normalize(this.text));
revision.setCreationTime(Instant.now());
revision.setAnchors(nullToEmpty(this.anchors).map(PostRequest::normalize).toList());
revision.setFootnotes(nullToEmpty(this.footnotes)
.filter(e -> e.getKey().startsWith("[") && e.getKey().endsWith("]"))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
revision.setImages(nullToEmpty(this.images).map(request -> request.toImage(repo)).toList());

return post;
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/teacon/chahoutan/network/PostResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.net.URI;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@JsonInclude(value = JsonInclude.Include.NON_NULL)
Expand All @@ -23,28 +24,31 @@ public record PostResponse(@JsonProperty(value = "id") int id,
@JsonProperty(value = "anchors") List<String> anchors,
@JsonProperty(value = "anchor_urls") List<String> anchorUrls,
@JsonProperty(value = "images") List<ImageResponse> postImages,
@JsonProperty(value = "footnotes") Map<String, String> footnotes,
@JsonProperty(value = "publish_time") OffsetDateTime publishTime)
{
public static PostResponse from(Post post)
{
var revision = post.getRevision();
var revisionName = revision.getTitle();
var publishTime = post.getPublishTime();
var footnotes = revision.getFootnotes();
var urlPrefix = URI.create(ChahoutanConfig.BACKEND_URL_PREFIX);
var url = urlPrefix.resolve("v1/posts/" + post.getId());
var revisionUrl = urlPrefix.resolve("v1/posts/" + revision.getId());
var type = post.getId() <= Post.getLastPublicPostId(null) ? "post" : "draft";
var editors = post.getEditors().stream().sorted().toList();
var images = revision.getImages().stream().map(ImageResponse::from).toList();
return new PostResponse(post.getId(), url, type, revisionName, revision.getText(), revision.getId(),
revisionUrl, editors, revision.getAnchors(), revision.getAnchorUrls(), images, publishTime);
revisionUrl, editors, revision.getAnchors(), revision.getAnchorUrls(), images, footnotes, publishTime);
}

public static PostResponse from(Revision revision)
{
var post = revision.getPost();
var revisionName = revision.getTitle();
var publishTime = post.getPublishTime();
var footnotes = revision.getFootnotes();
var isPost = post.getRevision() != null && post.getRevision().getId().equals(revision.getId());
var urlPrefix = URI.create(ChahoutanConfig.BACKEND_URL_PREFIX);
var url = isPost ? urlPrefix.resolve("v1/posts/" + post.getId()) : null;
Expand All @@ -53,6 +57,6 @@ public static PostResponse from(Revision revision)
var editors = isPost ? post.getEditors().stream().sorted().toList() : null;
var images = revision.getImages().stream().map(ImageResponse::from).toList();
return new PostResponse(post.getId(), url, type, revisionName, revision.getText(), revision.getId(),
revisionUrl, editors, revision.getAnchors(), revision.getAnchorUrls(), images, publishTime);
revisionUrl, editors, revision.getAnchors(), revision.getAnchorUrls(), images, footnotes, publishTime);
}
}

0 comments on commit 8676d6f

Please sign in to comment.