refactor(providers): replace provider status string with boolean for simplicity
This commit is contained in:
parent
76c71dbd81
commit
0032e032fe
@ -1,71 +0,0 @@
|
||||
# .pipeline.yml
|
||||
# -----------------
|
||||
# Build, publish, and deploy Java Spring Boot app
|
||||
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: maven:3.9.11-eclipse-temurin-25
|
||||
commands:
|
||||
- echo "🧪 Building and testing Spring Boot app...."
|
||||
- mvn -B clean verify
|
||||
when:
|
||||
- event: pull_request
|
||||
branch: [main, develop]
|
||||
- event: push
|
||||
branch: [ main, develop ]
|
||||
|
||||
- name: publish-image
|
||||
depends_on: [ test ]
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
platforms: linux/amd64
|
||||
repo: git.badger-pirarucu.ts.net/mangamochi/backend
|
||||
registry: git.badger-pirarucu.ts.net
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
username:
|
||||
from_secret: DOCKER_USER
|
||||
password:
|
||||
from_secret: DOCKER_PASSWORD
|
||||
tags:
|
||||
- latest
|
||||
- ${CI_COMMIT_SHA}
|
||||
when:
|
||||
event: [ push ]
|
||||
branch: [ main ]
|
||||
|
||||
- name: deploy
|
||||
depends_on: [ publish-image ]
|
||||
image: alpine:3.20
|
||||
environment:
|
||||
DEPLOY_USER: rov
|
||||
DEPLOY_HOST: mangamochi.badger-pirarucu.ts.net
|
||||
DEPLOY_PORT: 22
|
||||
IMAGE: git.badger-pirarucu.ts.net/mangamochi/backend:${CI_COMMIT_SHA}
|
||||
DEPLOY_SSH_KEY:
|
||||
from_secret: DEPLOY_SSH_KEY
|
||||
commands:
|
||||
- echo "🚀 Deploying to $DEPLOY_HOST..."
|
||||
- apk add --no-cache openssh-client docker-cli
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- ssh-keyscan -p $DEPLOY_PORT $DEPLOY_HOST >> ~/.ssh/known_hosts
|
||||
- >
|
||||
ssh -p $DEPLOY_PORT $DEPLOY_USER@$DEPLOY_HOST "
|
||||
docker pull $IMAGE &&
|
||||
docker stop mangamochi-backend 2>/dev/null || true &&
|
||||
docker rm mangamochi-backend 2>/dev/null || true &&
|
||||
docker run -d --name mangamochi-backend \
|
||||
--restart always \
|
||||
--network host \
|
||||
--env-file /home/rov/mangamochi/.env \
|
||||
-p 8080:8080 \
|
||||
$IMAGE
|
||||
"
|
||||
when:
|
||||
event: [ push ]
|
||||
branch: [ main ]
|
||||
@ -6,7 +6,6 @@ import com.magamochi.mangamochi.model.entity.Manga;
|
||||
import com.magamochi.mangamochi.model.entity.MangaAlternativeTitle;
|
||||
import com.magamochi.mangamochi.model.entity.MangaChapter;
|
||||
import com.magamochi.mangamochi.model.entity.MangaProvider;
|
||||
import com.magamochi.mangamochi.model.enumeration.ProviderStatus;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.OffsetDateTime;
|
||||
@ -54,7 +53,7 @@ public record MangaDTO(
|
||||
public record MangaProviderDTO(
|
||||
@NotNull long id,
|
||||
@NotBlank String providerName,
|
||||
@NotNull ProviderStatus providerStatus,
|
||||
boolean active,
|
||||
@NotNull Integer chaptersAvailable,
|
||||
@NotNull Integer chaptersDownloaded,
|
||||
@NotNull Boolean supportsChapterFetch) {
|
||||
@ -66,7 +65,7 @@ public record MangaDTO(
|
||||
return new MangaProviderDTO(
|
||||
mangaProvider.getId(),
|
||||
mangaProvider.getProvider().getName(),
|
||||
mangaProvider.getProvider().getStatus(),
|
||||
mangaProvider.getProvider().isActive(),
|
||||
chaptersAvailable,
|
||||
chaptersDownloaded,
|
||||
mangaProvider.getProvider().getSupportsChapterFetch());
|
||||
|
||||
@ -2,6 +2,7 @@ package com.magamochi.mangamochi.model.dto;
|
||||
|
||||
import com.magamochi.mangamochi.model.entity.*;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public record ProviderListDTO(@NotNull List<ProviderDTO> providers) {
|
||||
@ -9,9 +10,11 @@ public record ProviderListDTO(@NotNull List<ProviderDTO> providers) {
|
||||
return new ProviderListDTO(providers.stream().map(ProviderDTO::from).toList());
|
||||
}
|
||||
|
||||
record ProviderDTO(@NotNull Long id, @NotNull String name) {
|
||||
record ProviderDTO(
|
||||
@NotNull Long id, @NotNull String name, boolean active, Instant listLastUpdatedAt) {
|
||||
public static ProviderDTO from(Provider provider) {
|
||||
return new ProviderDTO(provider.getId(), provider.getName());
|
||||
return new ProviderDTO(
|
||||
provider.getId(), provider.getName(), provider.isActive(), provider.getListUpdatedAt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.magamochi.mangamochi.model.entity;
|
||||
|
||||
import com.magamochi.mangamochi.model.enumeration.ProviderStatus;
|
||||
import jakarta.persistence.*;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@ -22,8 +21,7 @@ public class Provider {
|
||||
|
||||
private String name;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ProviderStatus status;
|
||||
private boolean active;
|
||||
|
||||
@CreationTimestamp private Instant createdAt;
|
||||
|
||||
@ -35,4 +33,6 @@ public class Provider {
|
||||
@Builder.Default private Boolean supportsChapterFetch = true;
|
||||
|
||||
@Builder.Default private Boolean manualImport = false;
|
||||
|
||||
private Instant listUpdatedAt;
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
package com.magamochi.mangamochi.model.enumeration;
|
||||
|
||||
public enum ProviderStatus {
|
||||
ACTIVE,
|
||||
INACTIVE
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.magamochi.mangamochi.model.repository;
|
||||
import com.magamochi.mangamochi.model.entity.Manga;
|
||||
import com.magamochi.mangamochi.model.entity.MangaProvider;
|
||||
import com.magamochi.mangamochi.model.entity.Provider;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
@ -11,4 +12,6 @@ public interface MangaProviderRepository extends JpaRepository<MangaProvider, Lo
|
||||
|
||||
Optional<MangaProvider> findByMangaTitleIgnoreCaseAndProvider(
|
||||
String mangaTitle, Provider provider);
|
||||
|
||||
boolean existsByMangaTitleIgnoreCaseAndProvider(@NotBlank String title, Provider provider);
|
||||
}
|
||||
|
||||
@ -2,12 +2,16 @@ package com.magamochi.mangamochi.service;
|
||||
|
||||
import static java.util.Objects.isNull;
|
||||
|
||||
import com.magamochi.mangamochi.model.dto.ContentProviderMangaInfoResponseDTO;
|
||||
import com.magamochi.mangamochi.model.entity.MangaProvider;
|
||||
import com.magamochi.mangamochi.model.entity.Provider;
|
||||
import com.magamochi.mangamochi.model.repository.MangaProviderRepository;
|
||||
import com.magamochi.mangamochi.service.providers.PagedContentProviderFactory;
|
||||
import java.time.Instant;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Log4j2
|
||||
@Service
|
||||
@ -16,43 +20,39 @@ public class MangaListService {
|
||||
private final ProviderService providerService;
|
||||
private final MangaCreationService mangaCreationService;
|
||||
private final PagedContentProviderFactory pagedContentProviderFactory;
|
||||
|
||||
private final MangaProviderRepository mangaProviderRepository;
|
||||
|
||||
@Transactional
|
||||
public void updateMangaList(String contentProviderName, Integer page) {
|
||||
var contentProvider = pagedContentProviderFactory.getPagedContentProvider(contentProviderName);
|
||||
var provider = providerService.getOrCreateProvider(contentProviderName);
|
||||
|
||||
var mangas = contentProvider.getMangasFromPage(page);
|
||||
|
||||
mangas.forEach(
|
||||
mangaResponse -> {
|
||||
var mangaProvider =
|
||||
mangaProviderRepository.findByMangaTitleIgnoreCaseAndProvider(
|
||||
mangaResponse.title(), provider);
|
||||
mangas.forEach(mangaResponse -> processManga(mangaResponse, provider));
|
||||
|
||||
if (mangaProvider.isPresent()) {
|
||||
return;
|
||||
}
|
||||
provider.setListUpdatedAt(Instant.now());
|
||||
}
|
||||
|
||||
var manga =
|
||||
mangaCreationService.getOrCreateManga(
|
||||
mangaResponse.title(), mangaResponse.url(), provider);
|
||||
private void processManga(ContentProviderMangaInfoResponseDTO mangaResponse, Provider provider) {
|
||||
if (mangaProviderRepository.existsByMangaTitleIgnoreCaseAndProvider(
|
||||
mangaResponse.title(), provider)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNull(manga)) {
|
||||
return;
|
||||
}
|
||||
var manga =
|
||||
mangaCreationService.getOrCreateManga(mangaResponse.title(), mangaResponse.url(), provider);
|
||||
|
||||
if (!mangaProviderRepository.existsByMangaAndProviderAndUrlIgnoreCase(
|
||||
manga, provider, mangaResponse.url())) {
|
||||
mangaProviderRepository.save(
|
||||
MangaProvider.builder()
|
||||
.manga(manga)
|
||||
.mangaTitle(mangaResponse.title())
|
||||
.provider(provider)
|
||||
.url(mangaResponse.url())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
if (isNull(manga)) {
|
||||
log.warn("Failed to create manga: {}", mangaResponse.title());
|
||||
return;
|
||||
}
|
||||
|
||||
mangaProviderRepository.save(
|
||||
MangaProvider.builder()
|
||||
.manga(manga)
|
||||
.mangaTitle(mangaResponse.title())
|
||||
.provider(provider)
|
||||
.url(mangaResponse.url())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import com.magamochi.mangamochi.exception.NotFoundException;
|
||||
import com.magamochi.mangamochi.model.dto.ImportMangaResponseDTO;
|
||||
import com.magamochi.mangamochi.model.dto.ImportRequestDTO;
|
||||
import com.magamochi.mangamochi.model.entity.*;
|
||||
import com.magamochi.mangamochi.model.enumeration.ProviderStatus;
|
||||
import com.magamochi.mangamochi.model.repository.*;
|
||||
import com.magamochi.mangamochi.service.providers.ManualImportContentProviderFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -63,7 +62,7 @@ public class ProviderManualMangaImportService {
|
||||
.findById(providerId)
|
||||
.orElseThrow(() -> new NotFoundException("Provider not found"));
|
||||
|
||||
if (!provider.getStatus().equals(ProviderStatus.ACTIVE)) {
|
||||
if (!provider.isActive()) {
|
||||
throw new IllegalStateException("Provider is not active");
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import static java.util.Objects.nonNull;
|
||||
|
||||
import com.magamochi.mangamochi.model.dto.ProviderListDTO;
|
||||
import com.magamochi.mangamochi.model.entity.Provider;
|
||||
import com.magamochi.mangamochi.model.enumeration.ProviderStatus;
|
||||
import com.magamochi.mangamochi.model.repository.ProviderRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -36,7 +35,7 @@ public class ProviderService {
|
||||
providerRepository.save(
|
||||
Provider.builder()
|
||||
.name(providerName)
|
||||
.status(ProviderStatus.ACTIVE)
|
||||
.active(true)
|
||||
.supportsChapterFetch(supportsChapterFetch)
|
||||
.build()));
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package com.magamochi.mangamochi.task;
|
||||
|
||||
import com.magamochi.mangamochi.model.dto.UpdateMangaFollowChapterListCommand;
|
||||
import com.magamochi.mangamochi.model.entity.Manga;
|
||||
import com.magamochi.mangamochi.model.enumeration.ProviderStatus;
|
||||
import com.magamochi.mangamochi.model.repository.MangaRepository;
|
||||
import com.magamochi.mangamochi.queue.UpdateMangaFollowChapterListProducer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -46,8 +45,7 @@ public class MangaFollowUpdateTask {
|
||||
var mangaProviders = manga.getMangaProviders();
|
||||
|
||||
mangaProviders.stream()
|
||||
.filter(
|
||||
mangaProvider -> mangaProvider.getProvider().getStatus().equals(ProviderStatus.ACTIVE))
|
||||
.filter(mangaProvider -> mangaProvider.getProvider().isActive())
|
||||
.forEach(
|
||||
mangaProvider ->
|
||||
producer.sendUpdateMangaFollowChapterListCommand(
|
||||
|
||||
20
src/main/resources/db/migration/V0021__PROVIDERS_ACTIVE.sql
Normal file
20
src/main/resources/db/migration/V0021__PROVIDERS_ACTIVE.sql
Normal file
@ -0,0 +1,20 @@
|
||||
ALTER TABLE providers
|
||||
ADD COLUMN IF NOT EXISTS list_updated_at TIMESTAMP;
|
||||
|
||||
DO
|
||||
$$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'providers'
|
||||
AND column_name = 'status') THEN
|
||||
ALTER TABLE providers
|
||||
ALTER COLUMN status TYPE boolean
|
||||
USING (status = 'ACTIVE');
|
||||
|
||||
ALTER TABLE providers
|
||||
RENAME COLUMN status TO active;
|
||||
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
Loading…
x
Reference in New Issue
Block a user