Refines the local provider a bit
This commit is contained in:
@@ -108,7 +108,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
*/
|
*/
|
||||||
public static Set<String> getCodecs()
|
public static Set<String> getCodecs()
|
||||||
{
|
{
|
||||||
final Pattern FILEPAT = Pattern.compile("^\\s*D[E.]A[I.][L.][S.]\\s*([a-z1-9_]{2,})\\s*[A-Za-z1-9 \\(\\)-/'\\.\":]+$");
|
final Pattern FILEPAT = Pattern.compile("^\\s*D[E.]A[I.][L.][S.]\\s*([a-z1-9_]{2,})\\s*.+$");
|
||||||
final Pattern FILEPAT2 = Pattern.compile("[a-z1-9_]{2,}");
|
final Pattern FILEPAT2 = Pattern.compile("[a-z1-9_]{2,}");
|
||||||
Matcher matcher;
|
Matcher matcher;
|
||||||
String ffmpegData;
|
String ffmpegData;
|
||||||
@@ -427,16 +427,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (file.isDirectory())
|
if (file.getName().lastIndexOf(".") < file.getName().length() - 1)
|
||||||
{
|
|
||||||
totalUpdate--;
|
|
||||||
List<SongScanner> tasks = Arrays.stream(Objects.requireNonNullElse(file.listFiles(), new File[0]))
|
|
||||||
.map(SongScanner::new).collect(Collectors.toList());
|
|
||||||
totalUpdate += tasks.size();
|
|
||||||
triggerUpdateListeners();
|
|
||||||
invokeAll(tasks);
|
|
||||||
}
|
|
||||||
else if (file.getName().lastIndexOf(".") < file.getName().length() - 1)
|
|
||||||
{
|
{
|
||||||
type = file.getName().substring(file.getName().lastIndexOf('.') + 1).toLowerCase();
|
type = file.getName().substring(file.getName().lastIndexOf('.') + 1).toLowerCase();
|
||||||
if (getFormats().contains(type))
|
if (getFormats().contains(type))
|
||||||
@@ -454,6 +445,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
/*
|
/*
|
||||||
* No modifications needed
|
* No modifications needed
|
||||||
*/
|
*/
|
||||||
|
logger.debug("No update needed for {}", file);
|
||||||
updatedSongs++;
|
updatedSongs++;
|
||||||
triggerUpdateListeners();
|
triggerUpdateListeners();
|
||||||
return;
|
return;
|
||||||
@@ -465,7 +457,6 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentFolder = file.getPath();
|
currentFolder = file.getPath();
|
||||||
triggerUpdateListeners();
|
|
||||||
codec = null;
|
codec = null;
|
||||||
process = Runtime.getRuntime().exec(new String[] {"ffprobe", "-hide_banner", file.getAbsolutePath()});
|
process = Runtime.getRuntime().exec(new String[] {"ffprobe", "-hide_banner", file.getAbsolutePath()});
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
@@ -656,11 +647,11 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
sql.append("type='").append(codec).append("', ");
|
sql.append("type='").append(codec).append("', ");
|
||||||
if (title != null && !title.isEmpty())
|
if (title != null && !title.isEmpty())
|
||||||
{
|
{
|
||||||
sql.append("title='").append(title).append("', ");
|
sql.append("title='").append(title.replaceAll("'", "''")).append("', ");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql.append("title='").append(file.getName()).append("', ");
|
sql.append("title='").append(file.getName().replaceAll("'", "''")).append("', ");
|
||||||
}
|
}
|
||||||
if (artist != null && !artist.isEmpty())
|
if (artist != null && !artist.isEmpty())
|
||||||
{
|
{
|
||||||
@@ -722,7 +713,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
if (title != null && !title.isEmpty())
|
if (title != null && !title.isEmpty())
|
||||||
{
|
{
|
||||||
columns.append("title,");
|
columns.append("title,");
|
||||||
values.append('\'').append(title).append("',");
|
values.append('\'').append(title.replaceAll("'", "''")).append("',");
|
||||||
}
|
}
|
||||||
if (artist != null && !artist.isEmpty())
|
if (artist != null && !artist.isEmpty())
|
||||||
{
|
{
|
||||||
@@ -830,6 +821,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
ResultSet result;
|
ResultSet result;
|
||||||
Album album;
|
Album album;
|
||||||
LocalSong song;
|
LocalSong song;
|
||||||
|
int numAlbums = 0, numSongs = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -839,6 +831,22 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
*/
|
*/
|
||||||
synchronized (db)
|
synchronized (db)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Make sure that a "null" album is available
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (albums.get(null) == null)
|
||||||
|
{
|
||||||
|
album = new Album();
|
||||||
|
album.name = "Unknown";
|
||||||
|
albums.put(null, album);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (albums.get("Unknown") == null)
|
||||||
|
{
|
||||||
|
albums.put("Unknown", albums.get(null));
|
||||||
|
}
|
||||||
|
|
||||||
state = getDb().createStatement();
|
state = getDb().createStatement();
|
||||||
result = state.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='LOCAL_ALBUMS';");
|
result = state.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='LOCAL_ALBUMS';");
|
||||||
if (!result.next())
|
if (!result.next())
|
||||||
@@ -872,6 +880,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
album.genres = Optional.ofNullable(result.getString("genres")).map(s -> s.split(";")).orElse(new String[0]);
|
album.genres = Optional.ofNullable(result.getString("genres")).map(s -> s.split(";")).orElse(new String[0]);
|
||||||
album.totalTracks = result.getInt("tracks");
|
album.totalTracks = result.getInt("tracks");
|
||||||
album.totalDiscs = result.getInt("discs");
|
album.totalDiscs = result.getInt("discs");
|
||||||
|
numAlbums++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = state.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='LOCAL_SONGS';");
|
result = state.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='LOCAL_SONGS';");
|
||||||
@@ -898,6 +907,10 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
result = state.executeQuery("SELECT * FROM LOCAL_SONGS;");
|
result = state.executeQuery("SELECT * FROM LOCAL_SONGS;");
|
||||||
while (result.next())
|
while (result.next())
|
||||||
{
|
{
|
||||||
|
if (result.getString("file") == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
song = songs.get(new File(result.getString("file")));
|
song = songs.get(new File(result.getString("file")));
|
||||||
if (song == null)
|
if (song == null)
|
||||||
{
|
{
|
||||||
@@ -912,7 +925,8 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
song.trackNum = result.getInt("track");
|
song.trackNum = result.getInt("track");
|
||||||
song.disc = result.getInt("disc");
|
song.disc = result.getInt("disc");
|
||||||
song.duration = result.getLong("duration");
|
song.duration = result.getLong("duration");
|
||||||
song.album = Optional.ofNullable(result.getString("album")).map(albums::get).orElse(null);
|
song.album = Optional.ofNullable(result.getString("album")).map(albums::get).orElse(albums.get("Unknown"));
|
||||||
|
numSongs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.close();
|
state.close();
|
||||||
@@ -922,16 +936,41 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
{
|
{
|
||||||
logger.error("Could not query SQL database.", e);
|
logger.error("Could not query SQL database.", e);
|
||||||
}
|
}
|
||||||
logger.debug("Query complete.");
|
logger.debug("Query complete, retrieved {} albums and {} songs", numAlbums, numSongs);
|
||||||
updatedSongs = 0;
|
updatedSongs = 0;
|
||||||
totalUpdate = 0;
|
totalUpdate = 0;
|
||||||
triggerUpdateListeners();
|
triggerUpdateListeners();
|
||||||
|
|
||||||
if (scan)
|
if (scan)
|
||||||
{
|
{
|
||||||
logger.debug("Scanning for changes...");
|
LinkedList<SongScanner> scanners = new LinkedList<>();
|
||||||
totalUpdate = 1;
|
this.invokeFolder(source, scanners);
|
||||||
invokeAll(new SongScanner(source), new ScanCompletion());
|
triggerUpdateListeners();
|
||||||
|
logger.debug("Scanning for changes in {} files...", totalUpdate);
|
||||||
|
invokeAll(scanners.toArray(SongScanner[]::new));
|
||||||
|
invokeAll(new ScanCompletion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for all files and scans them
|
||||||
|
*
|
||||||
|
* @param dir - The file to scan
|
||||||
|
* @param scanners - The list to add the scanners to
|
||||||
|
*/
|
||||||
|
private void invokeFolder(File dir, List<SongScanner> scanners)
|
||||||
|
{
|
||||||
|
if (dir.isDirectory())
|
||||||
|
{
|
||||||
|
for (File file : Objects.requireNonNullElse(dir.listFiles(), new File[0]))
|
||||||
|
{
|
||||||
|
this.invokeFolder(file, scanners);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
totalUpdate++;
|
||||||
|
scanners.add(new SongScanner(dir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -948,6 +987,7 @@ public class LocalSongProvider implements SongProvider<LocalSong>
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.debug("Scan complete. Researching database");
|
||||||
SongScanner.currentFolder = "";
|
SongScanner.currentFolder = "";
|
||||||
updatedSongs = 0;
|
updatedSongs = 0;
|
||||||
totalUpdate = 0;
|
totalUpdate = 0;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public abstract class Song implements Comparable<Song>, Serializable
|
|||||||
{
|
{
|
||||||
if (o != null)
|
if (o != null)
|
||||||
{
|
{
|
||||||
int comp = this.album.compareTo(o.album);
|
int comp = this.album != null ? this.album.compareTo(o.album) : o.album != null ? 1 : 0;
|
||||||
if (comp == 0)
|
if (comp == 0)
|
||||||
{
|
{
|
||||||
comp = Integer.compare(this.disc, o.disc);
|
comp = Integer.compare(this.disc, o.disc);
|
||||||
@@ -36,7 +36,7 @@ public abstract class Song implements Comparable<Song>, Serializable
|
|||||||
comp = Integer.compare(this.trackNum, o.trackNum);
|
comp = Integer.compare(this.trackNum, o.trackNum);
|
||||||
if (comp == 0)
|
if (comp == 0)
|
||||||
{
|
{
|
||||||
comp = this.title.compareTo(o.title);
|
comp = this.title != null ? this.title.compareTo(o.title) : o.title != null ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public class CollectionList extends ScrollablePanel
|
|||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
this.setFocusCycleRoot(true);
|
this.setFocusCycleRoot(true);
|
||||||
// this.setFocusable(true);
|
// this.setFocusable(true);
|
||||||
|
this.setScrollableWidth(ScrollableSizeHint.FIT);
|
||||||
|
this.setScrollableHeight(ScrollableSizeHint.STRETCH);
|
||||||
this.addFocusListener(new FocusAdapter()
|
this.addFocusListener(new FocusAdapter()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -228,12 +228,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
{
|
{
|
||||||
this.songList.listAlbums(songs);
|
this.songList.listAlbums(songs);
|
||||||
this.centerView.setViewportView(this.songList);
|
this.centerView.setViewportView(this.songList);
|
||||||
// this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
this.songList.revalidate();
|
||||||
// .getExtentSize().width, Integer.MAX_VALUE));
|
this.centerView.revalidate();
|
||||||
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
|
||||||
.getExtentSize().width, this.songList
|
|
||||||
.getMinimumSize().height));
|
|
||||||
this.centerView.validate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -241,27 +237,13 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
{
|
{
|
||||||
this.collectionList.listCollection(type, collections);
|
this.collectionList.listCollection(type, collections);
|
||||||
this.centerView.setViewportView(this.collectionList);
|
this.centerView.setViewportView(this.collectionList);
|
||||||
// this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
this.collectionList.revalidate();
|
||||||
// .getExtentSize().width, Integer.MAX_VALUE));
|
this.centerView.revalidate();
|
||||||
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
|
||||||
.getExtentSize().width, this.collectionList
|
|
||||||
.getMinimumSize().height));
|
|
||||||
this.centerView.validate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentResized(ComponentEvent event)
|
public void componentResized(ComponentEvent event)
|
||||||
{
|
{
|
||||||
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
|
||||||
.getExtentSize().width, Integer.MAX_VALUE));
|
|
||||||
this.songList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
|
||||||
.getExtentSize().width, this.songList
|
|
||||||
.getMinimumSize().height));
|
|
||||||
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
|
||||||
.getExtentSize().width, Integer.MAX_VALUE));
|
|
||||||
this.collectionList.setPreferredSize(new Dimension(this.centerView.getViewport()
|
|
||||||
.getExtentSize().width, this.collectionList
|
|
||||||
.getMinimumSize().height));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class SongList extends ScrollablePanel
|
|||||||
this.listAlbums(provider.getSongs());
|
this.listAlbums(provider.getSongs());
|
||||||
|
|
||||||
this.setScrollableWidth(ScrollableSizeHint.FIT);
|
this.setScrollableWidth(ScrollableSizeHint.FIT);
|
||||||
|
this.setScrollableHeight(ScrollableSizeHint.STRETCH);
|
||||||
this.setFocusTraversalPolicy(new SongListPolicy());
|
this.setFocusTraversalPolicy(new SongListPolicy());
|
||||||
this.addFocusListener(new FocusAdapter()
|
this.addFocusListener(new FocusAdapter()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,12 +14,15 @@
|
|||||||
</File>
|
</File>
|
||||||
</Appenders>
|
</Appenders>
|
||||||
<Loggers>
|
<Loggers>
|
||||||
<Root level="info">
|
<Root level="debug">
|
||||||
<AppenderRef ref="File"/>
|
<AppenderRef ref="File"/>
|
||||||
</Root>
|
</Root>
|
||||||
<Logger name="edu.regis.universeplayer.localPlayer.LocalPlayer" level="debug">
|
<Logger name="edu.regis.universeplayer.data.LocalSongProvider" level="debug">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
|
<!-- <Logger name="edu.regis.universeplayer.localPlayer.LocalPlayer" level="debug">-->
|
||||||
|
<!-- <AppenderRef ref="Console"/>-->
|
||||||
|
<!-- </Logger>-->
|
||||||
<!-- <Logger name="edu.regis.universeplayer.player.Interface" level="debug">-->
|
<!-- <Logger name="edu.regis.universeplayer.player.Interface" level="debug">-->
|
||||||
<!-- <AppenderRef ref="Console"/>-->
|
<!-- <AppenderRef ref="Console"/>-->
|
||||||
<!-- </Logger>-->
|
<!-- </Logger>-->
|
||||||
|
|||||||
Reference in New Issue
Block a user