use of com.faendir.zachtronics.bot.repository.CategoryRecord in project zachtronics-leaderboard-bot by F43nd1r.
the class IfController method getRecord.
@GetMapping(path = "/puzzle/{puzzleId}/category/{categoryId}/record", produces = MediaType.APPLICATION_JSON_VALUE)
public IfRecordDTO getRecord(@PathVariable String puzzleId, @PathVariable String categoryId) {
IfPuzzle puzzle = findPuzzle(puzzleId);
IfCategory category = findCategory(categoryId);
IfRecord record = repository.find(puzzle, category);
if (record != null)
return IfRecordDTO.fromCategoryRecord(new CategoryRecord<>(record, EnumSet.of(category)));
else
return null;
}
use of com.faendir.zachtronics.bot.repository.CategoryRecord in project zachtronics-leaderboard-bot by F43nd1r.
the class SzSolutionRepository method archiveOne.
/**
* @param solutions the list is modified with the updated state
*/
@Override
@NotNull
protected SubmitResult<SzRecord, SzCategory> archiveOne(@NotNull GitRepository.ReadWriteAccess access, @NotNull List<SzSolution> solutions, @NotNull SzSubmission submission) {
SzPuzzle puzzle = submission.getPuzzle();
Path puzzlePath = getPuzzlePath(access, puzzle);
List<CategoryRecord<SzRecord, SzCategory>> beatenCategoryRecords = new ArrayList<>();
SzSolution candidate = new SzSolution(submission.getScore(), submission.getAuthor());
try {
for (ListIterator<SzSolution> it = solutions.listIterator(); it.hasNext(); ) {
SzSolution solution = it.next();
int r = dominanceCompare(candidate.getScore(), solution.getScore());
if (r > 0) {
// TODO actually return all of the beating sols
CategoryRecord<SzRecord, SzCategory> categoryRecord = solution.extendToCategoryRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore()));
return new SubmitResult.NothingBeaten<>(Collections.singletonList(categoryRecord));
} else if (r < 0) {
// allow same-score solution changes only if you are the original author
if (candidate.getScore().equals(solution.getScore()) && !candidate.getAuthor().equals(solution.getAuthor())) {
return new SubmitResult.AlreadyPresent<>();
}
// remove beaten score and get categories
candidate.getCategories().addAll(solution.getCategories());
Files.delete(makeArchivePath(puzzlePath, solution.getScore()));
// the beaten record has no data anymore
beatenCategoryRecords.add(solution.extendToCategoryRecord(puzzle, null, null));
it.remove();
}
}
// the new record may have gained categories of records it didn't pareto-beat, do the transfers
for (SzSolution solution : solutions) {
EnumSet<SzCategory> lostCategories = EnumSet.noneOf(SzCategory.class);
for (SzCategory category : solution.getCategories()) {
if (category.supportsScore(candidate.getScore()) && category.getScoreComparator().compare(candidate.getScore(), solution.getScore()) < 0) {
lostCategories.add(category);
}
}
if (!lostCategories.isEmpty()) {
// add a CR holding the lost categories, then correct the solutions
CategoryRecord<SzRecord, SzCategory> beatenCR = new CategoryRecord<>(solution.extendToRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore())), lostCategories);
beatenCategoryRecords.add(beatenCR);
solution.getCategories().removeAll(lostCategories);
candidate.getCategories().addAll(lostCategories);
}
}
int index = Collections.binarySearch(solutions, candidate, COMPARATOR);
if (index < 0) {
index = -index - 1;
}
solutions.add(index, candidate);
String filename = makeFilename(submission.getPuzzle().getId(), candidate.getScore());
Path solutionPath = puzzlePath.resolve(filename);
// ensure there is one and only one newline at the end
String data = submission.getData().replaceFirst("\\s*$", "\n");
Files.writeString(solutionPath, data, StandardOpenOption.CREATE_NEW);
marshalSolutions(solutions, puzzlePath);
} catch (IOException e) {
// failures could happen after we dirtied the repo, so we call reset&clean on the puzzle dir
access.resetAndClean(puzzlePath.toFile());
return new SubmitResult.Failure<>(e.toString());
}
if (access.status().isClean()) {
// the same exact sol was already archived,
return new SubmitResult.AlreadyPresent<>();
}
String result = commit(access, submission, puzzlePath);
return new SubmitResult.Success<>(result, beatenCategoryRecords);
}
use of com.faendir.zachtronics.bot.repository.CategoryRecord in project zachtronics-leaderboard-bot by F43nd1r.
the class SzController method getRecord.
@Override
public SzRecordDTO getRecord(@NotNull String puzzleId, @NotNull String categoryId) {
SzPuzzle puzzle = findPuzzle(puzzleId);
SzCategory category = findCategory(categoryId);
SzRecord record = repository.find(puzzle, category);
if (record != null)
return SzRecordDTO.fromCategoryRecord(new CategoryRecord<>(record, EnumSet.of(category)));
else
return null;
}
use of com.faendir.zachtronics.bot.repository.CategoryRecord in project zachtronics-leaderboard-bot by F43nd1r.
the class ScSolutionRepository method archiveOne.
/**
* @param solutions the list is modified with the updated state
*/
@Override
@NotNull
protected SubmitResult<ScRecord, ScCategory> archiveOne(@NotNull GitRepository.ReadWriteAccess access, @NotNull List<ScSolution> solutions, @NotNull ScSubmission submission) {
ScPuzzle puzzle = submission.getPuzzle();
Path puzzlePath = getPuzzlePath(access, puzzle);
List<CategoryRecord<ScRecord, ScCategory>> beatenCategoryRecords = new ArrayList<>();
ScSolution candidate = new ScSolution(submission.getScore(), submission.getAuthor(), submission.getDisplayLink(), false);
try {
for (ListIterator<ScSolution> it = solutions.listIterator(); it.hasNext(); ) {
ScSolution solution = it.next();
int r = dominanceCompare(candidate.getScore(), solution.getScore());
if (r > 0) {
// TODO actually return all of the beating sols
CategoryRecord<ScRecord, ScCategory> categoryRecord = solution.extendToCategoryRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore()));
return new SubmitResult.NothingBeaten<>(Collections.singletonList(categoryRecord));
} else if (r < 0) {
// allow same-score changes if you bring a video or you are the original author and don't regress the video state
if (candidate.getScore().equals(solution.getScore()) && candidate.getDisplayLink() == null && !(candidate.getAuthor().equals(solution.getAuthor()) && solution.getDisplayLink() == null)) {
return new SubmitResult.AlreadyPresent<>();
}
// remove beaten score and get categories
candidate.getCategories().addAll(solution.getCategories());
if (// video-only sols have no data
!solution.isVideoOnly())
Files.delete(makeArchivePath(puzzlePath, solution.getScore()));
// the beaten record has no data anymore
beatenCategoryRecords.add(solution.extendToCategoryRecord(puzzle, null, null));
if (candidate.getDisplayLink() == null && solution.getDisplayLink() != null) {
// we beat the solution, but we can't replace the video, we keep the solution entry as a video-only
// empty categories
it.set(solution.withVideoOnly(true));
} else {
it.remove();
}
}
}
// the new record may have gained categories of records it didn't pareto-beat, do the transfers
for (ScSolution solution : solutions) {
EnumSet<ScCategory> lostCategories = EnumSet.noneOf(ScCategory.class);
for (ScCategory category : solution.getCategories()) {
if (category.supportsScore(candidate.getScore()) && category.getScoreComparator().compare(candidate.getScore(), solution.getScore()) < 0) {
lostCategories.add(category);
}
}
if (!lostCategories.isEmpty()) {
// add a CR holding the lost categories, then correct the solutions
CategoryRecord<ScRecord, ScCategory> beatenCR = new CategoryRecord<>(solution.extendToRecord(puzzle, makeArchiveLink(puzzle, solution.getScore()), makeArchivePath(puzzlePath, solution.getScore())), lostCategories);
beatenCategoryRecords.add(beatenCR);
solution.getCategories().removeAll(lostCategories);
candidate.getCategories().addAll(lostCategories);
}
}
int index = Collections.binarySearch(solutions, candidate, COMPARATOR);
if (index < 0) {
index = -index - 1;
}
solutions.add(index, candidate);
String filename = makeScoreFilename(candidate.getScore());
Path solutionPath = puzzlePath.resolve(filename);
// ensure there is one and only one newline at the end
String data = submission.getData().replaceFirst("\\s*$", "\n");
Files.writeString(solutionPath, data, StandardOpenOption.CREATE_NEW);
marshalSolutions(solutions, puzzlePath);
} catch (IOException e) {
// failures could happen after we dirtied the repo, so we call reset&clean on the puzzle dir
access.resetAndClean(puzzlePath.toFile());
return new SubmitResult.Failure<>(e.toString());
}
if (access.status().isClean()) {
// the same exact sol was already archived,
return new SubmitResult.AlreadyPresent<>();
}
String result = commit(access, submission, puzzlePath);
return new SubmitResult.Success<>(result, beatenCategoryRecords);
}
use of com.faendir.zachtronics.bot.repository.CategoryRecord in project zachtronics-leaderboard-bot by F43nd1r.
the class SolRepoFindTest method testFindCategoryHolders.
@Test
public void testFindCategoryHolders() {
ScPuzzle puzzle = ScPuzzle.research_example_1;
List<CategoryRecord<ScRecord, ScCategory>> categoryHolders = repository.findCategoryHolders(puzzle, false);
assertEquals(2, categoryHolders.size());
List<ScCategory> coveredCategories = categoryHolders.stream().map(CategoryRecord::getCategories).flatMap(Set::stream).sorted().toList();
assertEquals(puzzle.getSupportedCategories(), coveredCategories);
}
Aggregations