Compare commits

..

6 Commits

Author SHA1 Message Date
JW
eea691a5aa - implementing publishing messages 2024-03-01 02:20:11 +01:00
Jacek W
a249ac0cdd Merge pull request #62 from jwdeveloper/develop-1.5.0-messages-to-file
Develop 1.5.0 messages to file
2024-03-01 01:53:21 +01:00
JW
b82c7184b3 Removed unused projects. 2024-03-01 01:52:54 +01:00
kohlerpop1
d3004d76c1 Merge remote-tracking branch 'origin/develop-1.5.0' into develop-1.5.0/messages-to-file 2024-02-28 12:27:05 -05:00
kohlerpop1
3ae73072ff Working on collecting to files! 2024-02-28 12:24:34 -05:00
Jacek W
9c5f97157a Merge pull request #61 from jwdeveloper/develop-1.5.0-remove-old-stuff
Develop 1.5.0 remove old stuff
2024-02-28 16:45:49 +01:00
16 changed files with 307 additions and 163 deletions

View File

@@ -61,7 +61,14 @@ public interface LiveClient {
*/ */
void publishEvent(TikTokEvent event); void publishEvent(TikTokEvent event);
void publishMessage(String base64);
/**
* @param webcastMessageName name of TikTok protocol-buffer message
* @param payloadBase64 protocol-buffer message bytes payload
*/
void publishMessage(String webcastMessageName, String payloadBase64);
void publishMessage(String webcastMessageName, byte[] payload);
/** /**
* Get information about gifts * Get information about gifts

View File

@@ -22,6 +22,7 @@
*/ */
package io.github.jwdeveloper.tiktok; package io.github.jwdeveloper.tiktok;
import com.google.protobuf.ByteString;
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent;
@@ -39,10 +40,12 @@ import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
import io.github.jwdeveloper.tiktok.live.GiftsManager; import io.github.jwdeveloper.tiktok.live.GiftsManager;
import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.live.LiveClient;
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo; import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
import io.github.jwdeveloper.tiktok.models.ConnectionState; import io.github.jwdeveloper.tiktok.models.ConnectionState;
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings; import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
import io.github.jwdeveloper.tiktok.websocket.SocketClient; import io.github.jwdeveloper.tiktok.websocket.SocketClient;
import java.util.Base64;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -56,8 +59,11 @@ public class TikTokLiveClient implements LiveClient {
private final TikTokListenersManager listenersManager; private final TikTokListenersManager listenersManager;
private final Logger logger; private final Logger logger;
private final GiftsManager giftsManager; private final GiftsManager giftsManager;
private final TikTokLiveMessageHandler messageHandler;
public TikTokLiveClient(GiftsManager giftsManager, public TikTokLiveClient(
TikTokLiveMessageHandler messageHandler,
GiftsManager giftsManager,
TikTokRoomInfo tikTokLiveMeta, TikTokRoomInfo tikTokLiveMeta,
LiveHttpClient tiktokHttpClient, LiveHttpClient tiktokHttpClient,
SocketClient webSocketClient, SocketClient webSocketClient,
@@ -65,6 +71,7 @@ public class TikTokLiveClient implements LiveClient {
LiveClientSettings clientSettings, LiveClientSettings clientSettings,
TikTokListenersManager listenersManager, TikTokListenersManager listenersManager,
Logger logger) { Logger logger) {
this.messageHandler = messageHandler;
this.giftsManager = giftsManager; this.giftsManager = giftsManager;
this.liveRoomInfo = tikTokLiveMeta; this.liveRoomInfo = tikTokLiveMeta;
this.httpClient = tiktokHttpClient; this.httpClient = tiktokHttpClient;
@@ -184,6 +191,20 @@ public class TikTokLiveClient implements LiveClient {
tikTokEventHandler.publish(this, event); tikTokEventHandler.publish(this, event);
} }
@Override
public void publishMessage(String webcastMessageName, String payloadBase64) {
this.publishMessage(webcastMessageName, Base64.getDecoder().decode(payloadBase64));
}
@Override
public void publishMessage(String webcastMessageName, byte[] payload) {
var builder = WebcastResponse.Message.newBuilder();
builder.setMethod(webcastMessageName);
builder.setPayload(ByteString.copyFrom(payload));
var message = builder.build();
messageHandler.handleSingleMessage(this, message);
}
@Override @Override
public GiftsManager getGiftManager() { public GiftsManager getGiftManager() {
return giftsManager; return giftsManager;

View File

@@ -129,6 +129,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
eventHandler); eventHandler);
return new TikTokLiveClient( return new TikTokLiveClient(
messageHandler,
giftsManager, giftsManager,
tiktokRoomInfo, tiktokRoomInfo,
liveHttpClient, liveHttpClient,

View File

@@ -40,12 +40,11 @@ public class CollectorExample {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
var collector = TikTokLiveCollector.use(settings -> var collector = TikTokLiveCollector.useMongo(settings ->
{ {
settings.setConnectionUrl("mongodb+srv://" + mongoUser + ":" + mongoPassword + "@" + mongoDatabase + "/?retryWrites=true&w=majority"); settings.setConnectionUrl("mongodb+srv://" + mongoUser + ":" + mongoPassword + "@" + mongoDatabase + "/?retryWrites=true&w=majority");
settings.setDatabaseName("tiktok");
}); });
collector.connectDatabase(); collector.connect();
var users = List.of("tehila_723", "dino123597", "domaxyzx", "dash4214", "obserwacje_live"); var users = List.of("tehila_723", "dino123597", "domaxyzx", "dash4214", "obserwacje_live");
Map<String, Object> additionalDataFields = Map.of("sessionTag", "ExampleTag"); Map<String, Object> additionalDataFields = Map.of("sessionTag", "ExampleTag");
@@ -71,6 +70,6 @@ public class CollectorExample {
} }
System.in.read(); System.in.read();
collector.disconnectDatabase(); collector.disconnect();
} }
} }

View File

@@ -1,7 +1,6 @@
package io.github.jwdeveloper.tiktok; package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokSubNotifyEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent; import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent; import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
@@ -11,7 +10,9 @@ import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftComboStateType; import io.github.jwdeveloper.tiktok.data.models.gifts.GiftComboStateType;
import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.live.LiveClient;
public class Events_And_Gifts_Testing_Example { public class Events_And_Gifts_Testing_Example
{
public static void main(String[] args) { public static void main(String[] args) {
LiveClient client = TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME) LiveClient client = TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
.configure(liveClientSettings -> .configure(liveClientSettings ->
@@ -35,6 +36,10 @@ public class Events_And_Gifts_Testing_Example {
{ {
liveClient.getLogger().info("New fake Gift: " + event.getGift()); liveClient.getLogger().info("New fake Gift: " + event.getGift());
}) })
.onLike((liveClient, event) ->
{
liveClient.getLogger().info("New fake Like event: " + event.getLikes());
})
.build(); .build();
var gifts = TikTokLive.gifts(); var gifts = TikTokLive.gifts();
@@ -57,11 +62,13 @@ public class Events_And_Gifts_Testing_Example {
client.publishEvent(fakeMessage); client.publishEvent(fakeMessage);
client.publishEvent(fakeSubscriber); client.publishEvent(fakeSubscriber);
client.publishEvent(fakeFollow); client.publishEvent(fakeFollow);
client.publishEvent(fakeLike);
client.publishEvent(fakeJoin); client.publishEvent(fakeJoin);
client.publishEvent(fakeLike);
client.publishMessage("WebcastLikeMessage", webcastLikeMessageBase64);
client.disconnect(); client.disconnect();
} }
private static final String webcastLikeMessageBase64 = "SAFSBRABGKwCUgcIAhABGKwCCv8BUAFYAbABA7gBARCflqWWo8Ha72UgzoPZhd8xQrwBGg4gkAMKCSNmZmZmZmZmZiJ/qgF6CngIhYjjgPWJv7RgGhDwnZKm8J2TjvCdk47wk4WTsgIKa3lsbGVlaGFsbPICTE1TNHdMakFCQUFBQXUyX21LNEw4WGJYa3lNaUFvZzJUTnNmVjk5N09WM2tpQ3NCTkNjYWkwcWxIcUt0Q3B0UGU1N2RLYVhxb0xWSXoICwoQcG1fbXRfbXNnX3ZpZXdlchIXezA6dXNlcn0gbGlrZWQgdGhlIExJVkVIAQoSV2ViY2FzdExpa2VNZXNzYWdlGIaWvY+RhdjvZTABwAEBEA8Y+Voq7RCyAQYImwEQjwK6AQCCAgDyAkxNUzR3TGpBQkFBQUF1Ml9tSzRMOFhiWGt5TWlBb2cyVE5zZlY5OTdPVjNraUNzQk5DY2FpMHFsSHFLdENwdFBlNTdkS2FYcW9MVkl6ggTqCLoBnwUqBggBEAEYIFoNCgASCSNCMzQ3N0VGRoABDwgEEtgEEix3ZWJjYXN0LXZhL2dyYWRlX2JhZGdlX2ljb25fbGl0ZV9sdjE1X3YyLnBuZzrpAnNzbG9jYWw6Ly93ZWJjYXN0X2x5bnh2aWV3X3BvcHVwP3VzZV9zcGFyaz0xJnVybD1odHRwcyUzQSUyRiUyRmxmMTYtZ2Vja28tc291cmNlLnRpa3Rva2Nkbi5jb20lMkZvYmolMkZieXRlLWd1cmQtc291cmNlLXNnJTJGdGlrdG9rJTJGZmUlMkZsaXZlJTJGdGlrdG9rX2xpdmVfcmV2ZW51ZV91c2VyX2xldmVsX21haW4lMkZzcmMlMkZwYWdlcyUyRnByaXZpbGVnZSUyRnBhbmVsJTJGdGVtcGxhdGUuanMmaGlkZV9zdGF0dXNfYmFyPTAmaGlkZV9uYXZfYmFyPTEmY29udGFpbmVyX2JnX2NvbG9yPTAwMDAwMDAwJmhlaWdodD05MCUyNSZiZGhtX2JpZD10aWt0b2tfbGl2ZV9yZXZlbnVlX3VzZXJfbGV2ZWxfbWFpbiZ1c2VfZm9yZXN0PTEKXWh0dHBzOi8vcDE2LXdlYmNhc3QudGlrdG9rY2RuLmNvbS93ZWJjYXN0LXZhL2dyYWRlX2JhZGdlX2ljb25fbGl0ZV9sdjE1X3YyLnBuZ350cGx2LW9iai5pbWFnZQpdaHR0cHM6Ly9wMTktd2ViY2FzdC50aWt0b2tjZG4uY29tL3dlYmNhc3QtdmEvZ3JhZGVfYmFkZ2VfaWNvbl9saXRlX2x2MTVfdjIucG5nfnRwbHYtb2JqLmltYWdlIgIxNTIAOgYaAhIAIgBiDQoAEgkjQjM0NzdFRkZ4DqIBBggBEAEYIAgEEBQYCCABUukCc3Nsb2NhbDovL3dlYmNhc3RfbHlueHZpZXdfcG9wdXA/dXNlX3NwYXJrPTEmdXJsPWh0dHBzJTNBJTJGJTJGbGYxNi1nZWNrby1zb3VyY2UudGlrdG9rY2RuLmNvbSUyRm9iaiUyRmJ5dGUtZ3VyZC1zb3VyY2Utc2clMkZ0aWt0b2slMkZmZSUyRmxpdmUlMkZ0aWt0b2tfbGl2ZV9yZXZlbnVlX3VzZXJfbGV2ZWxfbWFpbiUyRnNyYyUyRnBhZ2VzJTJGcHJpdmlsZWdlJTJGcGFuZWwlMkZ0ZW1wbGF0ZS5qcyZoaWRlX3N0YXR1c19iYXI9MCZoaWRlX25hdl9iYXI9MSZjb250YWluZXJfYmdfY29sb3I9MDAwMDAwMDAmaGVpZ2h0PTkwJTI1JmJkaG1fYmlkPXRpa3Rva19saXZlX3JldmVudWVfdXNlcl9sZXZlbF9tYWluJnVzZV9mb3Jlc3Q9MVgBYk8qAjE1CgEyEhM3MTM4MzgxNzQ3MjkyNTQyNzU2GgEwIi5tb2NrX2ZpeF93aWR0aF90cmFuc3BhcmVudF83MTM4MzgxNzQ3MjkyNTQyNzU2CIWI44D1ib+0YBoQ8J2SpvCdk47wnZOO8JOFk0r1BhJBMTAweDEwMC90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzEK0gFodHRwczovL3AxOS1wdS1zaWduLXVzZWFzdDgudGlrdG9rY2RuLXVzLmNvbS90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT1VMlNEbUk3Z3R5RW9rMlBlWFdmeTNsM1F6NlElM0QKyAFodHRwczovL3AxNi1wdS1zaWduLXVzZWFzdDgudGlrdG9rY2RuLXVzLmNvbS90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzF+YzVfMTAweDEwMC53ZWJwP2xrM3M9YTVkNDgwNzgmeC1leHBpcmVzPTE3MDkzMTI0MDAmeC1zaWduYXR1cmU9aWNWZEVZa0FnWkYlMkZ2WU5OTSUyRlVNMzE2eG9HdyUzRArGAWh0dHBzOi8vcDE5LXB1LXNpZ24tdXNlYXN0OC50aWt0b2tjZG4tdXMuY29tL3Rvcy11c2Vhc3Q4LWF2dC0wMDY4LXR4Mi82NjQ2Yzg2NmMzMjUxYTA5Njc2OGJiNjg5NTI4NWMzMX5jNV8xMDB4MTAwLndlYnA/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT1PQzdBQ3htQUklMkJsYlp4RkVuWktJT1RyRExGUSUzRArGAWh0dHBzOi8vcDE2LXB1LXNpZ24tdXNlYXN0OC50aWt0b2tjZG4tdXMuY29tL3Rvcy11c2Vhc3Q4LWF2dC0wMDY4LXR4Mi82NjQ2Yzg2NmMzMjUxYTA5Njc2OGJiNjg5NTI4NWMzMX5jNV8xMDB4MTAwLmpwZWc/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT02YUwlMkZNZWtOeHg5NXlvVTVLOTZON0xwRUlNdyUzRLICCmt5bGxlZWhhbGxCyQEIgojG1pKb0clgErwBChBwbV9tdF9tc2dfdmlld2VyEhd7MDp1c2VyfSBsaWtlZCB0aGUgTElWRRoOCgkjZmZmZmZmZmYgkAMifwgLqgF6CngIhYjjgPWJv7RgGhDwnZKm8J2TjvCdk47wk4WTsgIKa3lsbGVlaGFsbPICTE1TNHdMakFCQUFBQXUyX21LNEw4WGJYa3lNaUFvZzJUTnNmVjk5N09WM2tpQ3NCTkNjYWkwcWxIcUt0Q3B0UGU1N2RLYVhxb0xWSXo=";
} }

View File

@@ -22,19 +22,34 @@
*/ */
package io.github.jwdeveloper.tiktok.extension.collector; package io.github.jwdeveloper.tiktok.extension.collector;
import io.github.jwdeveloper.tiktok.extension.collector.api.LiveDataCollector; import io.github.jwdeveloper.tiktok.extension.collector.api.settings.FileDataCollectorSettings;
import io.github.jwdeveloper.tiktok.extension.collector.api.data.LiveDataCollectorSettings; import io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo.MongoDataCollectorSettings;
import io.github.jwdeveloper.tiktok.extension.collector.impl.TikTokLiveDataCollector; import io.github.jwdeveloper.tiktok.extension.collector.impl.*;
import io.github.jwdeveloper.tiktok.extension.collector.impl.storages.FileStorage;
import io.github.jwdeveloper.tiktok.extension.collector.impl.storages.MongoStorage;
import java.util.function.Consumer; import java.util.function.Consumer;
/**
*
*/
public class TikTokLiveCollector public class TikTokLiveCollector
{ {
public static TikTokLiveDataCollector use(Consumer<LiveDataCollectorSettings> consumer) public static DataCollector useMongo(Consumer<MongoDataCollectorSettings> consumer) {
{ var settings = new MongoDataCollectorSettings();
var settings = new LiveDataCollectorSettings();
consumer.accept(settings); consumer.accept(settings);
return new TikTokLiveDataCollector(settings);
var storage = new MongoStorage(settings);
return new DataCollector(storage);
}
public static DataCollector useFile(Consumer<FileDataCollectorSettings> consumer) {
var settings = new FileDataCollectorSettings();
consumer.accept(settings);
var storage = new FileStorage(settings);
return new DataCollector(storage);
} }
} }

View File

@@ -0,0 +1,11 @@
package io.github.jwdeveloper.tiktok.extension.collector.api;
import org.bson.Document;
public interface Storage {
void connect();
void disconnect();
void insert(Document document);
}

View File

@@ -1,4 +1,4 @@
package io.github.jwdeveloper.tiktok.extension.collector.api.data; package io.github.jwdeveloper.tiktok.extension.collector.api.settings;
import lombok.Data; import lombok.Data;
import org.bson.Document; import org.bson.Document;

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.github.jwdeveloper.tiktok.extension.collector.api.settings;
import lombok.Data;
import java.io.File;
@Data
public class FileDataCollectorSettings {
private File parentFile;
}

View File

@@ -20,34 +20,19 @@
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
package io.github.jwdeveloper.tiktok.extension.collector.api.data; package io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo;
import lombok.Setter;
import lombok.experimental.Accessors;
@Setter
@Accessors(chain = true)
public class MongoDBConnectionStringBuilder { public class MongoDBConnectionStringBuilder {
private String username; private String username;
private String password; private String password;
private String database; private String database;
private String cluster; private String cluster;
public MongoDBConnectionStringBuilder setUsername(String username) {
this.username = username;
return this;
}
public MongoDBConnectionStringBuilder setPassword(String password) {
this.password = password;
return this;
}
public MongoDBConnectionStringBuilder setDatabase(String database) {
this.database = database;
return this;
}
public MongoDBConnectionStringBuilder setCluster(String cluster) {
this.cluster = cluster;
return this;
}
public String build() { public String build() {
return String.format("mongodb+srv://%s:%s@%s/%s?retryWrites=true&w=majority", return String.format("mongodb+srv://%s:%s@%s/%s?retryWrites=true&w=majority",
username, password, cluster, database); username, password, cluster, database);

View File

@@ -20,27 +20,23 @@
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
package io.github.jwdeveloper.tiktok.extension.collector.api.data; package io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo;
import lombok.Data; import lombok.*;
import java.util.function.Consumer; import java.util.function.Consumer;
@Data @Data
public class LiveDataCollectorSettings { public class MongoDataCollectorSettings {
@Setter
private String connectionUrl; private String connectionUrl;
private String databaseName; private String databaseName = "tiktok";
private String sessionTag; private String collectionName = "data";
public void connectionBuilder(Consumer<MongoDBConnectionStringBuilder> consumer) {
public void setConnectionUrl(String connectionUrl) {
this.connectionUrl = connectionUrl;
}
public void setConnectionUrl(Consumer<MongoDBConnectionStringBuilder> consumer) {
var builder = new MongoDBConnectionStringBuilder(); var builder = new MongoDBConnectionStringBuilder();
consumer.accept(builder); consumer.accept(builder);
connectionUrl = builder.build(); connectionUrl = builder.build();

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.github.jwdeveloper.tiktok.extension.collector.impl;
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.CollectorListenerSettings;
import org.bson.Document;
import java.util.Map;
import java.util.function.Function;
public class DataCollector {
private final Storage storage;
public DataCollector(Storage storage) {
this.storage = storage;
}
public void connect() {
storage.connect();
}
public void disconnect() {
storage.disconnect();
}
public DataCollectorListener newListener() {
return newListener(Map.of());
}
public DataCollectorListener newListener(Map<String, Object> additionalFields) {
return newListener(additionalFields, (e) -> true);
}
public DataCollectorListener newListener(Map<String, Object> additionalFields,
Function<Document, Boolean> filter) {
var settings = new CollectorListenerSettings();
settings.setExtraFields(additionalFields);
settings.setFilter(filter);
return new DataCollectorListener(storage, settings);
}
}

View File

@@ -1,6 +1,5 @@
package io.github.jwdeveloper.tiktok.extension.collector.impl; package io.github.jwdeveloper.tiktok.extension.collector.impl;
import com.mongodb.client.MongoCollection;
import io.github.jwdeveloper.tiktok.annotations.TikTokEventObserver; import io.github.jwdeveloper.tiktok.annotations.TikTokEventObserver;
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
@@ -8,7 +7,8 @@ import io.github.jwdeveloper.tiktok.data.events.control.TikTokConnectingEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent; import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException; import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
import io.github.jwdeveloper.tiktok.extension.collector.api.LiveDataCollector; import io.github.jwdeveloper.tiktok.extension.collector.api.LiveDataCollector;
import io.github.jwdeveloper.tiktok.extension.collector.api.data.CollectorListenerSettings; import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.CollectorListenerSettings;
import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.live.LiveClient;
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
import io.github.jwdeveloper.tiktok.utils.JsonUtil; import io.github.jwdeveloper.tiktok.utils.JsonUtil;
@@ -19,15 +19,15 @@ import java.io.StringWriter;
import java.util.Base64; import java.util.Base64;
import java.util.UUID; import java.util.UUID;
public class TikTokLiveDataCollectorListener implements LiveDataCollector { public class DataCollectorListener implements LiveDataCollector {
private final MongoCollection<Document> collection; private final Storage storage;
private final CollectorListenerSettings settings; private final CollectorListenerSettings settings;
private String sessionId; private String sessionId;
private String userName; private String userName;
public TikTokLiveDataCollectorListener(MongoCollection<Document> collection, CollectorListenerSettings settings) { public DataCollectorListener(Storage collection, CollectorListenerSettings settings) {
this.collection = collection; this.storage = collection;
this.settings = settings; this.settings = settings;
} }
@@ -35,10 +35,7 @@ public class TikTokLiveDataCollectorListener implements LiveDataCollector {
@TikTokEventObserver @TikTokEventObserver
private void onResponse(LiveClient liveClient, TikTokWebsocketResponseEvent event) { private void onResponse(LiveClient liveClient, TikTokWebsocketResponseEvent event) {
includeResponse(liveClient, event.getResponse()); includeResponse(liveClient, event.getResponse());
event.getResponse().getMessagesList().forEach(message -> event.getResponse().getMessagesList().forEach(message -> includeMessage(liveClient, message));
{
includeMessage(liveClient, message);
});
} }
@TikTokEventObserver @TikTokEventObserver
@@ -103,7 +100,7 @@ public class TikTokLiveDataCollectorListener implements LiveDataCollector {
if (!settings.getFilter().apply(document)) { if (!settings.getFilter().apply(document)) {
return; return;
} }
collection.insertOne(document); storage.insert(document);
} }

View File

@@ -1,89 +0,0 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.github.jwdeveloper.tiktok.extension.collector.impl;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.ServerApi;
import com.mongodb.ServerApiVersion;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Indexes;
import io.github.jwdeveloper.tiktok.extension.collector.api.data.CollectorListenerSettings;
import io.github.jwdeveloper.tiktok.extension.collector.api.data.LiveDataCollectorSettings;
import org.bson.Document;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
public class TikTokLiveDataCollector {
private final LiveDataCollectorSettings settings;
private MongoClient mongoClient;
private MongoDatabase database;
private MongoCollection<Document> collection;
public TikTokLiveDataCollector(LiveDataCollectorSettings settings) {
this.settings = settings;
}
public void connectDatabase() {
var serverApi = ServerApi.builder()
.version(ServerApiVersion.V1)
.build();
var mongoSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(settings.getConnectionUrl()))
.serverApi(serverApi)
.build();
mongoClient = MongoClients.create(mongoSettings);
database = mongoClient.getDatabase(settings.getDatabaseName());
collection = database.getCollection("data");
collection.createIndex(Indexes.hashed("session"));
collection.createIndex(Indexes.hashed("dataType"));
}
public void disconnectDatabase() {
mongoClient.close();
}
public TikTokLiveDataCollectorListener newListener() {
return newListener(Map.of());
}
public TikTokLiveDataCollectorListener newListener(Map<String, Object> additionalFields) {
return newListener(additionalFields, (e)->true);
}
public TikTokLiveDataCollectorListener newListener(Map<String, Object> additionalFields,
Function<Document, Boolean> filter) {
var settings = new CollectorListenerSettings();
settings.setExtraFields(additionalFields);
settings.setFilter(filter);
return new TikTokLiveDataCollectorListener(collection, settings);
}
}

View File

@@ -0,0 +1,41 @@
package io.github.jwdeveloper.tiktok.extension.collector.impl.storages;
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.FileDataCollectorSettings;
import org.bson.Document;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
public class FileStorage implements Storage {
private final FileDataCollectorSettings settings;
public FileStorage(FileDataCollectorSettings fileDataCollectorSettings) {
this.settings = fileDataCollectorSettings;
}
@Override
public void connect() {
}
@Override
public void disconnect() {
}
@Override
public void insert(Document document) {
var fileName = document.get("dataType") + ":" + document.get("dataTypeName") + ".json";
try {
var file = new File(settings.getParentFile(), fileName);
file.createNewFile();
Files.writeString(file.toPath(), document.toJson(), StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,58 @@
package io.github.jwdeveloper.tiktok.extension.collector.impl.storages;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.ServerApi;
import com.mongodb.ServerApiVersion;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Indexes;
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo.MongoDataCollectorSettings;
import org.bson.Document;
public class MongoStorage implements Storage {
private MongoClient mongoClient;
private MongoDatabase database;
private MongoCollection<Document> collection;
private final MongoDataCollectorSettings settings;
public MongoStorage(MongoDataCollectorSettings settings) {
this.settings = settings;
}
@Override
public void connect() {
var serverApi = ServerApi.builder()
.version(ServerApiVersion.V1)
.build();
var mongoSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(settings.getConnectionUrl()))
.serverApi(serverApi)
.build();
mongoClient = MongoClients.create(mongoSettings);
database = mongoClient.getDatabase(settings.getDatabaseName());
collection = database.getCollection(settings.getCollectionName());
collection.createIndex(Indexes.hashed("session"));
collection.createIndex(Indexes.hashed("dataType"));
}
@Override
public void disconnect() {
if (mongoClient == null) {
return;
}
mongoClient.close();
}
@Override
public void insert(Document document) {
collection.insertOne(document);
}
}