GitBucket
4.23.0
Toggle navigation
Sign in
Files
Branches
1
Releases
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
yhornisse
/
bremer
Browse code
fix a bug and refactor
master
1 parent
9c2227e
commit
2be064315326ccee7c2d8980192c7496c6c8b339
yhornisse
authored
on 13 Aug 2023
Patch
Showing
2 changed files
src/main/kotlin/config/BremerConfig.kt
src/main/kotlin/service/AudioService.kt
Ignore Space
Show notes
View
src/main/kotlin/config/BremerConfig.kt
/* * Copyright (c) 2023. yo-saito. All Rights Reserved. */ package net.piedpiper.bremer.config import net.piedpiper.bremer.service.LoginService import org.springframework.beans.factory.annotation.Qualifier import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.web.SecurityFilterChain import org.springframework.web.filter.ForwardedHeaderFilter @Configuration class AppConfig { @Bean("bremer.PasswordEncoder") fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder() @Bean fun forwardedHeaderFilter(): ForwardedHeaderFilter = ForwardedHeaderFilter() } @Configuration @EnableWebSecurity class WebSecurityConfig( @Qualifier("bremer.service.LoginService") private val loginService: LoginService ) { @Bean fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { http.authorizeHttpRequests { authorize -> authorize .requestMatchers( "/bremer/login", "/bremer/login.html", "/bremer/icon/*" ).permitAll() .anyRequest().authenticated() }.formLogin { login -> login.loginPage("/bremer/login.html").permitAll() .loginProcessingUrl("/bremer/login").permitAll() .usernameParameter("id") .passwordParameter("password") .defaultSuccessUrl("/bremer/hello.html") .failureUrl("/bremer/login.html?failed") }.logout { logout -> logout .logoutUrl("/bremer/logout") .deleteCookies("JSESSIONID") .invalidateHttpSession(true) .logoutSuccessUrl("/bremer/login.html?logout") } .csrf { it.disable() } .userDetailsService(loginService) return http.build() } }
/* * Copyright (c) 2023. yo-saito. All Rights Reserved. */ package net.piedpiper.bremer.config import net.piedpiper.bremer.service.LoginService import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger import org.springframework.beans.factory.annotation.Qualifier import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.web.SecurityFilterChain import org.springframework.web.filter.ForwardedHeaderFilter import kotlin.reflect.KProperty @Configuration class AppConfig { @Bean("bremer.PasswordEncoder") fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder() @Bean fun forwardedHeaderFilter(): ForwardedHeaderFilter = ForwardedHeaderFilter() } @Configuration @EnableWebSecurity class WebSecurityConfig( @Qualifier("bremer.service.LoginService") private val loginService: LoginService ) { @Bean fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { http.authorizeHttpRequests { authorize -> authorize .requestMatchers( "/bremer/login", "/bremer/login.html", "/bremer/icon/*" ).permitAll() .anyRequest().authenticated() }.formLogin { login -> login.loginPage("/bremer/login.html").permitAll() .loginProcessingUrl("/bremer/login").permitAll() .usernameParameter("id") .passwordParameter("password") .defaultSuccessUrl("/bremer/hello.html") .failureUrl("/bremer/login.html?failed") }.logout { logout -> logout .logoutUrl("/bremer/logout") .deleteCookies("JSESSIONID") .invalidateHttpSession(true) .logoutSuccessUrl("/bremer/login.html?logout") } .csrf { it.disable() } .userDetailsService(loginService) return http.build() } } class Log { companion object { private val log = LogManager.getLogger(Log::class.java) } operator fun getValue(thisRef: Any, property: KProperty<*>): Logger = log }
Ignore Space
Show notes
View
src/main/kotlin/service/AudioService.kt
/* * Copyright (c) 2023. yo-saito. All Rights Reserved. */ package net.piedpiper.bremer.service import net.piedpiper.bremer.dao.* import net.piedpiper.bremer.entity.AudioEntity import net.piedpiper.bremer.entity.AudioPlayHistoryEntity import net.piedpiper.bremer.exception.NotFoundException import net.piedpiper.bremer.model.api.AudioListResponse import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.io.File import java.time.LocalDateTime import java.time.ZoneId @Service("bremer.service.AudioService") class AudioService( @Qualifier("bremer.dao.AudioDao") private val audioDao: AudioDao, @Qualifier("bremer.dao.ArtistDao") private val artistDao: ArtistDao, @Qualifier("bremer.dao.AlbumDao") private val albumDao: AlbumDao, @Qualifier("bremer.dao.AudioPlayHistoryDao") private val audioPlayHistoryDao: AudioPlayHistoryDao, @Qualifier("bremer.dao.TagDao") private val tagDao: TagDao ) { /** 音楽ファイル取得 */ @Transactional fun getAudioFile(slug: String): File { val audio = audioDao.findOneBySlug(slug) ?: throw NotFoundException() val file = File(audio.path) if (!file.exists()) { throw NotFoundException() } audioPlayHistoryDao.insertOrUpdateOne( AudioPlayHistoryEntity( audioId = audio.id, lastPlayedAt = LocalDateTime.now(ZoneId.of("Asia/Tokyo")) ) ) return file } /** キーワード検索 */ @Transactional fun getByKeywords( audioNameLike: String?, artistNameLike: String?, albumNameLike: String?, tagNameLike: String?, pageSize: Int ): AudioListResponse { val set = mutableSetOf<AudioEntity>() if (audioNameLike?.isNotEmpty() == true) { set.addAll(audioDao.findAllByNameLikeLimit(audioNameLike, pageSize)) } if (artistNameLike?.isNotEmpty() == true && set.size <= pageSize) { set.addAll(findAllByArtistNameLikeLimit(artistNameLike, pageSize)) } if (albumNameLike?.isNotEmpty() == true && set.size <= pageSize) { set.addAll(findAllByAlbumNameLikeLimit(albumNameLike, pageSize)) } if (tagNameLike?.isNotEmpty() == true && set.size <= pageSize) { set.addAll(findAllByTagNameLikeLimit(tagNameLike, pageSize)) } return AudioListResponse( set.sortedWith(compareBy({ it.albumId }, { it.sequence })) .take(pageSize) .toList() ) } /** 最近再生した曲一覧を取得 */ @Transactional fun getLeastRecentlyAccessedAudio(pageSize: Int): AudioListResponse { val historyMap = audioPlayHistoryDao.findAllOrderLastPlayedAtDescLimit(pageSize) .associateBy { it.audioId } return if (historyMap.isNotEmpty()) audioDao.findAllByIdIn(historyMap.keys.map { it }) .sortedByDescending { historyMap[it.id]?.lastPlayedAt ?: LocalDateTime.MIN }.let { AudioListResponse(it) } else AudioListResponse() } private fun findAllByArtistNameLikeLimit( artistNameLike: String, limit: Int ): List<AudioEntity> { val artists = artistDao.findAllByNameLikeLimit(artistNameLike, limit) if (artists.isEmpty()) { return emptyList() } val albums = albumDao.findAllByArtistIdInLimit(artists.map { it.id }.distinct(), limit) if (albums.isEmpty()) { return emptyList() } return audioDao.findAllByAlbumIdIn(albums.map { it.id }.distinct()) } private fun findAllByAlbumNameLikeLimit(albumNameLike: String, limit: Int): List<AudioEntity> { val albums = albumDao.findAllByNameLikeLimit(albumNameLike, limit) return if (albums.isNotEmpty()) audioDao .findAllByAlbumIdIn(albums.map { it.id }) else emptyList() } private fun findAllByTagNameLikeLimit(tagNameLike: String, limit: Int): List<AudioEntity> { val tags = tagDao.findAllByNameLikeLimit(tagNameLike, limit) return if (tags.isNotEmpty()) audioDao.findAllByTagIdIn(tags.map { it.id }) else emptyList() } }
/* * Copyright (c) 2023. yo-saito. All Rights Reserved. */ package net.piedpiper.bremer.service import net.piedpiper.bremer.dao.* import net.piedpiper.bremer.entity.AudioEntity import net.piedpiper.bremer.entity.AudioPlayHistoryEntity import net.piedpiper.bremer.exception.NotFoundException import net.piedpiper.bremer.model.api.AudioListResponse import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.io.File import java.time.LocalDateTime import java.time.ZoneId @Service("bremer.service.AudioService") class AudioService( @Qualifier("bremer.dao.AudioDao") private val audioDao: AudioDao, @Qualifier("bremer.dao.ArtistDao") private val artistDao: ArtistDao, @Qualifier("bremer.dao.AlbumDao") private val albumDao: AlbumDao, @Qualifier("bremer.dao.AudioPlayHistoryDao") private val audioPlayHistoryDao: AudioPlayHistoryDao, @Qualifier("bremer.dao.TagDao") private val tagDao: TagDao ) { /** 音楽ファイル取得 */ @Transactional fun getAudioFile(slug: String): File { val audio = audioDao.findOneBySlug(slug) ?: throw NotFoundException() val file = File(audio.path) if (!file.exists()) { throw NotFoundException() } audioPlayHistoryDao.insertOrUpdateOne( AudioPlayHistoryEntity( audioId = audio.id, lastPlayedAt = LocalDateTime.now(ZoneId.of("Asia/Tokyo")) ) ) return file } /** キーワード検索 */ @Transactional fun getByKeywords( audioNameLike: String?, artistNameLike: String?, albumNameLike: String?, tagNameLike: String?, pageSize: Int ): AudioListResponse { val set = mutableSetOf<AudioEntity>() if (audioNameLike?.isNotEmpty() == true) { set.addAll(audioDao.findAllByNameLikeLimit(audioNameLike, pageSize)) } if (artistNameLike?.isNotEmpty() == true && set.size <= pageSize) { set.addAll(findAllByArtistNameLikeLimit(artistNameLike, pageSize)) } if (albumNameLike?.isNotEmpty() == true && set.size <= pageSize) { set.addAll(findAllByAlbumNameLikeLimit(albumNameLike, pageSize)) } if (tagNameLike?.isNotEmpty() == true && set.size <= pageSize) { set.addAll(findAllByTagNameLikeLimit(tagNameLike, pageSize)) } return AudioListResponse( set.sortedWith(compareBy({ it.albumId }, { it.sequence })) .take(pageSize) .toList() ) } /** 最近再生した曲一覧を取得 */ @Transactional fun getLeastRecentlyAccessedAudio(pageSize: Int): AudioListResponse { val historyMap = audioPlayHistoryDao.findAllOrderLastPlayedAtDescLimit(pageSize) .associateBy { it.audioId } return if (historyMap.isNotEmpty()) audioDao.findAllByIdIn(historyMap.keys.map { it }) .sortedByDescending { historyMap[it.id]?.lastPlayedAt ?: LocalDateTime.MIN }.let { AudioListResponse(it) } else AudioListResponse() } private fun findAllByArtistNameLikeLimit( artistNameLike: String, limit: Int ): List<AudioEntity> { val artists = artistDao.findAllByNameLikeLimit(artistNameLike, limit) if (artists.isEmpty()) { return emptyList() } val albums = albumDao.findAllByArtistIdInLimit(artists.map { it.id }.distinct(), limit) if (albums.isEmpty()) { return emptyList() } return audioDao.findAllByAlbumIdIn(albums.map { it.id }.distinct()) } private fun findAllByAlbumNameLikeLimit(albumNameLike: String, limit: Int): List<AudioEntity> { val albums = albumDao.findAllByNameLikeLimit(albumNameLike, limit) return if (albums.isNotEmpty()) audioDao .findAllByAlbumIdIn(albums.map { it.id }) else emptyList() } private fun findAllByTagNameLikeLimit(tagNameLike: String, limit: Int) = audioDao.findAllByTagIdIn( tagDao.findAllByNameLikeLimit(tagNameLike, limit) .map { it.id } ) }
Show line notes below