c-eg / showrenamer Goto Github PK
View Code? Open in Web Editor NEWRenames movies and tv shows in the format the user has specified
License: GNU General Public License v3.0
Renames movies and tv shows in the format the user has specified
License: GNU General Public License v3.0
Describe the bug
When trying to rename files, if the renamed show includes any characters not supported by files, the rename will fail.
See here for a list of unsupported characters.
Expected behavior
The unsupported characters will either be removed or replaced by ones that are supported by files.
Desktop (please complete the following information):
OS: Windows 10
Additional context
Might be good to have a function, checking the name of the show and the name of the episode if it's a tv show, to return an acceptable name for the file to be renamed to.
Currently the user must download Amazon Corretto JDK 17 in order to use the application.
To fix this we should create a module-info.java, which allows us to easily package the application into an installer,
The page navigation buttons (currently Rename and Settings) don't look great. We should update the styling for these to make them look better.
Currently not sure how this should look like, open for suggestions.
Currently, the properties are loaded in the static block of TMDBSuggestionProvider.
I think that class should be refactored to remove the static block. Reasoning: https://stackoverflow.com/questions/2070293/why-doesnt-java-allow-to-throw-a-checked-exception-from-static-initialization-b#comment54228450_15289277
A new class should be implemented to load properties.
Currently the properties loading logic is used where needed, e.g. RenameController to load the api key for the movie database api. This functionality to load the property should be moved to a separate class so it can be used anywhere, and is easier to test.
Is your feature request related to a problem? Please describe.
If you do not want to use the GUI, there's no way to use the app.
Describe the solution you'd like
A way to use the app from CLI.
Additional context
A discussion is needed before any work is done.
Is your feature request related to a problem? Please describe.
Readme isn't very helpful setting up the project once forked, or downloading the app to use.
Describe the solution you'd like
Write a clear description of how to setup the project in your own envrionment.
Write a clear description of how to use the app, with a screenshot or two.
Currently a test is failing testMatchYearContainingYearInTitle
.
It fails to capture the correct year if the movie contains a year in the title.
e.g. some.random.movie.2012.2010.1080p.bluray.x264
would match as 2012
of the correct match 2010
Describe the solution you'd like
Add documentation in README.md to show how to run the app using Linux
Describe the solution you'd like
Add documentation in README.md to show how to run the app using Mac
File type filtering functionality should be implemented so that when files are added, it will only add the files that are in the supported types.
A section in the settings page navigation will need to be added to select which files types are supported. There should be the following:
The current code base is badly written and not abstracted enough, it needs to be split down into seperate classes to simplify everything.
This will result in much cleaner code, and allow CLI support to be implemented as well as having an option to implement multiple APIs for show data.
The current code for using the API is very slow. It should be refactored to make it more efficient and reduce the number of unnecessary API calls.
I believe the issue is in the getSuggestedNames() function in RenameController.java, starting line 116.
The user cannot customise the suggestion format, currently it is:
Implement the backend functionality to enable the user to select the rename format.
Is your feature request related to a problem? Please describe.
User can't automatically rename any anime
Describe the solution you'd like
Add support for anime
Create a menu on the rename page, adding the following text, along with an image:
For now, the settings page can remain empty, with the same background styling as the rename page.
UI:
Backend:
Movie: "{title} ({year})"
For tv shows, it should rename the folder to the title of the show, then create sub folders for each season present, e.g. Season 1, Season 2
Currently a name like movie_title.en.srt will show the file name in the list as movie_title.en.
Is your feature request related to a problem? Please describe.
If the user wants a different format for shows other than 'Movie (Year)' or 'Show - SXXEXX - Episode Name' they will still have to manually rename.
Describe the solution you'd like
Add a new page called settings, which would allow you to customise the format you would like a Movie and a Show to output as.
Currently the way the list views are set up to listen to events from the HashMap cause the lists to re-order when getting rename suggestions. This is because hash maps do not have ordering, and the map gets update, causing the listener to trigger, updating the list views.
Is your feature request related to a problem? Please describe.
There is currently no icon for the application.
Describe the solution you'd like
An icon made for the application, preferably multi-coloured.
Idea is to remove the os platform window for the application, and create a custom one with css, mapped to buttons that perform the same functions.
https://stackoverflow.com/questions/11839199/custom-title-bar-in-javafx-2-0
https://stackoverflow.com/questions/9861178/javafx-primarystage-remove-windows-borders
A logger needs to be created to log each step of the process
Describe the bug
If you add more than one source of files to rename, the rename will not work. Causing an IndexOutOfBounds Exception.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Renames all files is seperate folders
Additional context
It does rename the first source folder added but not other source folders added.
Error:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8885)
at javafx.scene.control.Button.fire(Button.java:203)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3890)
at javafx.scene.Scene.processMouseEvent(Scene.java:1885)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2618)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
at com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at com.sun.glass.ui.View.notifyMouse(View.java:942)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1784)
... 46 more
Caused by: java.lang.IndexOutOfBoundsException: start 0, end -1, length 200
at java.base/java.lang.AbstractStringBuilder.checkRange(AbstractStringBuilder.java:1805)
at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:686)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:212)
at uk.co.conoregan.showrenamer.controller.RenameController.renameAll(RenameController.java:174)
... 58 more
Currently there are no tests for the view controllers, e.g. RenameController, SettingsController.
These resources may be helpful:
Is your feature request related to a problem? Please describe.
Having to manually select every folder can be annoying, adding a checkbox to include sub-folders in the initial directory given would solve this.
Describe the solution you'd like
A checkbox next to the directory dialog button, which if checked would include sub-folders when selecting the directory. This could be done with recursion.
Custom Exceptions should be created to handle errors properly.
An example of this is ShowNotFoundException
Is your feature request related to a problem? Please describe.
Can't rename a single show in the list.
Describe the solution you'd like
Select the show you would like to rename, click rename show, renames only the selected show and none of the others.
When the application is making requests to the movie database api, it doesn't update the ui until all results are retrieved, and a suggested is returned for each. This means there could be a fairly long delay for the user with no feedback.
To fix this, we should add an animation so that the user knows the application is working and getting the suggestion results for them.
The loading animation should go over the Suggested Titles list view.
Is your feature request related to a problem? Please describe.
Searching for subtitles for a large amount of shows is extremely tedious.
Describe the solution you'd like
A page to read in a directory of shows (like on the rename page) and list all shows. Each show would have a checkbox to make that would be set to checked by defualt. If a checkbox is ticked it will download the subtitles for that show. And buttons at the bottom to get all subtitles or get a subtitle for a selected show (again like on the rename page). An output directory would need to be specified here too.
Clicking on Get Suggestions results in
$> java -jar show-renamer-1.3.0.jar
Nov 25, 2023 12:09:28 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @6ced7109'
[JavaFX Application Thread] INFO uk.co.conoregan.showrenamer.ShowRenamerApplication - Show Renamer successfully started.
[ForkJoinPool.commonPool-worker-2] INFO uk.co.conoregan.showrenamer.suggestion.FileSuggestionProvider - No result found for title: <my title>
Not sure if I installed the prerequisite JDK properly. Maybe the app could detect it and if it's not there give some kind of notice.
Currently the user can only clear all current titles. It would be good if the user could clear each row separately.
To make sure the license is applied to all code in the repo, according to GNU. Attatch this to the top of each file:
/*
* This file is part of ShowRenamer.
*
* ShowRenamer is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ShowRenamer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ShowRenamer. If not, see <https://www.gnu.org/licenses/>.
*/
Describe the bug
Error when trying to rename files when you add some via source, then remove some.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Should still rename after some files were removed
Additional context
Error stack trace:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8885)
at javafx.scene.control.Button.fire(Button.java:203)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3890)
at javafx.scene.Scene.processMouseEvent(Scene.java:1885)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2618)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
at com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at com.sun.glass.ui.View.notifyMouse(View.java:942)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1784)
... 46 more
Caused by: java.lang.IndexOutOfBoundsException: Index 8 out of bounds for length 8
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:373)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at uk.co.conoregan.showrenamer.controller.RenameController.renameAll(RenameController.java:164)
... 58 more
Currently when the user clicks the Save All button to save all suggestions, there is no feedback to the user to say it was successful - it just clears the lists. We should implement some form of feedback to say the renaming was successful.
If the file is a file, then it should show a 'file' icon.
If the file is a dir, then it should show a 'folder' icon.
Stage 1 - When no files are loaded:
Stage 2 - When at least 1 file is loaded:
Stage 3 - When suggestions have been retrieved:
Is your feature request related to a problem? Please describe.
Different people like diferent colour schemes/themes. Such as light mode and dark mode.
Describe the solution you'd like
Add an option in the settings page to select a theme for the application. Have a seperate css file for each theme. Could add support for custom themes too in the future.
Currently a test is failing testMatchTitleContainingYear
.
It fails to capture the full title of the movie if the title also contains a year.
e.g. some.random.movie.2012.2010.1080p.bluray.x264
would match as some.random.movie
instead of the correct match some.random.movie.2012
Currently when the user drags files over the Source & Options section, there is no indication that this is the correct usage.
We should add a green border around the section to indicate that this is the correct usage.
Is your feature request related to a problem? Please describe.
The default font for JavaFX is basic
Describe the solution you'd like
A new modern font
Is your feature request related to a problem? Please describe.
2 buttons to help the user clear the list view of Shows they do not want to rename. 1. Can remove one show. 2. Clear all shows.
Describe the solution you'd like
Two buttons underneath the lists, one to clear a single show from the left list, one to clear all shows from the left list. The right list should be updated correctly after this is done.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.