all: fix formatting

This commit is contained in:
Alexander Capehart 2024-12-16 20:47:17 -05:00
parent 7fab7f7eeb
commit 880967f8be
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
17 changed files with 356 additions and 335 deletions

View file

@ -41,7 +41,7 @@ spotless {
cpp { cpp {
target "*/src/**/cpp/*.cpp" target "*/src/**/cpp/*.cpp"
clangFormat("18.1.8"). eclipseCdt()
licenseHeaderFile("NOTICE") licenseHeaderFile("NOTICE")
} }
} }

View file

@ -22,29 +22,30 @@
// TODO: Handle stream exceptions // TODO: Handle stream exceptions
JVMInputStream::JVMInputStream(JNIEnv *env, jobject inputStream) JVMInputStream::JVMInputStream(JNIEnv *env, jobject inputStream) : env(env), inputStream(
: env(env), inputStream(inputStream) { inputStream) {
if (!env->IsInstanceOf( if (!env->IsInstanceOf(inputStream,
inputStream,
env->FindClass("org/oxycblt/musikr/metadata/NativeInputStream"))) { env->FindClass("org/oxycblt/musikr/metadata/NativeInputStream"))) {
throw std::runtime_error("oStream is not an instance of TagLibOStream"); throw std::runtime_error("oStream is not an instance of TagLibOStream");
} }
jclass inputStreamClass = jclass inputStreamClass = env->FindClass(
env->FindClass("org/oxycblt/musikr/metadata/NativeInputStream"); "org/oxycblt/musikr/metadata/NativeInputStream");
inputStreamNameMethod = inputStreamNameMethod = env->GetMethodID(inputStreamClass, "name",
env->GetMethodID(inputStreamClass, "name", "()Ljava/lang/String;"); "()Ljava/lang/String;");
inputStreamReadBlockMethod = inputStreamReadBlockMethod = env->GetMethodID(inputStreamClass, "readBlock",
env->GetMethodID(inputStreamClass, "readBlock", "(J)[B"); "(J)[B");
inputStreamIsOpenMethod = env->GetMethodID(inputStreamClass, "isOpen", "()Z"); inputStreamIsOpenMethod = env->GetMethodID(inputStreamClass, "isOpen",
inputStreamSeekFromBeginningMethod = "()Z");
env->GetMethodID(inputStreamClass, "seekFromBeginning", "(J)V"); inputStreamSeekFromBeginningMethod = env->GetMethodID(inputStreamClass,
inputStreamSeekFromCurrentMethod = "seekFromBeginning", "(J)V");
env->GetMethodID(inputStreamClass, "seekFromCurrent", "(J)V"); inputStreamSeekFromCurrentMethod = env->GetMethodID(inputStreamClass,
inputStreamSeekFromEndMethod = "seekFromCurrent", "(J)V");
env->GetMethodID(inputStreamClass, "seekFromEnd", "(J)V"); inputStreamSeekFromEndMethod = env->GetMethodID(inputStreamClass,
"seekFromEnd", "(J)V");
inputStreamClearMethod = env->GetMethodID(inputStreamClass, "clear", "()V"); inputStreamClearMethod = env->GetMethodID(inputStreamClass, "clear", "()V");
inputStreamTellMethod = env->GetMethodID(inputStreamClass, "tell", "()J"); inputStreamTellMethod = env->GetMethodID(inputStreamClass, "tell", "()J");
inputStreamLengthMethod = env->GetMethodID(inputStreamClass, "length", "()J"); inputStreamLengthMethod = env->GetMethodID(inputStreamClass, "length",
"()J");
env->DeleteLocalRef(inputStreamClass); env->DeleteLocalRef(inputStreamClass);
} }
@ -54,8 +55,8 @@ JVMInputStream::~JVMInputStream() {
} }
TagLib::FileName JVMInputStream::name() const { TagLib::FileName JVMInputStream::name() const {
auto name = auto name = (jstring) env->CallObjectMethod(inputStream,
(jstring)env->CallObjectMethod(inputStream, inputStreamNameMethod); inputStreamNameMethod);
const char *nameChars = env->GetStringUTFChars(name, nullptr); const char *nameChars = env->GetStringUTFChars(name, nullptr);
auto fileName = TagLib::FileName(nameChars); auto fileName = TagLib::FileName(nameChars);
env->ReleaseStringUTFChars(name, nameChars); env->ReleaseStringUTFChars(name, nameChars);
@ -63,8 +64,8 @@ TagLib::FileName JVMInputStream::name() const {
} }
TagLib::ByteVector JVMInputStream::readBlock(size_t length) { TagLib::ByteVector JVMInputStream::readBlock(size_t length) {
auto data = (jbyteArray)env->CallObjectMethod( auto data = (jbyteArray) env->CallObjectMethod(inputStream,
inputStream, inputStreamReadBlockMethod, length); inputStreamReadBlockMethod, length);
jsize dataLength = env->GetArrayLength(data); jsize dataLength = env->GetArrayLength(data);
auto dataBytes = env->GetByteArrayElements(data, nullptr); auto dataBytes = env->GetByteArrayElements(data, nullptr);
TagLib::ByteVector byteVector(reinterpret_cast<const char*>(dataBytes), TagLib::ByteVector byteVector(reinterpret_cast<const char*>(dataBytes),
@ -86,7 +87,9 @@ void JVMInputStream::removeBlock(TagLib::offset_t start, size_t length) {
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
bool JVMInputStream::readOnly() const { return true; } bool JVMInputStream::readOnly() const {
return true;
}
bool JVMInputStream::isOpen() const { bool JVMInputStream::isOpen() const {
return env->CallBooleanMethod(inputStream, inputStreamIsOpenMethod); return env->CallBooleanMethod(inputStream, inputStreamIsOpenMethod);
@ -100,7 +103,8 @@ void JVMInputStream::seek(TagLib::offset_t offset, Position p) {
joffset); joffset);
break; break;
case Current: case Current:
env->CallVoidMethod(inputStream, inputStreamSeekFromCurrentMethod, joffset); env->CallVoidMethod(inputStream, inputStreamSeekFromCurrentMethod,
joffset);
break; break;
case End: case End:
env->CallVoidMethod(inputStream, inputStreamSeekFromEndMethod, joffset); env->CallVoidMethod(inputStream, inputStreamSeekFromEndMethod, joffset);

View file

@ -21,8 +21,9 @@
#include <taglib/mp4tag.h> #include <taglib/mp4tag.h>
#include <taglib/textidentificationframe.h> #include <taglib/textidentificationframe.h>
JVMMetadataBuilder::JVMMetadataBuilder(JNIEnv *env) JVMMetadataBuilder::JVMMetadataBuilder(JNIEnv *env) : env(env), id3v2(env), xiph(
: env(env), id3v2(env), xiph(env), mp4(env), cover(), properties(nullptr) {} env), mp4(env), cover(), properties(nullptr) {
}
void JVMMetadataBuilder::setMimeType(const std::string_view type) { void JVMMetadataBuilder::setMimeType(const std::string_view type) {
this->mimeType = type; this->mimeType = type;
@ -35,13 +36,12 @@ void JVMMetadataBuilder::setId3v2(const TagLib::ID3v2::Tag &tag) {
TagLib::StringList frameText = txxxFrame->fieldList(); TagLib::StringList frameText = txxxFrame->fieldList();
// Frame text starts with the description then the remaining values // Frame text starts with the description then the remaining values
auto begin = frameText.begin(); auto begin = frameText.begin();
TagLib::String key = TagLib::String key = TagLib::String(frame->frameID()) + ":"
TagLib::String(frame->frameID()) + ":" + begin->upper(); + begin->upper();
frameText.erase(begin); frameText.erase(begin);
id3v2.add(key, frameText); id3v2.add(key, frameText);
} else if (auto textFrame = } else if (auto textFrame =
dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>( dynamic_cast<TagLib::ID3v2::TextIdentificationFrame*>(frame)) {
frame)) {
TagLib::String key = frame->frameID(); TagLib::String key = frame->frameID();
TagLib::StringList frameText = textFrame->fieldList(); TagLib::StringList frameText = textFrame->fieldList();
id3v2.add(key, frameText); id3v2.add(key, frameText);
@ -96,8 +96,8 @@ void JVMMetadataBuilder::setMp4(const TagLib::MP4::Tag &tag) {
// It's inefficient going from the integer representation back into // It's inefficient going from the integer representation back into
// a string, but I fully expect taggers to just write "NN/TT" strings // a string, but I fully expect taggers to just write "NN/TT" strings
// anyway, and musikr doesn't have to do as much fiddly variant handling. // anyway, and musikr doesn't have to do as much fiddly variant handling.
auto value = std::to_string(itemValue.toIntPair().first) + "/" + auto value = std::to_string(itemValue.toIntPair().first) + "/"
std::to_string(itemValue.toIntPair().second); + std::to_string(itemValue.toIntPair().second);
id3v2.add(itemName, value); id3v2.add(itemName, value);
return; return;
} }
@ -129,19 +129,19 @@ void JVMMetadataBuilder::setProperties(TagLib::AudioProperties *properties) {
} }
jobject JVMMetadataBuilder::build() { jobject JVMMetadataBuilder::build() {
jclass propertiesClass = jclass propertiesClass = env->FindClass(
env->FindClass("org/oxycblt/musikr/metadata/Properties"); "org/oxycblt/musikr/metadata/Properties");
jmethodID propertiesInit = jmethodID propertiesInit = env->GetMethodID(propertiesClass, "<init>",
env->GetMethodID(propertiesClass, "<init>", "(Ljava/lang/String;JII)V"); "(Ljava/lang/String;JII)V");
jobject propertiesObj = env->NewObject( jobject propertiesObj = env->NewObject(propertiesClass, propertiesInit,
propertiesClass, propertiesInit, env->NewStringUTF(mimeType.data()), env->NewStringUTF(mimeType.data()),
(jlong) properties->lengthInMilliseconds(), properties->bitrate(), (jlong) properties->lengthInMilliseconds(), properties->bitrate(),
properties->sampleRate()); properties->sampleRate());
env->DeleteLocalRef(propertiesClass); env->DeleteLocalRef(propertiesClass);
jclass metadataClass = env->FindClass("org/oxycblt/musikr/metadata/Metadata"); jclass metadataClass = env->FindClass(
jmethodID metadataInit = "org/oxycblt/musikr/metadata/Metadata");
env->GetMethodID(metadataClass, "<init>", jmethodID metadataInit = env->GetMethodID(metadataClass, "<init>",
"(Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;[BLorg/" "(Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;[BLorg/"
"oxycblt/musikr/metadata/Properties;)V"); "oxycblt/musikr/metadata/Properties;)V");
jobject id3v2Map = id3v2.getObject(); jobject id3v2Map = id3v2.getObject();
@ -154,9 +154,8 @@ jobject JVMMetadataBuilder::build() {
env->SetByteArrayRegion(coverArray, 0, coverSize, env->SetByteArrayRegion(coverArray, 0, coverSize,
reinterpret_cast<const jbyte*>(cover->data())); reinterpret_cast<const jbyte*>(cover->data()));
} }
jobject metadataObj = jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map,
env->NewObject(metadataClass, metadataInit, id3v2Map, xiphMap, mp4Map, xiphMap, mp4Map, coverArray, propertiesObj);
coverArray, propertiesObj);
env->DeleteLocalRef(metadataClass); env->DeleteLocalRef(metadataClass);
return metadataObj; return metadataObj;
} }

View file

@ -24,27 +24,28 @@ JVMTagMap::JVMTagMap(JNIEnv *env) : env(env) {
hashMap = env->NewObject(hashMapClass, init); hashMap = env->NewObject(hashMapClass, init);
hashMapGetMethod = env->GetMethodID(hashMapClass, "get", hashMapGetMethod = env->GetMethodID(hashMapClass, "get",
"(Ljava/lang/Object;)Ljava/lang/Object;"); "(Ljava/lang/Object;)Ljava/lang/Object;");
hashMapPutMethod = env->GetMethodID( hashMapPutMethod = env->GetMethodID(hashMapClass, "put",
hashMapClass, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
env->DeleteLocalRef(hashMapClass); env->DeleteLocalRef(hashMapClass);
jclass arrayListClass = env->FindClass("java/util/ArrayList"); jclass arrayListClass = env->FindClass("java/util/ArrayList");
arrayListInitMethod = env->GetMethodID(arrayListClass, "<init>", "()V"); arrayListInitMethod = env->GetMethodID(arrayListClass, "<init>", "()V");
arrayListAddMethod = arrayListAddMethod = env->GetMethodID(arrayListClass, "add",
env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); "(Ljava/lang/Object;)Z");
env->DeleteLocalRef(arrayListClass); env->DeleteLocalRef(arrayListClass);
} }
JVMTagMap::~JVMTagMap() { env->DeleteLocalRef(hashMap); } JVMTagMap::~JVMTagMap() {
env->DeleteLocalRef(hashMap);
}
void JVMTagMap::add(TagLib::String &key, std::string_view value) { void JVMTagMap::add(TagLib::String &key, std::string_view value) {
jstring jKey = env->NewStringUTF(key.toCString(true)); jstring jKey = env->NewStringUTF(key.toCString(true));
jstring jValue = env->NewStringUTF(value.data()); jstring jValue = env->NewStringUTF(value.data());
// check if theres already a value arraylist in the map // check if theres already a value arraylist in the map
jobject existingValue = jobject existingValue = env->CallObjectMethod(hashMap, hashMapGetMethod,
env->CallObjectMethod(hashMap, hashMapGetMethod, jKey); jKey);
// if there is, add to the value to the existing arraylist // if there is, add to the value to the existing arraylist
if (existingValue != nullptr) { if (existingValue != nullptr) {
env->CallBooleanMethod(existingValue, arrayListAddMethod, jValue); env->CallBooleanMethod(existingValue, arrayListAddMethod, jValue);
@ -62,8 +63,8 @@ void JVMTagMap::add(TagLib::String &key, TagLib::StringList &value) {
jstring jKey = env->NewStringUTF(key.toCString(true)); jstring jKey = env->NewStringUTF(key.toCString(true));
// check if theres already a value arraylist in the map // check if theres already a value arraylist in the map
jobject existingValue = jobject existingValue = env->CallObjectMethod(hashMap, hashMapGetMethod,
env->CallObjectMethod(hashMap, hashMapGetMethod, jKey); jKey);
// if there is, add to the value to the existing arraylist // if there is, add to the value to the existing arraylist
if (existingValue != nullptr) { if (existingValue != nullptr) {
for (auto &val : value) { for (auto &val : value) {
@ -83,4 +84,6 @@ void JVMTagMap::add(TagLib::String &key, TagLib::StringList &value) {
} }
} }
jobject JVMTagMap::getObject() { return hashMap; } jobject JVMTagMap::getObject() {
return hashMap;
}

View file

@ -19,8 +19,6 @@
package org.oxycblt.musikr.graph package org.oxycblt.musikr.graph
import org.oxycblt.musikr.Music import org.oxycblt.musikr.Music
import org.oxycblt.musikr.Playlist
import org.oxycblt.musikr.playlist.PlaylistFile
import org.oxycblt.musikr.playlist.SongPointer import org.oxycblt.musikr.playlist.SongPointer
import org.oxycblt.musikr.playlist.interpret.PrePlaylist import org.oxycblt.musikr.playlist.interpret.PrePlaylist
import org.oxycblt.musikr.tag.interpret.PreAlbum import org.oxycblt.musikr.tag.interpret.PreAlbum

View file

@ -41,7 +41,11 @@ internal interface LibraryFactory {
} }
private class LibraryFactoryImpl() : LibraryFactory { private class LibraryFactoryImpl() : LibraryFactory {
override fun create(graph: MusicGraph, storage: Storage, interpretation: Interpretation): MutableLibrary { override fun create(
graph: MusicGraph,
storage: Storage,
interpretation: Interpretation
): MutableLibrary {
val songs = val songs =
graph.songVertex.mapTo(mutableSetOf()) { vertex -> graph.songVertex.mapTo(mutableSetOf()) { vertex ->
SongImpl(SongVertexCore(vertex)).also { vertex.tag = it } SongImpl(SongVertexCore(vertex)).also { vertex.tag = it }
@ -105,8 +109,7 @@ private class LibraryFactoryImpl() : LibraryFactory {
private class PlaylistVertexCore(vertex: PlaylistVertex) : PlaylistCore { private class PlaylistVertexCore(vertex: PlaylistVertex) : PlaylistCore {
override val prePlaylist = vertex.prePlaylist override val prePlaylist = vertex.prePlaylist
override val songs = vertex.songVertices.mapNotNull { vertex -> override val songs =
vertex?.let { it.tag as Song } vertex.songVertices.mapNotNull { vertex -> vertex?.let { it.tag as Song } }
}
} }
} }

View file

@ -24,11 +24,7 @@ import org.oxycblt.musikr.MutableLibrary
import org.oxycblt.musikr.Playlist import org.oxycblt.musikr.Playlist
import org.oxycblt.musikr.Song import org.oxycblt.musikr.Song
import org.oxycblt.musikr.Storage import org.oxycblt.musikr.Storage
import org.oxycblt.musikr.cover.StoredCovers
import org.oxycblt.musikr.fs.Path import org.oxycblt.musikr.fs.Path
import org.oxycblt.musikr.playlist.PlaylistHandle
import org.oxycblt.musikr.playlist.db.PlaylistInfo
import org.oxycblt.musikr.playlist.db.StoredPlaylists
internal data class LibraryImpl( internal data class LibraryImpl(
override val songs: Collection<SongImpl>, override val songs: Collection<SongImpl>,

View file

@ -21,7 +21,6 @@ package org.oxycblt.musikr.model
import org.oxycblt.musikr.Playlist import org.oxycblt.musikr.Playlist
import org.oxycblt.musikr.Song import org.oxycblt.musikr.Song
import org.oxycblt.musikr.cover.Cover import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.playlist.PlaylistHandle
import org.oxycblt.musikr.playlist.interpret.PrePlaylistInfo import org.oxycblt.musikr.playlist.interpret.PrePlaylistInfo
import org.oxycblt.musikr.tag.Name import org.oxycblt.musikr.tag.Name

View file

@ -23,7 +23,6 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.merge
@ -33,8 +32,6 @@ import org.oxycblt.musikr.MutableLibrary
import org.oxycblt.musikr.Storage import org.oxycblt.musikr.Storage
import org.oxycblt.musikr.graph.MusicGraph import org.oxycblt.musikr.graph.MusicGraph
import org.oxycblt.musikr.model.LibraryFactory import org.oxycblt.musikr.model.LibraryFactory
import org.oxycblt.musikr.model.PlaylistImpl
import org.oxycblt.musikr.playlist.SongPointer
import org.oxycblt.musikr.playlist.interpret.PlaylistInterpreter import org.oxycblt.musikr.playlist.interpret.PlaylistInterpreter
import org.oxycblt.musikr.tag.interpret.TagInterpreter import org.oxycblt.musikr.tag.interpret.TagInterpreter
@ -46,7 +43,8 @@ internal interface EvaluateStep {
): MutableLibrary ): MutableLibrary
companion object { companion object {
fun new(): EvaluateStep = EvaluateStepImpl(TagInterpreter.new(), PlaylistInterpreter.new(), LibraryFactory.new()) fun new(): EvaluateStep =
EvaluateStepImpl(TagInterpreter.new(), PlaylistInterpreter.new(), LibraryFactory.new())
} }
} }
@ -60,7 +58,8 @@ private class EvaluateStepImpl(
interpretation: Interpretation, interpretation: Interpretation,
extractedMusic: Flow<ExtractedMusic> extractedMusic: Flow<ExtractedMusic>
): MutableLibrary { ): MutableLibrary {
val filterFlow = extractedMusic.divert { val filterFlow =
extractedMusic.divert {
when (it) { when (it) {
is ExtractedMusic.Song -> Divert.Right(it.song) is ExtractedMusic.Song -> Divert.Right(it.song)
is ExtractedMusic.Playlist -> Divert.Left(it.file) is ExtractedMusic.Playlist -> Divert.Left(it.file)
@ -72,15 +71,16 @@ private class EvaluateStepImpl(
.map { tagInterpreter.interpret(it, interpretation) } .map { tagInterpreter.interpret(it, interpretation) }
.flowOn(Dispatchers.Main) .flowOn(Dispatchers.Main)
.buffer(Channel.UNLIMITED) .buffer(Channel.UNLIMITED)
val prePlaylists = filterFlow.left val prePlaylists =
filterFlow.left
.map { playlistInterpreter.interpret(it, interpretation) } .map { playlistInterpreter.interpret(it, interpretation) }
.flowOn(Dispatchers.Main) .flowOn(Dispatchers.Main)
.buffer(Channel.UNLIMITED) .buffer(Channel.UNLIMITED)
val graphBuilder = MusicGraph.builder() val graphBuilder = MusicGraph.builder()
val graphBuild = merge( val graphBuild =
merge(
preSongs.onEach { graphBuilder.add(it) }, preSongs.onEach { graphBuilder.add(it) },
prePlaylists.onEach { graphBuilder.add(it) } prePlaylists.onEach { graphBuilder.add(it) })
)
graphBuild.collect() graphBuild.collect()
val graph = graphBuilder.build() val graph = graphBuilder.build()
return libraryFactory.create(graph, storage, interpretation) return libraryFactory.create(graph, storage, interpretation)

View file

@ -23,7 +23,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
@ -52,7 +51,8 @@ private class ExtractStepImpl(
private val tagParser: TagParser private val tagParser: TagParser
) : ExtractStep { ) : ExtractStep {
override fun extract(storage: Storage, nodes: Flow<ExploreNode>): Flow<ExtractedMusic> { override fun extract(storage: Storage, nodes: Flow<ExploreNode>): Flow<ExtractedMusic> {
val filterFlow = nodes.divert { val filterFlow =
nodes.divert {
when (it) { when (it) {
is ExploreNode.Audio -> Divert.Right(it.file) is ExploreNode.Audio -> Divert.Right(it.file)
is ExploreNode.Playlist -> Divert.Left(it.file) is ExploreNode.Playlist -> Divert.Left(it.file)

View file

@ -26,6 +26,7 @@ import org.oxycblt.musikr.playlist.SongPointer
interface StoredPlaylists { interface StoredPlaylists {
suspend fun new(name: String, songs: List<Song>): PlaylistHandle suspend fun new(name: String, songs: List<Song>): PlaylistHandle
suspend fun read(): List<PlaylistFile> suspend fun read(): List<PlaylistFile>
companion object { companion object {
@ -36,17 +37,8 @@ interface StoredPlaylists {
private class StoredPlaylistsImpl(private val playlistDao: PlaylistDao) : StoredPlaylists { private class StoredPlaylistsImpl(private val playlistDao: PlaylistDao) : StoredPlaylists {
override suspend fun new(name: String, songs: List<Song>): PlaylistHandle { override suspend fun new(name: String, songs: List<Song>): PlaylistHandle {
val info = val info = PlaylistInfo(Music.UID.auxio(Music.UID.Item.PLAYLIST), name)
PlaylistInfo( playlistDao.insertPlaylist(RawPlaylist(info, songs.map { PlaylistSong(it.uid) }))
Music.UID.auxio(Music.UID.Item.PLAYLIST),
name
)
playlistDao.insertPlaylist(
RawPlaylist(
info,
songs.map { PlaylistSong(it.uid) }
)
)
return StoredPlaylistHandle(info, playlistDao) return StoredPlaylistHandle(info, playlistDao)
} }
@ -55,7 +47,6 @@ private class StoredPlaylistsImpl(private val playlistDao: PlaylistDao) : Stored
PlaylistFile( PlaylistFile(
it.playlistInfo.name, it.playlistInfo.name,
it.songs.map { song -> SongPointer.UID(song.songUid) }, it.songs.map { song -> SongPointer.UID(song.songUid) },
StoredPlaylistHandle(it.playlistInfo, playlistDao) StoredPlaylistHandle(it.playlistInfo, playlistDao))
)
} }
} }

View file

@ -1,9 +1,26 @@
/*
* Copyright (c) 2024 Auxio Project
* PlaylistInterpreter.kt is part of Auxio.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.playlist.interpret package org.oxycblt.musikr.playlist.interpret
import org.oxycblt.musikr.Interpretation import org.oxycblt.musikr.Interpretation
import org.oxycblt.musikr.playlist.PlaylistFile import org.oxycblt.musikr.playlist.PlaylistFile
import org.oxycblt.musikr.playlist.PlaylistHandle import org.oxycblt.musikr.playlist.PlaylistHandle
import org.oxycblt.musikr.playlist.SongPointer
internal interface PlaylistInterpreter { internal interface PlaylistInterpreter {
fun interpret(file: PlaylistFile, interpretation: Interpretation): PrePlaylist fun interpret(file: PlaylistFile, interpretation: Interpretation): PrePlaylist
@ -25,18 +42,12 @@ private data object PlaylistInterpreterImpl : PlaylistInterpreter {
name = interpretation.naming.name(file.name, null), name = interpretation.naming.name(file.name, null),
rawName = file.name, rawName = file.name,
handle = file.handle, handle = file.handle,
songPointers = file.songPointers songPointers = file.songPointers)
)
override fun interpret( override fun interpret(
name: String, name: String,
handle: PlaylistHandle, handle: PlaylistHandle,
interpretation: Interpretation interpretation: Interpretation
): PostPlaylist = ): PostPlaylist =
PostPlaylist( PostPlaylist(name = interpretation.naming.name(name, null), rawName = name, handle = handle)
name = interpretation.naming.name(name, null),
rawName = name,
handle = handle
)
} }

View file

@ -1,3 +1,21 @@
/*
* Copyright (c) 2024 Auxio Project
* PrePlaylist.kt is part of Auxio.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.playlist.interpret package org.oxycblt.musikr.playlist.interpret
import org.oxycblt.musikr.playlist.PlaylistHandle import org.oxycblt.musikr.playlist.PlaylistHandle

View file

@ -67,12 +67,13 @@ sealed interface Name : Comparable<Name> {
} }
/** An individual part of a name string that can be compared intelligently. */ /** An individual part of a name string that can be compared intelligently. */
class Token class Token internal constructor(internal val collationKey: CollationKey, internal val type: Type) :
internal constructor(internal val collationKey: CollationKey, internal val type: Type) :
Comparable<Token> { Comparable<Token> {
override fun equals(other: Any?) = override fun equals(other: Any?) =
other is Token && collationKey == other.collationKey && type == other.type other is Token && collationKey == other.collationKey && type == other.type
override fun hashCode() = 31 * collationKey.hashCode() + type.hashCode() override fun hashCode() = 31 * collationKey.hashCode() + type.hashCode()
val value: String val value: String
get() = collationKey.sourceString get() = collationKey.sourceString

View file

@ -24,7 +24,6 @@ import org.oxycblt.musikr.Music
import org.oxycblt.musikr.cover.Cover import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.fs.Format import org.oxycblt.musikr.fs.Format
import org.oxycblt.musikr.fs.Path import org.oxycblt.musikr.fs.Path
import org.oxycblt.musikr.playlist.PlaylistHandle
import org.oxycblt.musikr.tag.Date import org.oxycblt.musikr.tag.Date
import org.oxycblt.musikr.tag.Disc import org.oxycblt.musikr.tag.Disc
import org.oxycblt.musikr.tag.Name import org.oxycblt.musikr.tag.Name

View file

@ -21,7 +21,6 @@ package org.oxycblt.musikr.tag.interpret
import org.oxycblt.musikr.Interpretation import org.oxycblt.musikr.Interpretation
import org.oxycblt.musikr.fs.Format import org.oxycblt.musikr.fs.Format
import org.oxycblt.musikr.pipeline.RawSong import org.oxycblt.musikr.pipeline.RawSong
import org.oxycblt.musikr.playlist.PlaylistFile
import org.oxycblt.musikr.tag.Disc import org.oxycblt.musikr.tag.Disc
import org.oxycblt.musikr.tag.Name import org.oxycblt.musikr.tag.Name
import org.oxycblt.musikr.tag.Placeholder import org.oxycblt.musikr.tag.Placeholder