Skip to content

Commit 45c8d35

Browse files
committed
DB config via yaml, move atomic filmlist, backwards compatibility
1 parent b6da2c9 commit 45c8d35

12 files changed

Lines changed: 93 additions & 25 deletions

File tree

src/main/java/de/mediathekview/mserver/base/config/MServerDBConfig.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,57 @@ public class MServerDBConfig {
77
private String url;
88
private String username;
99
private String password;
10+
private Integer refreshIntervalInDays;
11+
private Integer checkUrlIntervalInDays;
12+
private Integer batchSize;
1013

1114
public MServerDBConfig() {
12-
active = true;
15+
active = false;
1316
url = "jdbc:postgresql://postgresMV:55432/crawler";
1417
username = "crawler";
1518
password = "secret";
19+
refreshIntervalInDays = 7;
20+
checkUrlIntervalInDays = 3;
21+
batchSize = 2000;
1622
}
1723

18-
public MServerDBConfig(Boolean active, String url, String username, String password) {
24+
public MServerDBConfig(Boolean active, String url, String username, String password, int refreshIntervalInDays, int checkUrlIntervalInDays, int batchSize ) {
1925
this.active = active;
2026
this.url = url;
2127
this.username = username;
2228
this.password = password;
29+
this.refreshIntervalInDays = refreshIntervalInDays;
30+
this.checkUrlIntervalInDays = checkUrlIntervalInDays;
31+
this.batchSize = batchSize;
2332
}
2433

2534

2635

36+
public Integer getBatchSize() {
37+
return batchSize;
38+
}
39+
40+
public void setBatchSize(Integer batchSize) {
41+
this.batchSize = batchSize;
42+
}
43+
44+
public Integer getRefreshIntervalInDays() {
45+
return refreshIntervalInDays;
46+
}
47+
48+
public void setRefreshIntervalInDays(Integer refreshIntervalInDays) {
49+
this.refreshIntervalInDays = refreshIntervalInDays;
50+
}
51+
52+
public Integer getCheckUrlIntervalInDays() {
53+
return checkUrlIntervalInDays;
54+
}
55+
56+
public void setCheckUrlIntervalInDays(Integer checkUrlIntervalInDays) {
57+
this.checkUrlIntervalInDays = checkUrlIntervalInDays;
58+
}
59+
60+
2761
public Boolean getActive() {
2862
return active;
2963
}

src/main/java/de/mediathekview/mserver/base/uploader/copy/FileCopyTask.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ protected void upload() {
3232
Path backup = backupExistingFile(target);
3333
LOG.debug("CopyTask found existing file - rename existing file to {} before overwrite", backup.getFileName());
3434
}
35-
Files.copy(sourcePath, uploadTarget.getTargetPath(), StandardCopyOption.REPLACE_EXISTING);
35+
Path tmpTarget = Files.createTempFile( uploadTarget.getTargetPath().getParent(), uploadTarget.getTargetPath().getFileName().toString(), ".tmp");
36+
Files.copy(sourcePath, tmpTarget, StandardCopyOption.REPLACE_EXISTING);
37+
Files.move(tmpTarget, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
3638
} catch (final IOException ioException) {
3739
LOG.error("Something went wrong on copying the film list.", ioException);
3840
printMessage(ServerMessages.FILE_COPY_ERROR);

src/main/java/de/mediathekview/mserver/base/utils/FilmDBService.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ public class FilmDBService {
4545
private final Gson gson;
4646
private final ExecutorService executorService;
4747
private final int batchSize;
48+
private final Integer refreshIntervalInDays;
4849

49-
public FilmDBService(ExecutorService executorService, int batchSize) {
50+
public FilmDBService(ExecutorService executorService, int batchSize, int refreshIntervalInDays) {
5051
this.dataSource = PostgreSQLDataSourceProvider.get();
5152
this.executorService = executorService;
5253
this.batchSize = batchSize;
54+
this.refreshIntervalInDays = refreshIntervalInDays;
5355

5456
this.gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new GsonLocalDateTimeAdapter())
5557
.registerTypeAdapter(Duration.class, new GsonDurationAdapter()).create();
@@ -153,10 +155,14 @@ public <T> List<T> filterNewVideos(Sender sender, List<T> videos, Function<T, St
153155
List<T> batch = allVideos.subList(from, to);
154156
futures.add(executorService.submit(() -> {
155157
List<T> newVideos = new ArrayList<>();
156-
// update every 7 days
157-
String sql = "UPDATE filme SET last_seen = now() WHERE id = ? AND last_seen - last_update <= interval '7' DAY";
158-
159-
try (Connection con = dataSource.getConnection(); PreparedStatement ps = con.prepareStatement(sql)) {
158+
StringBuffer sql = new StringBuffer();
159+
sql.append("UPDATE filme SET last_seen = now() ")
160+
.append("WHERE id = ? AND (")
161+
.append("( cast(created_at as date) = cast(last_update as date) and cast(created_at as date) <> cast(now() as date) )")
162+
.append(" OR ")
163+
.append("(last_seen - last_update <= interval '").append(refreshIntervalInDays).append("' DAY)")
164+
.append(")");
165+
try (Connection con = dataSource.getConnection(); PreparedStatement ps = con.prepareStatement(sql.toString())) {
160166

161167
for (T video : batch) {
162168
String id = idExtractor.apply(video);

src/main/java/de/mediathekview/mserver/crawler/CrawlerManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public MServerConfigManager getConfigManager() {
9595
}
9696

9797
public void storeFilmsToDB() {
98-
FilmDBService filmDBService = new FilmDBService(executorService, 200);
98+
FilmDBService filmDBService = new FilmDBService(executorService, getConfigManager().getConfig().getDatabaseConfig().getBatchSize(), getConfigManager().getConfig().getDatabaseConfig().getRefreshIntervalInDays());
9999
try {
100100
filmDBService.saveAll(filmlist);
101101
} catch (Exception e) {
@@ -459,7 +459,7 @@ private Set<AbstractCrawler> getCrawlerToRun() {
459459
}
460460

461461
private Optional<Filmlist> importFilmlistFromDB() throws IOException {
462-
FilmDBService filmDBService = new FilmDBService(getExecutorService(), 2000);
462+
FilmDBService filmDBService = new FilmDBService(getExecutorService(), getConfigManager().getConfig().getDatabaseConfig().getBatchSize(), getConfigManager().getConfig().getDatabaseConfig().getRefreshIntervalInDays());
463463
Optional<Filmlist> dbFilmlist = filmDBService.readFilmlistFromDB();
464464
return dbFilmlist;
465465
}

src/main/java/de/mediathekview/mserver/crawler/ard/ArdCrawler.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import org.apache.logging.log4j.LogManager;
1414
import org.apache.logging.log4j.Logger;
1515

16-
import java.time.format.DateTimeFormatter;
1716
import java.util.Collection;
1817
import java.util.HashSet;
1918
import java.util.List;
@@ -24,8 +23,6 @@
2423
public class ArdCrawler extends AbstractCrawler {
2524

2625
private static final Logger LOG = LogManager.getLogger(ArdCrawler.class);
27-
private static final DateTimeFormatter DAY_PAGE_DATE_FORMATTER =
28-
DateTimeFormatter.ofPattern("yyyy-MM-dd");
2926

3027
public ArdCrawler(
3128
final ForkJoinPool aForkJoinPool,

src/main/java/de/mediathekview/mserver/crawler/basic/AbstractCrawler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ protected AbstractCrawler(
7171
rootConfig.getSenderConfig(getSender()).getSocketTimeoutInSeconds(),
7272
runtimeConfig.getMaximumCpuThreads());
7373
rateLimiter = RateLimiter.create(rootConfig.getSenderConfig(getSender()).getMaximumRequestsPerSecond());
74-
filmDBService = new FilmDBService(forkJoinPool, 200);
74+
filmDBService = new FilmDBService(forkJoinPool, getRuntimeConfig().getDatabaseConfig().getBatchSize(), getRuntimeConfig().getDatabaseConfig().getRefreshIntervalInDays());
7575
films = ConcurrentHashMap.newKeySet();
7676
}
7777

src/main/java/de/mediathekview/mserver/crawler/dw/tasks/DwFilmDetailTask.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import de.mediathekview.mserver.daten.Film;
55
import de.mediathekview.mserver.crawler.basic.AbstractCrawler;
66
import de.mediathekview.mserver.crawler.basic.AbstractRecursiveConverterTask;
7-
import de.mediathekview.mserver.crawler.basic.CrawlerUrlDTO;
87
import de.mediathekview.mserver.crawler.basic.TopicUrlDTO;
98
import de.mediathekview.mserver.crawler.dw.DWTaskBase;
109
import de.mediathekview.mserver.crawler.dw.parser.DwFilmDetailDeserializer;
@@ -46,7 +45,8 @@ protected void processRestTarget(final TopicUrlDTO aDTO, final WebTarget aTarget
4645
} catch (Exception e) {
4746
LOG.error("error processing {} ", aDTO.getUrl(), e);
4847
}
49-
if (filmDetailDtoOptional.isEmpty()) {
48+
// Optional can be null if response code is 200 and response body is empty
49+
if (filmDetailDtoOptional == null || filmDetailDtoOptional.isEmpty()) {
5050
crawler.incrementAndGetErrorCount();
5151
crawler.updateProgress();
5252
return;

src/main/java/de/mediathekview/mserver/crawler/zdf/tasks/ZdfFilmTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private static void updateTitle(final String aLanguage, final Film aFilm) {
108108
@Override
109109
protected void processRestTarget(ZdfFilmDto aDTO, WebTarget aTarget) {
110110
final Optional<DownloadDto> downloadDto =
111-
deserialize(aTarget, OPTIONAL_DOWNLOAD_DTO_TYPE_TOKEN);
111+
deserializeOptional(aTarget, OPTIONAL_DOWNLOAD_DTO_TYPE_TOKEN);
112112
if (downloadDto.isPresent()) {
113113
try {
114114
addFilm(downloadDto.get(), createFilm(aDTO, downloadDto.get()), aDTO.getVideoType());

src/main/java/de/mediathekview/mserver/filmlisten/writer/AbstractFilmlistWriter.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
import java.io.FileOutputStream;
99
import java.io.IOException;
1010
import java.io.OutputStream;
11+
import java.nio.file.Files;
1112
import java.nio.file.Path;
13+
import java.nio.file.StandardCopyOption;
14+
1215
import org.apache.logging.log4j.LogManager;
1316
import org.apache.logging.log4j.Logger;
1417

@@ -26,9 +29,17 @@ protected AbstractFilmlistWriter(final MessageListener... aListeners) {
2629
public abstract boolean write(Filmlist filmlist, OutputStream outputStream) throws IOException;
2730

2831
public boolean write(Filmlist filmlist, Path savePath) {
29-
try (final OutputStream os = new FileOutputStream(savePath.toFile());
30-
final BufferedOutputStream fos = new BufferedOutputStream(os, 512000)) {
31-
return write(filmlist, fos);
32+
try {
33+
Path tmpTarget = Files.createTempFile( savePath.getParent(), savePath.getFileName().toString(), ".tmp");
34+
try (final OutputStream os = new FileOutputStream(tmpTarget.toFile());
35+
final BufferedOutputStream fos = new BufferedOutputStream(os, 512000)) {
36+
boolean succuess = write(filmlist, fos);
37+
fos.close();
38+
if (succuess) {
39+
Files.move(tmpTarget, savePath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
40+
}
41+
return succuess;
42+
}
3243
} catch (final IOException ioException) {
3344
LOG.debug("Something went wrong on writing the film list.", ioException);
3445
publishMessage(FilmListMessages.FILMLIST_WRITE_ERROR, savePath.toAbsolutePath().toString());

src/main/java/de/mediathekview/mserver/filmlisten/writer/FilmlistOldFormatWriter.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.io.OutputStreamWriter;
1717
import java.net.URL;
1818
import java.nio.charset.StandardCharsets;
19+
import java.time.LocalDateTime;
1920
import java.time.LocalTime;
2021
import java.time.ZoneId;
2122
import java.time.ZoneOffset;
@@ -41,6 +42,7 @@ public class FilmlistOldFormatWriter extends AbstractFilmlistWriter {
4142
private static final char GEO_SPLITTERATOR = '-';
4243
private static final DateTimeFormatter DATE_TIME_FORMAT =
4344
DateTimeFormatter.ofLocalizedDateTime(MEDIUM, SHORT).withLocale(Locale.GERMANY);
45+
private static final LocalDateTime EMPTY_DATE_TIME= LocalDateTime.of(1970, 1, 1, 00, 00, 00);
4446

4547
private static final String META_HEADER_VERSION = "4";
4648
private static final String META_HEADER_VERSION_LONG = "MSearch [Vers.: 4.0.1]";
@@ -196,10 +198,16 @@ private String writeRecord03Titel(AbstractMediaResource<?> in) {
196198
}
197199

198200
private String writeRecord04Datum(AbstractMediaResource<?> in) {
201+
if(in.getTime().isEqual(EMPTY_DATE_TIME)) {
202+
return "";
203+
}
199204
return in.getTime().format(DATE_FORMATTER);
200205
}
201206

202207
private String writeRecord05Zeit(AbstractMediaResource<?> in) {
208+
if(in.getTime().isEqual(EMPTY_DATE_TIME)) {
209+
return "";
210+
}
203211
return in.getTime().format(TIME_FORMATTER);
204212
}
205213

@@ -211,7 +219,7 @@ private String writeRecord06Dauer(AbstractMediaResource<?> in) {
211219
}
212220

213221
private String writeRecord07Groesse(AbstractMediaResource<?> in) {
214-
if ((in instanceof Podcast pIn) && pIn.getUrl(Resolution.NORMAL) != null)
222+
if ((in instanceof Podcast pIn) && pIn.getUrl(Resolution.NORMAL) != null && pIn.getUrl(Resolution.NORMAL).getFileSize() != 0)
215223
return (pIn.getUrl(Resolution.NORMAL).getFileSize()/1024) + "";
216224
return "";
217225
}

0 commit comments

Comments
 (0)