diff --git a/.classpath b/.classpath deleted file mode 100644 index 93567b78aca19447709856b9d9b6b68a6e9f08e4..0000000000000000000000000000000000000000 --- a/.classpath +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" path="src"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/controlsfx"/> - <classpathentry combineaccessrules="false" kind="src" path="/_Tools"/> - <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/GSON"/> - <classpathentry kind="output" path="class"/> -</classpath> diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6f1710d081b2e9e92260ad1ca91579b9e1c03306 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/settings.json diff --git a/.project b/.project deleted file mode 100644 index 0f44efaf383096d125d705b951f3f1a5aa474d06..0000000000000000000000000000000000000000 --- a/.project +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>SaveMyPlaylist</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.xtext.ui.shared.xtextBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.xtext.ui.shared.xtextNature</nature> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 3a21537071bf4118b9e1ee864cb4bc258aa48211..0000000000000000000000000000000000000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/CHANGELOG.txt b/CHANGELOG.txt deleted file mode 100644 index efb2a3b34877fc3dabff4ceeef98c6e89add528e..0000000000000000000000000000000000000000 --- a/CHANGELOG.txt +++ /dev/null @@ -1,27 +0,0 @@ -[CHANGELOG] -=========== - -SaveMyPlaylist -============== - ->>> start-date: 2015 ->>> status-date: 05.03.17 -____________________________________________________ - -v.1.1.0 - (2) -=============== - --used GSON for JSOn parsing - ->>> end-work: 05.03.17 - -v.1.0.0 - (1) -=============== - --basic implementation - ->>> end-work: 2015 - -____________________________________________________ - -[/CHANGELOG] \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000000000000000000000000000000000000..f0545290632ebad820d4efb2f11460d8f9cd14c1 --- /dev/null +++ b/Pipfile @@ -0,0 +1,13 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[requires] +python_version = "3.7" + +[packages] +google-api-python-client = "==1.7.11" +youtube_dl = "==2019.10.16" + +[dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000000000000000000000000000000000000..e1a7e2a1f38a95e50cc483fc2d561fa0a201dd8a --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,101 @@ +{ + "_meta": { + "hash": { + "sha256": "0b25aa17f2c8f2ecd8768ad8eb85313cdf7682655c8179c7fb62068bf0e4ed9d" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "cachetools": { + "hashes": [ + "sha256:428266a1c0d36dc5aca63a2d7c5942e88c2c898d72139fca0e97fdd2380517ae", + "sha256:8ea2d3ce97850f31e4a08b0e2b5e6c34997d7216a9d2c98e0f3978630d4da69a" + ], + "version": "==3.1.1" + }, + "google-api-python-client": { + "hashes": [ + "sha256:3121d55d106ef1a2756e8074239512055bd99eb44da417b3dd680f9a1385adec", + "sha256:a8a88174f66d92aed7ebbd73744c2c319b4b1ce828e565f9ec721352d2e2fb8c" + ], + "index": "pypi", + "version": "==1.7.11" + }, + "google-auth": { + "hashes": [ + "sha256:0f7c6a64927d34c1a474da92cfc59e552a5d3b940d3266606c6a28b72888b9e4", + "sha256:20705f6803fd2c4d1cc2dcb0df09d4dfcb9a7d51fd59e94a3a28231fd93119ed" + ], + "version": "==1.6.3" + }, + "google-auth-httplib2": { + "hashes": [ + "sha256:098fade613c25b4527b2c08fa42d11f3c2037dda8995d86de0745228e965d445", + "sha256:f1c437842155680cf9918df9bc51c1182fda41feef88c34004bd1978c8157e08" + ], + "version": "==0.0.3" + }, + "httplib2": { + "hashes": [ + "sha256:34537dcdd5e0f2386d29e0e2c6d4a1703a3b982d34c198a5102e6e5d6194b107", + "sha256:409fa5509298f739b34d5a652df762cb0042507dc93f6633e306b11289d6249d" + ], + "version": "==0.14.0" + }, + "pyasn1": { + "hashes": [ + "sha256:62cdade8b5530f0b185e09855dd422bc05c0bbff6b72ff61381c09dac7befd8c", + "sha256:a9495356ca1d66ed197a0f72b41eb1823cf7ea8b5bd07191673e8147aecf8604" + ], + "version": "==0.4.7" + }, + "pyasn1-modules": { + "hashes": [ + "sha256:0c35a52e00b672f832e5846826f1fb7507907f7d52fba6faa9e3c4cbe874fe4b", + "sha256:b6ada4f840fe51abf5a6bd545b45bf537bea62221fa0dde2e8a553ed9f06a4e3" + ], + "version": "==0.2.7" + }, + "rsa": { + "hashes": [ + "sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66", + "sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487" + ], + "version": "==4.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "uritemplate": { + "hashes": [ + "sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd", + "sha256:1b9c467a940ce9fb9f50df819e8ddd14696f89b9a8cc87ac77952ba416e0a8fd", + "sha256:c02643cebe23fc8adb5e6becffe201185bf06c40bda5c0b4028a93f1527d011d" + ], + "version": "==3.0.0" + }, + "youtube-dl": { + "hashes": [ + "sha256:2d93776170dad5ef7b2d2cafdd0bdfb3db625e71d55ab66d725e04d05ce64d75", + "sha256:7c78705c4b43f032df751d7791821bea80a80bc26a024514e194e2b7cdd3a643" + ], + "index": "pypi", + "version": "==2019.10.16" + } + }, + "develop": {} +} diff --git a/SaveMyPlaylist.py b/SaveMyPlaylist.py new file mode 100644 index 0000000000000000000000000000000000000000..d7a6e80b138b99fab63ff30e1b93647f2770e82b --- /dev/null +++ b/SaveMyPlaylist.py @@ -0,0 +1,141 @@ +from __future__ import unicode_literals + +import json +import os +import sys + +import googleapiclient.discovery +import googleapiclient.errors +import youtube_dl + + +VERSION = (2, 0, 0) + + +class MyLogger(object): + def debug(self, msg): + pass + + def warning(self, msg): + pass + + def error(self, msg): + print(msg, file=sys.stderr) + + +def my_hook(d): + if d['status'] == 'finished': + print('Download finished!') + + +class SaveMyPlaylist: + SCOPES = ['https://www.googleapis.com/auth/youtube.readonly'] + API_NAME = 'youtube' + API_VERSION = 'v3' + + CHANNEL = 0 + TITLE = 1 + VIDEO_ID = 2 + + ILLEGAL_CHARS = ['NUL', '\',''//', ':', '*', '"', '<', '>', '|'] + + def __init__(self, apiKey, playlistId): + print('### SaveMyPlaylist v{} ###'.format('.'.join(str(i) for i in VERSION))) + print('=============================\n') + self.__apiKey = apiKey + self.__playlistId = playlistId + self.__youtubeApi = googleapiclient.discovery.build(self.API_NAME, self.API_VERSION, developerKey=self.__apiKey) + self.__items = self.__fetch_all_playlist_items() + + def __fetch_all_playlist_items(self): + items = [] + + nextPageToken = 0 + while nextPageToken is not None: + pageItems, nextPageToken = self.__fetch_playlist_items(nextPageToken) + items.extend(pageItems) + + print('\n>>> Found {} items in playlist\n'.format(len(items))) + return items + + def __fetch_playlist_items(self, nextPageToken=None): + if nextPageToken is None or nextPageToken == 0: + request = self.__youtubeApi.playlistItems().list( + part='snippet', + playlistId=self.__playlistId, + maxResults=50, + ) + else: + request = self.__youtubeApi.playlistItems().list( + part='snippet', + playlistId=self.__playlistId, + maxResults=50, + pageToken=nextPageToken + ) + + response = request.execute() + + items = [] + for item in response['items']: + snippet = item['snippet'] + title = snippet['title'] + channel = snippet['channelTitle'] + videoId = snippet['resourceId']['videoId'] + items.append((channel, title, videoId)) + print('{} - {} (videoId: {})'.format(channel, title, videoId)) + + nextPageToken = None + if 'nextPageToken' in response: + nextPageToken = response['nextPageToken'] + + return items, nextPageToken + + def download_items(self, destinationFolder, debug=False): + print('>>> Scanning destination folder...') + downloadedVideos = [f for f in os.listdir(destinationFolder) if + os.path.isfile(os.path.join(destinationFolder, f)) and f.endswith('.mp4')] + + print('>>> Found {} videos in destination folder'.format(len(downloadedVideos))) + + print('\n>>> Started Downloading...') + newVideos = [] + for idx, item in enumerate(self.__items): + fileName = '{} - {}.mp4'.format(item[self.TITLE], item[self.CHANNEL]) + fileName = self.__escape_file_name(fileName) + if fileName in downloadedVideos: + print('Skipping {}/{}: "{}" as it already exists'.format(idx + 1, len(self.__items), fileName)) + continue + + print('Downloading {}/{}: "{}"'.format(idx + 1, len(self.__items), fileName)) + newVideos.append(item) + + ydl_opts = { + 'format': 'bestaudio/best', + 'merge_output_format': 'mp4', + 'outtmpl': os.path.join(destinationFolder, fileName), + 'logger': MyLogger(), + 'progress_hooks': [my_hook], + } + + if debug: + continue + + with youtube_dl.YoutubeDL(ydl_opts) as ydl: + ydl.download(['https://www.youtube.com/watch?v={}'.format(item[self.VIDEO_ID])]) + + print('\n>>> Finished Downloading') + print('Downloaded {} new videos'.format(len(newVideos))) + + def __escape_file_name(self, fileName): + for char in self.ILLEGAL_CHARS: + fileName = fileName.replace(char, '') + + return fileName + + +if __name__ == '__main__': + with open("settings.json", "r") as f: + SETTINGS = json.load(f) + + saveMyPlaylist = SaveMyPlaylist(SETTINGS['apiKey'], SETTINGS['playlistId']) + saveMyPlaylist.download_items(SETTINGS['destinationFolder'], SETTINGS['skipDownload']) diff --git a/build.fxbuild b/build.fxbuild deleted file mode 100644 index c1106de4a5571cce30464ff73037e42533fa94bf..0000000000000000000000000000000000000000 --- a/build.fxbuild +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="ASCII"?> -<anttasks:AntTask xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:anttasks="http://org.eclipse.fx.ide.jdt/1.0" buildDirectory="${project}/build"> - <deploy> - <application name="SaveMyPlaylist"/> - <info/> - </deploy> - <signjar/> -</anttasks:AntTask> diff --git a/settings-example.json b/settings-example.json new file mode 100644 index 0000000000000000000000000000000000000000..db554f79695e7a4990a9dc8a722d2034ba185725 --- /dev/null +++ b/settings-example.json @@ -0,0 +1,6 @@ +{ + "apiKey": "", + "playlistId": "", + "destinationFolder": "", + "skipDownload": false +} \ No newline at end of file diff --git a/src/application/Channel.java b/src/application/Channel.java deleted file mode 100644 index 801f4e00164793ce556a0c42d0dab2b28bf38ef4..0000000000000000000000000000000000000000 --- a/src/application/Channel.java +++ /dev/null @@ -1,41 +0,0 @@ -package application; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -public class Channel -{ - public static String getChannelNameForID(String ID) - { - String infos = ""; - try - { - URL url = new URL("http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v="+ ID + "&format=json"); - BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); - - String inputLine; - while ((inputLine = in.readLine()) != null) - { - infos = infos + inputLine; - } - in.close(); - - JsonElement jsonElement = new JsonParser().parse(infos); - JsonObject jsonObject = jsonElement.getAsJsonObject(); - String author = jsonObject.get("author_name").getAsString(); - - return author; - } - catch(IOException e) - { - //video is not available - return ""; - } - } -} \ No newline at end of file diff --git a/src/application/Controller.java b/src/application/Controller.java deleted file mode 100644 index ad920ac134398c4740245635c199a1d0fcaa3f02..0000000000000000000000000000000000000000 --- a/src/application/Controller.java +++ /dev/null @@ -1,140 +0,0 @@ -package application; - -import java.io.File; -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ResourceBundle; - -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.ProgressIndicator; -import javafx.scene.control.TextField; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.stage.DirectoryChooser; -import javafx.stage.Stage; -import tools.Worker; - -public class Controller implements Initializable -{ - @FXML private TextField textFieldPath; - @FXML private TextField textFieldID; - @FXML public Button buttonPath; - @FXML public Button buttonSave; - @FXML private ImageView imageView; - @FXML public ProgressIndicator progressIndicator; - - public Stage stage; - private boolean pathSelected; - private String path; - public boolean running; - public static File[] files; - - public void setStage(Stage s) - { - stage = s; - } - - @FXML - public void buttonPath(ActionEvent e) - { - DirectoryChooser chooser = new DirectoryChooser(); - chooser.setTitle("Speicherort ausw�hlen"); - File file = chooser.showDialog(stage); - if(file != null) - { - path = file.getPath() + "\\"; - textFieldPath.setText(path); - pathSelected = true; - - files = file.listFiles(); - } - } - - @FXML - public void buttonSave(ActionEvent e) - { - if(pathSelected) - { - String ID = textFieldID.getText(); - if(ID.equals("")) - { - Alert alert = new Alert(AlertType.WARNING); - alert.setTitle("Achtung"); - alert.setHeaderText(""); - alert.getDialogPane().setPrefSize(350, 120); - alert.setContentText("Bitte eine Playlist-ID eingeben!"); - alert.initOwner(stage); - alert.showAndWait(); - } - else - { - progressIndicator.setVisible(true); - buttonPath.setDisable(true); - buttonSave.setDisable(true); - imageView.requestFocus(); - running = true; - - Playlist playlist = new Playlist(ID); - PlaylistHandler handler = new PlaylistHandler(path, playlist, this); - Worker.runLater(()->{ - handler.run(); - }); - } - } - else - { - Alert alert = new Alert(AlertType.WARNING); - alert.setTitle("Achtung"); - alert.setHeaderText(""); - alert.getDialogPane().setPrefSize(350, 120); - alert.setContentText("Bitte einen Speicherort ausw�hlen!"); - alert.initOwner(stage); - alert.showAndWait(); - } - } - - @Override - public void initialize(URL arg0, ResourceBundle arg1) - { - pathSelected = false; - - Image icon = new Image("/application/list.png"); - imageView.setImage(icon); - progressIndicator.setVisible(false); - running = false; - - try - { - String jarPath = Controller.class.getProtectionDomain().getCodeSource().getLocation().getPath(); - String decodedPath = URLDecoder.decode(jarPath, "UTF-8"); - decodedPath = decodedPath.substring(1, decodedPath.length()); - int start = decodedPath.lastIndexOf("/"); - decodedPath = decodedPath.substring(0, start + 1); - textFieldPath.setText(decodedPath); - path = decodedPath; - pathSelected = true; - refreshFiles(); - } - catch(UnsupportedEncodingException e) - { - e.printStackTrace(); - } - } - - public void refreshFiles() - { - File newFile = new File(path); - files = newFile.listFiles(); - } - - public Stage getStage() - { - return stage; - } -} \ No newline at end of file diff --git a/src/application/Main.java b/src/application/Main.java deleted file mode 100644 index fefe20fdce241706b562d1c06f7485d2a125562e..0000000000000000000000000000000000000000 --- a/src/application/Main.java +++ /dev/null @@ -1,55 +0,0 @@ -package application; - -import javafx.application.Application; -import javafx.application.Platform; -import javafx.event.EventHandler; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.image.Image; -import javafx.stage.Stage; -import javafx.stage.WindowEvent; -import tools.Worker; - -public class Main extends Application -{ - @Override - public void start(Stage stage) - { - try - { - FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("application/SaveMyPlayListGUI.fxml")); - Parent root = (Parent)loader.load(); - - Scene scene = new Scene(root, 600, 290); - stage.setResizable(false); - stage.getIcons().add(new Image("/application/list.png")); - Controller controller = ((Controller)loader.getController()); - controller.setStage(stage); - - Platform.runLater(() -> { - - stage.setOnCloseRequest(new EventHandler<WindowEvent>() - { - public void handle(WindowEvent we) - { - Worker.shutdown(); - } - }); - }); - - stage.setTitle("SaveMyPlaylist - v1.1.0 (2)"); - stage.setScene(scene); - stage.show(); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - - public static void main(String[] args) - { - launch(args); - } -} \ No newline at end of file diff --git a/src/application/Playlist.java b/src/application/Playlist.java deleted file mode 100644 index a535d18df488e3da99b10e8d653b8e18e79c00da..0000000000000000000000000000000000000000 --- a/src/application/Playlist.java +++ /dev/null @@ -1,382 +0,0 @@ -package application; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -public class Playlist -{ - private String playlistID; - private final String API_KEY = "AIzaSyBomwTB7zr2Kn6FhSE05U0opKJX4YJBLas"; - private boolean compared; - private int missing; - private final String PLAYLIST_ITEM_IDENTIFIER = "youtube#playlistItem"; - - public Playlist(String playlistID) - { - this.playlistID = playlistID; - } - - private String getJSON(String pageToken, String playlistID) throws IOException - { - URL url; - if(!pageToken.equals("")) - { - url = new URL("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlistID + "&pageToken=" + pageToken + "&key=" + API_KEY); - } - else - { - url = new URL("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlistID + "&key=" + API_KEY); - } - - BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); - - String infos = ""; - - String inputLine; - while ((inputLine = in.readLine()) != null) - { - infos = infos + inputLine; - } - in.close(); - - return infos; - } - - private JsonObject getCompleteJSON(String playlistID) throws IOException - { - ArrayList<String> allJSON = new ArrayList<String>(); - - String json = getJSON("",playlistID); - allJSON.add(json); - int lastIndex = 0; - - while(allJSON.get(lastIndex).contains("nextPageToken")) - { - JsonElement jsonElement = new JsonParser().parse(allJSON.get(lastIndex)); - JsonObject jsonObject = jsonElement.getAsJsonObject(); - String nextPageToken = jsonObject.get("nextPageToken").getAsString(); - - allJSON.add(getJSON(nextPageToken, playlistID)); - lastIndex++; - } - - JsonArray resultArray = new JsonArray(); - - for(String currentString : allJSON) - { - JsonElement currentElement = new JsonParser().parse(currentString); - resultArray.add(currentElement); - } - - JsonObject resultObject = new JsonObject(); - resultObject.add("pages", resultArray); - - return resultObject; - } - - private ArrayList<PlaylistItem> getPlaylistItems(JsonObject json) - { - ArrayList<PlaylistItem> playlistItems = new ArrayList<>(); - - JsonArray jsonArray = json.getAsJsonArray("pages"); - - for(int i = 0; i < jsonArray.size(); i++) - { - JsonObject currentPage = jsonArray.get(i).getAsJsonObject(); - JsonArray itemsArray = currentPage.getAsJsonArray("items"); - - for(int k = 0; k < itemsArray.size(); k++) - { - JsonObject currentItem = itemsArray.get(k).getAsJsonObject(); - - if(currentItem.get("kind").getAsString().equalsIgnoreCase(PLAYLIST_ITEM_IDENTIFIER)) - { - String channelName = Channel.getChannelNameForID(currentItem.getAsJsonObject("snippet").getAsJsonObject("resourceId").get("videoId").getAsString()); - String title = currentItem.get("snippet").getAsJsonObject().get("title").getAsString(); - playlistItems.add(new PlaylistItem(channelName, title)); - } - } - } - - return playlistItems; - } - - private int getLongestChannelCharacterCount(ArrayList<PlaylistItem> playlistItems) - { - int longest = 0; - for(PlaylistItem currentItem : playlistItems) - { - if(currentItem.getChannel().length() > longest) - { - longest = currentItem.getChannel().length(); - } - } - - return longest; - } - - @SuppressWarnings("static-access") - private void writeToFile(String path, ArrayList<PlaylistItem> playlistItems, String playlistID) throws IOException - { - String date = getDate(); - File datei = null; - - datei = new File (path + playlistID + "-" + date + ".txt"); - datei.createNewFile(); - - int longest = getLongestChannelCharacterCount(playlistItems) + 15; - - BufferedWriter out = null; - - out = new BufferedWriter(new FileWriter(datei, true)); - out.write("Playlist-ID = " + playlistID); - out.newLine(); - out.newLine(); - String headline = ""; - headline = headline.format("%-10s %-" + longest +"s %s", "Nummer", "Kanal", "Video"); - out.write(headline); - out.newLine(); - out.newLine(); - - - for(int i = 0; i < playlistItems.size(); i++) - { - String formatted = ""; - - formatted = formatted.format("%-10s %-" + longest +"s %s", i+1, playlistItems.get(i).getChannel(), playlistItems.get(i).getVideoName()); - - out.write(formatted); - out.newLine(); - } - - ArrayList<String> removedLines = comparePlaylists(readLogFile(checkForPreviousLogs(Controller.files, playlistID)), playlistItems); - - if(removedLines.size() > 0) - { - out.newLine(); - out.write("Fehlende Videos:"); - out.newLine(); - out.newLine(); - for(int j = 0; j < removedLines.size(); j++) - { - String line = removedLines.get(j); - out.write(line); - out.newLine(); - } - } - out.close(); - } - - private String getDate() - { - Calendar cal = Calendar.getInstance(); - SimpleDateFormat ausgabe = new SimpleDateFormat("dd.MM.yyyy_HH-mm-ss"); - return ausgabe.format(cal.getTime()); - } - - private boolean playlistExists(String playlistID) - { - try - { - URL url = new URL("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlistID + "&key=" + API_KEY); - BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); - in.close(); - - return true; - } - catch(IOException e) - { - return false; - } - } - - public void savePlaylist(String path) throws IllegalArgumentException, IOException - { - if(playlistExists(playlistID)) - { - JsonObject json = getCompleteJSON(playlistID); - ArrayList<PlaylistItem> playlistItems = getPlaylistItems(json); - writeToFile(path, playlistItems, playlistID); - } - else - { - throw new IllegalArgumentException(); - } - } - - private File checkForPreviousLogs(File[] files, String playlistID) - { - ArrayList<File> logsPaths = new ArrayList<File>(); - ArrayList<String> logs = new ArrayList<String>(); - for(int i = 0; i < files.length; i++) - { - if(files[i].getName().contains(playlistID)) - { - logsPaths.add(files[i]); - logs.add(files[i].getName()); - } - } - - if(logs.size() == 0) - { - return null; - } - else if(logs.size() == 1) - { - return logsPaths.get(0); - } - else - { - ArrayList<Date> dates = new ArrayList<Date>(); - for(int j = 0; j < logs.size(); j++) - { - String current = logs.get(j); - int start = current.indexOf("-"); - current = current.substring(start + 1, current.length()); - logs.set(j, current); - DateFormat format = new SimpleDateFormat("dd.MM.yyyy_HH-mm-ss"); - - try - { - Date date = format.parse(current); - dates.add(date); - } - catch(ParseException e) - { - return null; - } - } - - - int latest = 1; - Date latestDate = dates.get(0); - - for(int k = 1; k < dates.size(); k++) - { - if(dates.get(k).after(latestDate)) - { - latestDate = dates.get(k); - latest = k; - } - else - { - latest = k; - } - } - return logsPaths.get(latest); - } - } - - private ArrayList<String> readLogFile(File file) - { - if(file != null) - { - try - { - FileInputStream fis = new FileInputStream(file); - BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); - - ArrayList<String> lines = new ArrayList<>(); - String line; - while ((line = reader.readLine()) != null) - { - lines.add(line); - } - - reader.close(); - - int lineNumber = -1; - for(int i = 0; i < lines.size(); i++) - { - if(lines.get(i).contains("Fehlende Videos:")) - { - lineNumber = i; - } - } - - if(lineNumber != -1) - { - for(int j = lines.size()-1; j > lineNumber-2; j--) - { - lines.remove(j); - } - } - - return lines; - } - catch(IOException e) - { - return null; - } - } - return null; - } - - private ArrayList<String> comparePlaylists( ArrayList<String> lines, ArrayList<PlaylistItem> playlistItems) - { - ArrayList<String> removedLines = new ArrayList<String>(); - if(lines != null) - { - boolean[] removed = new boolean[lines.size()]; - removed[0] = false; - removed[1] = false; - removed[2] = false; - removed[3] = false; - - for(int i = 4; i < lines.size(); i++) - { - removed[i] = true; - for(int j = 0; j < playlistItems.size(); j++) - { - if(lines.get(i).contains(playlistItems.get(j).getChannel()) && lines.get(i).contains(playlistItems.get(j).getVideoName())) - { - removed[i] = false; - } - } - } - - missing = 0; - for(int k = 0; k < removed.length; k++) - { - if(removed[k] == true) - { - missing ++; - removedLines.add(lines.get(k)); - } - } - compared = true; - } - else - { - compared = false; - } - return removedLines; - } - - public boolean getCompared() - { - return compared; - } - - public int getMissing() - { - return missing; - } -} \ No newline at end of file diff --git a/src/application/PlaylistHandler.java b/src/application/PlaylistHandler.java deleted file mode 100644 index fdb1f03c537f7f9e2643e388beab5b1ab07c1c4f..0000000000000000000000000000000000000000 --- a/src/application/PlaylistHandler.java +++ /dev/null @@ -1,103 +0,0 @@ -package application; - -import java.io.IOException; - -import javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; - -public class PlaylistHandler -{ - private String path; - private Playlist playlist; - private Controller controller; - - public PlaylistHandler(String path, Playlist playlist, Controller controller) - { - this.path = path; - this.playlist = playlist; - this.controller = controller; - } - - public void run() - { - try - { - - try - { - playlist.savePlaylist(path); - controller.refreshFiles(); - } - catch(IOException e) - { - Platform.runLater(()->{ - Alert alert = new Alert(AlertType.WARNING); - alert.setTitle("Fehler"); - alert.setHeaderText(""); - alert.getDialogPane().setPrefSize(350, 120); - alert.setContentText("Ein Fehler ist aufgetreten!"); - alert.initOwner(controller.getStage()); - alert.showAndWait(); - }); - } - - Platform.runLater(()->{ - controller.progressIndicator.setVisible(false); - controller.buttonPath.setDisable(false); - controller.buttonSave.setDisable(false); - controller.running = false; - }); - - if(playlist.getCompared()) - { - Platform.runLater(()->{ - Alert alert = new Alert(AlertType.INFORMATION); - alert.setTitle("Abgeschlossen"); - alert.setHeaderText(""); - alert.getDialogPane().setPrefSize(350, 145); - alert.setContentText("Playlist erfolgreich gespeichert. \n" - + "\n" - + "Fehlende Videos: " + playlist.getMissing() + "\n" - + "Für weitere Informationen siehe Textdatei."); - alert.initOwner(controller.getStage()); - alert.showAndWait(); - }); - } - else - { - Platform.runLater(()->{ - Alert alert = new Alert(AlertType.INFORMATION); - alert.setTitle("Abgeschlossen"); - alert.setHeaderText(""); - alert.getDialogPane().setPrefSize(350, 120); - alert.setContentText("Playlist erfolgreich gespeichert. \n" - + "\n" - + "Keine Datei zum Vergleich gefunden."); - alert.initOwner(controller.getStage()); - alert.showAndWait(); - }); - } - } - catch(IllegalArgumentException ex) - { - ex.printStackTrace(); - Platform.runLater(()->{ - controller.progressIndicator.setVisible(false); - controller.buttonPath.setDisable(false); - controller.buttonSave.setDisable(false); - controller.running = false; - }); - - Platform.runLater(()->{ - Alert alert = new Alert(AlertType.WARNING); - alert.setTitle("Fehler"); - alert.setHeaderText(""); - alert.getDialogPane().setPrefSize(350, 120); - alert.setContentText("Keine Playlist zur eingegebenen ID gefunden!"); - alert.initOwner(controller.getStage()); - alert.showAndWait(); - }); - } - } -} \ No newline at end of file diff --git a/src/application/PlaylistItem.java b/src/application/PlaylistItem.java deleted file mode 100644 index 67972a420b3f30f76a83c988e934aa1647d4793e..0000000000000000000000000000000000000000 --- a/src/application/PlaylistItem.java +++ /dev/null @@ -1,29 +0,0 @@ -package application; - -public class PlaylistItem -{ - private String channel; - private String videoName; - - public PlaylistItem(String channel, String videoName) - { - this.channel = channel; - this.videoName = videoName; - } - - public String getChannel() - { - return channel; - } - - public String getVideoName() - { - return videoName; - } - - @Override - public String toString() - { - return "PlaylistItem [channel=" + channel + ", videoName=" + videoName + "]"; - } -} diff --git a/src/application/SaveMyPlayListGUI.fxml b/src/application/SaveMyPlayListGUI.fxml deleted file mode 100644 index 9ac66dfaea152f84d979e9f4791fc02593044ca9..0000000000000000000000000000000000000000 --- a/src/application/SaveMyPlayListGUI.fxml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.scene.image.*?> -<?import javafx.scene.text.*?> -<?import javafx.scene.control.*?> -<?import java.lang.*?> -<?import javafx.scene.layout.*?> -<?import javafx.scene.layout.AnchorPane?> - -<AnchorPane prefHeight="290.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller"> - <children> - <Label layoutX="218.0" layoutY="29.0" text="SaveMyPlaylist"> - <font> - <Font name="System Bold" size="25.0" /> - </font> - </Label> - <Button fx:id="buttonPath" layoutX="424.0" layoutY="115.0" mnemonicParsing="false" onAction="#buttonPath" text="Speicherort wählen" /> - <Button fx:id="buttonSave" layoutX="256.0" layoutY="230.0" mnemonicParsing="false" onAction="#buttonSave" text="Speichern"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Button> - <TextField fx:id="textFieldPath" editable="false" layoutX="173.0" layoutY="115.0" prefHeight="25.0" prefWidth="231.0" /> - <TextField fx:id="textFieldID" layoutX="173.0" layoutY="175.0" prefHeight="25.0" prefWidth="231.0" /> - <Label layoutX="69.0" layoutY="175.0" text="Playlist-ID:"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Label layoutX="59.0" layoutY="115.0" text="Speicherort:"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <ImageView fx:id="imageView" fitHeight="45.0" fitWidth="45.0" layoutX="164.0" layoutY="25.0" pickOnBounds="true" preserveRatio="true" /> - <ProgressIndicator fx:id="progressIndicator" layoutX="353.0" layoutY="227.0" prefHeight="36.0" prefWidth="25.0" /> - </children> -</AnchorPane> diff --git a/src/application/application.css b/src/application/application.css deleted file mode 100644 index 83d6f3343843c65d5dfaf3fedb97b6494c19113d..0000000000000000000000000000000000000000 --- a/src/application/application.css +++ /dev/null @@ -1 +0,0 @@ -/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */ \ No newline at end of file diff --git a/src/application/list.png b/src/application/list.png deleted file mode 100644 index a1e3eb721f36a0b5b2603c07a4e589fa817721ba..0000000000000000000000000000000000000000 Binary files a/src/application/list.png and /dev/null differ