Implementing artist/album lookup in CLI.

This commit is contained in:
Jonathan Bernard
2016-02-10 09:53:12 -06:00
parent 6e6defe544
commit 90a11569da
6 changed files with 377 additions and 152 deletions

View File

@ -17,7 +17,7 @@ public class MediaLibrary {
private static Logger logger = LoggerFactory.getLogger(MediaLibrary)
private ORM orm
@Delegate ORM orm
private File libraryRoot
public MediaLibrary(ORM orm, File rootDir) {
@ -66,7 +66,7 @@ public class MediaLibrary {
mf.name = fileTag?.getFirst(TITLE)?.trim() ?: f.name
mf.filePath = relPath
mf.comment = fileTag?.getFirst(COMMENT)?.trim()
mf.trackNumber = (fileTag?.getFirst(TRACK) ?: null) as Integer
mf.trackNumber = safeToInteger(fileTag?.getFirst(TRACK))
def folderParts = mf.filePath.split("[\\\\/]")[1..<-1] as LinkedList
@ -91,6 +91,20 @@ public class MediaLibrary {
}
}
public def getByIdOrName(String input, Class modelClass) {
def match
if (safeToInteger(input)) match = [orm.getById(safeToInteger(input), modelClass)]
else {
match = orm.getByName(input, modelClass)
if (!match) match = orm.getLike(["name"], [input], modelClass) }
return match }
public List<Artist> getArtistsByName(String name) {
return orm.getArtistByName(name) ?: orm.getArtistsLikeName(name) }
public List<Album> getAlbumsByName(String name) {
return orm.getAlbumByName(name) ?: orm.getAlbumsLikeName(name) }
private void associateWithArtistAndAlbum(MediaFile mf, String artistName,
String albumName, JATag fileTag) {
Artist artist = null
@ -108,9 +122,13 @@ public class MediaLibrary {
album = orm.getAlbumByName(albumName)
if (!album) {
newAlbumOrArtist = true
album = new Album(name: albumName,
year: (fileTag?.getFirst(YEAR) ?: null) as Integer,
trackTotal: (fileTag?.getFirst(TRACK_TOTAL) ?: null) as Integer)
try {
album = new Album(name: albumName,
year: safeToInteger(fileTag?.getFirst(YEAR)),
trackTotal: safeToInteger(fileTag?.getFirst(TRACK_TOTAL))) }
catch (UnsupportedOperationException use) {
album = new Album(name: albumName,
year: safeToInteger(fileTag?.getFirst(YEAR))) }
orm.create(album) } }
if (artist && album && newAlbumOrArtist)
@ -144,4 +162,8 @@ public class MediaLibrary {
return (['.'] + childPath[b..<childPath.length]).join('/') }
public static Integer safeToInteger(def val) {
if (val == null) return null
try { return val as Integer }
catch (NumberFormatException nfe) { return null } }
}

View File

@ -32,6 +32,12 @@ public class ORM {
public void shutdown() { dataSource.shutdown() }
/// ### Common
public def getAll(Class modelClass) {
def query = "SELECT * FROM " +
pluralize(nameFromModel(modelClass.simpleName))
logger.debug("Selecting models.\n\tSQL: {}", query)
return sql.rows(query).collect { recordToModel(it, modelClass) } }
public def getById(int id, Class modelClass) {
def query = new StringBuilder()
.append("SELECT * FROM ")
@ -50,7 +56,7 @@ public class ORM {
.toString()
logger.debug("Selecting model.\n\tSQL: {}\n\tPARAMS: {}", query, name)
return recordToModel(sql.firstRow(query, [name]), modelClass) }
return sql.rows(query, [name]).collect { recordToModel(it, modelClass) } }
public def getBy(List<String> columns, List<Object> values,
Class modelClass) {
@ -65,6 +71,20 @@ public class ORM {
return sql.rows(query, values)
.collect { recordToModel(it, modelClass) } }
public def getLike(List<String> columns, List<Object> values,
Class modelClass) {
values = values.collect { "%$it%".toString() }
String query = new StringBuilder()
.append("SELECT * FROM ")
.append(pluralize(nameFromModel(modelClass.simpleName)))
.append(" WHERE ")
.append(columns.collect { """"$it" LIKE ?"""}.join(' AND '))
.toString()
logger.debug("Selecting models.\n\tSQL: {}\n\tPARAMS: {}", query, values)
return sql.rows(query, values)
.collect { recordToModel(it, modelClass) } }
public def save(def model) {
if (model.id > 0) return update(model)
else return create(model) }
@ -130,13 +150,13 @@ public class ORM {
public def associate(Class modelClass1, Class modelClass2 , Integer firstId, Integer secondId) {
String linkTable = pluralize(nameFromModel(modelClass1.simpleName)) +
"_" + pluralize(nameFromModel(modelClass2.simpleName))
String col1 = nameFromModel(modelClass1) + "_id"
String col2 = nameFromModel(modelClass2) + "_id"
String col1 = nameFromModel(modelClass1.simpleName) + "_id"
String col2 = nameFromModel(modelClass2.simpleName) + "_id"
withTransaction {
def query = """\
SELECT * FROM $linkTable
WHERE "${col1}"_id = ? AND "${col2}" = ?"""
WHERE "${col1}" = ? AND "${col2}" = ?"""
def params = [firstId, secondId]
// Look first for an existing association before creating one.
@ -154,7 +174,10 @@ public class ORM {
/// ### Album-specific methods
public Album getAlbumById(int id) { return getById(id, Album) }
public Album getAlbumByName(String name) { return getByName(name, Album) }
public List<Album> getAlbumByName(String name) {
return getByName(name, Album) }
public Album getAlbumByNameAndArtistId(String name, int artistId) {
def query = """\
SELECT al.*
@ -170,7 +193,7 @@ public class ORM {
.collect { recordToModel(it, Album) }
return albums ? albums[0] : null }
public Album getAlbumsByArtistId(int artistId) {
public List<Album> getAlbumsByArtistId(int artistId) {
def query = """\
SELECT al.*
FROM albums al JOIN
@ -182,14 +205,21 @@ public class ORM {
return sql.rows(query, [artistId])
.collect { recordToModel(it, Album) } }
public List<Album> getAlbums() { return getAll(Album) }
public List<Album> getAlbumsLikeName(String name) {
return getLike(["name"], [name], Album) }
public List<Album> removeEmptyAlbums() {
throw new UnsupportedOperationException("Not yet implemented.");
}
/// ### Artist-specific methods
public Artist getArtistById(int id) { return getById(id, Artist) }
public Artist getArtistByName(String name) { return getByName(name, Artist) }
public Artist getArtistsByAlbum(int albumId) {
public List<Artist> getArtistByName(String name) {
return getByName(name, Artist) }
public List<Artist> getArtists() { return getAll(Artist) }
public List<Artist> getArtistsByAlbumId(int albumId) {
var query = """\
SELECT ar.*
FROM artists ar JOIN
@ -200,6 +230,9 @@ public class ORM {
return sql.rows(query, [albumId])
.collect { recordToModel(it, Artist) } }
public List<Artist> getArtistsLikeName(String name) {
return getLike(["name"], [name], Artist) }
public List<Artist> removeEmptyArtists() {
throw new UnsupportedOperationException("Not yet implemented.");
}
@ -209,14 +242,25 @@ public class ORM {
/// ### Bookmark-specific methods
public Bookmark getBookmarkById(int id) { return getById(id, Bookmark) }
public Bookmark getBookmarkByName(String name) { return getByName(name, Bookmark) }
public List<Bookmark> getBookmarkByName(String name) {
return getByName(name, Bookmark) }
public List<Bookmark> getBookmarks() { return getAll(Bookmark) }
/// ### Image-specific methods
public Image getImageById(int id) { return getById(id, Image) }
/// ### MediaFile-specific methods
public MediaFile getMediaFileById(int id) { return getById(id, MediaFile) }
public MediaFile getMediaFileByName(String name) { return getByName(name, MediaFile) }
public List<MediaFile> getMediaFileByName(String name) {
return getByName(name, MediaFile) }
public List<MediaFile> getMediaFiles() { return getAll(MediaFile) }
public List<MediaFile> getMediaFilesLikeName(String name) {
return getLike(["name"], [name], MediaFile) }
public MediaFile getMediaFileByFilePath(String filePath) {
def files = getBy(["file_path"], [filePath], MediaFile)
@ -245,7 +289,11 @@ public class ORM {
/// ### Playlist-specific methods
public Playlist getPlaylistById(int id) { return getById(id, Playlist) }
public Playlist getPlaylistByName(String name) { return getByName(name, Playlist) }
public List<Playlist> getPlaylistByName(String name) {
return getByName(name, Playlist) }
public List<Playlist> getPlaylists() { return getAll(Playlist) }
public List<Playlist> removeEmptyPlaylists() {
throw new UnsupportedOperationException("Not yet implemented.");
@ -253,10 +301,13 @@ public class ORM {
/// ### Tag-specific methods
public Tag getTagById(int id) { return getById(id, Tag) }
public Tag getTagByName(String name) { return getByName(name, Tag) }
public Tag getTagByName(String name) { return getByName(name, Tag)[0] }
/// ### Utility functions
public void withTransaction(Closure c) { sql.withTransaction(c) }
public void withTransaction(Closure c) {
try { sql.execute("BEGIN TRANSACTION"); c() }
finally { sql.execute("COMMIT") }
}
public static String nameToModel(String name) {
def pts = name.toLowerCase().split('_')
return pts.length == 1 ? pts[0] :