Initial commit

This commit is contained in:
steckbrief 2017-11-12 14:22:01 +01:00
commit 5cacf94ecc
25 changed files with 390 additions and 0 deletions

23
.classpath Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-core-4.2.1.jar" sourcepath="/smack-core/src"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-extensions-4.2.1.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/jxmpp-core-0.5.0.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/jxmpp-jid-0.5.0.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/xmlpull-1.1.3.1.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/xpp3_min-1.1.4c.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-experimental-4.2.1.jar" sourcepath="/smack-experimental"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-java7-4.2.1.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-resolver-minidns-4.2.1.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-tcp-4.2.1.jar" sourcepath="/smack-tcp"/>
<classpathentry kind="lib" path="libs/3rdParty/minidns-core-0.2.4.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/minidns-hla-0.2.4.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/minidns-iterative-resolver-0.2.4.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/minidns-dnssec-0.2.4.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/jxmpp-util-cache-0.5.0.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-im-4.2.1.jar"/>
<classpathentry kind="lib" path="libs/3rdParty/smack/smack-sasl-javax-4.2.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
bin
.settings
dist

17
.project Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>MamHistoryLoader</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

45
build.xml Normal file
View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_run_jar" name="Create Runnable Jar for Project MamHistoryLoader with libraries in sub-folder">
<!--this file was created by Eclipse Runnable JAR Export Wizard-->
<!--ANT 1.7 is required -->
<!--define folder properties-->
<property name="dir.buildfile" value="."/>
<property name="dir.workspace" value="${dir.buildfile}/.."/>
<property name="dir.jarfile" value="${dir.buildfile}/dist"/>
<property name="dir.libs" value="${dir.jarfile}/libs"/>
<target name="create_run_jar">
<delete dir="${dir.libs}"/>
<mkdir dir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-core-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-extensions-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/jxmpp-core-0.5.0.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/jxmpp-jid-0.5.0.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/xmlpull-1.1.3.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/xpp3_min-1.1.4c.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-experimental-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-java7-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-resolver-minidns-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-tcp-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/minidns-core-0.2.4.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/minidns-hla-0.2.4.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/minidns-iterative-resolver-0.2.4.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/minidns-dnssec-0.2.4.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/jxmpp-util-cache-0.5.0.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-im-4.2.1.jar" todir="${dir.libs}"/>
<copy file="${dir.buildfile}/libs/3rdParty/smack/smack-sasl-javax-4.2.1.jar" todir="${dir.libs}"/>
<manifestclasspath property="mamloader.manifest.classpath" jarfile="${dir.jarfile}/MAMLoader.jar">
<classpath>
<fileset dir="${dir.libs}" includes="*.jar" />
</classpath>
</manifestclasspath>
<jar destfile="${dir.jarfile}/MAMLoader.jar">
<manifest>
<attribute name="Main-Class" value="de.thedevstack.xmpp.mamloader.MamLoader"/>
<attribute name="Class-Path" value="${mamloader.manifest.classpath}"/>
</manifest>
<fileset dir="${dir.buildfile}/bin"/>
</jar>
</target>
</project>

BIN
libs/3rdParty/jxmpp-core-0.5.0.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/jxmpp-jid-0.5.0.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/jxmpp-util-cache-0.5.0.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/libidn-1.15.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/minidns-core-0.2.4.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/minidns-dnssec-0.2.4.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/minidns-hla-0.2.4.jar vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/3rdParty/smack/smack-core-4.2.1.jar vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/3rdParty/smack/smack-im-4.2.1.jar vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/3rdParty/smack/smack-tcp-4.2.1.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/xmlpull-1.1.3.1.jar vendored Normal file

Binary file not shown.

BIN
libs/3rdParty/xpp3_min-1.1.4c.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,121 @@
package de.thedevstack.xmpp.mamloader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.forward.packet.Forwarded;
import org.jivesoftware.smackx.mam.MamManager;
import org.jivesoftware.smackx.mam.MamManager.MamQueryResult;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
public class MamLoadClient {
private static final int LIMIT_PER_REQUEST = 50;
private AbstractXMPPConnection connection;
private MamManager mamManager;
private boolean debug;
public MamLoadClient(boolean debug) {
this.debug = debug;
}
public void connectAndLogin(String username, String password) throws SmackException, IOException, XMPPException, InterruptedException {
BareJid userJid = JidCreate.bareFrom(username);
this.connectAndLogin(userJid.getLocalpartOrThrow().toString(), password, userJid.getDomain().toString());
}
private void connectAndLogin(String username, String password, String host) throws SmackException, IOException, XMPPException, InterruptedException {
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setUsernameAndPassword(username, password)
.setXmppDomain(host)
.setHost(host)
.setDebuggerEnabled(this.debug)
//.setCustomSSLContext(SSLHelper.createNaiveSSLContext())
.setResource("MAMLoader_" + UUID.randomUUID())
.setSendPresence(false)
.build();
connection = new XMPPTCPConnection(config);
connection.connect();
connection.login();
mamManager = MamManager.getInstanceFor(connection);
}
public void disconnect() {
this.connection.disconnect();
}
public List<Forwarded> loadHistory(String jid) throws XmppStringprepException, NoResponseException, XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
return this.loadHistory(jid, null, null);
}
public List<Forwarded> loadHistory(String jid, Date start) throws XmppStringprepException, NoResponseException, XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
return this.loadHistory(jid, start, null);
}
public List<Forwarded> loadHistory(String jid, Date start, Date end) throws XmppStringprepException, NoResponseException, XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
List<Forwarded> allMessages = new ArrayList<>();
if (mamManager.isSupported()) {
Jid withJid = JidCreate.bareFrom(jid);
MamQueryResult archive = mamManager.queryArchive(null, start, end, withJid, null);
allMessages.addAll(archive.forwardedMessages);
while (!archive.mamFin.isComplete()) {
archive = mamManager.pageNext(archive, LIMIT_PER_REQUEST);
allMessages.addAll(archive.forwardedMessages);
}
allMessages = this.filterAndSort(allMessages);
}
return allMessages;
}
public List<Forwarded> loadHistory(String jid, int limit) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotLoggedInException, XmppStringprepException {
List<Forwarded> allMessages = new ArrayList<>();
if (mamManager.isSupported()) {
Jid withJid = JidCreate.bareFrom(jid);
MamQueryResult archive = mamManager.mostRecentPage(withJid, LIMIT_PER_REQUEST);
allMessages.addAll(archive.forwardedMessages);
while (!archive.mamFin.isComplete() && limit > allMessages.size()) {
int requestLimit = limit - allMessages.size();
archive = mamManager.pagePrevious(archive, (requestLimit < LIMIT_PER_REQUEST ? requestLimit : LIMIT_PER_REQUEST));
allMessages.addAll(archive.forwardedMessages);
}
allMessages = this.filterAndSort(allMessages);
}
return allMessages;
}
private List<Forwarded> filterAndSort(List<Forwarded> messages) {
return messages.stream()
.filter(forwarded -> forwarded.getForwardedStanza() instanceof Message
&& ((Message)forwarded.getForwardedStanza()).getBody() != null)
.sorted(new Comparator<Forwarded>() {
@Override
public int compare(Forwarded o1, Forwarded o2) {
return o1.getDelayInformation().getStamp().compareTo(o2.getDelayInformation().getStamp());
}
})
.collect(Collectors.toList());
}
}

View file

@ -0,0 +1,135 @@
package de.thedevstack.xmpp.mamloader;
import java.io.BufferedReader;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smackx.forward.packet.Forwarded;
public class MamLoader {
private static final SimpleDateFormat SDF = new SimpleDateFormat("dd.MM.YYYY HH:mm:ss");
private static final SimpleDateFormat INPUT = new SimpleDateFormat("dd.MM.YYYY");
public static void main(String[] args) throws InterruptedException, SmackException, IOException, XMPPException {
if (2 > args.length) {
System.err.println("Your JID and the JID of your chatpartner is needed.");
System.exit(1);
}
String myjid = args[0];
String jid = args[1];
String password;
boolean debug = false;
Date start = null;
Date end = null;
int limit = -1;
for (int i = 2; i < args.length; i++) {
switch (args[i]) {
case "-debug":
debug = true;
break;
case "-from":
start = parseDate(args[++i]);
break;
case "-to":
end = parseDate(args[++i]);
break;
case "-limit":
limit = Integer.parseInt(args[++i]);
break;
}
}
if (null != end && null == start) {
System.err.println("End without start not supported.");
System.exit(1);
} else if (null != start && -1 < limit) {
System.err.println("Limit not supported if start date is given.");
System.exit(1);
} else if (null == jid || null == myjid) {
System.err.println("Your JID and the JID of your chatpartner is needed.");
System.exit(1);
}
Console console = System.console();
if (null == console) {
System.out.println("Testenvironment!");
System.out.println("Warning: Password will be shown.");
System.out.print("Password: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
password = reader.readLine();
} else {
password = String.valueOf(console.readPassword("Password: "));
}
System.out.println("Loading history for chats with " + jid);
MamLoadClient mlc = new MamLoadClient(debug);
try {
mlc.connectAndLogin(myjid, password);
// mlc.loadHistory(jid, Date.from(LocalDate.of(2017, 11, 8).atStartOfDay().toInstant(ZoneOffset.UTC)), Date.from(LocalDate.of(2017, 11, 9).atStartOfDay().toInstant(ZoneOffset.UTC)));
// mlc.loadHistory(jid);
List<Forwarded> messages = null;
if (start == null && -1 == limit) {
messages = mlc.loadHistory(jid);
} else if (start == null && -1 < limit) {
messages = mlc.loadHistory(jid, limit);
} else if (start != null && end == null) {
messages = mlc.loadHistory(jid, start);
} else {
messages = mlc.loadHistory(jid, start, end);
}
System.out.println(messages.size() + " messages found");
printMessagesWithBody(messages, jid);
} finally {
mlc.disconnect();
}
}
private static Date parseDate(String dateToParse) {
try {
return INPUT.parse(dateToParse);
} catch (ParseException e) {
System.err.println("Could not parse date: " + dateToParse);
System.err.println("Needed format: dd.MM.YYYY");
System.exit(1);
return null;
}
}
private static void printMessagesWithBody(List<Forwarded> messages, String withJid) {
for (Forwarded f : messages) {
Stanza stanza = f.getForwardedStanza();
if (stanza instanceof Message) {
StringBuilder sb = new StringBuilder();
Message message = (Message) stanza;
if (null != message.getBody()) {
if (withJid.equals(message.getFrom().asBareJid().toString())) {
sb.append("<");
} else {
sb.append(">");
}
sb.append(" ");
sb.append(SDF.format(f.getDelayInformation().getStamp()));
sb.append(": ");
sb.append(message.getBody());
System.out.println(sb.toString());
}
}
}
}
}

View file

@ -0,0 +1,46 @@
package de.thedevstack.xmpp.mamloader;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public final class SSLHelper {
public static final SSLContext createNaiveSSLContext() {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
System.out.println(arg0[0].getSubjectDN());
}
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
System.out.println(arg0[0].getSubjectDN());
}
} };
sslContext.init(null, trustAllCerts, new SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sslContext;
}
}