Skip to content

Commit

Permalink
Merge pull request #244 from guusdk/video
Browse files Browse the repository at this point in the history
Feed: Replace Discourse video element with HTML5
  • Loading branch information
akrherz authored May 26, 2024
2 parents 85e1dbf + 3f5f103 commit c9356a2
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/main/java/org/jivesoftware/site/FeedItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public FeedItem( JSONObject entry )

final JSONObject firstPost = entry.getJSONObject( "post_stream" ).getJSONArray( "posts" ).getJSONObject( 0 );
contents = firstPost.getString( "cooked" );
contents = replaceVideo(contents);

publishedDate = javax.xml.bind.DatatypeConverter.parseDateTime( firstPost.getString( "created_at" ) ).getTime();

final JSONArray arrayElements = entry.getJSONArray("tags");
Expand All @@ -33,6 +35,64 @@ public FeedItem( JSONObject entry )
replyCount = entry.getInt( "posts_count" );
}

/**
* Replaces embedded video in Discourse markup with a HTML5 'video' element.
*/
public static String replaceVideo(final String data) {
if (data == null) {
return data;
}

final int start = data.indexOf("<div class=\"video-placeholder-container\" ");
if (start < 0) {
return data;
}
int end = data.indexOf("</div>", start);
if (end < 0) {
return data;
} else {
end += "</div>".length();
}

// Video
int startVideoSrc = data.indexOf("data-video-src=\"", start);
if (startVideoSrc < 0) {
return data;
} else {
startVideoSrc += "data-video-src=\"".length();
}
int endVideoSrc = data.indexOf('"', startVideoSrc);
final String videoSrc = data.substring(startVideoSrc, endVideoSrc);

// Thumbnail ('poster')
final String videoPoster;
int startVideoPoster = data.indexOf("data-thumbnail-src=\"", start);
if (startVideoPoster >= 0) {
startVideoPoster += "data-thumbnail-src=\"".length();
int endVideoPoster = data.indexOf('"', startVideoPoster);
if (endVideoPoster < 0) {
return data; // No closing quote? Sounds dodgy. Better abort.
} else {
videoPoster = data.substring(startVideoPoster, endVideoPoster);
}
} else {
videoPoster = null;
}

// Build replacement data.
final StringBuilder replacement = new StringBuilder();
replacement.append("<video width=\"696\"");
if (videoPoster != null && !videoPoster.isEmpty()) {
replacement.append(" poster=\"").append(videoPoster).append("\"");
}
replacement.append(" controls>");
replacement.append("<source src=\"").append(videoSrc).append("\"/>");
replacement.append("Unable to show a video. <a href=\"").append(videoSrc).append("\">Download the video</a>");
replacement.append("</video>");

// Switch the original with the replacement.
return data.substring(0, start) + replacement + data.substring(end);
}
// public FeedItem( SyndEntry entry )
// {
// super( entry );
Expand Down
35 changes: 35 additions & 0 deletions src/test/java/org/jivesoftware/site/FeedItemTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.jivesoftware.site;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class FeedItemTest
{
@Test
public void testVideoReplacement()
{
// Setup test fixture.
final String input = "<p>We are excited to be able to announce the immediate availability of a new plugin for Openfire: XMPP Web!</p>\n" +
"<p>This new plugin for the real-time communications server provided by the <a href=\"https://www.igniterealtime.org/\">Ignite Realtime community</a> allows you to install the third-party webclient named ‘<a href=\"https://github.com/nioc/xmpp-web\">XMPP Web</a>’ in mere seconds! By installing this new plugin, the web client is immediately ready for use.</p>\n" +
"<p></p><div class=\"video-placeholder-container\" data-video-src=\"/uploads/default/original/2X/5/5a21cdad5c5e2053c693aa7734a48f684879b63f.mp4\" data-thumbnail-src=\"https://discourse.igniterealtime.org/uploads/default/original/2X/0/098bfee9e4e77052a15f0a17ddcf06008bd341c9.png\">\n" +
"</div><p></p>\n" +
"<p>This new plugin compliments others that similarly allow to deploy a web client with great ease, like <a href=\"https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=candy\">Candy</a>, <a href=\"https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=inverse\">inVerse</a> and <a href=\"https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=jsxc\">JSXC</a>! With the addition of XMPP Web, the selection of easy-to-install clients for your users to use becomes even larger!</p>\n" +
"<p>The XMPP Web plugin for Openfire is based on release 0.10.2 of the upstream project, which currently is the latest release. It will automatically become available for installation in the admin console of your Openfire server in the next few days. Alternatively, you can download it immediately from its archive page.</p>\n" +
"<p>Do you think this is a good addition to the suite of plugins? Do you have any questions or concerns? Do you just want to say hi? Please stop by our <a href=\"https://discourse.igniterealtime.org/\">community forum</a> or our <a href=\"https://www.igniterealtime.org/support/group_chat.jsp\">live groupchat</a>!</p>\n" +
"<p>For other release announcements and news follow us on <a href=\"https://toot.igniterealtime.org/@news\">Mastodon</a> or <a href=\"https://x.com/IgniteRealtime\">X</a></p>\n";

// Execute system under test.
final String result = FeedItem.replaceVideo(input);

// Verify results.
final String expected = "<p>We are excited to be able to announce the immediate availability of a new plugin for Openfire: XMPP Web!</p>\n" +
"<p>This new plugin for the real-time communications server provided by the <a href=\"https://www.igniterealtime.org/\">Ignite Realtime community</a> allows you to install the third-party webclient named ‘<a href=\"https://github.com/nioc/xmpp-web\">XMPP Web</a>’ in mere seconds! By installing this new plugin, the web client is immediately ready for use.</p>\n" +
"<p></p><video width=\"696\" poster=\"https://discourse.igniterealtime.org/uploads/default/original/2X/0/098bfee9e4e77052a15f0a17ddcf06008bd341c9.png\" controls><source src=\"/uploads/default/original/2X/5/5a21cdad5c5e2053c693aa7734a48f684879b63f.mp4\"/>Unable to show a video. <a href=\"/uploads/default/original/2X/5/5a21cdad5c5e2053c693aa7734a48f684879b63f.mp4\">Download the video</a></video><p></p>\n" +
"<p>This new plugin compliments others that similarly allow to deploy a web client with great ease, like <a href=\"https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=candy\">Candy</a>, <a href=\"https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=inverse\">inVerse</a> and <a href=\"https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=jsxc\">JSXC</a>! With the addition of XMPP Web, the selection of easy-to-install clients for your users to use becomes even larger!</p>\n" +
"<p>The XMPP Web plugin for Openfire is based on release 0.10.2 of the upstream project, which currently is the latest release. It will automatically become available for installation in the admin console of your Openfire server in the next few days. Alternatively, you can download it immediately from its archive page.</p>\n" +
"<p>Do you think this is a good addition to the suite of plugins? Do you have any questions or concerns? Do you just want to say hi? Please stop by our <a href=\"https://discourse.igniterealtime.org/\">community forum</a> or our <a href=\"https://www.igniterealtime.org/support/group_chat.jsp\">live groupchat</a>!</p>\n" +
"<p>For other release announcements and news follow us on <a href=\"https://toot.igniterealtime.org/@news\">Mastodon</a> or <a href=\"https://x.com/IgniteRealtime\">X</a></p>\n";
assertEquals(expected, result);
}
}

0 comments on commit c9356a2

Please sign in to comment.