diff --git a/src/main/java/org/bot/MyBot.java b/src/main/java/org/bot/MyBot.java
index db49543..8f9c089 100644
--- a/src/main/java/org/bot/MyBot.java
+++ b/src/main/java/org/bot/MyBot.java
@@ -4,6 +4,7 @@
import org.bot.commands.*;
import org.bot.commands.base.AuthorizedCommandDecorator;
import org.bot.commands.base.CommandHandler;
+import org.bot.commands.base.CommandProcessor;
import org.bot.operations.KucoinOperations;
import org.bot.operations.OperationsDispatcher;
import org.bot.utils.EnvVars;
@@ -35,7 +36,7 @@ private MyBot() {
commandHandler.register(new AuthorizedCommandDecorator(new BalanceCommand()));
commandHandler.register(new AuthorizedCommandDecorator(new TradeCommand()));
- // CommandProcessor.getInstance().registerPortfolioCommands();
+ CommandProcessor.getInstance().registerPortfolioCommands();
OperationsDispatcher.getInstance().register(new KucoinOperations());
}
diff --git a/src/main/java/org/bot/commands/PortfolioCommand.java b/src/main/java/org/bot/commands/PortfolioCommand.java
index fbb2308..77fe4ba 100644
--- a/src/main/java/org/bot/commands/PortfolioCommand.java
+++ b/src/main/java/org/bot/commands/PortfolioCommand.java
@@ -5,7 +5,8 @@
import org.bot.commands.base.Command;
import org.bot.models.Portfolio;
import org.bot.models.PortfolioLink;
-import org.bot.utils.CoingeckoFacade;
+import org.bot.providers.CoinMarketCapProvider;
+import org.bot.providers.DataProvider;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
@@ -40,8 +41,8 @@ public String getDescription() {
private String buildPortfolioResponse() {
try {
- CoingeckoFacade coingeckoFacade = CoingeckoFacade.getInstance();
- Portfolio portfolio = coingeckoFacade.getCoingeckoPortfolio(getPortfolioLink().getLink());
+ DataProvider provider = CoinMarketCapProvider.getInstance();
+ Portfolio portfolio = provider.getPortfolio(getPortfolioLink().getLink());
portfolio.sort();
return portfolio.toString();
} catch (Exception e) {
diff --git a/src/main/java/org/bot/commands/TrendingCommand.java b/src/main/java/org/bot/commands/TrendingCommand.java
index edaccb6..74b931e 100644
--- a/src/main/java/org/bot/commands/TrendingCommand.java
+++ b/src/main/java/org/bot/commands/TrendingCommand.java
@@ -1,11 +1,16 @@
package org.bot.commands;
+import lombok.extern.slf4j.Slf4j;
import org.bot.commands.base.Command;
import org.bot.models.Trending;
-import org.bot.utils.CoingeckoFacade;
+import org.bot.providers.CoingeckoProvider;
+import org.bot.providers.DataProvider;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
+import java.util.Arrays;
+
+@Slf4j
public class TrendingCommand implements Command {
public TrendingCommand() {
@@ -26,12 +31,17 @@ public String getName() {
@Override
public String getDescription() {
- return "show trending coins on Coingecko";
+ return "show trending coins";
}
private String buildTrendingResponse() {
- CoingeckoFacade coingeckoFacade = CoingeckoFacade.getInstance();
- Trending trending = coingeckoFacade.getTrendingCoins();
- return trending.toString();
+ try {
+ DataProvider provider = CoingeckoProvider.getInstance();
+ Trending trending = provider.getTrendingCoins();
+ return trending.toString();
+ } catch (Exception e) {
+ log.error(Arrays.toString(e.getStackTrace()));
+ return e.getMessage();
+ }
}
}
diff --git a/src/main/java/org/bot/models/factory/CoinFactory.java b/src/main/java/org/bot/models/factory/CoinFactory.java
deleted file mode 100644
index a6e10a7..0000000
--- a/src/main/java/org/bot/models/factory/CoinFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.bot.models.factory;
-
-import lombok.extern.slf4j.Slf4j;
-import org.bot.models.Coin;
-
-@Slf4j
-public class CoinFactory {
-
- private CoinFactory() {
-
- }
-
- public static Coin fromRawCoin(String raw) {
- Coin coin = new Coin();
- try {
- coin.setCoinName(raw.split(" \\(")[0]);
- coin.setTicker(raw.split("\\(")[1].split("\\)")[0]);
- coin.setLink("https://www.coingecko.com" + raw.split("\"width: 115px;\" href=\"")[1].split("\"")[0]);
- coin.setPrice(Double.parseDouble(raw.split("
")[2].split("<")[0]);
- } catch (Exception e) {
- log.warn("some info for token ignored: " + e.getMessage());
- }
- return coin;
- }
-}
diff --git a/src/main/java/org/bot/providers/CoinMarketCapProvider.java b/src/main/java/org/bot/providers/CoinMarketCapProvider.java
new file mode 100644
index 0000000..5d771d3
--- /dev/null
+++ b/src/main/java/org/bot/providers/CoinMarketCapProvider.java
@@ -0,0 +1,97 @@
+package org.bot.providers;
+
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.http.client.HttpResponseException;
+import org.bot.models.Coin;
+import org.bot.models.Portfolio;
+import org.bot.models.Trending;
+import org.bot.utils.exceptions.CoingeckoException;
+import org.bot.utils.exceptions.NotImplementedException;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Slf4j
+public class CoinMarketCapProvider implements DataProvider {
+ private static CoinMarketCapProvider instance;
+
+ private CoinMarketCapProvider() {
+ // Private constructor to prevent instantiation
+ }
+
+ public static CoinMarketCapProvider getInstance() {
+ if (instance == null) {
+ instance = new CoinMarketCapProvider();
+ }
+ return instance;
+ }
+
+ @Override
+ public Portfolio getPortfolio(String url) {
+ Map coins = new LinkedHashMap<>();
+ Response response = null;
+ OkHttpClient client = new OkHttpClient();
+ try {
+ Request request = this.buildGetRequest(url);
+ response = client.newCall(request).execute();
+ if (!response.isSuccessful())
+ throw new HttpResponseException(response.code(), response.toString());
+ assert response.body() != null;
+ String responseBody = response.body().string();
+ String[] coinsRaw = responseBody.split("class=\"sc-4984dd93-0 kKpPOn\">");
+ for (int i = 1; i < coinsRaw.length; i = i + 1) {
+ Coin coin = this.fromRawCoin(coinsRaw[i]);
+ if (coin.getTicker() != null) coins.put(coin.getTicker().toUpperCase(), coin);
+ }
+ } catch (Exception e) {
+ log.error(Arrays.toString(e.getStackTrace()));
+ log.error(e.toString());
+ throw new CoingeckoException();
+ } finally {
+ if (response != null) {
+ response.close();
+ }
+ }
+ return new Portfolio(coins);
+ }
+
+ @Override
+ public Trending getTrendingCoins() {
+ throw new NotImplementedException();
+ }
+
+ @Override
+ public Coin fromRawCoin(String raw) {
+ Coin coin = new Coin();
+ try {
+ coin.setCoinName(raw.split("<")[0]);
+ } catch (Exception e) {
+ log.warn("name for token ignored: " + e);
+ }
+ try {
+ coin.setTicker(raw.split("click=\"true\">")[1].split("<")[0]);
+ } catch (Exception e) {
+ log.warn("ticker for token ignored: " + e);
+ }
+ try {
+ coin.setLink("https://coinmarketcap.com" + raw.split("\\$")[1].split("<")[0].replace(",", "")));
+ } catch (Exception e) {
+ log.warn("price for token ignored: " + e);
+ }
+ try {
+ coin.setChange24(raw.split("display:inline-block\">")[2].split("<")[0]);
+ } catch (Exception e) {
+ log.warn("change24 for token ignored: " + e);
+ }
+ return coin;
+ }
+}
diff --git a/src/main/java/org/bot/utils/CoingeckoFacade.java b/src/main/java/org/bot/providers/CoingeckoProvider.java
similarity index 61%
rename from src/main/java/org/bot/utils/CoingeckoFacade.java
rename to src/main/java/org/bot/providers/CoingeckoProvider.java
index f727fe9..9436c50 100644
--- a/src/main/java/org/bot/utils/CoingeckoFacade.java
+++ b/src/main/java/org/bot/providers/CoingeckoProvider.java
@@ -1,4 +1,4 @@
-package org.bot.utils;
+package org.bot.providers;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
@@ -9,33 +9,32 @@
import org.bot.models.Coin;
import org.bot.models.Portfolio;
import org.bot.models.Trending;
-import org.bot.models.factory.CoinFactory;
import org.bot.utils.exceptions.CoingeckoException;
import java.util.*;
@Slf4j
-public class CoingeckoFacade {
+public class CoingeckoProvider implements DataProvider {
- private static CoingeckoFacade instance;
+ private static CoingeckoProvider instance;
- private CoingeckoFacade() {
+ private CoingeckoProvider() {
// Private constructor to prevent instantiation
}
- public static CoingeckoFacade getInstance() {
+ public static CoingeckoProvider getInstance() {
if (instance == null) {
- instance = new CoingeckoFacade();
+ instance = new CoingeckoProvider();
}
return instance;
}
- public Portfolio getCoingeckoPortfolio(String url) {
+ public Portfolio getPortfolio(String url) {
Map coins = new LinkedHashMap<>();
Response response = null;
OkHttpClient client = new OkHttpClient();
try {
- Request request = Helpers.buildRequestCoingecko(url);
+ Request request = this.buildGetRequest(url);
response = client.newCall(request).execute();
if (!response.isSuccessful())
throw new HttpResponseException(response.code(), response.toString());
@@ -43,7 +42,7 @@ public Portfolio getCoingeckoPortfolio(String url) {
String responseBody = response.body().string();
String[] coinsRaw = responseBody.split("")[2].split("<")[0]);
+ } catch (Exception e) {
+ log.warn("some info for token ignored: " + e.getMessage());
+ }
+ return coin;
+ }
}
diff --git a/src/main/java/org/bot/providers/DataProvider.java b/src/main/java/org/bot/providers/DataProvider.java
new file mode 100644
index 0000000..2e991d6
--- /dev/null
+++ b/src/main/java/org/bot/providers/DataProvider.java
@@ -0,0 +1,21 @@
+package org.bot.providers;
+
+import okhttp3.Request;
+import org.bot.models.Coin;
+import org.bot.models.Portfolio;
+import org.bot.models.Trending;
+
+public interface DataProvider {
+ Portfolio getPortfolio(String url);
+
+ Trending getTrendingCoins();
+
+ default Request buildGetRequest(String url) {
+ return new Request.Builder()
+ .url(url)
+ .get()
+ .build();
+ }
+
+ Coin fromRawCoin(String raw);
+}
diff --git a/src/main/java/org/bot/tasks/NotifyPercentageChangeTask.java b/src/main/java/org/bot/tasks/NotifyPercentageChangeTask.java
index 987093f..b7e1572 100644
--- a/src/main/java/org/bot/tasks/NotifyPercentageChangeTask.java
+++ b/src/main/java/org/bot/tasks/NotifyPercentageChangeTask.java
@@ -11,7 +11,7 @@
import org.bot.repositories.CoinNotifyRepository;
import org.bot.repositories.PortfolioLinkRepository;
import org.bot.tasks.base.Task;
-import org.bot.utils.CoingeckoFacade;
+import org.bot.providers.CoingeckoProvider;
import org.bot.utils.formatters.ToBoldDecorator;
import java.util.List;
@@ -31,9 +31,9 @@ public void run() {
if (coinsToCheck.isEmpty())
return;
List portfolios = CacheFlyWeight.getInstance(PortfolioLink.class, PortfolioLinkRepository.getInstance()).findAll();
- Portfolio portfolio = null;
+ Portfolio portfolio;
try {
- portfolio = CoingeckoFacade.getInstance().getCoingeckoPortfolio(portfolios.get(0).getLink());
+ portfolio = CoingeckoProvider.getInstance().getPortfolio(portfolios.get(0).getLink());
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -56,7 +56,7 @@ public void run() {
}
i++;
}
- }catch (Exception e) {
+ } catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/main/java/org/bot/utils/Helpers.java b/src/main/java/org/bot/utils/Helpers.java
index 956075c..87aed8d 100644
--- a/src/main/java/org/bot/utils/Helpers.java
+++ b/src/main/java/org/bot/utils/Helpers.java
@@ -1,7 +1,5 @@
package org.bot.utils;
-import okhttp3.Request;
-
import java.util.Map;
public class Helpers {
@@ -11,15 +9,4 @@ private Helpers() {
public static void addToMapOrSum(Map map, String key, Double value) {
map.compute(key, (k, v) -> (v == null) ? value : v + value);
}
-
- public static Request buildRequestCoingecko(String url) {
- return new Request.Builder()
- .url(url)
- .header("Upgrade-Insecure-Requests", "1")
- .header("Sec-Fetch-Dest", "document")
- .header("Sec-Fetch-Mode", "navigate")
- .header("Sec-Fetch-Site", "cross-site")
- .get()
- .build();
- }
}
diff --git a/src/main/java/org/bot/visitor/ValidatingCommandVisitor.java b/src/main/java/org/bot/visitor/ValidatingCommandVisitor.java
index 20e5856..9325598 100644
--- a/src/main/java/org/bot/visitor/ValidatingCommandVisitor.java
+++ b/src/main/java/org/bot/visitor/ValidatingCommandVisitor.java
@@ -20,8 +20,8 @@ public void visitSavePortofolioLinkCommand() {
if (parts.length != 3)
throw new InvalidCommandException();
String link = parts[2];
- if (!link.contains("coingecko.com") || !link.contains("portfolios/public/"))
- throw new InvalidCommandException("Coingecko link not valid");
+ if (!link.contains("coinmarketcap.com/watchlist"))
+ throw new InvalidCommandException("Portfolio link not valid");
}
@Override
|