Skip to content

Commit

Permalink
[BE-FEAT] 포켓몬의 기술 리스트 불러오는 API (#237)
Browse files Browse the repository at this point in the history
* refactor: WeatherRepository 컴포넌트 애너테이션 변경

* feat: 기술 데이터 세팅

* refactor: 기술 id 저장 데이터 변경

* feat: 포켓몬의 기술 데이터 세팅

* feat: 포켓몬의 기술 리스트 불러오는 api

* chore: 기술 데이터 추가

* feat: 기술 리스트에서 타입, 카테고리 로고 함께 반환

* fix: 빈 문자열 저장하는 오류

* refactor: 포켓몬 타입 enum 생성

* test: 모든 도감 번호에 대해서 기술 리스트 조회 테스트

* refactor: 포켓몬 타입 레포지토리 생성

* refactor: 기술 카테고리 enum 생성

* style: 개행 추가

* style: enum 개행 추가

* chore: 데이터 추가 히스토리 맞추기

* fix: 중복되는 bean 이름 변경
  • Loading branch information
jongmee authored Aug 19, 2024
1 parent 7c7c17f commit 12ecdfe
Show file tree
Hide file tree
Showing 22 changed files with 476 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ public class S3Service {

private static final String POKEMON_IMAGE_FOLDER = "image/";
private static final String TYPE_IMAGE_FOLDER = "type/";
private static final String POKEROGUE_TYPE_IMAGE_FOLDER = "pokerogue/type/";
private static final String POKEROGUE_MOVE_CATEGORY_IMAGE_FOLDER = "pokerogue/move-category/";
private static final String SVG_EXTENSION = ".svg";
private static final String PNG_EXTENSION = ".png";

private final S3ImageClient s3ImageClient;

Expand All @@ -35,6 +38,11 @@ private String makeRandomFileName() {
}

private String makeTypeFileName(String typeName) {
return TYPE_IMAGE_FOLDER + typeName + SVG_EXTENSION;
return TYPE_IMAGE_FOLDER + typeName + SVG_EXTENSION;
}

public String getPokerogueTypeImageFromS3(String typeName) {
String key = POKEROGUE_TYPE_IMAGE_FOLDER + typeName + "-1" + PNG_EXTENSION;
return s3ImageClient.getFileUrl(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
Expand All @@ -18,4 +19,9 @@ public class BattleController {
public ApiResponse<List<WeatherResponse>> weatherList() {
return new ApiResponse<>("날씨 리스트 불러오기에 성공했습니다.", battleService.findWeathers());
}

@GetMapping("/api/v1/moves")
public ApiResponse<List<MoveResponse>> moveByPokemonList(@RequestParam("pokedex-number") Integer pokedexNumber) {
return new ApiResponse<>("포켓몬의 기술 리스트 불러오기에 성공했습니다.", battleService.findMovesByPokemon(pokedexNumber));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.pokerogue.helper.battle;

public record BattleMove(
String id,
String name,
String nameAppend,
String effect,
String type,
String defaultTypeId,
String category,
String moveTarget,
Integer power,
Integer accuracy,
Integer pp,
Integer chance,
Integer priority,
Integer generation,
String flags
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.pokerogue.helper.battle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.stereotype.Repository;

@Repository
public class BattleMoveRepository {

private final Map<String, BattleMove> moves = new HashMap<>();

public void save(BattleMove battleMove) {
moves.put(battleMove.id(), battleMove);
}

public List<BattleMove> findAll() {
return moves.values()
.stream()
.toList();
}

public Optional<BattleMove> findById(String id) {
return Optional.ofNullable(moves.get(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.pokerogue.helper.battle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.stereotype.Repository;

@Repository
public class BattlePokemonTypeRepository {

private final Map<String, PokemonType> pokemonTypes = new HashMap<>();

public void save(PokemonType pokemonType) {
pokemonTypes.put(pokemonType.name(), pokemonType);
}

public List<PokemonType> findAll() {
return pokemonTypes.values()
.stream()
.toList();
}

public Optional<PokemonType> findByName(String name) {
return Optional.ofNullable(pokemonTypes.get(name));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.pokerogue.helper.battle;

import com.pokerogue.helper.global.exception.ErrorMessage;
import com.pokerogue.helper.global.exception.GlobalCustomException;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -9,10 +12,51 @@
public class BattleService {

private final WeatherRepository weatherRepository;
private final BattleMoveRepository battleMoveRepository;
private final PokemonMovesByEggRepository pokemonMovesByEggRepository;
private final PokemonMovesBySelfRepository pokemonMovesBySelfRepository;
private final PokemonMovesByMachineRepository pokemonMovesByMachineRepository;
private final BattlePokemonTypeRepository battlePokemonTypeRepository;

public List<WeatherResponse> findWeathers() {
return weatherRepository.findAll().stream()
.map(WeatherResponse::from)
.toList();
}

public List<MoveResponse> findMovesByPokemon(Integer pokedexNumber) {
List<String> allMoveIds = new ArrayList<>();
PokemonMovesBySelf pokemonMovesBySelf = pokemonMovesBySelfRepository.findByPokedexNumber(pokedexNumber)
.orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_BY_SELF_NOT_FOUND));
PokemonMovesByMachine pokemonMovesByMachine = pokemonMovesByMachineRepository.findByPokedexNumber(pokedexNumber)
.orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_BY_MACHINE_NOT_FOUND));
PokemonMovesByEgg pokemonMovesByEgg = pokemonMovesByEggRepository.findByPokedexNumber(pokedexNumber)
.orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_BY_EGG_NOT_FOUND));

allMoveIds.addAll(pokemonMovesBySelf.moveIds());
allMoveIds.addAll(pokemonMovesByMachine.moveIds());
allMoveIds.addAll(pokemonMovesByEgg.moveIds());
List<BattleMove> battleMoves = allMoveIds.stream()
.map(this::findMoveById)
.toList();

return battleMoves.stream()
.map(this::toMoveResponseWithLogo)
.toList();
}

private BattleMove findMoveById(String id) {
return battleMoveRepository.findById(id)
.orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_NOT_FOUND));
}

private MoveResponse toMoveResponseWithLogo(BattleMove battleMove) {
PokemonType pokemonType = battlePokemonTypeRepository.findByName(battleMove.type())
.orElseThrow(() -> new GlobalCustomException(ErrorMessage.POKEMON_TYPE_NOT_FOUND));
String typeLogo = pokemonType.image();
MoveCategory moveCategory = MoveCategory.findByName(battleMove.category().toLowerCase());
String categoryLogo = moveCategory.getName();

return MoveResponse.of(battleMove, typeLogo, categoryLogo);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.pokerogue.helper.battle;

import com.pokerogue.external.s3.service.S3Service;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
Expand All @@ -18,45 +19,143 @@
@RequiredArgsConstructor
public class DataInitializer implements ApplicationRunner {

private static final int FIRST_LINE = 3;
private static final int FIRST_LINE_NUMBER = 3;
private static final String FIELD_DELIMITER = "/";
private static final String LIST_DELIMITER = ",";

private final WeatherRepository weatherRepository;
private final BattleMoveRepository battleMoveRepository;
private final PokemonMovesByMachineRepository pokemonMovesByMachineRepository;
private final PokemonMovesBySelfRepository pokemonMovesBySelfRepository;
private final PokemonMovesByEggRepository pokemonMovesByEggRepository;
private final BattlePokemonTypeRepository battlePokemonTypeRepository;
private final S3Service s3Service;

@Override
public void run(ApplicationArguments args) {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("weather.txt");
saveData("weather.txt", fields -> {
Weather weather = createWeather(fields);
weatherRepository.save(weather);
});
saveData("battle-move.txt", fields -> {
BattleMove battleMove = createMove(fields);
battleMoveRepository.save(battleMove);
});
saveData("tms.txt", fields -> {
PokemonMovesByMachine pokemonMovesByMachine = createPokemonMovesByMachine(fields);
pokemonMovesByMachineRepository.save(pokemonMovesByMachine);
});
saveData("battle-pokemon.txt", fields -> {
PokemonMovesBySelf pokemonMovesBySelf = createPokemonMovesBySelf(fields);
pokemonMovesBySelfRepository.save(pokemonMovesBySelf);
PokemonMovesByEgg pokemonMovesByEgg = createPokemonMovesByEgg(fields);
pokemonMovesByEggRepository.save(pokemonMovesByEgg);
});
saveData("type.txt", fields -> {
PokemonType pokemonType = createPokemonType(fields);
battlePokemonTypeRepository.save(pokemonType);
});
}

private void saveData(String path, Consumer<List<String>> createAndSaveOperation) {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
int lineCount = 0;
String line;
while ((line = br.readLine()) != null) {
lineCount++;
if (lineCount < FIRST_LINE) {
if (lineCount < FIRST_LINE_NUMBER) {
continue;
}
Weather weather = createWeather(line);
weatherRepository.save(weather);
List<String> fields = splitFields(line);
createAndSaveOperation.accept(fields);
}
} catch (IOException e) {
log.error("error message : {}", e.getStackTrace()[0]);
log.error("error message : {}", e.getMessage(), e);
}
}

private Weather createWeather(String data) {
List<String> fields = Arrays.stream(data.split(FIELD_DELIMITER))
private List<String> splitFields(String line) {
return Arrays.stream(line.split(FIELD_DELIMITER))
.map(String::trim)
.toList();
}

private Weather createWeather(List<String> fields) {
String id = fields.get(0);
String name = fields.get(1);
String description = fields.get(2);
List<String> effects = Arrays.stream(fields.get(3).split(LIST_DELIMITER))
.map(String::trim)
.toList();

return new Weather(id, name, description, effects);
}

private String createId(String data) {
return data.replace(' ', '-');
private BattleMove createMove(List<String> fields) {
return new BattleMove(
fields.get(1), /* 우선은 한글 이름을 id로 설정, 추후 숫자로 변경 */
fields.get(1),
fields.get(2),
fields.get(3),
fields.get(4),
fields.get(5),
fields.get(6),
fields.get(7),
convertToInteger(fields.get(8)),
convertToInteger(fields.get(9)),
convertToInteger(fields.get(10)),
convertToInteger(fields.get(11)),
convertToInteger(fields.get(12)),
convertToInteger(fields.get(13)),
fields.get(14)
);
}

private PokemonMovesByMachine createPokemonMovesByMachine(List<String> fields) {
Integer pokedexNumber = convertToInteger(fields.get(0));
List<String> moveIds = Arrays.stream(fields.get(2).split(LIST_DELIMITER))
.map(String::trim)
.filter(s -> !s.isEmpty())
.toList();

return new PokemonMovesByMachine(pokedexNumber, moveIds);
}

private PokemonMovesBySelf createPokemonMovesBySelf(List<String> fields) {
Integer pokedexNumber = convertToInteger(fields.get(0));
List<String> moveIds = Arrays.stream(fields.get(19).split(LIST_DELIMITER))
.map(String::trim)
.filter(s -> !s.isEmpty())
.toList();

return new PokemonMovesBySelf(pokedexNumber, moveIds);
}

private PokemonMovesByEgg createPokemonMovesByEgg(List<String> fields) {
Integer pokedexNumber = convertToInteger(fields.get(0));
List<String> moveIds = Arrays.stream(fields.get(18).split(LIST_DELIMITER))
.map(String::trim)
.filter(s -> !s.isEmpty())
.toList();

return new PokemonMovesByEgg(pokedexNumber, moveIds);
}

private PokemonType createPokemonType(List<String> fields) {
String name = fields.get(0);
String engName = fields.get(1);
String image = s3Service.getPokerogueTypeImageFromS3(engName);

return new PokemonType(name, engName, image);
}


private Integer convertToInteger(String data) {
try {
return Integer.valueOf(data);
} catch (NumberFormatException e) {
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.pokerogue.helper.battle;

import com.pokerogue.helper.global.exception.ErrorMessage;
import com.pokerogue.helper.global.exception.GlobalCustomException;
import java.util.Arrays;
import lombok.Getter;

@Getter
public enum MoveCategory {

STATUS("status", "https://dl70s9ccojnge.cloudfront.net/pokerogue-helper/pokerogue/move-category/status.png"),
SPECIAL("special", "https://dl70s9ccojnge.cloudfront.net/pokerogue-helper/pokerogue/move-category/special.png"),
PHYSICAL("physical", "https://dl70s9ccojnge.cloudfront.net/pokerogue-helper/pokerogue/move-category/physical.png"),
;

private final String name;
private final String image;

MoveCategory(String name, String image) {
this.name = name;
this.image = image;
}

public static MoveCategory findByName(String name) {
return Arrays.stream(values())
.filter(category -> category.hasSameName(name))
.findAny()
.orElseThrow(() -> new GlobalCustomException(ErrorMessage.MOVE_CATEGORY_NOT_FOUND));
}

private boolean hasSameName(String name) {
return this.name.equals(name);
}
}
Loading

0 comments on commit 12ecdfe

Please sign in to comment.