Skip to content

Commit

Permalink
#212 remove transaction annotation from MediaScannerService
Browse files Browse the repository at this point in the history
  • Loading branch information
kagemomiji committed Nov 29, 2023
1 parent 7d9d09e commit 6d6a917
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,22 @@ public int getAlbumCount(List<MusicFolder> musicFolders) {
return albumRepository.countByFolderInAndPresentTrue(musicFolders);
}

/**
* mark all albums as non present that were last scanned before lastScanned
*
* @param lastScanned last scanned date
*/
public void markNonPresent(Instant lastScanned) {
albumRepository.markNonPresent(lastScanned);
}

/**
* Save album to database
*
* @param album album to save
*/
public Album save(Album album) {
return albumRepository.save(album);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,23 @@ public void expunge() {
artistRepository.deleteAllByPresentFalse();
}

/**
* Mark artists that are not present
*
* @param lastScanned last scanned date
*/
public void markNonPresent(Instant lastScanned) {
artistRepository.markNonPresent(lastScanned);
}

/**
* Save artist
*
* @param artist artist to save
* @return saved artist
*/
public Artist save(Artist artist) {
return artistRepository.save(artist);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.airsonic.player.domain.entity.UserRating;
import org.airsonic.player.i18n.LocaleResolver;
import org.airsonic.player.repository.AlbumRepository;
import org.airsonic.player.repository.ArtistRepository;
import org.airsonic.player.repository.GenreRepository;
import org.airsonic.player.repository.MediaFileRepository;
import org.airsonic.player.repository.MusicFileInfoRepository;
Expand All @@ -42,8 +43,10 @@
import org.airsonic.player.service.metadata.MetaData;
import org.airsonic.player.service.metadata.MetaDataParser;
import org.airsonic.player.service.metadata.MetaDataParserFactory;
import org.airsonic.player.service.search.IndexManager;
import org.airsonic.player.util.FileUtil;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.digitalmediaserver.cuelib.CueParser;
Expand Down Expand Up @@ -75,6 +78,8 @@
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -118,6 +123,10 @@ public class MediaFileService {
private MusicFileInfoRepository musicFileInfoRepository;
@Autowired
private GenreRepository genreRepository;
@Autowired
private IndexManager indexManager;
@Autowired
private ArtistRepository artistRepository;

private boolean memoryCacheEnabled = true;

Expand Down Expand Up @@ -1478,4 +1487,151 @@ private MediaFile delete(MediaFile file) {
public void expunge() {
mediaFileRepository.deleteAllByPresentFalse();
}

/**
* update album stats
*
* @param file media file
* @param musicFolder music folder
* @param lastScanned last scanned time
* @param albumCount album count
* @param albums albums
* @param albumsInDb albums in db
*/
public void updateAlbum(MediaFile file, MusicFolder musicFolder,
Instant lastScanned, Map<String, AtomicInteger> albumCount, Map<String, Album> albums,
Map<Integer, Album> albumsInDb) {

String artist = file.getAlbumArtist() != null ? file.getAlbumArtist() : file.getArtist();
if (file.getAlbumName() == null || artist == null || file.getParentPath() == null || !file.isAudio()) {
return;
}

final AtomicBoolean firstEncounter = new AtomicBoolean(false);
Album album = albums.compute(file.getAlbumName() + "|" + artist, (k, v) -> {
Album a = v;

if (a == null) {
a = albumRepository.findByArtistAndName(artist, file.getAlbumName())
.map(dbAlbum -> {
albumsInDb.computeIfAbsent(dbAlbum.getId(), aid -> {
// reset stats when first retrieve from the db for new scan
dbAlbum.setDuration(0);
dbAlbum.setSongCount(0);
return dbAlbum;
});
return dbAlbum;
}).orElse(null);
}

if (a == null) {
a = new Album();
a.setPath(file.getParentPath());
a.setName(file.getAlbumName());
a.setArtist(artist);
a.setCreated(file.getChanged());
}

firstEncounter.set(!lastScanned.equals(a.getLastScanned()));

if (file.getDuration() != null) {
a.incrementDuration(file.getDuration());
}
if (file.isAudio()) {
a.incrementSongCount();
}

a.setLastScanned(lastScanned);
a.setPresent(true);

return a;
});

if (file.getMusicBrainzReleaseId() != null) {
album.setMusicBrainzReleaseId(file.getMusicBrainzReleaseId());
}
if (file.getYear() != null) {
album.setYear(file.getYear());
}
if (file.getGenre() != null) {
album.setGenre(file.getGenre());
}

if (album.getArt() == null) {
MediaFile parent = getParentOf(file, true); // true because the parent has recently already been scanned
if (parent != null) {
CoverArt art = coverArtService.get(EntityType.MEDIA_FILE, parent.getId());
if (!CoverArt.NULL_ART.equals(art)) {
album.setArt(new CoverArt(-1, EntityType.ALBUM, art.getPath(), art.getFolder(), false));
}
}
}

if (firstEncounter.get()) {
album.setFolder(musicFolder);

albumRepository.saveAndFlush(album);
albumCount.computeIfAbsent(artist, k -> new AtomicInteger(0)).incrementAndGet();
indexManager.index(album);
}

// Update the file's album artist, if necessary.
if (!ObjectUtils.equals(album.getArtist(), file.getAlbumArtist())) {
file.setAlbumArtist(album.getArtist());
updateMediaFile(file);
}
}

/**
* update artist stats
*
* @param file media file
* @param musicFolder music folder
* @param lastScanned last scanned time
* @param albumCount album count
* @param artists artists
*/
public void updateArtist(MediaFile file, MusicFolder musicFolder, Instant lastScanned,
Map<String, AtomicInteger> albumCount, Map<String, Artist> artists) {
if (file.getAlbumArtist() == null || !file.isAudio()) {
return;
}

final AtomicBoolean firstEncounter = new AtomicBoolean(false);

Artist artist = artists.compute(file.getAlbumArtist(), (k, v) -> {
Artist a = v;

if (a == null) {
a = artistRepository.findByName(k).orElse(new Artist(k));
}

int n = Math.max(Optional.ofNullable(albumCount.get(a.getName())).map(x -> x.get()).orElse(0),
Optional.ofNullable(a.getAlbumCount()).orElse(0));
a.setAlbumCount(n);

firstEncounter.set(!lastScanned.equals(a.getLastScanned()));

a.setLastScanned(lastScanned);
a.setPresent(true);

return a;
});

if (artist.getArt() == null) {
MediaFile parent = getParentOf(file, true); // true because the parent has recently already been scanned
if (parent != null) {
CoverArt art = coverArtService.get(EntityType.MEDIA_FILE, parent.getId());
if (!CoverArt.NULL_ART.equals(art)) {
artist.setArt(new CoverArt(-1, EntityType.ARTIST, art.getPath(), art.getFolder(), false));
}
}
}

if (firstEncounter.get()) {
artist.setFolder(musicFolder);
artistRepository.saveAndFlush(artist);
indexManager.index(artist, musicFolder);
}
}
}
Loading

0 comments on commit 6d6a917

Please sign in to comment.