Skip to content

Commit

Permalink
ARTE: handle Collections in CategoryFilmList
Browse files Browse the repository at this point in the history
  • Loading branch information
alex1702 committed May 28, 2022
2 parents 6fafc76 + ee0a47f commit e230651
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 35 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8
group = 'de.mediathekview'
archivesBaseName = "MServer"
version = '3.1.196'
version = '3.1.197'

def jarName = 'MServer.jar'
def mainClass = 'mServer.Main'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import de.mediathekview.mlib.tool.Log;

import java.lang.reflect.Type;

/**
Expand All @@ -25,7 +27,17 @@ public ArteCategoryFilmsDTO deserialize(JsonElement aJsonElement, Type aType, Js
for (JsonElement jsonElement : aJsonElement.getAsJsonObject().get(JSON_ELEMENT_DATA).getAsJsonArray()) {
String programId = jsonElement.getAsJsonObject().get(JSON_ELEMENT_PROGRAMID).getAsString();
if (programId != null) {
dto.addProgramId(programId);
if (programId.startsWith("RC-")) {
// add 1 to collection id to get list of episodes
try {
long collectionId = Long.parseLong(programId.replace("RC-", "")) + 1;
dto.addCollection(String.format("RC-%06d", collectionId));
} catch (NumberFormatException e) {
Log.errorLog(12834939, "Invalid collection id: " + programId);
}
} else {
dto.addProgramId(programId);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@
public class ArteCategoryFilmsDTO {

private final ArrayList<String> programIds = new ArrayList<>();
private final ArrayList<String> collectionIds = new ArrayList<>();

private boolean hasNextPage;

public void addProgramId(String aProgramId) {
programIds.add(aProgramId);
}
public void addCollection(String aCollectionId) {
collectionIds.add(aCollectionId);
}

public ArrayList<String> getProgramIds() {
return programIds;
}
public ArrayList<String> getCollectionIds() {
return collectionIds;
}

public boolean hasNextPage() {
return hasNextPage;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package mServer.crawler.sender.arte;

import com.google.gson.*;
import mServer.crawler.sender.base.JsonUtils;

import java.lang.reflect.Type;

public class ArteCollectionDeserializer implements JsonDeserializer<ArteCategoryFilmsDTO> {
private static final String ATTRIBUTE_PROGRAM_ID = "programId";
private static final String ELEMENT_PROGRAMS = "programs";
private static final String ELEMENT_VIDEOS = "videos";

public ArteCategoryFilmsDTO deserialize(
final JsonElement aJsonElement,
final Type aType,
final JsonDeserializationContext aJsonDeserializationContext)
throws JsonParseException {
final ArteCategoryFilmsDTO result = new ArteCategoryFilmsDTO();
if (aJsonElement.isJsonObject()) {
final JsonObject mainObj = aJsonElement.getAsJsonObject();

if (JsonUtils.checkTreePath(mainObj, ELEMENT_PROGRAMS)) {
final JsonArray programs = mainObj.get(ELEMENT_PROGRAMS).getAsJsonArray();
programs.forEach(
program -> {
final JsonObject programObject = program.getAsJsonObject();
if (JsonUtils.checkTreePath(programObject, ELEMENT_VIDEOS)) {
programObject
.get(ELEMENT_VIDEOS)
.getAsJsonArray()
.forEach(
filmElement ->
JsonUtils.getAttributeAsString(filmElement.getAsJsonObject(), ATTRIBUTE_PROGRAM_ID)
.ifPresent(result::addProgramId));
}
});
}
}
return result;
}

}
85 changes: 52 additions & 33 deletions src/main/java/mServer/crawler/sender/arte/MediathekArte.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,40 @@
import de.mediathekview.mlib.daten.DatenFilm;
import de.mediathekview.mlib.daten.ListeFilme;
import de.mediathekview.mlib.tool.Log;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import mServer.crawler.CrawlerTool;
import mServer.crawler.FilmeSuchen;
import mServer.crawler.sender.MediathekReader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

public class MediathekArte extends MediathekReader {

/*
* Informationen zu den ARTE-URLs:
* {} sind nur Makierungen, dass es Platzhalter sind, sie gehören nicht zur URL.
*
* Allgemeine URL eines Films: (050169-002-A = ID des Films); (die-spur-der-steine = Titel)
* http://www.arte.tv/de/videos/{050169-002-A}/{die-spur-der-steine}
*
* Alle Sendungen: (Deutsch = DE; Französisch = FR)
* https://api.arte.tv/api/opa/v3/videos?channel={DE}
*
* Informationen zum Film: (050169-002-A = ID des Films); (de für deutsch / fr für französisch)
* https://api.arte.tv/api/player/v1/config/{de}/{050169-002-A}?platform=ARTE_NEXT
*
* Zweite Quelle für Informationen zum Film: (050169-002-A = ID des Films); (de für deutsch / fr für französisch)
* https://api.arte.tv/api/opa/v3/programs/{de}/{050169-002-A}
*
* Hintergrundinfos zum Laden der Filme nach Kategorien im langen Lauf:
* 1. statische Informationen über verfügbare Kategorien laden: URL_STATIC_CONTENT
* 2. für jede Kategorie die Unterkategorien ermitteln: URL_CATEGORY
* 3. für jede Unterkategorie die enthaltenen ProgramId ermitteln: URL_SUBCATEGORY
* 4. für alle ProgramIds die Videoinformationen laden (wie kurze Variante)
* Informationen zu den ARTE-URLs:
* {} sind nur Makierungen, dass es Platzhalter sind, sie gehören nicht zur URL.
*
* Allgemeine URL eines Films: (050169-002-A = ID des Films); (die-spur-der-steine = Titel)
* http://www.arte.tv/de/videos/{050169-002-A}/{die-spur-der-steine}
*
* Alle Sendungen: (Deutsch = DE; Französisch = FR)
* https://api.arte.tv/api/opa/v3/videos?channel={DE}
*
* Informationen zum Film: (050169-002-A = ID des Films); (de für deutsch / fr für französisch)
* https://api.arte.tv/api/player/v1/config/{de}/{050169-002-A}?platform=ARTE_NEXT
*
* Zweite Quelle für Informationen zum Film: (050169-002-A = ID des Films); (de für deutsch / fr für französisch)
* https://api.arte.tv/api/opa/v3/programs/{de}/{050169-002-A}
*
* Hintergrundinfos zum Laden der Filme nach Kategorien im langen Lauf:
* 1. statische Informationen über verfügbare Kategorien laden: URL_STATIC_CONTENT
* 2. für jede Kategorie die Unterkategorien ermitteln: URL_CATEGORY
* 3. für jede Unterkategorie die enthaltenen ProgramId ermitteln: URL_SUBCATEGORY
* 4. für alle ProgramIds die Videoinformationen laden (wie kurze Variante)
*/
private static final Logger LOG = LogManager.getLogger(MediathekArte.class);
private static final String ARTE_API_TAG_URL_PATTERN = "https://api.arte.tv/api/opa/v3/videos?channel=%s&arteSchedulingDay=%s";
Expand All @@ -66,6 +60,8 @@ public class MediathekArte extends MediathekReader {
"CIV", "LGP", "XXE"
};

private static final String COLLECTION_URL = "https://api.arte.tv/api/opa/v3/programs/%s/%s";

private static final DateTimeFormatter ARTE_API_DATEFORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final boolean PARSE_SUBCATEGORY_SUB_PAGES = false; // Flag, ob Unterseiten der Unterkategorien verarbeitet werden soll

Expand Down Expand Up @@ -152,7 +148,7 @@ private void addCategories() {
senderLanguages.forEach((sender, langCode) -> {
for (String subCategory : SUBCATEGORIES) {
String subCategoryUrl = String.format(URL_SUBCATEGORY, langCode.toLowerCase(), subCategory, 1);
listeThemen.add(new String[]{sender, langCode, subCategory, subCategoryUrl});
listeThemen.add(new String[]{sender, langCode, subCategory, subCategoryUrl});
}
});
}
Expand Down Expand Up @@ -209,6 +205,7 @@ private void addFilmeForTag(String sender, String aUrl) {
*/
class CategoryLoader extends Thread {


@Override
public void run() {
try {
Expand All @@ -225,19 +222,27 @@ public void run() {
}

private void loadSubCategory(String sender, String langCode, String aCategory, String aUrl) {
Gson gson = new GsonBuilder().registerTypeAdapter(ArteCategoryFilmsDTO.class, new ArteCategoryFilmListDeserializer()).create();
Gson gson = new GsonBuilder()
.registerTypeAdapter(ArteCategoryFilmsDTO.class, new ArteCategoryFilmListDeserializer())
.create();
Gson gsonCollection = new GsonBuilder()
.registerTypeAdapter(ArteCategoryFilmsDTO.class, new ArteCollectionDeserializer())
.create();

// erste Seite laden
int i = 2;
ArteCategoryFilmsDTO dto = loadSubCategoryPage(gson, sender, aUrl);
if (dto != null) {
loadCollections(sender, langCode, gsonCollection, dto);

ArteCategoryFilmsDTO nextDto = dto;
while (PARSE_SUBCATEGORY_SUB_PAGES && nextDto != null && nextDto.hasNextPage()) {

// weitere Seiten laden und zu programId-liste des ersten DTO hinzufügen
String url = String.format(URL_SUBCATEGORY, langCode.toLowerCase(), aCategory, i);
nextDto = loadSubCategoryPage(gson, sender, url);
if (nextDto != null) {
loadCollections(sender, langCode, gsonCollection, nextDto);
nextDto.getProgramIds().forEach(programId -> dto.addProgramId(programId));
}

Expand All @@ -251,6 +256,20 @@ private void loadSubCategory(String sender, String langCode, String aCategory, S
}
}

private void loadCollections(String sender, String langCode, Gson gson, ArteCategoryFilmsDTO dto) {
dto.getCollectionIds().forEach(collectionId -> {
final String url = String.format(COLLECTION_URL, langCode, collectionId);
try {
final ArteCategoryFilmsDTO collectionDto = ArteHttpClient.executeRequest(sender, LOG, gson, url, ArteCategoryFilmsDTO.class);
if (collectionDto != null) {
collectionDto.getProgramIds().forEach(dto::addProgramId);
}
} catch (Exception e) {
Log.errorLog(894330855, e, url);
}
});
}

private ListeFilme loadPrograms(String sender, String langCode, ArteCategoryFilmsDTO dto) {
ListeFilme listeFilme = new ListeFilme();

Expand Down

0 comments on commit e230651

Please sign in to comment.