Youtube Search rework

This commit is contained in:
Sebastien 2019-09-16 12:19:35 +02:00
parent a00c054453
commit d2c8729a87
7 changed files with 139 additions and 12 deletions

View File

@ -71,6 +71,8 @@ dependencies {
compile 'com.google.api-client:google-api-client:1.23.0' compile 'com.google.api-client:google-api-client:1.23.0'
compile 'com.google.apis:google-api-services-youtube:v3-rev192-1.23.0' compile 'com.google.apis:google-api-services-youtube:v3-rev192-1.23.0'
compile group: 'org.jsoup', name: 'jsoup', version: '1.12.1'
testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('com.jayway.jsonpath:json-path') testCompile('com.jayway.jsonpath:json-path')

View File

@ -6,6 +6,7 @@ import net.Broken.MainBot;
import net.Broken.Tools.EmbedMessageUtils; import net.Broken.Tools.EmbedMessageUtils;
import net.Broken.Tools.MessageTimeOut; import net.Broken.Tools.MessageTimeOut;
import net.Broken.audio.Youtube.SearchResult; import net.Broken.audio.Youtube.SearchResult;
import net.Broken.audio.Youtube.YoutubeSearchRework;
import net.Broken.audio.Youtube.YoutubeTools; import net.Broken.audio.Youtube.YoutubeTools;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
@ -16,6 +17,7 @@ import org.apache.logging.log4j.Logger;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class YtSearch implements Commande { public class YtSearch implements Commande {
@ -23,22 +25,24 @@ public class YtSearch implements Commande {
@Override @Override
public void action(String[] args, MessageReceivedEvent event) { public void action(String[] args, MessageReceivedEvent event) {
YoutubeTools youtubeT = YoutubeTools.getInstance();
YoutubeSearchRework youtubeSearch = YoutubeSearchRework.getInstance();
if (args.length < 1) { if (args.length < 1) {
logger.info("YtSearch: Missing args, user: " + event.getAuthor().getName()); logger.info("YtSearch: Missing args, user: " + event.getAuthor().getName());
Message message = event.getChannel().sendMessage(EmbedMessageUtils.buildStandar(EmbedMessageUtils.getError("Missing search query!"))).complete(); Message message = event.getChannel().sendMessage(EmbedMessageUtils.buildStandar(EmbedMessageUtils.getError("Missing search query!"))).complete();
new MessageTimeOut(MainBot.messageTimeOut, message, event.getMessage()).start(); new MessageTimeOut(MainBot.messageTimeOut, message, event.getMessage()).start();
} else { } else {
try { try {
ArrayList<SearchResult> result = youtubeT.search(args[0], 5, false);
StringBuilder builder = new StringBuilder();
for (String arg : args) {
builder.append(arg);
}
List<SearchResult> result = youtubeSearch.searchVideo(builder.toString(), 5, false);
for (SearchResult item : result) { for (SearchResult item : result) {
event.getChannel().sendMessage(EmbedMessageUtils.searchResult(item)).queue(); event.getChannel().sendMessage(EmbedMessageUtils.searchResult(item)).queue();
} }
} catch (GoogleJsonResponseException e) {
logger.error("There was a service error: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage());
event.getChannel().sendMessage(EmbedMessageUtils.getInternalError()).queue();
} catch (IOException t) { } catch (IOException t) {
logger.catching(t); logger.catching(t);
event.getChannel().sendMessage(EmbedMessageUtils.getInternalError()).queue(); event.getChannel().sendMessage(EmbedMessageUtils.getInternalError()).queue();

View File

@ -13,6 +13,7 @@ import net.Broken.Tools.UserManager.UserUtils;
import net.Broken.audio.AudioM; import net.Broken.audio.AudioM;
import net.Broken.audio.GetVoiceChanels; import net.Broken.audio.GetVoiceChanels;
import net.Broken.audio.Youtube.SearchResult; import net.Broken.audio.Youtube.SearchResult;
import net.Broken.audio.Youtube.YoutubeSearchRework;
import net.Broken.audio.Youtube.YoutubeTools; import net.Broken.audio.Youtube.YoutubeTools;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.VoiceChannel; import net.dv8tion.jda.api.entities.VoiceChannel;
@ -206,8 +207,10 @@ public class MusicWebAPIController {
if(token != null && !token.isEmpty()) { if(token != null && !token.isEmpty()) {
try { try {
UserEntity user = userUtils.getUserWithApiToken(userRepository, token); UserEntity user = userUtils.getUserWithApiToken(userRepository, token);
YoutubeTools youtubeTools = YoutubeTools.getInstance(); // YoutubeTools youtubeTools = YoutubeTools.getInstance();
ArrayList<SearchResult> result = youtubeTools.search(query, 25, playlist); // ArrayList<SearchResult> result = youtubeTools.search(query, 25, playlist);
YoutubeSearchRework youtubeSearch = YoutubeSearchRework.getInstance();
List<SearchResult> result = youtubeSearch.searchVideo(query, 25, playlist);
return new ResponseEntity<>(result, HttpStatus.OK); return new ResponseEntity<>(result, HttpStatus.OK);
}catch (UnknownTokenException e){ }catch (UnknownTokenException e){

View File

@ -113,7 +113,7 @@ public class EmbedMessageUtils {
.setColor(Color.CYAN) .setColor(Color.CYAN)
.setTitle(result.title) .setTitle(result.title)
.setImage(result.imageUrl) .setImage(result.imageUrl)
.addField("Duration: ", YoutubeTools.getInstance().ytTimeToString(result.duration), false) .addField("Duration: ", result.duration, false)
.addField("URL:","https://www.youtube.com/watch?v="+result.id,false) .addField("URL:","https://www.youtube.com/watch?v="+result.id,false)
.addField("Chanel:", result.channelTittle, false); .addField("Chanel:", result.channelTittle, false);
return buildStandar(builder); return buildStandar(builder);

View File

@ -23,4 +23,15 @@ public class SearchResult {
imageUrl = result.getSnippet().getThumbnails().getDefault().getUrl(); imageUrl = result.getSnippet().getThumbnails().getDefault().getUrl();
this.duration = duration; this.duration = duration;
} }
public SearchResult(String id, String title, String description, String publishedAt, String channelId, String channelTittle, String imageUrl, String duration) {
this.id = id;
this.title = title;
this.description = description;
this.publishedAt = publishedAt;
this.channelId = channelId;
this.channelTittle = channelTittle;
this.imageUrl = imageUrl;
this.duration = duration;
}
} }

View File

@ -0,0 +1,107 @@
package net.Broken.audio.Youtube;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class YoutubeSearchRework {
private Logger logger = LogManager.getLogger();
private static YoutubeSearchRework INSTANCE;
public static YoutubeSearchRework getInstance() {
if (INSTANCE == null) {
INSTANCE = new YoutubeSearchRework();
}
return INSTANCE;
}
public List<SearchResult> searchVideo(String search, int maxResult, boolean playlist) throws IOException {
search = URLEncoder.encode(search, StandardCharsets.UTF_8.toString());
String url = "https://www.youtube.com/results?search_query=" + search + "&sp="+ (playlist ? "EgIQAw%3D%3D" :"EgIQAQ%3D%3D");
Document doc = getYoutubeSearchDocument(url);
return extractVideoInfo(doc, maxResult, playlist);
}
private Document getYoutubeSearchDocument(String URL) throws IOException {
return Jsoup.connect(URL).userAgent("Googlebot/2.1 (+http://www.googlebot.com/bot.html)").header("Accept-Language", "en-US").get();
}
// video = EgIQAQ==
private List<SearchResult> extractVideoInfo(Document doc, int maxResult, boolean playlist) {
Elements videosDivs = doc.select(".yt-lockup");
List<SearchResult> results = new ArrayList<>();
int i = 0;
for (Element videoDiv : videosDivs) {
if(i >= maxResult)
break;
Element titleDiv = videoDiv.selectFirst(".yt-uix-tile-link");
String id;
if(!playlist)
id = titleDiv.attributes().get("href").replace("/watch?v=", "");
else{
String listUrl = titleDiv.attributes().get("href");
int listIndex = listUrl.indexOf("list=");
id = listUrl.substring(listIndex).replace("list=", "");
}
String title = titleDiv.text();
Elements metas = videoDiv.selectFirst(".yt-lockup-meta-info").getElementsByTag("li");
String view = "";
String date = "";
if(!playlist){
for (Element metaElem : metas) {
if (metaElem.text().contains("view")) {
view = metaElem.text();
} else {
date = metaElem.text();
}
}
}
Element chanelTag = videoDiv.selectFirst(".yt-lockup-byline").getElementsByTag("a").get(0);
String channelTittle = chanelTag.text();
String channelId = chanelTag.attributes().get("href").replace("/channel/", "");
String imageUrl;
String duration;
if(!playlist){
duration = videoDiv.selectFirst(".video-time").text();
imageUrl = "https://i.ytimg.com/vi/" + id + "/hqdefault.jpg";
}
else{
String listUrl = titleDiv.attributes().get("href");
int listIndex = listUrl.indexOf("&list=");
listUrl = listUrl.substring(0, listIndex).replace("/watch?v=", "");
imageUrl = "https://i.ytimg.com/vi/" + listUrl + "/hqdefault.jpg";
duration = videoDiv.selectFirst(".formatted-video-count-label").text();
}
results.add(new SearchResult(id, title, "", date, channelId, channelTittle, imageUrl, duration));
i++;
}
return results;
}
}

View File

@ -446,7 +446,7 @@ function search() {
"<li class=\"collection-item avatar\">" + "<li class=\"collection-item avatar\">" +
" <img src=\"" + item["imageUrl"] + "\" alt=\"\" class=\"\">" + " <img src=\"" + item["imageUrl"] + "\" alt=\"\" class=\"\">" +
" <a class=\"title truncate\" href='" + url + item["id"] + "' target=\"_blank\"><b>" + item["title"] + "</b></a>" + " <a class=\"title truncate\" href='" + url + item["id"] + "' target=\"_blank\"><b>" + item["title"] + "</b></a>" +
" <p class='truncate grey-text text-darken-1'>" + item["channelTittle"] + " &#9553 " + item["publishedAt"].substr(0, item["publishedAt"].indexOf('T')) + " <br>" + ytTimeToTime(item["duration"]) + " <p class='truncate grey-text text-darken-1'>" + item["channelTittle"] + " &#9553 " + item["publishedAt"] + " <br>" + item["duration"] +
" </p>" + " </p>" +
" <a href=\"#!\" class=\"secondary-content btn waves-effect waves-light green add-btn-list scale-transition\" id='" + item["id"] + "'><i class=\"material-icons \">add_circle_outline</i></a>" + " <a href=\"#!\" class=\"secondary-content btn waves-effect waves-light green add-btn-list scale-transition\" id='" + item["id"] + "'><i class=\"material-icons \">add_circle_outline</i></a>" +
" </div>" + " </div>" +