Nouvelle version, réécriture de quasiment tout le code.

This commit is contained in:
Mysaa 2021-05-25 22:36:52 +02:00
parent 90cd59ed9a
commit add0165a3d
13 changed files with 473 additions and 206 deletions

View File

@ -2,22 +2,18 @@ apply plugin: 'java'
apply plugin: 'maven'
repositories {
jcenter()
mavenCentral()
maven {
url "http://ftp.bernard.890m.com/mavenRepository/"
credentials {
username 'u890869027.maven'
password 'bernard'
}
}
}
dependencies {
//Pour gradle
compile 'org.slf4j:slf4j-api:1.7.21'
testCompile 'junit:junit:4.12'
compile 'com.bernard:bernardUtil:alpha'
}
compile "com.google.guava:guava:20.0"
compile "org.mortbay.jetty:jetty:6.1.15"
compile "com.mpatric:mp3agic:0.8.3"
compile "com.google.apis:google-api-services-youtube:v3-rev180-1.22.0"
compile "com.google.api-client:google-api-client:1.22.0"
compile "com.google.oauth-client:google-oauth-client-java6:1.11.0-beta"
compile "com.google.oauth-client:google-oauth-client-jetty:1.11.0-beta"
compile "org.jyaml:jyaml:1.3"
}

View File

@ -1,6 +1,6 @@
/*
* This settings file was auto generated by the Gradle buildInit task
* by 'Samy' at '02/02/17 18:25' with Gradle 3.2.1
* by 'Samy' at '27/12/16 19:13' with Gradle 3.2.1
*
* The settings file is used to specify which projects to include in your build.
* In a single project build this file can be empty or even removed.

View File

@ -0,0 +1,87 @@
package com.bernard.zikator;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.List;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.StoredCredential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.DataStore;
import com.google.api.client.util.store.FileDataStoreFactory;
/**
* Shared class used by every sample. Contains methods for authorizing a user
* and caching credentials.
*/
public class Auth {
/**
* Define a global instance of the HTTP transport.
*/
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
/**
* Define a global instance of the JSON factory.
*/
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
/**
* This is the directory that will be used under the user's home directory
* where OAuth tokens will be stored.
*/
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
/**
* Authorizes the installed application to access user's protected data.
*
* @param scopes
* list of scopes needed to run youtube upload.
* @param credentialDatastore
* name of the credential datastore to cache OAuth tokens
* @throws Exception
*/
public static Credential authorize(List<String> scopes, String credentialDatastore) throws Exception {
// Load client secrets.
URL url = Auth.class.getResource("/client_secrets.json");
System.out.println(url);
Reader clientSecretReader = new InputStreamReader(new FileInputStream(url.getFile()), "UTF-8");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
// Checks that the defaults have been replaced (Default = "Enter X
// here").
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
System.exit(1);
}
// This creates the credentials datastore at
// ~/.oauth-credentials/${credentialDatastore}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(
new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, scopes).setCredentialDataStore(datastore).build();
// Build the local server and bind it to port 8080
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build();
// Authorize.
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
}

View File

@ -0,0 +1,95 @@
package com.bernard.zikator;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import org.ho.yaml.Yaml;
public abstract class BaseFrame<Configuration> extends JFrame implements ActionListener {
/**
* Just for eclipse to shut up
*/
private static final long serialVersionUID = -2440841592914910177L;
private final String defaultConfigPath = "config.yml";
private Configuration config = getConfig();
private Class<?> configurationClass;
public BaseFrame(String title,int width,int height,Class<?> configClass) {
configurationClass = configClass;
this.setTitle(title);
this.setSize(width,height);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
super.windowClosing(arg0);
end();
}
});
init();
this.setVisible(true);
}
public abstract void init();
/**
* To be overrided : default output : "config.yml"
* @return the yaml config file path (relative or absolute)
*/
public String getConfigPath(){
return "config.yml";
}
@SuppressWarnings("unchecked")//Les tests sont faits
public Configuration getConfig(){
File configFile = new File(getConfigPath());
if(configFile.exists()){
Configuration out;
try {
out = (Configuration)Yaml.load(configFile);
return out;
} catch (FileNotFoundException e) {//TODO add others errors witch need to be catched
error("Fichier non trouvé", "Le fichier n'a pas été trouvé");
}catch(ClassCastException e){
error("Fichier corrompu","Le fichier de configuration (\""+configFile.getPath()+"\") est corrompu : supprimez ou remplacez le");
}
}else{
try {
return (Configuration) configurationClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
error("Impossible de créer le fichier de configuration","La configuration n'a pas pu être créée : verifiez que le paramêtre configClass représente une classe accessible et instanciable sans arguments.");
} catch (ClassCastException e) {
error("Non correspondance","Le type génerique \"Configuration\" et l'objet configurationClass ne correspondent pas");
}
}
return null;
}
private void error(String title,String description){
JOptionPane.showMessageDialog(null,description,title,JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
public void end(){
try {
Yaml.dump(config, new File(defaultConfigPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public abstract void actionPerformed(ActionEvent e);
}

View File

@ -0,0 +1,18 @@
package com.bernard.zikator;
import java.net.URL;
import com.bernard.zikator.download.VideoDownload;
public class Config {
URL[] fileToDownload;
VideoDownload[] videoToDownload;
public Config() {
fileToDownload = new URL[0];
videoToDownload = new VideoDownload[0];
}
}

View File

@ -1,34 +0,0 @@
package com.bernard.zikator;
public class Download
{
protected String type;
protected String downloadUrl;
protected String storeUrl;
protected long size;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public String getStoreUrl() {
return storeUrl;
}
public void setStoreUrl(String storeUrl) {
this.storeUrl = storeUrl;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
}

View File

@ -0,0 +1,215 @@
package com.bernard.zikator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.media.MediaHttpDownloader;
import com.google.api.client.googleapis.media.MediaHttpDownloaderProgressListener;
import com.google.api.client.http.GenericUrl;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelContentDetails.RelatedPlaylists;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtube.model.PlaylistItem;
import com.google.api.services.youtube.model.PlaylistItemListResponse;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoCategory;
import com.google.api.services.youtube.model.VideoCategoryListResponse;
import com.google.api.services.youtube.model.VideoListResponse;
import com.google.common.collect.Lists;
import com.mpatric.mp3agic.ID3v1;
import com.mpatric.mp3agic.ID3v1Tag;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.NotSupportedException;
import com.mpatric.mp3agic.UnsupportedTagException;
public class DownloadsManager {
public static void main2(String[] args) {
class CustomProgressListener implements MediaHttpDownloaderProgressListener {
public void progressChanged(MediaHttpDownloader downloader) {
switch (downloader.getDownloadState()) {
case MEDIA_IN_PROGRESS:
System.out.println(downloader.getProgress());
break;
case MEDIA_COMPLETE:
System.out.println("Download is complete!");
case NOT_STARTED:
break;
default:
break;
}
}
}
OutputStream out;
try {
out = new FileOutputStream("C:\\Users\\Samy\\Documents\\file.jpg");
MediaHttpDownloader downloader = new MediaHttpDownloader(GoogleNetHttpTransport.newTrustedTransport(),
null);
downloader.setProgressListener(new CustomProgressListener());
downloader.download(
new GenericUrl(
"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails&maxResults=50&playlistId=UUpRmvjdu3ixew5ahydZ67uA&key=AIzaSyCW0-x7AXEdkxHIUM_MJjoB6aMgUodGHoM"),
out);
} catch (IOException | GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static YouTube youtube;
public static final List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube");
public static void authentificate() throws Exception{
// Authorize the request.
Credential credential = Auth.authorize(scopes, "channelbulletin");
// This object is used to make YouTube Data API requests.
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)
.setApplicationName("zikator").build();
}
public static Channel getChannel(String name) throws IOException{
YouTube.Channels.List channelRequest = youtube.channels().list("contentDetails");
channelRequest.setForUsername("BobGmbH3000");
ChannelListResponse channelResult = channelRequest.execute();
List<Channel> channelsList = channelResult.getItems();
System.out.println("Responce : "+channelsList.toString());
if (channelsList != null && channelsList.size()>0)
return channelsList.get(0);
else
return null;
}
public static List<String> getUploadedVideosIds(Channel channel) throws IOException{
String uploadPlaylistID = ((RelatedPlaylists) channel.getContentDetails().get("relatedPlaylists")).getUploads();
String nextPageToken = null;
List<String> uploadedVideosIDs = new ArrayList<>();
while(true){
YouTube.PlaylistItems.List playlistItemRequest = youtube.playlistItems().list("contentDetails");
playlistItemRequest.setPlaylistId(uploadPlaylistID);
playlistItemRequest.setMaxResults(50L);
playlistItemRequest.setPageToken(nextPageToken);
PlaylistItemListResponse playlistItemsResponce = playlistItemRequest.execute();
for (PlaylistItem item : playlistItemsResponce.getItems())
uploadedVideosIDs.add(item.getContentDetails().getVideoId());
nextPageToken = playlistItemsResponce.getNextPageToken();
if(nextPageToken == null)
break;
}
return uploadedVideosIDs;
}
public static Video getVideoByID(String ID) throws IOException{
YouTube.Videos.List request = youtube.videos().list("contentDetails,snippet");
request.setId(ID);
VideoListResponse reponce = request.execute();
if(reponce.getItems().isEmpty())
return null;
return reponce.getItems().get(0);
}
public static Map<String,VideoCategory> getCategories() throws IOException{
//TODO getCategory(ID) if not in hashmap, put
YouTube.VideoCategories.List request = youtube.videoCategories().list("snippet");
request.setRegionCode("FR");
VideoCategoryListResponse responce = request.execute();
Map<String,VideoCategory> out = new HashMap<>();
for(VideoCategory category : responce.getItems()){
out.put(category.getId(), category);
}
return out;
}
public static void main(String[] args) {
String ytbername = "BobGmbH3000";
int i=1;
try{
authentificate();
//final Map<String,VideoCategory> categories = getCategories();
Channel ytber = getChannel(ytbername);
List<String> toDownload = getUploadedVideosIds(ytber);
File out = new File("out.m4a");
System.out.println(out.getAbsolutePath());
for(String id:toDownload){
downloadVideo(id, "out.m4a", "m4a");
File current = new File(id+".m4a");
if(!current.exists())
continue;
Video video = getVideoByID(id);
Mp3File fichier = new Mp3File(current);
ID3v1 id3v1Tag;
if (fichier.hasId3v1Tag()) {
id3v1Tag = fichier.getId3v1Tag();
} else {
// mp3 does not have an ID3v1 tag, let's create one..
id3v1Tag = new ID3v1Tag();
fichier.setId3v1Tag(id3v1Tag);
}
id3v1Tag.setTrack(Integer.toString(i));
id3v1Tag.setArtist(ytbername);
id3v1Tag.setTitle(video.getSnippet().getTitle());
id3v1Tag.setYear(Integer.toString((int)Math.floor(video.getSnippet().getPublishedAt().getValue()/1000/60/60/24/365.24)));
id3v1Tag.setComment(video.getSnippet().getDescription());
try {
fichier.save(video.getSnippet().getTitle()+" - "+ytbername+".mp3");
} catch (NotSupportedException e) {
System.err.println("Fichier non sauvegardé");
e.printStackTrace();
}
i++;
}
}catch(IOException error){
error.printStackTrace();
} catch (UnsupportedTagException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public static void downloadVideo(String ID,String outputPath,String format) throws IOException{
System.out.println("Downloading "+ID);
//TODO ... à votre avis ...
//ProcessBuilder processing = new ProcessBuilder("C:\\Users\\Samy\\workspace\\MavZik\\youtube-dl.exe");//,"-o \""+outputPath+"\"","-f "+format+" -id ",ID);
String command = "C:\\Users\\Samy\\workspace\\MavZik\\youtube-dl.exe"/* -o "+outputPath*/+" -f "+format+" --id "+ID;
System.out.println(command);
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", command);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}

View File

@ -0,0 +1,38 @@
package com.bernard.zikator;
import java.awt.Frame;
import javax.swing.JDialog;
public class ErrorDialog extends JDialog{
/**
* JFESU
*/
private static final long serialVersionUID = 5223556105926415144L;
private Exception exception;
public ErrorDialog(Exception e,Frame f) {
super(f,"A "+e.getClass().getName()+" occured",true);
exception = e;
this.setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
this.setSize(500, 200);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setVisible(false);
this.initComponent();
}
private void initComponent() {
// TODO Auto-generated method stub
}
public ErrorDialog(Exception e) {
this(e,null);
}
}

View File

@ -1,23 +0,0 @@
package com.bernard.zikator;
import java.awt.Color;
public class ZiKonfig
{
public Download[] downloads;
public Color progressColor;
public Color progressBackground;
public Color progressTextColor;
public String fileProgressFormat;
public String filesProgressFormat;
public ZiKonfig()
{
downloads = new Download[0];
progressColor = Color.GREEN;
progressBackground = Color.DARK_GRAY;
progressTextColor = Color.BLACK;
fileProgressFormat = "%l octets sur %l";
filesProgressFormat = "Fichier %i sur %i";
}
}

View File

@ -1,19 +0,0 @@
package com.bernard.zikator;
import com.bernard.zikator.view.MainFrame;
public class Zikator {
public static final MainFrame theFrame;
static{
theFrame = new MainFrame();
}
public static final ZiKonfig theKonfig;
static{
theKonfig = new ZiKonfig();
}
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,9 @@
package com.bernard.zikator.download;
import com.google.api.services.youtube.model.Video;
public class VideoDownload {
public Video video;
public String format;
}

View File

@ -1,64 +0,0 @@
package com.bernard.zikator.view;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JPanel;
import com.bernard.util.ConfiguredFrame;
import com.bernard.zikator.ZiKonfig;
public class MainFrame extends ConfiguredFrame<ZiKonfig>
{
JButton addDownloadButton,viewDownloadsButton,switchDownloadButton;
/** JFESH */
private static final long serialVersionUID = 849892775235695501L;
public MainFrame()
{
super("Zikator", 400, 600, ZiKonfig.class);
}
@Override
public void init()
{
JPanel buttonsPanel = new JPanel();
GridLayout buttonLayout = new GridLayout(3,1);
buttonLayout.setVgap(10);
buttonsPanel.setLayout(buttonLayout);
addDownloadButton = new JButton("Add a download");
viewDownloadsButton = new JButton("View downloads");
switchDownloadButton = new JButton("No downloads");
buttonsPanel.add(addDownloadButton);
buttonsPanel.add(viewDownloadsButton);
buttonsPanel.add(switchDownloadButton);
JPanel progressPanel = new JPanel();
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(progressPanel, BorderLayout.SOUTH);
this.getContentPane().add(buttonsPanel,BorderLayout.CENTER);
}
//TODO supress this function (for offline tests)
public ZiKonfig getConfig(){
return new ZiKonfig();
}
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
}
public static void main(String[] args) {
new MainFrame();
}
}

View File

@ -1,51 +0,0 @@
package com.bernard.zikator.view;
import java.awt.Graphics;
import java.util.List;
import javax.swing.JPanel;
import com.bernard.zikator.Download;
/**
*
* Affche deux barres de progression
*
* Cycle de vie :
* setDownloads();
* prepareDownload(); return the next download in the list
* startDownload(); the download starts. before that,the progress bar will print "Preparing"
* setCurrentFileProgress();looping
* downloadFinished();//prints Done
*
* @author Mysaa
*
*/
public class ZikaProgressPanel extends JPanel {
private static final long serialVersionUID = 3133794283368644062L;
List<Download> download;
int currentDownload;
long currentFileProgress;
public void setCurrentFileProgress(long currentProgress){
currentFileProgress = currentProgress;
}
public void setCurrentFileProgress(float currentProgress){
currentFileProgress = (long)(currentProgress*download.get(currentDownload).getSize());
}
@Override
protected void paintComponent(Graphics arg0) {
int filesProgressWidth = (int) (Math.floorDiv(currentDownload*this.getWidth(),download.size()));
int fileProgressWidth = (int) (Math.floorDiv(currentFileProgress*this.getWidth(),download.get(currentDownload).getSize()));
}
}