package com.mcmoddev.bot.util;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// Based on code by Jared
public class CurseData {
// TODO clean this all up it's gross lol
// TODO add a time stamp to regenerate
// TODO implemnt caching
public static final String PROFILE_URL = "https://minecraft.curseforge.com/members/";
public static final String PROJECTS_PAGE_URL = "https://minecraft.curseforge.com/members/%s/projects?page=";
public static final String PROJECT_URL = "https://minecraft.curseforge.com/";
private String username;
private String avatar;
private String profile;
private List<String> projectURLs;
private Map<String, Long> downloads;
private long totalDownloads;
private boolean foundUser = true;
private boolean foundProject = false;
public CurseData (String username) {
this.username = username;
this.profile = PROFILE_URL + username;
this.projectURLs = new ArrayList<>();
this.downloads = new HashMap<>();
final String baseURL = String.format(PROJECTS_PAGE_URL, username);
int page = 1;
boolean foundDuplicatePage = false;
boolean foundAvatar = false;
while (!foundDuplicatePage) {
try (InputStream stream = new URL(baseURL + page).openStream()) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
for (String line = reader.readLine(); line != null; line = reader.readLine())
// Find avatar
if (!foundAvatar && line.contains("<div class=\"avatar avatar-100 user user-role-curse-premium\">")) {
reader.readLine();
final String imageLine = reader.readLine();
if (imageLine.contains("<img src=")) {
this.avatar = imageLine.split("\"")[1];
foundAvatar = true;
}
}
// Find projects
else if (line.contains("a href=\"/projects/")) {
final String projectURL = "https://minecraft.curseforge.com" + line.split("\"")[1].split("\"")[0];
if (!this.projectURLs.contains(projectURL)) {
this.projectURLs.add(projectURL);
this.foundProject = true;
}
else {
foundDuplicatePage = true;
break;
}
}
if (page == 1 && !this.foundProject)
return;
}
catch (final Exception e) {
if (e instanceof java.io.IOException && e.getMessage().contains("HTTP response code: 400") || e instanceof MalformedURLException || e instanceof FileNotFoundException && (e.getMessage().contains("https://minecraft.curseforge.com/not-found?404") || e.getMessage().contains("https://minecraft.curseforge.com/members/"))) {
this.foundUser = false;
break;
}
else
e.printStackTrace();
}
page++;
}
if (!this.foundUser || !this.foundProject)
return;
// downloads
for (final String projectUrl : this.projectURLs)
try (InputStream stream = new URL(projectUrl).openStream()) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
boolean foundDownloads = false;
for (String line = reader.readLine(); line != null; line = reader.readLine())
if (foundDownloads) {
final long projectDownloads = Long.parseLong(line.split(">")[1].split("<")[0].replaceAll(",", ""));
this.totalDownloads += projectDownloads;
final String name = projectUrl.replace("https://minecraft.curseforge.com/projects/", "").replaceAll("-", " ");
this.downloads.put("[" + name + "](" + projectUrl.replaceAll(" ", "-") + ")", projectDownloads);
break;
}
else if (line.contains("Total Downloads"))
foundDownloads = true;
}
catch (final Exception e) {
e.printStackTrace();
}
this.downloads = Utilities.sortByValue(this.downloads, true);
}
public boolean exists () {
return this.foundUser;
}
public String getUsername () {
return this.username;
}
public String getAvatar () {
return this.avatar;
}
public boolean hasAvatar () {
return this.avatar != null && !this.avatar.isEmpty();
}
public String getProfile () {
return this.profile;
}
public List<String> getProjectURLs () {
return this.projectURLs;
}
public Map<String, Long> getDownloads () {
return this.downloads;
}
public boolean hasProjects () {
return this.foundProject && !this.projectURLs.isEmpty() && !this.downloads.isEmpty();
}
public int getProjectCount () {
return this.projectURLs.size();
}
public long getTotalDownloads () {
return this.totalDownloads;
}
}