Added better logging and browser support.

We still need to work on the Linux browser a bit.
This commit is contained in:
Markil3
2021-07-26 20:27:43 -07:00
parent 77c0b4fa67
commit 66ce116da4
14 changed files with 601 additions and 146 deletions

View File

@@ -39,10 +39,10 @@ targetCompatibility = JavaVersion.VERSION_16
mainClassName = defaultPackage + '.player.Interface'
//mainClassName = defaultPackage + '.localPlayer.Player'
compileJava.dependsOn rootProject.bundleAddOn
run {
systemProperty "java.library.path", file("${project(":player").buildDir}/lib/main/debug").absolutePath
}
compileJava.dependsOn ':player:linkDebug'
compileJava.dependsOn rootProject.bundleAddOn
compileJava.dependsOn ':player:linkDebug'
compileJava.dependsOn ':addonInter:installAddon'

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.data;
import java.io.File;
/**
* This song represents a song found on the local file system.
*/
public abstract class LocalSong extends Song
{
public File file;
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.data;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
public class LocalSongProvider implements SongProvider
{
private File source;
private HashMap<File, Song> songs = new HashMap<>();
private class SongScanner implements Runnable
{
@Override
public void run()
{
}
private void scanFolder(File folder)
{
String type;
LinkedList<File> subFolders = new LinkedList<>();
for (File file: folder.listFiles())
{
if (file.isDirectory())
{
this.scanFolder(file);
}
if (file.getName().lastIndexOf(".") < file.getName().length() - 1)
{
type = file.getName().substring(file.getName().lastIndexOf('.') + 1).toLowerCase();
switch (type)
{
case "mp3":
}
}
}
}
}
public LocalSongProvider(File source)
{
this.source = source;
if (this.source == null || !this.source.isDirectory())
{
throw new IllegalArgumentException("File source must be existing directory");
}
}
/**
* Obtains all albums within the collection.
*
* @return A list of albums.
*/
@Override
public Collection<Album> getAlbums()
{
return null;
}
/**
* Obtains all songs within the collection.
*
* @return A list of songs.
*/
@Override
public Collection<Song> getSongs()
{
return null;
}
/**
* Obtains a list of all artists.
*
* @return All artists.
*/
@Override
public Collection<String> getArtists()
{
return null;
}
/**
* Obtains a list of all album artists.
*
* @return All album artists.
*/
@Override
public Collection<String> getAlbumArtists()
{
return null;
}
/**
* Obtains a list of all genres.
*
* @return All genres.
*/
@Override
public Collection<String> getGenres()
{
return null;
}
/**
* Obtains a list of all years that have albums.
*
* @return All years.
*/
@Override
public Collection<Integer> getYears()
{
return null;
}
/**
* Obtains all songs from an album.
*
* @param album - The album to obtain
* @return All songs from the requested album, or null if that album is not in the database.
*/
@Override
public Collection<Song> getSongsFromAlbum(Album album)
{
return null;
}
/**
* Obtains all songs written by a given artist.
*
* @param artist - The artist to search for
* @return A list of all songs from the specified artist, or null if that artist is not in the
* database.
*/
@Override
public Collection<Song> getSongsFromArtist(String artist)
{
return null;
}
/**
* Obtains an album by a specific name.
*
* @param name - The name to search for.
* @return - The first album that matches the given name, or null if that album name is not in
* the database.
*/
@Override
public Album getAlbumByName(String name)
{
return null;
}
/**
* Obtains all albums that were written by a certain artist.
*
* @param artist - The artist to search for.
* @return - The collection on matching albums.
*/
@Override
public Collection<Album> getAlbumsFromArtist(String artist)
{
return null;
}
/**
* Obtains all albums that match a certain genre
*
* @param genre - The genre to search for.
* @return - The collection on matching albums.
*/
@Override
public Collection<Album> getAlbumsFromGenre(String genre)
{
return null;
}
/**
* Obtains all albums that were released a certain year.
*
* @param year - The year to search for.
* @return - The collection on matching albums.
*/
@Override
public Collection<Album> getAlbumsFromYear(int year)
{
return null;
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.data;
import com.mpatric.mp3agic.ID3v1;
import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import java.io.File;
import java.io.IOException;
/**
* This will specifically import an MP3 file.
*
* @author William Hubbard
* @version 0.1
*/
public class MP3Song extends LocalSong
{
public MP3Song(File file)
{
Mp3File metadata;
ID3v1 tag1;
ID3v2 tag2;
this.file = file;
try
{
metadata = new Mp3File(file);
this.album = new Album();
if (metadata.hasId3v1Tag())
{
tag1 = metadata.getId3v1Tag();
this.title = tag1.getTitle();
this.artists = tag1.getArtist().split(";");
/**
* Trim the artists as needed.
*/
for (int i = 0, l = this.artists.length; i < l; i++)
{
this.artists[i] = this.artists[i].trim();
}
this.trackNum = Integer.parseInt(tag1.getTrack().split("/")[0]);
this.album.name = tag1.getAlbum();
this.album.genres = tag1.getGenreDescription().split(";");
for (int i = 0, l = this.album.genres.length; i < l; i++)
{
this.album.genres[i] = this.album.genres[i].trim();
}
this.album.year = Integer.parseInt(tag1.getYear());
}
/**
* Make sure that the v2 tag doesn't contain any contradictory information.
*/
if (metadata.hasId3v2Tag())
{
tag2 = metadata.getId3v2Tag();
if (!tag2.getTitle().isEmpty())
{
this.title = tag2.getTitle();
}
if (!tag2.getTitle().isEmpty())
{
this.artists = tag2.getArtist().split(";");
/**
* Trim the artists as needed.
*/
for (int i = 0, l = this.artists.length; i < l; i++)
{
this.artists[i] = this.artists[i].trim();
}
}
if (!tag2.getTitle().isEmpty())
{
this.trackNum = Integer.parseInt(tag2.getTrack().split("/")[0]);
}
if (!tag2.getAlbum().isEmpty())
{
this.album.name = tag2.getAlbum();
}
if (!tag2.getAlbumArtist().isEmpty())
{
this.album.artists = tag2.getAlbumArtist().split(";");
/**
* Trim the artists as needed.
*/
for (int i = 0, l = this.album.artists.length; i < l; i++)
{
this.album.artists[i] = this.album.artists[i].trim();
}
}
if (!tag2.getGenreDescription().isEmpty())
{
this.album.genres = tag2.getGenreDescription().split(";");
for (int i = 0, l = this.album.genres.length; i < l; i++)
{
this.album.genres[i] = this.album.genres[i].trim();
}
}
if (!tag2.getYear().isEmpty())
{
this.album.year = Integer.parseInt(tag2.getYear());
}
}
}
catch (IOException e)
{
throw new IllegalArgumentException("Invalid MP3 File", e);
}
catch (UnsupportedTagException | InvalidDataException e)
{
}
}
}

View File

@@ -21,6 +21,8 @@ import edu.regis.universeplayer.browser.Browser;
import edu.regis.universeplayer.browser.MessageManager;
import edu.regis.universeplayer.data.CollectionType;
import edu.regis.universeplayer.data.Song;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Interface class serves as the primary GUI that the player interacts with.
@@ -30,6 +32,8 @@ import edu.regis.universeplayer.data.Song;
*/
public class Interface extends JFrame implements SongDisplayListener, ComponentListener, WindowListener, PlaybackCommandListener
{
private static Logger logger = LoggerFactory.getLogger(Interface.class);
/**
* A reference to the panel containing links to different collection views.
*/
@@ -46,23 +50,23 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
* A reference to the central view scroll pane.
*/
private JScrollPane centerView;
/**
* A link to the browser.
*/
private MessageManager browser;
public static void main(String[] args)
{
try
{
Browser.launchBrowser();
}
catch (IOException e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(null, e, "Could not open browser background", JOptionPane.ERROR_MESSAGE);
}
/*
* Add this just in case of a crash or something. It won't work if the
* program is forcible terminated by the OS, but it could be helpful
* otherwise.
*/
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Browser.closeBrowser();
}));
logger.info("Starting application");
Interface inter = new Interface();
try
{
@@ -70,13 +74,26 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
}
catch (IOException e)
{
e.printStackTrace();
logger.error("Could not open browser communication", e);
JOptionPane.showMessageDialog(null, e, "Could not open browser communication", JOptionPane.ERROR_MESSAGE);
}
inter.pack();
inter.setVisible(true);
/*
* Launch the browser in the background.
*/
try
{
Browser.launchBrowser();
}
catch (IOException e)
{
logger.error("Could not open browser background", e);
JOptionPane.showMessageDialog(inter, e, "Could not open browser background", JOptionPane.ERROR_MESSAGE);
}
}
/**
* Creates an interface
*/
@@ -84,93 +101,93 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
{
super();
PlayerControls controls;
this.setTitle("Universal Music Player");
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane()
.add(this.collectionTypes = new Collections(), BorderLayout.LINE_START);
.add(this.collectionTypes = new Collections(), BorderLayout.LINE_START);
this.collectionTypes.addSongDisplayListener(this);
controls = new PlayerControls();
controls.addCommandListener(this);
this.getContentPane().add(controls, BorderLayout.PAGE_END);
this.songList = new SongList();
this.collectionList = new CollectionList();
this.collectionList.addSongDisplayListener(this);
this.centerView = new JScrollPane(this.songList);
this.getContentPane().add(this.centerView, BorderLayout.CENTER);
this.componentResized(null);
this.addComponentListener(this);
this.addWindowListener(this);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void updateSongs(Collection<Song> songs)
{
this.songList.listAlbums(songs);
this.centerView.setViewportView(this.songList);
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, Integer.MAX_VALUE));
.getExtentSize().width, Integer.MAX_VALUE));
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, this.songList
.getExtentSize().width, this.songList
.getMinimumSize().height));
}
@Override
public void updateCollections(CollectionType type, Collection<?> collections)
{
this.collectionList.listCollection(type, collections);
this.centerView.setViewportView(this.collectionList);
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, Integer.MAX_VALUE));
.getExtentSize().width, Integer.MAX_VALUE));
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, this.collectionList
.getExtentSize().width, this.collectionList
.getMinimumSize().height));
}
@Override
public void componentResized(ComponentEvent event)
{
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, Integer.MAX_VALUE));
.getExtentSize().width, Integer.MAX_VALUE));
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, this.songList
.getExtentSize().width, this.songList
.getMinimumSize().height));
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, Integer.MAX_VALUE));
.getExtentSize().width, Integer.MAX_VALUE));
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
.getExtentSize().width, this.collectionList
.getExtentSize().width, this.collectionList
.getMinimumSize().height));
}
@Override
public void componentMoved(ComponentEvent event)
{
}
@Override
public void componentShown(ComponentEvent event)
{
}
@Override
public void componentHidden(ComponentEvent event)
{
}
@Override
public void windowOpened(WindowEvent windowEvent)
{
logger.info("Interface opened");
}
@Override
public void windowClosing(WindowEvent windowEvent)
{
@@ -183,40 +200,40 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
}
catch (IOException e)
{
e.printStackTrace();
logger.error("Could not close browser", e);
}
}
}
@Override
public void windowClosed(WindowEvent windowEvent)
{
}
@Override
public void windowIconified(WindowEvent windowEvent)
{
}
@Override
public void windowDeiconified(WindowEvent windowEvent)
{
}
@Override
public void windowActivated(WindowEvent windowEvent)
{
}
@Override
public void windowDeactivated(WindowEvent windowEvent)
{
}
/**
* Called when a playback command is issued.
*
@@ -238,7 +255,7 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
}
catch (IOException e)
{
e.printStackTrace();
logger.error("Could not send message to browser", e);
JOptionPane.showMessageDialog(this, e, "Could not send message to browser", JOptionPane.ERROR_MESSAGE);
}
}