mirror of
https://github.com/igniterealtime/Spark.git
synced 2025-10-29 19:57:28 +00:00
Compare commits
6 Commits
9ed3557bd6
...
4f9fc75347
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f9fc75347 | ||
|
|
364d1a837f | ||
|
|
a0f28184ad | ||
|
|
43a37bf697 | ||
|
|
c4affe809d | ||
|
|
b6771fa03c |
@ -10,10 +10,10 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>meet</artifactId>
|
<artifactId>meet</artifactId>
|
||||||
<version>0.0.9</version>
|
<version>0.2.0</version>
|
||||||
|
|
||||||
<name>Pade Meetings Plugin</name>
|
<name>Online Meetings Plugin</name>
|
||||||
<description>Adds support for Pade Meetings to the Spark IM client.</description>
|
<description>Adds support for XEP-0483: HTTP Online Meetings to the Spark IM client.</description>
|
||||||
|
|
||||||
<contributors>
|
<contributors>
|
||||||
<contributor>
|
<contributor>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
This is a plugin for Spark that allows users to join audio and video conferences hosted by [Pade Meetings](https://github.com/igniterealtime/openfire-pade-plugin/releases).
|
This is a plugin for Spark that allows users to join audio and video conferences supported by [XEP-0483: HTTP Online Meetings](https://xmpp.org/extensions/xep-0483.html)
|
||||||
See the documentation for more details. It provides a button from a Multi User Chat (MUC) room or chat window within the Spark client, to open a Chrome window using the URL for the Jitsi Meet web client.
|
See the documentation for more details. It provides a button from a Multi User Chat (MUC) room or chat window within the Spark client, to open a Chrome window using the URL provided.
|
||||||
It uses Electron instead of depending on Chrome installed and configured as the default browser.
|
It uses Electron instead of depending on Chrome installed and configured as the default browser.
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@ -43,19 +43,17 @@ public class ChatRoomDecorator
|
|||||||
ofmeetButton = new RolloverButton(SparkRes.getImageIcon("PADE_ICON"));
|
ofmeetButton = new RolloverButton(SparkRes.getImageIcon("PADE_ICON"));
|
||||||
ofmeetButton.setToolTipText(GraphicUtils.createToolTip(SparkMeetResource.getString("name")));
|
ofmeetButton.setToolTipText(GraphicUtils.createToolTip(SparkMeetResource.getString("name")));
|
||||||
final String roomId = getNode(room.getBareJid().toString());
|
final String roomId = getNode(room.getBareJid().toString());
|
||||||
final String sessionID = roomId + "-" + System.currentTimeMillis();
|
final String sessionID = String.valueOf(System.currentTimeMillis());
|
||||||
|
|
||||||
ofmeetButton.addActionListener(event -> {
|
ofmeetButton.addActionListener(event -> {
|
||||||
String newUrl, newRoomId;
|
String newUrl, newRoomId = roomId + "-" + sessionID;
|
||||||
|
|
||||||
if ("groupchat".equals(room.getChatType().toString()))
|
if ("groupchat".equals(room.getChatType().toString()))
|
||||||
{
|
{
|
||||||
newRoomId = roomId + "-" + sessionID;
|
|
||||||
newUrl = plugin.url + newRoomId;
|
newUrl = plugin.url + newRoomId;
|
||||||
plugin.handleClick(newUrl, room, newUrl, Message.Type.groupchat);
|
plugin.handleClick(newUrl, room, newUrl, Message.Type.groupchat);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
newRoomId = sessionID;
|
|
||||||
newUrl = plugin.url + newRoomId;
|
newUrl = plugin.url + newRoomId;
|
||||||
plugin.handleClick(newUrl, room, newUrl, Message.Type.chat);
|
plugin.handleClick(newUrl, room, newUrl, Message.Type.chat);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.spark.plugin.ofmeet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.XmlEnvironment;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||||
|
import org.jivesoftware.smack.xml.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IQ packet that's a request for an online meeting URL
|
||||||
|
* according to XEP-0483.
|
||||||
|
*/
|
||||||
|
public class QueryRequest extends IQ
|
||||||
|
{
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:http:online-meetings:0";
|
||||||
|
public static final String ELEMENT_NAME = "query";
|
||||||
|
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
public String url = null;
|
||||||
|
|
||||||
|
public QueryRequest()
|
||||||
|
{
|
||||||
|
super( "query", NAMESPACE );
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryRequest(String type)
|
||||||
|
{
|
||||||
|
super( "query", NAMESPACE );
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IQChildElementXmlStringBuilder getIQChildElementBuilder( IQChildElementXmlStringBuilder buf )
|
||||||
|
{
|
||||||
|
buf.append(" type=\"" + type + "\"");
|
||||||
|
buf.rightAngleBracket();
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider extends IQProvider<QueryRequest>
|
||||||
|
{
|
||||||
|
public Provider()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryRequest parse(XmlPullParser parser, int i, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException
|
||||||
|
{
|
||||||
|
final QueryRequest queryRequest = new QueryRequest();
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
while ( !done )
|
||||||
|
{
|
||||||
|
XmlPullParser.Event eventType = parser.next();
|
||||||
|
|
||||||
|
if ( eventType == XmlPullParser.Event.START_ELEMENT )
|
||||||
|
{
|
||||||
|
if ( parser.getName().equals( "url" ) )
|
||||||
|
{
|
||||||
|
queryRequest.url = parser.nextText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( eventType == XmlPullParser.Event.END_ELEMENT )
|
||||||
|
{
|
||||||
|
if ( parser.getName().equals( "query" ) )
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -28,7 +28,14 @@ import java.lang.reflect.*;
|
|||||||
|
|
||||||
import org.jivesoftware.Spark;
|
import org.jivesoftware.Spark;
|
||||||
import org.jivesoftware.spark.*;
|
import org.jivesoftware.spark.*;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
||||||
|
|
||||||
import org.jivesoftware.spark.plugin.*;
|
import org.jivesoftware.spark.plugin.*;
|
||||||
import org.jivesoftware.spark.ui.*;
|
import org.jivesoftware.spark.ui.*;
|
||||||
import org.jivesoftware.spark.util.log.*;
|
import org.jivesoftware.spark.util.log.*;
|
||||||
@ -36,7 +43,7 @@ import org.jivesoftware.spark.util.log.*;
|
|||||||
import org.jitsi.util.OSUtils;
|
import org.jitsi.util.OSUtils;
|
||||||
import de.mxro.process.*;
|
import de.mxro.process.*;
|
||||||
import org.jxmpp.jid.parts.*;
|
import org.jxmpp.jid.parts.*;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
|
||||||
public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageListener
|
public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageListener
|
||||||
{
|
{
|
||||||
@ -54,6 +61,7 @@ public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageL
|
|||||||
|
|
||||||
public void initialize()
|
public void initialize()
|
||||||
{
|
{
|
||||||
|
ProviderManager.addIQProvider("query", QueryRequest.NAMESPACE, new QueryRequest.Provider());
|
||||||
checkNatives();
|
checkNatives();
|
||||||
|
|
||||||
chatManager = SparkManager.getChatManager();
|
chatManager = SparkManager.getChatManager();
|
||||||
@ -87,8 +95,67 @@ public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageL
|
|||||||
chatManager.addGlobalMessageListener(this);
|
chatManager.addGlobalMessageListener(this);
|
||||||
|
|
||||||
SparkMeetPreference preference = new SparkMeetPreference(this);
|
SparkMeetPreference preference = new SparkMeetPreference(this);
|
||||||
SparkManager.getPreferenceManager().addPreference(preference);
|
SparkManager.getPreferenceManager().addPreference(preference);
|
||||||
|
|
||||||
|
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(SparkManager.getConnection());
|
||||||
|
|
||||||
|
DiscoverInfo discoverInfo = null;
|
||||||
|
String serverJid = SparkManager.getSessionManager().getServerAddress().toString();
|
||||||
|
|
||||||
|
try {
|
||||||
|
discoverInfo = discoManager.discoverInfo(JidCreate.domainBareFrom(serverJid));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Log.debug("Unable to disco " + serverJid);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean jitsiAvailable = false;
|
||||||
|
boolean galeneAvailable = false;
|
||||||
|
boolean ohunAvailable = false;
|
||||||
|
|
||||||
|
if (discoverInfo != null) {
|
||||||
|
jitsiAvailable = discoverInfo.containsFeature("urn:xmpp:http:online-meetings#jitsi");
|
||||||
|
galeneAvailable = discoverInfo.containsFeature("urn:xmpp:http:online-meetings#galene");
|
||||||
|
ohunAvailable = discoverInfo.containsFeature("urn:xmpp:http:online-meetings#ohun");
|
||||||
|
}
|
||||||
|
|
||||||
|
String sUrl = null;
|
||||||
|
|
||||||
|
if (jitsiAvailable) {
|
||||||
|
sUrl = getServerUrl("jitsi");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
if (galeneAvailable) {
|
||||||
|
sUrl = getServerUrl("galene");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
if (ohunAvailable) {
|
||||||
|
sUrl = getServerUrl("ohun");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sUrl != null) url = sUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getServerUrl(String app) {
|
||||||
|
String serverUrl = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
QueryRequest request = new QueryRequest(app);
|
||||||
|
request.setTo(JidCreate.fromOrThrowUnchecked(SparkManager.getSessionManager().getServerAddress()));
|
||||||
|
request.setType(IQ.Type.get);
|
||||||
|
IQ result = SparkManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||||
|
QueryRequest response = (QueryRequest) result;
|
||||||
|
|
||||||
|
Log.debug("SparkMeet response: url=" + response.url);
|
||||||
|
if (response.url != null) serverUrl = response.url + "/";
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Unable to get meet url from server for app type " + app);
|
||||||
|
}
|
||||||
|
return serverUrl;
|
||||||
|
}
|
||||||
|
|
||||||
public void commit(String url) {
|
public void commit(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
@ -109,6 +176,7 @@ public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageL
|
|||||||
{
|
{
|
||||||
Log.warning("shutdown");
|
Log.warning("shutdown");
|
||||||
chatManager.removeChatRoomListener(this);
|
chatManager.removeChatRoomListener(this);
|
||||||
|
ProviderManager.removeIQProvider("query", QueryRequest.NAMESPACE);
|
||||||
|
|
||||||
if (electronThread != null) electronThread.destory();
|
if (electronThread != null) electronThread.destory();
|
||||||
electronThread = null;
|
electronThread = null;
|
||||||
@ -354,7 +422,7 @@ public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageL
|
|||||||
jarFileSuffix = "-darwin-x64.zip";
|
jarFileSuffix = "-darwin-x64.zip";
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream inputStream = new URL("https://github.com/electron/electron/releases/download/v10.1.1/electron-v10.1.1" + jarFileSuffix).openStream();
|
InputStream inputStream = new URL("https://github.com/electron/electron/releases/download/v37.2.3/electron-v37.2.3" + jarFileSuffix).openStream();
|
||||||
ZipInputStream zipIn = new ZipInputStream(inputStream);
|
ZipInputStream zipIn = new ZipInputStream(inputStream);
|
||||||
ZipEntry entry = zipIn.getNextEntry();
|
ZipEntry entry = zipIn.getNextEntry();
|
||||||
|
|
||||||
@ -401,19 +469,12 @@ public class SparkMeetPlugin implements Plugin, ChatRoomListener, GlobalMessageL
|
|||||||
System.setProperty("java.library.path", newLibPath);
|
System.setProperty("java.library.path", newLibPath);
|
||||||
|
|
||||||
// this will reload the new setting
|
// this will reload the new setting
|
||||||
try {
|
Log.warning("Unable to modify 'java.library.path' dynamically. Please ensure the library path includes: " + libPath);
|
||||||
@SuppressWarnings("JavaReflectionMemberAccess")
|
|
||||||
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
|
|
||||||
fieldSysPath.setAccessible(true);
|
|
||||||
fieldSysPath.set(System.class.getClassLoader(), null);
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
// Happens on non Oracle JDK but has no influence since there is no cached field that needs a reset
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.warning("Error during loading of Pade Meetings plugin", e);
|
Log.warning(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ public class SparkMeetPreference implements Preference {
|
|||||||
public static final String NAMESPACE = "ofmeet";
|
public static final String NAMESPACE = "ofmeet";
|
||||||
|
|
||||||
private SparkMeetPlugin plugin;
|
private SparkMeetPlugin plugin;
|
||||||
private final PadePanel panel = new PadePanel();
|
private final MeetingPanel panel = new MeetingPanel();
|
||||||
|
|
||||||
public SparkMeetPreference(SparkMeetPlugin plugin) {
|
public SparkMeetPreference(SparkMeetPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@ -95,12 +95,12 @@ public class SparkMeetPreference implements Preference {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PadePanel extends JPanel {
|
private static class MeetingPanel extends JPanel {
|
||||||
private static final long serialVersionUID = -5992704440953686499L;
|
private static final long serialVersionUID = -5992704440953686499L;
|
||||||
private final JTextArea txtMessage = new JTextArea();
|
private final JTextArea txtMessage = new JTextArea();
|
||||||
private JLabel url = new JLabel(SparkMeetResource.getString("preference.url"));
|
private JLabel url = new JLabel(SparkMeetResource.getString("preference.url"));
|
||||||
|
|
||||||
PadePanel() {
|
MeetingPanel() {
|
||||||
txtMessage.setBorder(UIManager.getLookAndFeelDefaults().getBorder("TextField.border"));
|
txtMessage.setBorder(UIManager.getLookAndFeelDefaults().getBorder("TextField.border"));
|
||||||
txtMessage.setLineWrap(true);
|
txtMessage.setLineWrap(true);
|
||||||
setLayout(new VerticalFlowLayout());
|
setLayout(new VerticalFlowLayout());
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
name= Pade Meetings
|
name= Online Meetings
|
||||||
|
|
||||||
preference.sparkmeetEnabled = Enable Pade meeting
|
preference.sparkmeetEnabled = Enable Online Meetings
|
||||||
preference.url = Jitsi Meet URL
|
preference.url = Online Meetings Base URL
|
||||||
preference.title = Pade Meetings Settings
|
preference.title = Online Meetings Settings
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user