mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 16:59:39 -05:00
Changes:
- TikTokHttpResponseEvent - Fixed User attributes in CommentEvent - Redesign .onMapper method
This commit is contained in:
@@ -22,13 +22,35 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.webviewer;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.handlers.TikTokHandler;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokCollectorService;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokDatabaseService;
|
||||
import io.javalin.Javalin;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
var manager = new TikTokManager();
|
||||
public class Main {
|
||||
public static void main(String[] args) throws SQLException, ExecutionException, InterruptedException, IOException {
|
||||
var settings = new Settings();
|
||||
settings.setUserName("szalonamoniaxx");
|
||||
settings.setSessionTag("battle");
|
||||
settings.setDbName("db-battle");
|
||||
settings.setPort(8002);
|
||||
|
||||
var db = new TikTokDatabase(settings.getDbName());
|
||||
db.connect();
|
||||
|
||||
var service = new TikTokDatabaseService(db);
|
||||
var collectorService = new TikTokCollectorService(settings, db);
|
||||
var handler = new TikTokHandler(service, settings, collectorService);
|
||||
// var manager = new TikTokManager(service);
|
||||
var app = Javalin.create(config ->
|
||||
{
|
||||
config.plugins.enableCors(corsContainer ->
|
||||
@@ -39,13 +61,19 @@ public class Main {
|
||||
});
|
||||
});
|
||||
config.staticFiles.add("/public");
|
||||
}).start(8001);
|
||||
}).start(settings.getPort());
|
||||
|
||||
var handler = new TikTokHandler(manager);
|
||||
app.get("/tiktok/status", handler::connectionStatus);
|
||||
app.get("/tiktok/connect", handler::connect);
|
||||
app.get("/tiktok/disconnect", handler::disconnect);
|
||||
app.get("/tiktok/events", handler::events);
|
||||
app.get("/tiktok/events/pages", handler::eventPages);
|
||||
app.get("/tiktok/events/message", handler::eventMessage);
|
||||
|
||||
app.get("/tiktok/data/pages", handler::getDataPages);
|
||||
app.get("/tiktok/data/names", handler::getDataNames);
|
||||
app.get("/tiktok/data", handler::getData);
|
||||
|
||||
app.get("/tiktok/update", handler::updateSearch);
|
||||
app.get("/tiktok/sessions", handler::getUserSessionTags);
|
||||
app.get("/tiktok/users", handler::getUsers);
|
||||
app.get("/tiktok/data-types", handler::getDataTypes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.github.jwdeveloper.tiktok.webviewer;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Settings
|
||||
{
|
||||
|
||||
private int port;
|
||||
private String dbName;
|
||||
private String userName;
|
||||
private String sessionTag;
|
||||
}
|
||||
@@ -1,137 +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.webviewer;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.MessageCollector;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.TikTokMessageCollectorClient;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.client.TikTokMessagessCollectorBuilder;
|
||||
import io.github.jwdeveloper.tiktok.tools.util.MessageUtil;
|
||||
import lombok.Value;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class TikTokManager {
|
||||
TikTokMessagessCollectorBuilder client;
|
||||
MessageCollector msgCollector;
|
||||
|
||||
public static String dbName= "log";
|
||||
|
||||
public TikTokManager() {
|
||||
msgCollector = new MessageCollector(dbName);
|
||||
}
|
||||
|
||||
public void connect(String name) throws SQLException {
|
||||
disconnect();
|
||||
client = TikTokMessageCollectorClient.create(msgCollector, dbName)
|
||||
.addOnBuilder(liveClientBuilder ->
|
||||
{
|
||||
liveClientBuilder.onRoomInfo((liveClient, event) ->
|
||||
{
|
||||
|
||||
});
|
||||
liveClientBuilder.onGift((liveClient, event) ->
|
||||
{
|
||||
|
||||
});
|
||||
liveClientBuilder.onWebsocketUnhandledMessage((liveClient, event) ->
|
||||
{
|
||||
System.out.println("UNHANDLED MESSAGE! "+event.getMessage().getMethod());
|
||||
});
|
||||
|
||||
})
|
||||
.addUser(name);
|
||||
client.buildAndRun();
|
||||
}
|
||||
|
||||
public List<String> getEventsNames() {
|
||||
return msgCollector.getMessages().keySet().stream().toList();
|
||||
}
|
||||
|
||||
public List<String> getEventMessages(String eventName) {
|
||||
return msgCollector.getMessages().get(eventName).stream().map(MessageCollector.MessageData::getEventData).toList();
|
||||
}
|
||||
|
||||
|
||||
public MessageDto getMessage(String event, String index) throws InvalidProtocolBufferException {
|
||||
var eventData = msgCollector.getMessages().get(event);
|
||||
var messages = eventData.stream().toList();
|
||||
var random = new Random();
|
||||
|
||||
var msgIndex = 0;
|
||||
if (index != null && !index.isEmpty()) {
|
||||
msgIndex = Integer.parseInt(index);
|
||||
msgIndex = Math.min(msgIndex, messages.size() - 1);
|
||||
msgIndex = Math.max(msgIndex, 0);
|
||||
}
|
||||
|
||||
|
||||
var msg = messages.get(msgIndex);
|
||||
|
||||
|
||||
var bytes = Base64.getDecoder().decode(msg.getEventData());
|
||||
var content = MessageUtil.getContent(event, bytes);
|
||||
return new MessageDto(content, msg.getEventData(), event);
|
||||
}
|
||||
|
||||
|
||||
public PagesDto getPages(String event) throws InvalidProtocolBufferException {
|
||||
var eventData = msgCollector.getMessages().get(event);
|
||||
var messages = eventData.stream().toList();
|
||||
|
||||
var counter = new AtomicInteger(-1);
|
||||
var pages = messages.stream().map(e ->
|
||||
{
|
||||
return "http://localhost:8001/tiktok/events/message?eventName=" + event + "&page=" + counter.incrementAndGet();
|
||||
}).toList();
|
||||
|
||||
return new PagesDto(event, messages.size(), pages);
|
||||
}
|
||||
|
||||
@Value
|
||||
public class PagesDto {
|
||||
String eventName;
|
||||
int pages;
|
||||
List<String> links;
|
||||
}
|
||||
|
||||
|
||||
@Value
|
||||
public class MessageDto {
|
||||
String content;
|
||||
String base64;
|
||||
String eventName;
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
client.stop();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.webviewer;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkLayerMessage;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMessage;
|
||||
import io.github.jwdeveloper.tiktok.tools.TikTokLiveTools;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ToolsExamples {
|
||||
|
||||
private static final String tiktokUser = "debb.cl";
|
||||
|
||||
private static final String db = "db-battle";
|
||||
|
||||
private static final String sessionTag = "gifts";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// runCollector();
|
||||
runCollector();
|
||||
//runTester();
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
/*
|
||||
WebcastLinkMicArmies
|
||||
WebcastLinkMicBattle
|
||||
*/
|
||||
//WebcastLinkMicArmies battle data?
|
||||
//WebcastLinkMicBattlePunishFinish end of battle?
|
||||
//WebcastLinkLayerMessage send after end of battle
|
||||
// send after LinkLayer -> WebcastLinkMessage
|
||||
private static void runCollector() {
|
||||
TikTokLiveTools.createCollector(db)
|
||||
.addUser(tiktokUser)
|
||||
.setSessionTag(sessionTag)
|
||||
.configureLiveClient(liveClientBuilder ->
|
||||
{
|
||||
liveClientBuilder.configure(clientSettings ->
|
||||
{
|
||||
clientSettings.setPrintToConsole(true);
|
||||
});
|
||||
liveClientBuilder.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
for (var msg : event.getResponse().getMessagesList()) {
|
||||
System.out.println(msg.getMethod());
|
||||
}
|
||||
});
|
||||
liveClientBuilder.onConnected((liveClient, event) ->
|
||||
{
|
||||
liveClient.getLogger().info("Connected");
|
||||
});
|
||||
}).buildAndRun();
|
||||
}
|
||||
|
||||
private static void runTester() {
|
||||
TikTokLiveTools.createTester(db)
|
||||
.setSessionTag(sessionTag)
|
||||
.setUser(tiktokUser)
|
||||
.configureLiveClient(liveClientBuilder ->
|
||||
{
|
||||
liveClientBuilder.onError((liveClient, event) ->
|
||||
{
|
||||
event.getException().printStackTrace();
|
||||
;
|
||||
});
|
||||
|
||||
liveClientBuilder.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Response =====================================");
|
||||
for (var msg : event.getResponse().getMessagesList()) {
|
||||
System.out.println("Message -> " + msg.getMethod());
|
||||
}
|
||||
});
|
||||
liveClientBuilder.onEvent((liveClient, event) ->
|
||||
{
|
||||
System.out.println("Event -> " + event.getClass().getSimpleName());
|
||||
});
|
||||
})
|
||||
.buildAndRun();
|
||||
}
|
||||
}
|
||||
@@ -25,61 +25,153 @@ package io.github.jwdeveloper.tiktok.webviewer.handlers;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.TikTokManager;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.Settings;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokCollectorService;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokDatabaseService;
|
||||
import io.javalin.http.Context;
|
||||
import lombok.Value;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class TikTokHandler {
|
||||
private final TikTokManager tikTokManager;
|
||||
private final TikTokDatabaseService databaseService;
|
||||
private final Settings settings;
|
||||
private final TikTokCollectorService collectorService;
|
||||
|
||||
public TikTokHandler(TikTokManager tikTokManager) {
|
||||
this.tikTokManager = tikTokManager;
|
||||
public TikTokHandler(TikTokDatabaseService databaseService,
|
||||
Settings settings,
|
||||
TikTokCollectorService collectorService) {
|
||||
this.databaseService = databaseService;
|
||||
this.settings = settings;
|
||||
this.collectorService = collectorService;
|
||||
}
|
||||
|
||||
|
||||
public void connect(Context context) throws SQLException {
|
||||
String name = context.queryParam("name");
|
||||
if (name.equals(" ")) {
|
||||
context.result("Name can not be empty");
|
||||
context.status(400);
|
||||
return;
|
||||
}
|
||||
tikTokManager.connect(name);
|
||||
public void connect(Context context) {
|
||||
var name = context.queryParam("name");
|
||||
var sessionTag = context.queryParam("session");
|
||||
System.out.println("Session tag" + sessionTag);
|
||||
collectorService.start(name, sessionTag);
|
||||
settings.setUserName(name);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void disconnect(Context context){
|
||||
tikTokManager.disconnect();
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void events(Context context) {
|
||||
var events = tikTokManager.getEventsNames();
|
||||
var gson = getGson();
|
||||
var result = gson.toJson(events);
|
||||
public void connectionStatus(Context context) {
|
||||
var isWorking = collectorService.isRunning();
|
||||
var result = getGson().toJson(isWorking);
|
||||
context.result(result);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void eventMessage(Context context) throws InvalidProtocolBufferException {
|
||||
String name = context.queryParam("eventName");
|
||||
String page = context.queryParam("page");
|
||||
public void disconnect(Context context) {
|
||||
|
||||
var result = tikTokManager.getMessage(name, page);
|
||||
var gson = getGson();
|
||||
context.result(gson.toJson(result));
|
||||
collectorService.stop();
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void eventPages(Context context) throws InvalidProtocolBufferException {
|
||||
String name = context.queryParam("eventName");
|
||||
var result = tikTokManager.getPages(name);
|
||||
|
||||
public void getUsers(Context context) {
|
||||
var users = databaseService.getUsers();
|
||||
var result = getGson().toJson(users);
|
||||
context.result(result);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void getUserSessionTags(Context context) {
|
||||
var dataType = context.queryParam("user");
|
||||
var sessionsTags = databaseService.getSessionTag(dataType);
|
||||
|
||||
var result = getGson().toJson(sessionsTags);
|
||||
context.result(result);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void getDataTypes(Context context) {
|
||||
var result = getGson().toJson(List.of("event", "message", "response"));
|
||||
context.result(result);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
|
||||
public void updateSearch(Context context) {
|
||||
var userName = context.queryParam("user");
|
||||
var sessionTag = context.queryParam("session");
|
||||
|
||||
settings.setUserName(userName);
|
||||
settings.setSessionTag(sessionTag);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
|
||||
public void getDataNames(Context context) {
|
||||
var dataType = context.queryParam("type");
|
||||
var dataNames = databaseService.getDataNames(dataType, settings.getUserName(), settings.getSessionTag());
|
||||
var gson = getGson();
|
||||
context.result(gson.toJson(result));
|
||||
|
||||
|
||||
var result = gson.toJson(dataNames);
|
||||
context.result(result);
|
||||
context.status(200);
|
||||
}
|
||||
|
||||
public void getData(Context context) {
|
||||
var page = context.queryParam("page");
|
||||
var dataType = context.queryParam("type");
|
||||
var dataName = context.queryParam("name");
|
||||
if (page == null) {
|
||||
page = "0";
|
||||
}
|
||||
|
||||
|
||||
var asProto = context.queryParam("asProto");
|
||||
var asJson = asProto == null;
|
||||
var dto = new TikTokDatabaseService.DatabaseDataDto(dataType, dataName, settings.getUserName(), settings.getSessionTag(), asJson);
|
||||
var result = databaseService.getData(dto);
|
||||
var content = result.get(Integer.parseInt(page));
|
||||
|
||||
var response = new MessageDto(content, "", dataName);
|
||||
var gson = getGson();
|
||||
context.result(gson.toJson(response));
|
||||
}
|
||||
|
||||
public void getDataPages(Context context) throws InvalidProtocolBufferException {
|
||||
var dataType = context.queryParam("type");
|
||||
var dataName = context.queryParam("name");
|
||||
|
||||
var asJson = true;
|
||||
var dto = new TikTokDatabaseService.DatabaseDataDto(dataType, dataName, settings.getUserName(), settings.getSessionTag(), asJson);
|
||||
var result = databaseService.getData(dto);
|
||||
var counter = new AtomicInteger(-1);
|
||||
var pages = result.stream().map(e ->
|
||||
{
|
||||
return "http://localhost:" + settings.getPort() + "/tiktok/data?type=" + dataType + "&page=" + counter.incrementAndGet() + "&name=" + dataName;
|
||||
}).toList();
|
||||
|
||||
var response = new PagesDto(dataName, counter.get(), pages);
|
||||
var gson = getGson();
|
||||
context.result(gson.toJson(response));
|
||||
}
|
||||
|
||||
|
||||
public Gson getGson() {
|
||||
return new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
|
||||
}
|
||||
|
||||
|
||||
@Value
|
||||
public class PagesDto {
|
||||
String eventName;
|
||||
int pages;
|
||||
List<String> links;
|
||||
}
|
||||
|
||||
|
||||
@Value
|
||||
public class MessageDto {
|
||||
String content;
|
||||
String base64;
|
||||
String eventName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package io.github.jwdeveloper.tiktok.webviewer.services;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.tools.TikTokLiveTools;
|
||||
import io.github.jwdeveloper.tiktok.tools.collector.api.DataCollector;
|
||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
||||
import io.github.jwdeveloper.tiktok.webviewer.Settings;
|
||||
|
||||
public class TikTokCollectorService {
|
||||
private final Settings settings;
|
||||
private final TikTokDatabase database;
|
||||
|
||||
private boolean isConnected = false;
|
||||
|
||||
private DataCollector collector;
|
||||
|
||||
public TikTokCollectorService(Settings settings, TikTokDatabase database) {
|
||||
this.settings = settings;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public void start(String user, String sessionTag) {
|
||||
stop();
|
||||
collector = createClient(user, sessionTag);
|
||||
|
||||
collector.connect();
|
||||
}
|
||||
|
||||
public boolean isRunning()
|
||||
{
|
||||
if(collector == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (collector != null) {
|
||||
collector.disconnect(true);
|
||||
}
|
||||
isConnected =false;
|
||||
collector = null;
|
||||
try {
|
||||
database.close();
|
||||
database.connect();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private DataCollector createClient(String user, String sessionTag) {
|
||||
return TikTokLiveTools.createCollector("dupa")
|
||||
.addUser(user)
|
||||
.setSessionTag(sessionTag)
|
||||
.setDatabase(database)
|
||||
.configureLiveClient(liveClientBuilder ->
|
||||
{
|
||||
liveClientBuilder.configure(clientSettings ->
|
||||
{
|
||||
clientSettings.setPrintToConsole(true);
|
||||
});
|
||||
|
||||
liveClientBuilder.onWebsocketResponse((liveClient, event) ->
|
||||
{
|
||||
for (var msg : event.getResponse().getMessagesList()) {
|
||||
System.out.println(msg.getMethod());
|
||||
}
|
||||
});
|
||||
liveClientBuilder.onDisconnected((liveClient, event) ->
|
||||
{
|
||||
liveClient.getLogger().info("Disconnected");
|
||||
isConnected = false;
|
||||
});
|
||||
liveClientBuilder.onError((liveClient, event) ->
|
||||
{
|
||||
event.getException().printStackTrace();
|
||||
});
|
||||
liveClientBuilder.onConnected((liveClient, event) ->
|
||||
{
|
||||
liveClient.getLogger().info("Connected");
|
||||
isConnected = true;
|
||||
});
|
||||
}).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package io.github.jwdeveloper.tiktok.webviewer.services;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDataTableDAO;
|
||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokDataTable;
|
||||
import io.github.jwdeveloper.tiktok.tools.util.MessageUtil;
|
||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
||||
import io.github.jwdeveloper.tiktok.utils.ProtocolUtils;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
public class TikTokDatabaseService {
|
||||
public TikTokDatabase tikTokDatabase;
|
||||
private TikTokDataTableDAO table;
|
||||
|
||||
|
||||
public record DatabaseDataDto(String dataType, String dataName, String user, String sessionTag, boolean asJson) {
|
||||
}
|
||||
|
||||
|
||||
public TikTokDatabaseService(TikTokDatabase databaseName) {
|
||||
tikTokDatabase = databaseName;
|
||||
table = tikTokDatabase.getDataTableDAO();
|
||||
}
|
||||
|
||||
public List<String> getUsers() {
|
||||
return table.getUsers();
|
||||
}
|
||||
|
||||
public List<String> getSessionTag(String user) {
|
||||
return table.getSessionTagByUser(user);
|
||||
}
|
||||
|
||||
public List<String> getDataNames(String dataType, String user, String sessionTag) {
|
||||
|
||||
return tikTokDatabase.getDataNames(dataType, sessionTag, user);
|
||||
}
|
||||
|
||||
public List<String> getData(DatabaseDataDto dataDto) {
|
||||
var data = tikTokDatabase.getDataTableDAO().selectSessionData(dataDto.dataType(), dataDto.sessionTag(), dataDto.user());
|
||||
switch (dataDto.dataType()) {
|
||||
case "message" -> {
|
||||
return getMessages(dataDto.dataName(), data, dataDto.asJson);
|
||||
}
|
||||
case "event" -> {
|
||||
return getEvents(dataDto.dataName(), data);
|
||||
}
|
||||
case "response" -> {
|
||||
return getResponse(data,dataDto.dataName());
|
||||
}
|
||||
}
|
||||
return List.of("unknown dataType");
|
||||
}
|
||||
|
||||
|
||||
private List<String> getMessages(String messageName, List<TikTokDataTable> data, boolean asJson) {
|
||||
|
||||
var messages = data.stream()
|
||||
.filter(e -> e.getDataTypeName().equals(messageName))
|
||||
.map(e ->
|
||||
{
|
||||
|
||||
try {
|
||||
var bytes = Base64.getDecoder().decode(e.getContent());
|
||||
if (asJson == false) {
|
||||
return ProtocolUtils.getProtocolBufferStructure(bytes).toJson();
|
||||
}
|
||||
var parsedMessage = MessageUtil.getContent(messageName, bytes);
|
||||
return parsedMessage;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
|
||||
})
|
||||
.toList();
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
private List<String> getResponse(List<TikTokDataTable> data,String dataTypeName)
|
||||
{
|
||||
var messages = data.stream()
|
||||
.filter(e -> e.getDataTypeName().equals(dataTypeName))
|
||||
.map(e ->
|
||||
{
|
||||
if(e.getDataTypeName().equals("Http"))
|
||||
{
|
||||
return e.getContent();
|
||||
}
|
||||
try
|
||||
{
|
||||
var bytes = Base64.getDecoder().decode(e.getContent());
|
||||
var parsedMessage = WebcastResponse.parseFrom(bytes);
|
||||
var json = JsonUtil.toJson(parsedMessage);
|
||||
return json;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return "error";
|
||||
}
|
||||
|
||||
})
|
||||
.toList();
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
private List<String> getEvents(String dataName, List<TikTokDataTable> data) {
|
||||
var messages = data.stream()
|
||||
.filter(e -> e.getDataTypeName().equals(dataName))
|
||||
.map(TikTokDataTable::getContent)
|
||||
.toList();
|
||||
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
135
Tools-EventsWebViewer/src/main/resources/public/index.css
Normal file
135
Tools-EventsWebViewer/src/main/resources/public/index.css
Normal file
@@ -0,0 +1,135 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
color: whitesmoke;
|
||||
}
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.connect-btn
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
.dropdown
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
.dropdown-toggle
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
border-color: #2c2c2c;
|
||||
width: 100%;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.btn-primary
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
border-color: #2c2c2c;
|
||||
}
|
||||
.btn-primary:hover
|
||||
{
|
||||
background-color: #474747;
|
||||
border-color: #474747;
|
||||
}
|
||||
.margin
|
||||
{
|
||||
margin-top: 2em;
|
||||
}
|
||||
.form
|
||||
{
|
||||
|
||||
padding: 1em;
|
||||
|
||||
border-bottom: 2px solid #676767
|
||||
}
|
||||
.form-label
|
||||
{
|
||||
color: whitesmoke;
|
||||
}
|
||||
.editor-parent
|
||||
{
|
||||
height: 2000px;
|
||||
}
|
||||
.editor-container
|
||||
{
|
||||
resize: vertical;
|
||||
overflow: auto;
|
||||
}
|
||||
.list-group-item:hover
|
||||
{
|
||||
background-color: #474747;
|
||||
color: azure;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.list-group-item
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
color: azure;
|
||||
border-color: #252424;
|
||||
}
|
||||
.margin-left
|
||||
{
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
.content {
|
||||
flex-grow: 1; /* Takes up the remaining space */
|
||||
display: flex;
|
||||
}
|
||||
.col-md-10, .col-md-2 {
|
||||
padding: 0; /* Remove default padding */
|
||||
height: 100%;
|
||||
}
|
||||
.scrollable-element {
|
||||
|
||||
overflow-y: scroll; /* Enable vertical scrollbar */
|
||||
/* Other styles as needed */
|
||||
scrollbar-width: thin;
|
||||
height: 800px;
|
||||
scrollbar-color: #275c9c #000000; /* thumb and track color */
|
||||
}
|
||||
.dropdown-menu
|
||||
{
|
||||
width: 100%;
|
||||
background-color: #414040;
|
||||
color: whitesmoke;
|
||||
}
|
||||
.dropdown-item
|
||||
{
|
||||
-webkit-user-select: none; /* For webkit browsers */
|
||||
-moz-user-select: none; /* For Firefox */
|
||||
-ms-user-select: none; /* For Microsoft browsers */
|
||||
user-select: none; /* Standard syntax */
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.dropdown-item:hover
|
||||
{
|
||||
background-color: #696868;
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.dropdown-item:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 10px; /* Set width of the scrollbar */
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: #1e1e23; /* Track color */
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #123054; /* Thumb color */
|
||||
border-radius: 5px; /* Rounded corners */
|
||||
}
|
||||
@@ -3,252 +3,132 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
|
||||
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"
|
||||
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
|
||||
crossorigin="anonymous"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<title>Bootstrap Styled Javalin App</title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.css">
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/loader.min.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #121212; /* Dark background */
|
||||
}
|
||||
#app {
|
||||
height: 100vh; /* 100% of the viewport height */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.btn-primary
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
border-color: #2c2c2c;
|
||||
}
|
||||
.btn-primary:hover
|
||||
{
|
||||
background-color: #474747;
|
||||
border-color: #474747;
|
||||
}
|
||||
|
||||
#editor {
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.editor-container
|
||||
{
|
||||
|
||||
padding: 10em;
|
||||
}
|
||||
.list-group-item:hover
|
||||
{
|
||||
background-color: #474747;
|
||||
color: azure;
|
||||
cursor: pointer;
|
||||
}
|
||||
.list-group-item
|
||||
{
|
||||
background-color: #2c2c2c;
|
||||
color: azure;
|
||||
border-color: #252424;
|
||||
}
|
||||
.content {
|
||||
flex-grow: 1; /* Takes up the remaining space */
|
||||
display: flex;
|
||||
}
|
||||
.col-md-10, .col-md-2 {
|
||||
padding: 0; /* Remove default padding */
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.css">
|
||||
|
||||
<!-- Load Monaco Editor's main loader script -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/loader.min.js"></script>
|
||||
|
||||
<!-- Configure the loader -->
|
||||
<script>
|
||||
require.config({
|
||||
paths: {'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs'}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Load the editor -->
|
||||
<script>
|
||||
var editor;
|
||||
require(['vs/editor/editor.main'], function() {
|
||||
editor = monaco.editor.create(document.getElementById('editor'), {
|
||||
value: [
|
||||
'function x() {',
|
||||
'\tconsole.log("Hello world!");',
|
||||
'}'
|
||||
].join('\n'),
|
||||
language: 'json',
|
||||
theme: 'vs-dark'
|
||||
});
|
||||
editor.onDidChangeModelContent(function () {
|
||||
console.log("hello")
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/editor/editor.main.css">
|
||||
<link rel="stylesheet" , href="index.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs/loader.min.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
paths: {'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.30.1/min/vs'}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
var editor;
|
||||
var editor2;
|
||||
require(['vs/editor/editor.main'], function () {
|
||||
editor = monaco.editor.create(document.getElementById('editor'), {
|
||||
value: [
|
||||
'Hello world!',
|
||||
].join('\n'),
|
||||
language: 'json',
|
||||
theme: 'vs-dark',
|
||||
automaticLayout: true
|
||||
});
|
||||
|
||||
editor2 = monaco.editor.create(document.getElementById('editor2'), {
|
||||
value: [
|
||||
'Hello world!',
|
||||
].join('\n'),
|
||||
language: 'json',
|
||||
theme: 'vs-dark',
|
||||
automaticLayout: true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-dark">
|
||||
|
||||
<div id="app" class="container-fluid mt-5">
|
||||
<div >
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Name:</label>
|
||||
<input type="text" id="name" name="name" class="form-control">
|
||||
<body class="container-fluid bg-dark">
|
||||
|
||||
|
||||
<div class="row ">
|
||||
<div class="col-2 ">
|
||||
<div class="form margin">
|
||||
<h5 >Data collector</h5>
|
||||
<div class="form-group ">
|
||||
<label for="name" class="form-label">TikTok username</label>
|
||||
<input type="text" id="name" class="form-control">
|
||||
</div>
|
||||
<button type="button" onclick="connect()" class="btn btn-primary">Connect</button>
|
||||
<button type="button" onclick="disconnect()" class="btn btn-primary">Disconnect</button>
|
||||
<button onclick="showEvents()" class="btn btn-primary">Show Events</button>
|
||||
</div>
|
||||
|
||||
<div class="content row mt-5">
|
||||
|
||||
<div class="col-md-2 ">
|
||||
<ul id="eventList" class="list-group" style="max-height: 100%; overflow-y: auto;">
|
||||
<!-- List items will be added dynamically -->
|
||||
<div class="form-group ">
|
||||
<label class="form-label">SessionTag</label>
|
||||
<input type="text" id="sessionTag" class="form-control">
|
||||
</div>
|
||||
<button id="connectionButton" type="button" class="btn btn-primary mt-3 connect-btn">Connect </button>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="dropdown mt-3" id="usersDropDown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="usersDropDownButton"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
User
|
||||
</button>
|
||||
<div id="userDropdownContent" class="dropdown-menu" aria-labelledby="usersDropDownButton">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown mt-3" id="sessionTagDropDown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="sessionTagDropDownButton"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
SessionTag
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="sessionTagDropDownButton">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown mt-3" id="dataTypeDropDown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Data Type
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<ul id="dataList" class="list-group scrollable-element">
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-10 editor-container ">
|
||||
<nav aria-label="Page navigation example">
|
||||
<ul id="pages" class="pagination">
|
||||
<li class="page-item btn-primary"><a class="page-link" href="#">Previous</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div id="editor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
|
||||
<div class="col-10 margin">
|
||||
<nav aria-label="Page navigation example">
|
||||
<ul id="pages" class="pagination">
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="row editor-parent">
|
||||
<div class="col-6 editor-container" id="editor"></div>
|
||||
<div class="col-6 editor-container" id="editor2"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
async function connect() {
|
||||
let name = document.getElementById('name').value;
|
||||
// name = "bangbetmenygy"
|
||||
let response = await fetch(`http://localhost:8001/tiktok/connect?name=${name}`);
|
||||
let greeting = await response.text();
|
||||
console.log("connect",greeting);
|
||||
connected = true;
|
||||
}
|
||||
async function disconnect() {
|
||||
let response = await fetch(`http://localhost:8001/tiktok/disconnect`);
|
||||
let greeting = await response.text();
|
||||
console.log("disconnect",greeting);
|
||||
connected = false;
|
||||
}
|
||||
|
||||
async function loadMessage(event)
|
||||
{
|
||||
let response = await fetch(`http://localhost:8001/tiktok/events/message?eventName=${event}`);
|
||||
let json = await response.text();
|
||||
let root= JSON.parse(json);
|
||||
editor.setValue(root.content);
|
||||
}
|
||||
|
||||
async function loadMessageLink(link)
|
||||
{
|
||||
let response = await fetch(link);
|
||||
let json = await response.text();
|
||||
let root= JSON.parse(json);
|
||||
editor.setValue(root.content);
|
||||
}
|
||||
|
||||
async function loadPagination(event)
|
||||
{
|
||||
let response = await fetch(`http://localhost:8001/tiktok/events/pages?eventName=${event}`);
|
||||
let json = await response.text();
|
||||
let object = JSON.parse(json);
|
||||
let pages = object.links;
|
||||
console.log("PAGES: ",pages)
|
||||
$("#pages").empty();
|
||||
$.each(pages, function(index, element) {
|
||||
let content = $('<button>',{
|
||||
class: 'btn btn-primary',
|
||||
text: index
|
||||
}).click(async function()
|
||||
{
|
||||
await loadMessageLink(element);
|
||||
console.log(editor)
|
||||
});
|
||||
$("#pages").append(content);
|
||||
});
|
||||
}
|
||||
|
||||
async function showEvents() {
|
||||
let response = await fetch(`http://localhost:8001/tiktok/events`);
|
||||
let json = await response.text();
|
||||
console.log("events:",json);
|
||||
let events= JSON.parse(json);
|
||||
|
||||
$("#eventList").empty();
|
||||
$.each(events, function(index, event) {
|
||||
let listItem = $('<li>', {
|
||||
class: 'list-group-item',
|
||||
text: event
|
||||
}).click(async function()
|
||||
{
|
||||
await loadMessage(event);
|
||||
await loadPagination(event);
|
||||
});
|
||||
$("#eventList").append(listItem);
|
||||
});
|
||||
}
|
||||
|
||||
async function loop()
|
||||
{
|
||||
if(!connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
console.log("updating");
|
||||
await showEvents();
|
||||
}
|
||||
|
||||
var connected = false;
|
||||
var paginationIndex = 0;
|
||||
var maxPages = 10;
|
||||
var pages = [];
|
||||
setInterval(loop, 1000)
|
||||
showEvents()
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script src="index.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||
|
||||
210
Tools-EventsWebViewer/src/main/resources/public/index.js
Normal file
210
Tools-EventsWebViewer/src/main/resources/public/index.js
Normal file
@@ -0,0 +1,210 @@
|
||||
var dataType = "messages"
|
||||
var connected = false;
|
||||
var paginationIndex = 0;
|
||||
var maxPages = 10;
|
||||
var pages = [];
|
||||
var userName = "";
|
||||
|
||||
var port = 8002;
|
||||
var baseUrl = `http://localhost:${port}`
|
||||
|
||||
var data =
|
||||
{
|
||||
dataType: "event",
|
||||
dataName: "",
|
||||
user: "",
|
||||
sessionTag: "",
|
||||
page: 0,
|
||||
|
||||
collector:
|
||||
{
|
||||
connected: false,
|
||||
user: "",
|
||||
sessionTag: "",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
dropDown("usersDropDown", () => `${baseUrl}/tiktok/users`, async (e) => {
|
||||
data.user = e;
|
||||
update();
|
||||
|
||||
})
|
||||
|
||||
dropDown("dataTypeDropDown", () => `${baseUrl}/tiktok/data-types`, async (e) => {
|
||||
data.dataType = e;
|
||||
update();
|
||||
})
|
||||
|
||||
dropDown("sessionTagDropDown", () => `${baseUrl}/tiktok/sessions?user=${data.user}`, async (e) => {
|
||||
data.sessionTag = e;
|
||||
update();
|
||||
})
|
||||
|
||||
|
||||
function update() {
|
||||
new Promise(async function (resolve, reject) {
|
||||
await updateAsync();
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
|
||||
async function updateAsync() {
|
||||
console.log(data);
|
||||
await updateConnectionButton()
|
||||
await updateDataNamesList(async (dataName) => {
|
||||
data.dataName = dataName;
|
||||
data.page = 0;
|
||||
await updateContent();
|
||||
await updatePagination(async (page, link) => {
|
||||
data.page = page;
|
||||
let response = await fetch(link);
|
||||
let json = await response.text();
|
||||
console.log(link)
|
||||
let root = JSON.parse(json);
|
||||
editor.setValue(root.content);
|
||||
|
||||
if(data.dataType === 'message')
|
||||
{
|
||||
console.log("sending proto version")
|
||||
let response2 = await fetch(`${link}&asProto=true`);
|
||||
let json2 = await response2.text();
|
||||
let root2 = JSON.parse(json2);
|
||||
editor2.setValue(root2.content);
|
||||
}
|
||||
});
|
||||
});
|
||||
await fetch(`${baseUrl}/tiktok/update?user=${data.user}&session=${data.sessionTag}`);
|
||||
}
|
||||
|
||||
async function updatePagination(onSelect) {
|
||||
let response = await fetch(`${baseUrl}/tiktok/data/pages?name=${data.dataName}&type=${data.dataType}`);
|
||||
let json = await response.text();
|
||||
let object = JSON.parse(json);
|
||||
let pages = object.links;
|
||||
$("#pages").empty();
|
||||
let page = 0;
|
||||
$.each(pages, function (index, element) {
|
||||
|
||||
let currentPage = page;
|
||||
page++;
|
||||
let content = $('<button>', {
|
||||
class: 'btn btn-primary margin-left',
|
||||
text: index
|
||||
}).click(async function () {
|
||||
|
||||
await onSelect(currentPage, element);
|
||||
});
|
||||
$("#pages").append(content);
|
||||
});
|
||||
}
|
||||
|
||||
async function updateContent() {
|
||||
console.log("updating content", data)
|
||||
let response = await fetch(`${baseUrl}/tiktok/data?name=${data.dataName}&type=${data.dataType}&page=${data.page}`);
|
||||
let json = await response.text();
|
||||
let root = JSON.parse(json);
|
||||
editor.setValue(root.content);
|
||||
|
||||
|
||||
if(data.dataType === 'message')
|
||||
{
|
||||
console.log("sending proto version")
|
||||
let response2 = await fetch(`${baseUrl}/tiktok/data?name=${data.dataName}&type=${data.dataType}&page=${data.page}&asProto=true`);
|
||||
let json2 = await response2.text();
|
||||
let root2 = JSON.parse(json2);
|
||||
editor2.setValue(root2.content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function updateDataNamesList(onSelect) {
|
||||
let response = await fetch(`${baseUrl}/tiktok/data/names?type=${data.dataType}`);
|
||||
let json = await response.text();
|
||||
let responce = JSON.parse(json);
|
||||
let element = $("#dataList");
|
||||
console.log(responce)
|
||||
element.empty();
|
||||
$.each(responce, function (index, dataName) {
|
||||
let listItem = $('<li>', {
|
||||
class: 'list-group-item',
|
||||
text: dataName
|
||||
}).click(async function () {
|
||||
onSelect(dataName)
|
||||
});
|
||||
element.append(listItem);
|
||||
});
|
||||
}
|
||||
|
||||
function dropDown(elementId, onUrl, onSelect) {
|
||||
let dropDown = $("#" + elementId);
|
||||
dropDown.on('show.bs.dropdown', async function (e, b) {
|
||||
let response = await fetch(onUrl());
|
||||
let json = await response.text();
|
||||
let values = JSON.parse(json);
|
||||
let optionsElement = dropDown.find("div")
|
||||
optionsElement.empty();
|
||||
let displayElement = dropDown.find("button")
|
||||
for (let value of values) {
|
||||
let dropDownItem = $('<p>', {
|
||||
class: 'dropdown-item',
|
||||
text: value
|
||||
}).click(async function () {
|
||||
displayElement.text(value)
|
||||
onSelect(value)
|
||||
});
|
||||
optionsElement.append(dropDownItem)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
new Promise(async (a, b) => {
|
||||
await updateConnectionButton()
|
||||
});
|
||||
}, 1000)
|
||||
|
||||
|
||||
$("#connectionButton").on('click', async (a) => {
|
||||
|
||||
if (!data.collector.connected) {
|
||||
console.log("connecting")
|
||||
await connect()
|
||||
} else {
|
||||
console.log("disconnecting")
|
||||
await disconnect()
|
||||
}
|
||||
});
|
||||
|
||||
async function updateConnectionButton() {
|
||||
let button = $("#connectionButton");
|
||||
let response = await fetch(`${baseUrl}/tiktok/status`);
|
||||
let json = await response.text();
|
||||
let values = JSON.parse(json);
|
||||
console.log(values)
|
||||
data.collector.connected = values;
|
||||
if (data.collector.connected) {
|
||||
button.text("disconnect");
|
||||
} else {
|
||||
button.text("connect");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
let name = document.getElementById('name').value;
|
||||
let session = document.getElementById('sessionTag').value;
|
||||
data.collector.name = name
|
||||
data.collector.sessionTag =session
|
||||
|
||||
let response = await fetch(`${baseUrl}/tiktok/connect?name=${data.collector.name}&session=${data.collector.sessionTag}`);
|
||||
let greeting = await response.text();
|
||||
}
|
||||
|
||||
async function disconnect() {
|
||||
let response = await fetch(`${baseUrl}/tiktok/disconnect`);
|
||||
let greeting = await response.text();
|
||||
}
|
||||
|
||||
update()
|
||||
Reference in New Issue
Block a user