Refines the local provider a bit

This commit is contained in:
Markil3
2021-08-15 15:27:44 -06:00
parent e5ab98345f
commit 76594b279c
6 changed files with 76 additions and 48 deletions

View File

@@ -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;

View File

@@ -21,13 +21,13 @@ public abstract class Song implements Comparable<Song>, Serializable
* A reference to the album this song is part of. * A reference to the album this song is part of.
*/ */
public Album album; public Album album;
@Override @Override
public int compareTo(Song o) public int compareTo(Song o)
{ {
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;
} }
} }
} }

View File

@@ -48,11 +48,13 @@ public class CollectionList extends ScrollablePanel
public CollectionList() public CollectionList()
{ {
super(); super();
FlowLayout layout = new FlowLayout(); FlowLayout layout = new FlowLayout();
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

View File

@@ -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

View File

@@ -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()
{ {

View File

@@ -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>-->